Beispiel #1
0
def heat_set_insert(diameter, depth, excess_diameter, excess_depth, taper_angle_degrees = 8, negative_depth=0, negative_diameter=None):
    """
    taper angle is going to specify the deflection off of zero s.t. the diameter is slightly less
    as you move closer to the bottom. The taper angle specifies the slope of the line off of the
    radial axis. The excess parameters are for a smaller hole that collects the melted material, so that it's not the same size as the portion that bonds to the insert.

    negative_depth creates material of exactly diameter but the hole, to create a path to move the insert
    during assembly and provide screwdriver access. If negative_diameter is specified, that's used instead of the insert hole diameter.
    """
    top_radius = diameter / 2.0
    if taper_angle_degrees == 0:
        bottom_radius = diameter / 2.0
    else:
        bottom_radius = diameter/2.0 - tan(taper_angle_degrees * pi / 180) * depth / 2.0
    negative_hole = None
    if negative_depth != 0:
        if negative_diameter is None:
            negative_radius = diameter / 2.0
        else:
            negative_radius = negative_diameter / 2.0
        negative_hole = so.translate((0,0,-negative_depth - 0.01))(so.cylinder(r=negative_radius, h=negative_depth + 0.01))
    insert_hole = so.translate((0,0,-0.01))(so.cylinder(r1=top_radius, r2=bottom_radius, h=depth + 0.01))
    excess_hole = so.translate((0,0,depth - 0.01))(so.cylinder(r=excess_diameter / 2.0, h=excess_depth + 0.01))
    total =  insert_hole + excess_hole
    if negative_hole is not None:
        total += negative_hole
    return total
Beispiel #2
0
def basic_geometry():
    # SolidPython code can look a lot like OpenSCAD code.  It also has
    # some syntactic sugar built in that can make it look more pythonic.
    # Here are two identical pieces of geometry, one left and one right.

    # left_piece uses standard OpenSCAD grammar (note the commas between
    # block elements; OpenSCAD doesn't require this)
    left_piece = union()(translate((-15, 0, 0))(cube([10, 5, 3], center=True)),
                         translate(
                             (-10, 0, 0))(difference()(cylinder(r=5,
                                                                h=15,
                                                                center=True),
                                                       cylinder(r=4,
                                                                h=16,
                                                                center=True))))

    # Right piece uses a more Pythonic grammar.  + (plus) is equivalent to union(),
    # - (minus) is equivalent to difference() and * (star) is equivalent to intersection
    # solid.utils also defines up(), down(), left(), right(), forward(), and back()
    # for common transforms.
    right_piece = right(15)(cube([10, 5, 3], center=True))
    cyl = cylinder(r=5, h=15, center=True) - cylinder(r=4, h=16, center=True)
    right_piece += right(10)(cyl)

    return union()(left_piece, right_piece)
