OpenFlexure Microscope OpenSCAD docs
libs/wall.scad
- *
- OpenFlexure Microscope: Microscope body wall *
- *
- This defines utility functions to create the "wall" around the *
- main body of the microscope. *
- *
- (c) Richard Bowman, January 2016 *
- Released under the CERN Open Hardware License *
- *
module add_hull_base(h=1)
[Source]
module add_hull_base(h=1){ // Take the convex hull of some objects, and add it in as a // thin layer at the bottom union(){ intersection(){ hull(){ children(); } cylinder(r=999, $fn=8, h=h); //make the base thin } children(); } }
module add_roof(inner_h)
[Source]
module add_roof(inner_h){ // Take the convex hull of some objects, and add the top // of it as a roof. NB you must specify the height of // the underside of the roof - finding it automatically // would be too much work... union(){ difference(){ hull(){ children(); } cylinder(r=999, $fn=8, h=inner_h); } children(); } }
module wall_vertex(r=undef, h=undef, x_tilt=0, y_tilt=0)
[Source]
module wall_vertex(r=undef, h=undef, x_tilt=0, y_tilt=0){ // A cylinder, rotated by the given angles about X and Y, // but with the top and bottom kept in the XY plane // (i.e. it's sheared rather than tilted). These form the // stiffening "wall" that runs around the base of // the legs radius = if_undefined_set_default(r, microscope_wall_t()/2); height = if_undefined_set_default(h, actuator_wall_h()); sparse_matrix_transform(xz=tan(y_tilt), yz=-tan(x_tilt)){ cylinder(r=radius, h=height, $fn=8); } }
module inner_wall_vertex(params, leg_angle, x, h, thick=false)
[Source]
module inner_wall_vertex(params, leg_angle, x, h, thick=false){ // A thin cylinder, close to one of the legs. It // tilts inwards to clear the leg. These form the // corners of the stiffening "wall" that runs around // the base of the legs // leg_angle specifies which leg the wall is for // (the legs are at +/-45 and +/-150 deg) // x is the X position before rotation through leg_angle // h is the wall height. // If thick = true then the wall is double thickness. // unless specified, tilt the leg so the wall at the // edge is vertical (i.e. the bit at 45 degrees to // the leg frame) y_tilt = x>0?6:-6; r = thick ? microscope_wall_t() : microscope_wall_t()/2; y=-flex_dims().y-r; leg_frame(params, leg_angle){ translate([x,y,0]){ wall_vertex(r=r,h=h,x_tilt=6,y_tilt=y_tilt); } } }
module inner_wall_base_corner(params, leg_angle, x, y_inset)
[Source]
module inner_wall_base_corner(params, leg_angle, x, y_inset){ // This is a 2D circle at the base of the angled cylinders that // are defined by inner_wall_vertex(). // It is used to define the central optics cut-out under the stage. // leg_angle specifies which leg the wall is for // (the legs are at +/-45 and +/-150 deg) // x is the X position before rotation through leg_angle // h is the wall height. // If thick = true then the wall is double thickness. r = microscope_wall_t()/2; leg_r = key_lookup("leg_r", params); rotate_z(leg_angle){ translate([x, leg_r-y_inset, 0]){ circle(r=r, $fn=6); } } }
module z_bridge_wall_vertex(params)
[Source]
module z_bridge_wall_vertex(params){ // This is the vertex of the "inner wall" nearest the // new (cantilevered) Z axis. inner_wall_vertex(params, 45, leg_outer_w(params)/2+microscope_wall_t()/2, inner_wall_h(params)); }
function mounting_lug_wall_vertex_position(params)
[Source]
function mounting_lug_wall_vertex_position(params) = [-back_lug_x_pos(params)-microscope_wall_t()/2, -microscope_wall_t()/2, 0];
function outer_wall_tilt(params)
[Source]
function outer_wall_tilt(params) = atan(microscope_wall_t()/inner_wall_h(params));
module mounting_lug_wall_vertex(params)
[Source]
module mounting_lug_wall_vertex(params){ // This is the vertex of the supporting wall nearest // to the Z anchor - it doesn't make sense to use the // function above as it's got the wrong symmetry. // We also use this in a few places so it's worth saving //this is on the y_side it is reflected for the z_side translate(mounting_lug_wall_vertex_position(params)){ wall_vertex(h=inner_wall_h(params), y_tilt=outer_wall_tilt(params)); } }
function y_actuator_wall_vertex_position(params, inside=true)
[Source]
function y_actuator_wall_vertex_position(params, inside=true) = let( tansverse_distance = actuator_housing_xy_size().x/2 - microscope_wall_t()/2, x_sign = inside? 1 : -1 ) y_actuator_pos(params) + [x_sign, x_sign, 0]*tansverse_distance/sqrt(2);
module y_actuator_wall_vertex(params, inside=true)
[Source]
module y_actuator_wall_vertex(params, inside=true){ // A wall vertex for the y actuator. x=-1,1 picks the side // of the actuator where the vertex is placed. y_tilt = inside ? 0 : outer_wall_tilt(params); translate(y_actuator_wall_vertex_position(params, inside)){ wall_vertex(y_tilt=y_tilt); } }
module z_actuator_wall_vertex(params, front=true)
[Source]
module z_actuator_wall_vertex(params, front=true){ if (front){ y_tr = z_nut_y(params)+actuator_housing_xy_size().y/2-microscope_wall_t()/2; translate_y(y_tr){ wall_vertex(); } } else{ x_tr = -(z_anchor_w()/2+microscope_wall_t()/2+1); y_tr = z_anchor_y() + 1; translate([x_tr, y_tr, 0]){ wall_vertex(); } } }
module wall_inside_xy_stage(params)
[Source]
module wall_inside_xy_stage(params){ // First, go around the inside of the legs, under the stage. // This starts at the Z nut seat. I've split it into two // blocks, because the shape is not convex so the base // would be bigger than the walls otherwise. reflect_x(){ sequential_hull(){ mirror([1,0,0]){ z_bridge_wall_vertex(params); } wall_h = inner_wall_h(params); //radius on which wall sits. wall_rad = leg_outer_w(params)/2; wall_rad_thick = leg_outer_w(params)/2-microscope_wall_t()/2; z_bridge_wall_vertex(params); inner_wall_vertex(params, 45, -wall_rad, wall_h); mounting_lug_wall_vertex(params); inner_wall_vertex(params, 135, wall_rad, wall_h); //The wall that has the reflection illumination cut-out is double //thickness to improve stiffness inner_wall_vertex(params, 135, -wall_rad_thick, wall_h, thick=true); inner_wall_vertex(params, -135, wall_rad_thick, wall_h, thick=true); } } }
module wall_outside_xy_actuators(params)
[Source]
module wall_outside_xy_actuators(params){ // Add the wall from the XY actuator column to the middle sequential_hull(){ mounting_lug_wall_vertex(params); // anchor at the same angle on the actuator // NOTE: the base of the wall is outside the base of the // actuator housing y_actuator_wall_vertex(params, inside=false); } }
module wall_inside_xy_actuators(params)
[Source]
module wall_inside_xy_actuators(params){ // Connect the Z anchor to the XY actuators hull(){ z_actuator_wall_vertex(params, front=false); y_actuator_wall_vertex(params); } }
module wall_between_actuators(params, y_actuator=true)
[Source]
module wall_between_actuators(params, y_actuator=true){ // link the actuators together if (y_actuator){ hull(){ y_actuator_wall_vertex(params); z_actuator_wall_vertex(params, front=true); } } else{ //for the x actuator wall mirror the same function mirror([1,0,0]){ wall_between_actuators(params); } } }
module central_optics_cut_out_projection(params)
[Source]
module central_optics_cut_out_projection(params) { // A 2D shape for the central cut-out for the optics. // The form is based on wall_inside_xy_stage(), stepped in to leave a strengthening flange // First, go around the inside of the legs, under the stage. // This starts at the Z nut seat. // A 'zero' inset is needed to get from the position of the inner corners of the legs to just inside the walls. inset_zero = flex_dims().y + microscope_wall_t()*2; // a small flange inset from the wall by the z-axis, to make it clear the optics dovetail inset_at_z = inset_zero + 1; // a larger flange inset at the sides for strength flange_side = 5; inset_sides = inset_zero + flange_side; // even larger flange at the reflection optics cut-out inset_opposite = inset_zero + 6; hull(){ reflect_x(){ // A small correction translation to match the shape by the z-dovetail in versions up to v7.0.0-beta4 // This is needed because the central optics cutout determines the shape of the z-dovetail body on the actuator side correction_1 = [1.175, -0.157, 0]; translate(correction_1){ inner_wall_base_corner(params, 45, leg_outer_w(params)/2+microscope_wall_t()/2, y_inset=inset_at_z); } //radius on which wall sits. wall_rad = leg_outer_w(params)/2; wall_rad_thick = leg_outer_w(params)/2-microscope_wall_t()/2; inner_wall_base_corner(params, 45, x=-wall_rad, y_inset=inset_sides); // mounting_lug_wall_vertex_position(params) is negative mounting_lug_cutout_vertex_position = (-mounting_lug_wall_vertex_position(params).x) - microscope_wall_t()/2 - flange_side; translate_x(mounting_lug_cutout_vertex_position){ circle(r=microscope_wall_t()/2, $fn=6); } inner_wall_base_corner(params, 135, x=wall_rad, y_inset=inset_sides); // A small correction translation to match the shape by the reflection optics cutout in versions up to v7.0.0-beta4, for compatibility correction_2 = [-2.05, 1.76, 0]; translate(correction_2){ //More offset near the reflection optics cut out to improve stiffness inner_wall_base_corner(params, 135, x=-wall_rad_thick, y_inset=inset_opposite); } } } }
function y_wall_angle(params)
[Source]
function y_wall_angle(params) = let( wall_start = mounting_lug_wall_vertex_position(params), wall_end = y_actuator_wall_vertex_position(params, inside=false), wall_disp = wall_end - wall_start ) atan(wall_disp.y/wall_disp.x);
function side_housing_h(params)
[Source]
function side_housing_h(params) = y_motor_z_pos(params) + motor_bracket_h();
function housing_size(h)
[Source]
function housing_size(h) = [motor_connector_size().x+4+2,motor_connector_size().y+4+2+15.5, h];
module side_housing_placement(params)
[Source]
module side_housing_placement(params){ translate(y_actuator_wall_vertex_position(params, inside=false)){ rotate_z(y_wall_angle(params)-90){ children(); } } }
module side_housing(params, h=undef, cavity_h=undef, attach=true, screw_hole_type="none")
[Source]
module side_housing(params, h=undef, cavity_h=undef, attach=true, screw_hole_type="none"){ //attach: whether the housing it attached to the wall actuator_h = key_lookup("actuator_h", params); wall_h = is_undef(cavity_h) ? side_housing_h(params) : h; c_h = is_undef(cavity_h) ? wall_h+1 : cavity_h; shaft_z = motor_shaft_pos(actuator_h+xy_actuator_travel(params)).z; outer_r = 6; inner_r = 1; outer_x_pos = housing_size(wall_h).x - outer_r; difference(){ hull(){ side_housing_placement(params){ translate([outer_x_pos, outer_r+1.5, 0]){ cylinder(r=outer_r,h=wall_h); } translate([outer_x_pos, housing_size(wall_h).y-outer_r, 0]){ cylinder(r=outer_r,h=wall_h); } cylinder(r=inner_r,h=wall_h); translate_y(housing_size(wall_h).y){ cylinder(r=inner_r,h=wall_h); } } if(attach){ mounting_lug_wall_vertex(params); y_actuator_wall_vertex(params, inside=false); } } side_housing_cutout(params, h=c_h, screw_hole_type=screw_hole_type); translate(y_actuator_pos(params) + [0, 0, shaft_z-1.5]){ cylinder(d=30, h=80); } } }
function side_housing_cut_pos()
[Source]
function side_housing_cut_pos() = [2, 6, 0];
function side_housing_cut_size(h)
[Source]
function side_housing_cut_size(h) = [motor_connector_size().x+2, motor_connector_size().y+2, h];
function side_housing_screw_pos()
[Source]
function side_housing_screw_pos() = let( screw_hole_offset = 7.5, housing_cut_size = side_housing_cut_size(h=0), screw_location = [housing_cut_size.x/2, housing_cut_size.y + screw_hole_offset, 0] ) screw_location;
module side_housing_cutout(params, h, screw_hole_type="none")
[Source]
module side_housing_cutout(params, h, screw_hole_type="none"){ housing_cut_size = side_housing_cut_size(h=h+1); screw_hole_depth = 6.5; screw_location = side_housing_screw_pos(); side_housing_placement(params){ translate(side_housing_cut_pos()){ translate_z(-1){ cube(housing_cut_size); } // Cut holes for no 2 self tap screws if (screw_hole_type == "pilot"){ translate(screw_location){ translate_z(h-screw_hole_depth){ no2_selftap_hole(h=screw_hole_depth+tiny()); } } } else if (screw_hole_type == "counterbore"){ translate(screw_location){ translate_z(1.5){ no2_selftap_counterbore(tight=true); } } } } } }
module place_on_wall(params, is_y=true, housing=true)
[Source]
module place_on_wall(params, is_y=true, housing=true){ // The wall runs from the outside y actuator wall vertex to the // mounting lug wall vertex y_wall_start = mounting_lug_wall_vertex_position(params); wall_start = is_y ? y_wall_start : [-y_wall_start.x, y_wall_start.y, y_wall_start.z]; wall_angle = is_y ? y_wall_angle(params) : - y_wall_angle(params); wall_tr_y = housing ? -housing_size(0).x : -microscope_wall_t()/2; wall_tilt = housing ? 0 : outer_wall_tilt(params); // pivot about the starting corner of the wall so X is along it translate(wall_start){ rotate(wall_angle){ // move out to the surface (the above are centres of cylinders) translate_y(wall_tr_y){ // and then align y with the vertical axis of the wall rotate_x(90-wall_tilt){ // now X and Y are in the plane of the wall, and z=0 is its surface. children(); } } } } }