165 lines
5.5 KiB
Python
165 lines
5.5 KiB
Python
"""Modeled bolts, threaded fasteners, and joint bushings for Example 18."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import simplecadapi as scad
|
|
|
|
from leg_common import make_part_with_connectors_rpart
|
|
from leg_dimensions import KNEE_AXIS
|
|
|
|
|
|
def make_socket_head_screw_rpart(
|
|
*,
|
|
part_id: str,
|
|
shank_radius: float,
|
|
shank_length: float,
|
|
head_radius: float,
|
|
head_height: float,
|
|
material: scad.Material,
|
|
) -> scad.Part:
|
|
"""Create a socket-head screw with its seat plane at local Z=0."""
|
|
|
|
shank = scad.make_cylinder_rsolid(
|
|
radius=shank_radius,
|
|
height=shank_length,
|
|
bottom_face_center=(0.0, 0.0, -head_height - shank_length),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
head = scad.make_cylinder_rsolid(
|
|
radius=head_radius,
|
|
height=head_height,
|
|
bottom_face_center=(0.0, 0.0, -head_height),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
screw = scad.union_rsolid(shank, head, glue=False)
|
|
screw = scad.apply_tag(shape=screw, tag="role.socket_head_screw")
|
|
return make_part_with_connectors_rpart(
|
|
part_id=part_id,
|
|
body=screw,
|
|
name=f"Socket-head screw {shank_radius * 2.0:.1f} x {shank_length:.1f} mm",
|
|
material=material,
|
|
connectors=(("head_top_axis", (0.0, 0.0, 0.0), "z", "Flush screw head top plane"),),
|
|
)
|
|
|
|
|
|
def make_clamp_bolt_stack_rpart(*, material: scad.Material) -> scad.Part:
|
|
"""Create an M4 bolt plus flange-nut stack for a split collar."""
|
|
|
|
shank_length = 12.2
|
|
shank = scad.make_cylinder_rsolid(
|
|
radius=2.0,
|
|
height=shank_length,
|
|
bottom_face_center=(0.0, 0.0, -shank_length),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
head = scad.make_cylinder_rsolid(
|
|
radius=3.6,
|
|
height=3.2,
|
|
bottom_face_center=(0.0, 0.0, -0.05),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
nut = scad.make_cylinder_rsolid(
|
|
radius=3.8,
|
|
height=3.2,
|
|
bottom_face_center=(0.0, 0.0, -shank_length - 3.15),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
stack = scad.union_rsolid(shank, head, nut, glue=False)
|
|
stack = scad.apply_tag(shape=stack, tag="role.clamp_bolt_and_nut")
|
|
return make_part_with_connectors_rpart(
|
|
part_id="m4_split_clamp_bolt_stack",
|
|
body=stack,
|
|
name="M4 split-clamp socket bolt and flange nut",
|
|
material=material,
|
|
connectors=(("seat_axis", (0.0, 0.0, 0.0), "z", "Clamp bolt head seat"),),
|
|
)
|
|
|
|
|
|
def make_knee_bushing_rpart(*, material: scad.Material) -> scad.Part:
|
|
"""Create a continuous bronze knee sleeve and axial spacer."""
|
|
|
|
outer = scad.make_cylinder_rsolid(
|
|
radius=5.95,
|
|
height=13.0,
|
|
bottom_face_center=(KNEE_AXIS[0], KNEE_AXIS[1], 0.0),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
bore = scad.make_cylinder_rsolid(
|
|
radius=3.2,
|
|
height=15.0,
|
|
bottom_face_center=(KNEE_AXIS[0], KNEE_AXIS[1], -1.0),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
sleeve = scad.cut_rsolid(outer, bore, skip_non_intersecting=False)
|
|
sleeve = scad.apply_tag(shape=sleeve, tag="role.knee_bearing_bushing")
|
|
return make_part_with_connectors_rpart(
|
|
part_id="knee_bronze_bushing",
|
|
body=sleeve,
|
|
name="12 mm OD bronze knee bushing and spacer",
|
|
material=material,
|
|
connectors=(
|
|
("knee_axis", (KNEE_AXIS[0], KNEE_AXIS[1], 6.5), "z", "Knee revolute axis"),
|
|
("bolt_head_top_axis", (KNEE_AXIS[0], KNEE_AXIS[1], 16.0), "z", "Shoulder bolt head top plane"),
|
|
),
|
|
)
|
|
|
|
|
|
def make_knee_shoulder_bolt_stack_rpart(*, material: scad.Material) -> scad.Part:
|
|
"""Create the knee shoulder axle, socket head, and retained nut."""
|
|
|
|
shaft = scad.make_cylinder_rsolid(
|
|
radius=3.0,
|
|
height=13.0,
|
|
bottom_face_center=(KNEE_AXIS[0], KNEE_AXIS[1], 0.0),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
head = scad.make_cylinder_rsolid(
|
|
radius=5.5,
|
|
height=3.0,
|
|
bottom_face_center=(KNEE_AXIS[0], KNEE_AXIS[1], 13.0),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
nut = scad.make_cylinder_rsolid(
|
|
radius=5.5,
|
|
height=4.0,
|
|
bottom_face_center=(KNEE_AXIS[0], KNEE_AXIS[1], -4.0),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
axle = scad.union_rsolid(shaft, head, nut, glue=False)
|
|
axle = scad.apply_tag(shape=axle, tag="role.knee_shoulder_axle")
|
|
return make_part_with_connectors_rpart(
|
|
part_id="knee_shoulder_bolt_stack",
|
|
body=axle,
|
|
name="M6 knee shoulder axle with socket head and retained nut",
|
|
material=material,
|
|
connectors=(("knee_axis", (KNEE_AXIS[0], KNEE_AXIS[1], 6.5), "z", "Knee axle axis"),),
|
|
)
|
|
def make_linkage_pin_stack_rpart(*, material: scad.Material) -> scad.Part:
|
|
"""Create a retained M4 shoulder pin spanning crank, gap, and pushrod."""
|
|
|
|
span = 9.3
|
|
shaft = scad.make_cylinder_rsolid(
|
|
radius=2.0,
|
|
height=span,
|
|
bottom_face_center=(0.0, 0.0, -span / 2.0),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
retainers = [
|
|
scad.make_cylinder_rsolid(
|
|
radius=3.5,
|
|
height=1.2,
|
|
bottom_face_center=(0.0, 0.0, sign * span / 2.0 - (1.2 if sign < 0.0 else 0.0)),
|
|
axis=(0.0, 0.0, 1.0),
|
|
)
|
|
for sign in (-1.0, 1.0)
|
|
]
|
|
pin = scad.union_rsolid(shaft, retainers, glue=False)
|
|
pin = scad.apply_tag(shape=pin, tag="role.retained_linkage_pin")
|
|
return make_part_with_connectors_rpart(
|
|
part_id="m4_linkage_shoulder_pin_stack",
|
|
body=pin,
|
|
name="M4 retained linkage shoulder pin",
|
|
material=material,
|
|
connectors=(("pin_axis", (0.0, 0.0, 0.0), "z", "Linkage pin axis"),),
|
|
)
|