def pulley_arms(height=40, through_screw='m4', arm_width=15, arm_thickness=7.5, pully_width=10, base_width=30, base_thickness=10, spin_clearance=0.5):
    arm_base = so.translate((0,-arm_width/2.0,0))(so.cube((arm_thickness, arm_width, 1)))
    arm = so.hull()(so.translate((0,0,height-arm_width/2.0))(so.rotate((0,90,0))(so.cylinder(r=arm_width/2.0, h=arm_thickness))) + arm_base)
    def arms_xf_left(obj):
        return so.translate(((pully_width + spin_clearance)/2.0,0,0))(obj)
    def arms_xf_right(obj):
        return so.translate((-(pully_width + spin_clearance)/2.0,0,0))(so.rotate((0,0,180))(obj))
    arms = arms_xf_left(arm) + arms_xf_right(arm)
    plate_orig = so.translate((-base_width/2.0,-base_width/2.0,-base_thickness))(so.cube((base_width, base_width, base_thickness)))
    plate = so.hull()(plate_orig, so.translate((0,0,base_thickness/2.0))(arms_xf_left(arm_base)))
    plate += so.hull()(plate_orig, so.translate((0,0,base_thickness/2.0))(arms_xf_right(arm_base)))

    # add mount holes
    spacing = arm_thickness*2.0+pully_width
    bolt_hole = so.rotate((0,90,0))(so.translate((0,0,-spacing))(so.cylinder(r=screw_clearance[through_screw]/2.0, h=spacing*2.0)))
    nut_recess = so.translate((-spacing/2.0,0,0))(so.rotate((0,90,0))(hex(screw_nut[through_screw]['width'], screw_nut[through_screw]['depth'])))
    bolt_hole += nut_recess
    head_recess = so.translate((spacing/2.0,0,0))(so.rotate((0,-90,0))(so.cylinder(r=screw_head_sink[through_screw]['diameter']/2.0, h=screw_head_sink[through_screw]['h'])))
    bolt_hole += head_recess

    arms -= so.translate((0,0,height-arm_width/2.0))(bolt_hole)

    # add base mount hole
    head_recess = so.translate((0,0,-5))(so.cylinder(r=screw_head_sink[through_screw]['diameter']/2.0, h=screw_head_sink[through_screw]['h']*base_thickness))
    bolt_hole = so.translate((0,0,-base_thickness))(so.cylinder(r=screw_clearance[through_screw]/2.0, h=base_thickness*2.0))
    bolt_hole += head_recess

    return arms + plate - bolt_hole
Beispiel #4
0
def multipart_hole():
    # It's good to be able to keep holes empty, but often we want to put
    # things (bolts, etc.) in them.  The way to do this is to declare the
    # object containing the hole a "part".  Then, the hole will remain
    # empty no matter what you add to the 'part'.  But if you put an object
    # that is NOT part of the 'part' into the hole, it will still appear.

    # On the left (not_part), here's what happens if we try to put an object
    # into an explicit hole:  the object gets erased by the hole.

    # On the right (is_part), we mark the cube-with-hole as a "part",
    # and then insert the same 'bolt' cylinder into it.  The entire
    # bolt rematins.

    b = cube(10, center=True)
    c = cylinder(r=2, h=12, center=True)

    # A cube with an explicit hole
    not_part = b - hole()(c)

    # Mark this cube-with-hole as a separate part from the cylinder
    is_part = part()(not_part.copy())

    # This fits in the holes
    bolt = cylinder(r=1.5, h=14, center=True) + up(8)(cylinder(
        r=2.5, h=2.5, center=True))

    # The section of the bolt inside not_part disappears.  The section
    # of the bolt inside is_part is still there.
    return not_part + bolt + right(45)(is_part + bolt)
def lasershim(height):
    """lasershim

    This is a shim which can be used to pad. The base of the shim is in the
    XY plane at quadrant 1. One corner is at the origin. The width is parallel
    to the x-axis.
    The shim can be used if the laserbase is not correctly alligned.
    The laser was provided by Odic Force, productid OFL510-1.

    param: height: defines height shim [mm]
    """
    # PARAMETER
    xdisp = 48.5  # [mm], x-displacement screw
    ydisp = 16  # [mm], y-displacement screws
    r_shaft = 2 + 0.5  # [mm], shaft radius screws
    length = 75  # [mm], x-direction length laser
    width = 30  # [mm], y-direction width laser
    screw_offst = 7  # [mm], screw offset  +x-edge

    # MAXIMAL MATERIAL BASE
    base = cube([length, width, height])
    # screw holes
    screws = cylinder(h=height, r=r_shaft) + right(xdisp)(cylinder(h=height,
                                                                   r=r_shaft))
    spiegel = forward(ydisp / 2)(mirror([0, 1, 0])(back(ydisp / 2)(screws)))
    screws += spiegel
    # create holes
    base -= translate([length - xdisp - screw_offst, (width - ydisp) / 2,
                       0])(screws)
    return base
def screw(r_head, h_head, r_shaft, length, thick=THICK_WALL):
    """screw
    create a hole so a screw can be screwd into the box

    the center of the screw is aligned with the center of the coordinate system
    the screw is oriented as flipped T, i.e. it is standing on its head.
    screws are generated with an enclosing of THICK_WALL mm
    the interior is ensured via the hole function
    it is assumed that r_head > r_shaft
    The height of the head is h_head, an additional r_head-r_r_shaft is added
    to ensure printablity.

    :param r_head: radius of the head of the screw [mm]
    :param h_head: height of the head of the screw [mm]
    :param r_shaft: radius of the shaft of the screw [mm]
    :param length: desired length of the screw [mm]
    """
    h_shaft = length - h_head - (r_head - r_shaft)
    head = cylinder(h=h_head, r=r_head, segments=30)
    # 45 degrees cone for printability
    cone = up(h_head)(cylinder(h=r_head - r_shaft,
                               r1=r_head,
                               r2=r_shaft,
                               segments=30))
    shaft = up(h_head + (r_head - r_shaft))(cylinder(h=h_shaft,
                                                     r=r_shaft,
                                                     segments=30))
    inner = head + cone + shaft
    screw = cylinder(h=length, r=r_head + thick) - hole()(inner)
    return screw
    def slot(r_head, h_head, r_shaft, width, height):
        """slot

        openscad styled vertically oriented printable slot
        origin formed by the center of left circle

        :param r_head: the radius of the top of the screw, [mm]
        :param h_head: the height of the top of the screw, [mm]
        :param r_shaft: the radius of the shaft of the  screw, [mm]
        :param width: the width of the slot, [mm]
        :param height: the height of the slot, [mm]
         """
        h_shaft = height - h_head - (r_head - r_shaft)
        head = cylinder(h=h_head, r=r_head, segments=30)
        # 45 degrees cone for printability
        cone = up(h_head)(cylinder(h=r_head - r_shaft,
                                   r1=r_head,
                                   r2=r_shaft,
                                   segments=30))
        shaft = up(h_head + (r_head - r_shaft))(cylinder(h=h_shaft,
                                                         r=r_shaft,
                                                         segments=30))
        cyl = head + cone + shaft
        inner = hull()(cyl, right(width)(cyl))
        cyl = cylinder(h=height, r=r_head + THICK_WALL)
        outer = hull()(cyl, right(width)(cyl))
        slot = outer - hole()(inner)
        return slot
Beispiel #8
0
def m3_nut():
    hx = cylinder(r=nut_rad, h=nut_height)
    hx.add_param('$fn', 6)  # make the nut hexagonal
    n = difference()(
            hx,
            translate((0, 0, -EPSILON))(
                    cylinder(r=m3_rad, h=nut_height + 2 * EPSILON)
            )
    )
    return n
Beispiel #9
0
def board_cylinder():
    group = cube()  # FIXME: look into empties/children
    for x in [-m.rpi_hole_x_dist / 2, m.rpi_hole_x_dist / 2]:
        for y in [-m.rpi_hole_y_dist / 2, m.rpi_hole_y_dist / 2]:
            c = cylinder(r=m.rpi_cylinder / 2, h=5)

            c2 = up(m.rpi_board_height)(
                cylinder(r=m.rpi_hole / 2 - m.diameter_margin, h=m.rpi_board_height)
            )
            c = c + c2

            group += forward(y)(left(x)(c))

    return group
Beispiel #10
0
def pipe_intersection_no_hole():
    pipe_od = 12
    pipe_id = 10
    seg_length = 30

    outer = cylinder(r=pipe_od, h=seg_length, center=True)
    inner = cylinder(r=pipe_id, h=seg_length + 2, center=True)
    pipe_a = outer - inner

    pipe_b = rotate(a=90, v=FORWARD_VEC)(pipe_a)
    # pipe_a and pipe_b are both hollow, but because
    # their central voids aren't explicitly holes,
    # the union of both pipes has unwanted internal walls

    return pipe_a + pipe_b
def top_bracket(through_screw='m4', chamfer=1, clearance=0.25, bottom_thickness=10, height=30):
    body = bracket(bottom_thickness=bottom_thickness, chamfer=chamfer, height=height, clearance=clearance, through_offsets=[20])
    d = screw_nut[through_screw]['depth'] + 2.5
    nut_recess = so.translate((0,0,bottom_thickness-d))(hex(screw_nut[through_screw]['width'], d+10))

    bolt_hole = so.cylinder(r=screw_clearance[through_screw]/2.0, h=bottom_thickness)
    return body - nut_recess - bolt_hole
def stopper(screw='m4'):
    body = so.cube((40,20,10), center=True)
    nut_recess = hex(screw_nut[screw]['width'], screw_nut[screw]['depth'])
    bolt_hole = so.translate((0,0,-10))(so.cylinder(r=screw_clearance[screw]/2.0, h=20))
    nut_slide = so.translate((0,-screw_nut[screw]['width']/2.0))(so.cube((20, screw_nut[screw]['width'], screw_nut[screw]['depth'])))
    nut_attachment = so.rotate((0,-90,-90))(so.translate((0,0,-screw_nut[screw]['depth']/2.0))(nut_slide + nut_recess) + bolt_hole)
    return body - so.rotate((0,0,180))(so.translate((0,-13,-10))(expand_for_fit(0.3)(rail_section(20)))) - so.translate((0,-5,0))(nut_attachment)
Beispiel #13
0
def doohickey():
    hole_cyl = translate(
        (0, 0, -EPSILON))(cylinder(r=m3_rad, h=doohickey_h + 2 * EPSILON))
    d = difference()(cube([30, 10, doohickey_h], center=True),
                     translate((-10, 0, 0))(hole_cyl), hole_cyl,
                     translate((10, 0, 0))(hole_cyl))
    return d
Beispiel #14
0
def top_part():
    maze_path = os.path.join(os.path.dirname(__file__), 'maze7.png')

    depth_map = build_depth_map(maze_path)

    d = difference()
    u = union()
    u.add(bumpMapCylinder(depth_map, innerR, hn, 0, 255))
    u.add(cylinder(r=innerR + wall + gap, h=gripH))
    d.add(u)
    d.add(intersection().add(
        bumpMapCylinder(depth_map, innerR, hn + 2, wall,
                        0).set_modifier("")).add(
                            translate((0, 0, baseH)).add(
                                cylinder(r=innerR + 2 * wall,
                                         h=h * 1.1).set_modifier(""))))
    return d
def split_lock(diameter, thickness=3, depth=40, lip=10, chamfer=1, gap=2, screw='m4', shape='circle'):
    lip_part = so.translate((diameter/2.0,-thickness/2.0,0))(so.cube((lip,thickness,depth)))
    if shape == 'circle':
        hole = so.cylinder(r=diameter/2.0, h=depth*2)
        brace = so.cylinder(r=diameter/2.0+thickness, h=depth)
    elif shape == 'square':
        hole = so.rotate((0,0,45))(so.translate((-diameter/2.0,-diameter/2.0,0))(so.cube((diameter,diameter,depth*2))))
        brace = so.rotate((0,0,45))(so.translate((-diameter/2.0-thickness,-diameter/2.0-thickness,0))(so.cube((2*thickness+diameter,2*thickness+diameter,depth))))
    holder = so.translate((0,depth/2.0,0))(chamfer_hull(x=True,y=True)(so.rotate((90,0,0))(brace + lip_part)) - so.hole()(so.translate((0,depth/2.0,0))(so.rotate((90,0,0))(hole))))

    split = so.translate((0, -depth/2.0-chamfer, -gap/2.0))(so.cube((thickness + diameter + lip,depth+chamfer*2,gap)))
    split_nut_recess = so.translate((0,0,chamfer))(hex(screw_nut[screw]['width'], screw_nut[screw]['depth']))
    split_nut_slide = so.translate((0,-screw_nut[screw]['width']/2, chamfer))(so.cube((thickness + diameter, screw_nut[screw]['width'], screw_nut[screw]['depth'])))
    split_bolt_hole = so.translate((0,0,-thickness*2-chamfer))(so.cylinder(r=screw_clearance[screw]/2.0, h=100))
    split_head_recess = so.translate((0,0,-diameter-thickness*2.5))(so.cylinder(r=screw_head_sink[screw]['diameter']/2.0, h=diameter+thickness))
    split_tensioner = so.translate(((diameter+lip)/2.0,0,thickness/2.0+chamfer))(split_nut_recess + split_bolt_hole + split_nut_slide + split_head_recess)
    return holder - split - so.hole()(split_tensioner)
def carriage_plate(dims=(49, 42, 10), chamfer=1, screw_thickness=8, arm_screw='m4', arm_mount_dist=20):
    (x,y,z) = dims
    plate = so.translate((0,0,chamfer+z/2.0))(chamfer_hull(x=True,y=True,z=True)(so.cube(dims, center=True)))
    head_recess = so.translate((0,0,3))(so.cylinder(r=screw_head_sink['m3']['diameter']/2.0, h=screw_head_sink['m3']['h']*z))
    bolt_hole = so.translate((0,0,-z))(so.cylinder(r=screw_clearance['m3']/2.0, h=z*3.0))
    for m in [1,-1]:
        for t in [True, False]:
            x,y = (m,0)
            if t:
                x,y=y,x
            plate -= so.translate((y*41.0/2,x*34.5/2,0))(bolt_hole + head_recess)

    head_recess = so.cylinder(r=screw_head_sink[arm_screw]['diameter']/2.0, h=screw_head_sink[arm_screw]['h']+1)
    bolt_hole = so.cylinder(r=screw_clearance[arm_screw]/2.0, h=z+2*chamfer)
    mount_hole = head_recess + bolt_hole

    return plate - so.translate((arm_mount_dist/2.0,0,0))(mount_hole) - so.translate((-arm_mount_dist/2.0,0,0))(mount_hole)
Beispiel #17
0
def boxmount():
    base = cube([30, 50, 2])
    circ = cylinder(h=10, r=1.6, segments=30)
    circs = right(5)(circ) + right(25)(circ)
    base -= forward(5)(circs)
    base -= forward(25)(circs)
    base -= forward(45)(circs)
    base = rotate([90, 0, 90])(base)
    return base
Beispiel #18
0
def m3_12():
    bolt_height = 12
    m = union()(
            head(),
            translate((0, 0, -bolt_height))(
                    cylinder(r=m3_rad, h=bolt_height)
            )
    )
    return m
def hex(width, h, fillet_radius = 0.1):
    """
    width is the distance between opposing flat sides
    """
    r = width/2.0/cos(pi/6.0) # magic so that we have the width b/w flat faces instead of corners
    pole = so.translate((r - fillet_radius, 0, 0))(so.cylinder(r=fillet_radius, h=h))
    body = pole
    for i in range(1,6):
        body += so.rotate((0,0,60 * i))(pole)
    return so.hull()(body)
Beispiel #20
0
def assembly():
    pts = [(0, -1, 0),
           (1, 0, 0),
           (0, 1, 0),
           (-1, 0, 0),
           (-1, -1, 0)]

    a = thread(pts, inner_rad=10, pitch=6, length=2, segments_per_rot=31,
               neck_in_degrees=30, neck_out_degrees=30)

    return a + cylinder(10 + EPSILON, 2)
Beispiel #21
0
def pipe_intersection_hole():
    pipe_od = 12
    pipe_id = 10
    seg_length = 30

    outer = cylinder(r=pipe_od, h=seg_length, center=True)
    inner = cylinder(r=pipe_id, h=seg_length + 2, center=True)

    # By declaring that the internal void of pipe_a should
    # explicitly remain empty, the combination of both pipes
    # is empty all the way through.

    # Any OpenSCAD / SolidPython object can be declared a hole(),
    # and after that will always be empty
    pipe_a = outer + hole()(inner)
    # Note that "pipe_a = outer - hole()(inner)" would work identically;
    # inner will always be subtracted now that it's a hole

    pipe_b = rotate(a=90, v=FORWARD_VEC)(pipe_a)
    return pipe_a + pipe_b
Beispiel #22
0
def sidewall_clamp(): # my wood is 19.5mm wide and 38.6mm tall
    body = chamfer_hull(z=True, y=True)(so.cube((20, thickness, height)))
    body += chamfer_hull(z=True, y=True, x=[1])(so.translate((19,0,0))(so.cube((1, thickness, height))) + so.translate((50,-thickness*0.25,0))(so.cube((10, thickness*1.5, 45))))
    wood_cavity = so.translate((20,0,5))(so.cube((100,19.5,38.6)))
    body -= wood_cavity
    insert = so.rotate((0,90,0))(m3_heatset_insert_hole)
    for i in range(1,4):
        body -= so.translate((0,thickness/2.0,height/4.0*i))(insert)
        body -= so.translate((depth,thickness/2.0,height/4.0*i))(so.rotate((0,0,180))(insert))
    nut_recess = so.translate((54,-5,15))(so.rotate((90,30,0))(hex(screw_nut['m3']['width'], screw_nut['m3']['depth'])))
    screw_recess = so.translate((54,22.4+5,15))(so.rotate((90,0,0))(so.cylinder(screw_head_sink['m3']['diameter']/2.0, screw_nut['m3']['depth'])))
    screw_hole = so.translate((54,22.4+10,15))(so.rotate((90,0,0))(so.cylinder(screw_clearance['m3']/2.0, 100)))
    screw_capture = nut_recess + screw_recess + screw_hole
    def add_screw(x,y):
        nonlocal body
        body -= so.translate((-x,0,y))(screw_capture)
    add_screw(0,0)
    add_screw(0,17)
    add_screw(17/2.0,17/2.0)
    return body
def double_side_rail(h, bottom_thickness=10, holes=None):
    section = so.translate((0,5,0))(rail_section(h))
    stack = section + so.rotate((0,0,180))(section) + so.translate((-8,-5,0))(so.cube((16,10,h)))
    if holes is not None:
        bolt_hole = so.rotate((0,90,0))(so.translate((0,0,-40))(so.cylinder(r=screw_clearance[holes]/2.0, h=80)))
        def mkhole(offset):
            nonlocal stack
            stack -= so.translate((0,0,offset))(bolt_hole)
        mkhole(20-bottom_thickness)
        mkhole(40-bottom_thickness)
        mkhole(h-10)
    return stack
Beispiel #24
0
    def test_hole_transform_propagation(self):
        # earlier versions of holes had problems where a hole
        # that was used a couple places wouldn't propagate correctly.
        # Confirm that's still happening as it's supposed to
        h = hole()(rotate(a=90, v=[0, 1, 0])(cylinder(2, 20, center=True)))

        h_vert = rotate(a=-90, v=[0, 1, 0])(h)

        a = cube(10, center=True) + h + h_vert
        expected = '\n\ndifference(){\n\tunion() {\n\t\tcube(center = true, size = 10);\n\t\trotate(a = -90, v = [0, 1, 0]) {\n\t\t}\n\t}\n\t/* Holes Below*/\n\tunion(){\n\t\trotate(a = 90, v = [0, 1, 0]) {\n\t\t\tcylinder(center = true, h = 20, r = 2);\n\t\t}\n\t\trotate(a = -90, v = [0, 1, 0]){\n\t\t\trotate(a = 90, v = [0, 1, 0]) {\n\t\t\t\tcylinder(center = true, h = 20, r = 2);\n\t\t\t}\n\t\t}\n\t} /* End Holes */ \n}'
        actual = scad_render(a)
        self.assertEqual(expected, actual)
Beispiel #25
0
def bottom_part():
    top = difference()
    u = union()
    u2 = union()
    top.add(u)
    d = difference()
    d.add(cylinder(r=innerR + wall + gap, h=toph))
    d.add(translate((0, 0, baseH)).add(cylinder(r=innerR + gap, h=toph)))
    u.add(d)
    top.add(u2)
    for i in range(0, 3):
        a = i * 2 * pi / 3
        r = innerR + gap + wall / 2
        u.add(
            translate(((r - 0.3) * cos(a), (r - 0.3) * sin(a),
                       toph - 6)).add(sphere(r=2.4)))
        u2.add(
            translate(((r + wall - 0.3) * cos(a), (r + wall - 0.3) * sin(a),
                       toph - 6)).add(sphere(r=2.4)))

    return top
Beispiel #26
0
    def slot(radius, height, width):
        """slot

        openscad styled vertically oriented printable slot
        origin formed by the center of the left circle

        :param radius: the radius of the top of the screw
        :param height: the height of the slot
        :param width: the width of the slot, i.e. distance between radii
        """
        cyl = cylinder(h=height, r=radius)
        outer = hull()(cyl, right(width)(cyl))
        return outer
def assembly():
    section = screw_thread.default_thread_section(tooth_height=10,
                                                  tooth_depth=5)
    s = screw_thread.thread(outline_pts=section,
                            inner_rad=inner_rad,
                            pitch=screw_height,
                            length=screw_height,
                            segments_per_rot=SEGMENTS,
                            neck_in_degrees=90,
                            neck_out_degrees=90)

    c = cylinder(r=inner_rad, h=screw_height)
    return s + c
Beispiel #28
0
def basewall(passive=False):
    body = chamfer_hull(z=True, y=True, x=[-1])(so.cube((thickness, width, height)))
    m3_hole = so.translate((thickness + 1.0 ,0,0))(so.rotate((0,-90,0))(so.cylinder(r=screw_clearance['m3']/2.0, h=m3_support_depth) + so.translate((0,0,m3_support_depth))(so.cylinder(r=screw_head_sink['m3']['diameter']/2.0, h=thickness+2.0-m3_support_depth))))
    for i in range(1,4):
        body -= so.translate((0,thickness/2.0,height/4.0*i))(m3_hole)
        body -= so.translate((0,width-thickness/2.0,height/4.0*i))(m3_hole)
    shaft_hole = so.cylinder(r=39.0/2+0.05, h=10) + so.cylinder(r=15.2/2+0.3, h=thickness+2)
    for i in [0,90,180,270]:
        shaft_hole += so.rotate((0,0,i))(so.translate((19.5,0,0))(so.cylinder(r=2, h=thickness+2)))
    shaft_hole = so.rotate((0,-90,0))(shaft_hole)
    servo_offset = 75
    servo_vertical_offset = 8
    servo_shaft_offset = 9.7
    gear_spacing = 50
    gear_angle = 0.75
    for offset in [servo_offset - gear_spacing * cos(gear_angle), 110, 155, 200]:
        body -= so.translate((thickness + 1, offset, servo_vertical_offset + servo_shaft_offset + gear_spacing * sin(gear_angle)))(shaft_hole)
    if not passive:
        body -= so.translate((-1, servo_offset, servo_vertical_offset))(servo_mount())
    if passive:
        body = so.mirror((1,0,0))(body)
    return body
def iron_holder(thickness=20, depth=40, length=45, iron_diameter=20.5, chamfer=1, iron_holder_thickness=5,arm_screw='m4', arm_mount_dist=20, gap=5, split_screw='m4', cup_diameter=30, cup_thickness=5):
    arm = chamfer_hull(x=True,y=True,z=[1])(so.translate((-thickness/2.0, -depth/2.0, 0))(so.cube((thickness,depth,length + cup_diameter))))
    
    counterweight_cup = so.translate((0,depth/2.0,length-cup_thickness))(chamfer_hull(x=True,y=True)(so.rotate((90,0,0))(so.cylinder(r=cup_diameter/2.0+cup_thickness, h=depth))) - so.hole()(so.translate((0,depth/2.0-cup_thickness,0))(so.rotate((90,0,0))(so.cylinder(r=cup_diameter/2.0, h=depth)))))
    holder = so.translate((0,0,cup_diameter+length))(so.rotate((0,-90,0))(split_lock(iron_diameter, thickness=iron_holder_thickness, depth=depth, lip=10, chamfer=chamfer, gap=gap, screw=split_screw)))

    rope_tie = so.translate((0,depth/2.0+chamfer,length/2.0-iron_holder_thickness))(so.rotate((-90,90,0))(arch()))

    nut_recess = hex(screw_nut[arm_screw]['width'], screw_nut[arm_screw]['depth'])
    bolt_hole = so.cylinder(r=screw_clearance[arm_screw]/2.0, h=10)
    nut_slide = so.translate((0,-screw_nut[arm_screw]['width']/2.0))(so.cube((thickness, screw_nut[arm_screw]['width'], screw_nut[arm_screw]['depth'])))
    nut_attachment = so.translate((0,0,5))(nut_slide + nut_recess) + bolt_hole
    plate_install_holes = so.translate((0,0,-0.1))(carraige_plate_install_holes(diameter=4.95))
    return counterweight_cup + arm + holder - so.translate((0,arm_mount_dist/2.0,0))(nut_attachment) - so.translate((0,-arm_mount_dist/2.0,0))(nut_attachment) + rope_tie - plate_install_holes
Beispiel #30
0
def ueyeholder():
    """ueyeholder
    creates a holder for an ueye camera

    A holder for an uEye camera to view upward.
    The uEye camera cannot look upward due its connector on the back.
    This design solves this problem via a cubical enclosure.
    """
    #### UEYE cubical dimension
    margin = 0.3
    size_x = 34  # mm
    size_y = 32  # mm
    size_z = 34.6  # mm
    ### UEYE screw
    screw_d = 3  # mm
    screw_z = 30.4  # sep z-direction
    screw_z -= screw_d
    screw_ytop = 19.8  # mm
    screw_ytop -= screw_d
    screw_ybottom = 21.8
    screw_ybottom -= screw_d
    screw_zoff = 1.3 + screw_d / 2
    connector_z = 18  # mm
    connector_x = 16.2  # mm
    ####
    # box
    # camera is pushed in from bottom
    holder = cube([
        size_x + 2 * THCKW + margin, size_y + 2 * THCKW + margin,
        size_z + THCKW + connector_z + margin
    ])
    holder -= translate([THCKW, THCKW, THCKW])(cube([
        size_x + margin, size_y + margin, size_z + THCKW + connector_z + margin
    ]))
    # 4 screw holes
    socket = cylinder(h=size_x + 2 * THCKW, r=screw_d / 2, segments=SGM)
    socket = rotate([0, 90, 0])(socket)
    sockets = socket + forward(screw_ybottom)(socket)
    temp = (screw_ytop - screw_ybottom) * 0.5
    sockets += up(screw_z)(back(temp)(socket) +
                           forward(screw_ytop - temp)(socket))
    # substraction prep sockets
    holder -= translate([
        0, (size_y - screw_ybottom) * 0.5 + THCKW + 0.5 * margin,
        screw_zoff + THCKW + connector_z + 0.5 * margin
    ])(sockets)
    # space connector
    holder -= translate([THCKW + 0.5 * (size_x - connector_x), 0, THCKW])(cube(
        [connector_x, THCKW, size_z + THCKW + connector_z]))
    return holder