first commit
This commit is contained in:
@@ -0,0 +1,441 @@
|
||||
"""Herringbone ring, planet, carrier, and output parts for the 20:1 reducer."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
import simplecadapi as scad
|
||||
|
||||
try:
|
||||
from .common import (
|
||||
apply_tags,
|
||||
make_axis_part_rpart,
|
||||
make_axial_hole_cutters_rsolids,
|
||||
make_z_rotation_rplacement,
|
||||
)
|
||||
from .dimensions import (
|
||||
ADDENDUM_FACTOR,
|
||||
BACKLASH,
|
||||
CLEARANCE_FACTOR,
|
||||
GEAR_HEIGHT,
|
||||
HELIX_ANGLE,
|
||||
INTERSTAGE_BEARING_CENTER_Z,
|
||||
INTERSTAGE_SHAFT_RADIUS,
|
||||
OUTPUT_BEARING_1_CENTER_Z,
|
||||
OUTPUT_BEARING_2_CENTER_Z,
|
||||
OUTPUT_FLANGE_BOTTOM_Z,
|
||||
OUTPUT_FLANGE_RADIUS,
|
||||
OUTPUT_FLANGE_TOP_Z,
|
||||
OUTPUT_LINK_BOLT_ANGLES_DEGREES,
|
||||
OUTPUT_LINK_BOLT_COUNT,
|
||||
OUTPUT_LINK_HOLE_PCD,
|
||||
OUTPUT_LINK_TAP_RADIUS,
|
||||
OUTPUT_LINK_THREAD_DEPTH,
|
||||
OUTPUT_REGISTER_HEIGHT,
|
||||
OUTPUT_SHAFT_RADIUS,
|
||||
PLANET_BEARING,
|
||||
PLANET_COUNT,
|
||||
PRESSURE_ANGLE,
|
||||
RING_INSERT_OUTER_RADIUS,
|
||||
RING_RIM_THICKNESS,
|
||||
RING_SUPPORT_OVERLAP,
|
||||
STAGE1_ARM_WIDTH,
|
||||
STAGE1_CARRIER_BOTTOM_Z,
|
||||
STAGE1_CARRIER_THICKNESS,
|
||||
STAGE1_HUB_RADIUS,
|
||||
STAGE1_PAD_RADIUS,
|
||||
STAGE1_PIN_BOTTOM_Z,
|
||||
STAGE1_PIN_RADIUS,
|
||||
STAGE2_ARM_WIDTH,
|
||||
STAGE2_CARRIER_BOTTOM_Z,
|
||||
STAGE2_CARRIER_THICKNESS,
|
||||
STAGE2_HUB_RADIUS,
|
||||
STAGE2_PAD_RADIUS,
|
||||
STAGE2_PIN_BOTTOM_Z,
|
||||
STAGE2_PIN_RADIUS,
|
||||
STAGE_1,
|
||||
STAGE_2,
|
||||
StageSpec,
|
||||
)
|
||||
except ImportError: # Support direct execution from this example directory.
|
||||
from common import (
|
||||
apply_tags,
|
||||
make_axis_part_rpart,
|
||||
make_axial_hole_cutters_rsolids,
|
||||
make_z_rotation_rplacement,
|
||||
)
|
||||
from dimensions import (
|
||||
ADDENDUM_FACTOR,
|
||||
BACKLASH,
|
||||
CLEARANCE_FACTOR,
|
||||
GEAR_HEIGHT,
|
||||
HELIX_ANGLE,
|
||||
INTERSTAGE_BEARING_CENTER_Z,
|
||||
INTERSTAGE_SHAFT_RADIUS,
|
||||
OUTPUT_BEARING_1_CENTER_Z,
|
||||
OUTPUT_BEARING_2_CENTER_Z,
|
||||
OUTPUT_FLANGE_BOTTOM_Z,
|
||||
OUTPUT_FLANGE_RADIUS,
|
||||
OUTPUT_FLANGE_TOP_Z,
|
||||
OUTPUT_LINK_BOLT_ANGLES_DEGREES,
|
||||
OUTPUT_LINK_BOLT_COUNT,
|
||||
OUTPUT_LINK_HOLE_PCD,
|
||||
OUTPUT_LINK_TAP_RADIUS,
|
||||
OUTPUT_LINK_THREAD_DEPTH,
|
||||
OUTPUT_REGISTER_HEIGHT,
|
||||
OUTPUT_SHAFT_RADIUS,
|
||||
PLANET_BEARING,
|
||||
PLANET_COUNT,
|
||||
PRESSURE_ANGLE,
|
||||
RING_INSERT_OUTER_RADIUS,
|
||||
RING_RIM_THICKNESS,
|
||||
RING_SUPPORT_OVERLAP,
|
||||
STAGE1_ARM_WIDTH,
|
||||
STAGE1_CARRIER_BOTTOM_Z,
|
||||
STAGE1_CARRIER_THICKNESS,
|
||||
STAGE1_HUB_RADIUS,
|
||||
STAGE1_PAD_RADIUS,
|
||||
STAGE1_PIN_BOTTOM_Z,
|
||||
STAGE1_PIN_RADIUS,
|
||||
STAGE2_ARM_WIDTH,
|
||||
STAGE2_CARRIER_BOTTOM_Z,
|
||||
STAGE2_CARRIER_THICKNESS,
|
||||
STAGE2_HUB_RADIUS,
|
||||
STAGE2_PAD_RADIUS,
|
||||
STAGE2_PIN_BOTTOM_Z,
|
||||
STAGE2_PIN_RADIUS,
|
||||
STAGE_1,
|
||||
STAGE_2,
|
||||
StageSpec,
|
||||
)
|
||||
|
||||
|
||||
def make_stage_ring_gear_rpart(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
material: scad.Material,
|
||||
) -> scad.Part:
|
||||
"""Create one herringbone ring insert with a full housing support rim."""
|
||||
|
||||
ring = scad.std.gear.make_herringbone_ring_gear_rsolid(
|
||||
n_teeth=stage.ring_teeth,
|
||||
module=stage.module,
|
||||
pressure_angle=PRESSURE_ANGLE,
|
||||
helix_angle=-HELIX_ANGLE,
|
||||
gear_height=GEAR_HEIGHT,
|
||||
rim_thickness=RING_RIM_THICKNESS,
|
||||
backlash=BACKLASH,
|
||||
addendum_factor=ADDENDUM_FACTOR,
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
)
|
||||
support = scad.make_cylinder_rsolid(
|
||||
radius=RING_INSERT_OUTER_RADIUS,
|
||||
height=GEAR_HEIGHT,
|
||||
bottom_face_center=(0.0, 0.0, 0.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
support_bore = scad.make_cylinder_rsolid(
|
||||
radius=stage.ring_outer_radius - RING_SUPPORT_OVERLAP,
|
||||
height=GEAR_HEIGHT + 2.0,
|
||||
bottom_face_center=(0.0, 0.0, -1.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
support = scad.cut_rsolid(support, support_bore, skip_non_intersecting=False)
|
||||
ring = scad.union_rsolid(ring, support, glue=False)
|
||||
ring = apply_tags(
|
||||
shape=ring,
|
||||
tags=(f"role.{stage.stage_id}.fixed_ring_gear", "role.ring_gear_press_fit", "group.two_stage_reducer"),
|
||||
)
|
||||
print(
|
||||
f"{stage.stage_id}_ring: teeth={stage.ring_teeth} pitch_r={stage.ring_pitch_radius:.3f} "
|
||||
f"toothed_outer_r={stage.ring_outer_radius:.3f} insert_d={RING_INSERT_OUTER_RADIUS * 2.0:.2f}"
|
||||
)
|
||||
return make_axis_part_rpart(
|
||||
part_id=f"{stage.stage_id}_fixed_ring",
|
||||
body=ring,
|
||||
name=f"{stage.label} replaceable fixed herringbone ring insert",
|
||||
material=material,
|
||||
connectors=(("axis", (0.0, 0.0, GEAR_HEIGHT / 2.0), "Fixed ring axis"),),
|
||||
)
|
||||
|
||||
|
||||
def make_stage_planet_gear_rpart(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
material: scad.Material,
|
||||
) -> scad.Part:
|
||||
"""Create one reusable herringbone planet with a standard-bearing seat."""
|
||||
|
||||
planet = scad.std.gear.make_herringbone_gear_rsolid(
|
||||
n_teeth=stage.planet_teeth,
|
||||
module=stage.module,
|
||||
pressure_angle=PRESSURE_ANGLE,
|
||||
helix_angle=-HELIX_ANGLE,
|
||||
gear_height=GEAR_HEIGHT,
|
||||
addendum_factor=ADDENDUM_FACTOR,
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
backlash=BACKLASH,
|
||||
)
|
||||
bearing_seat_radius = PLANET_BEARING.outer_diameter / 2.0 + 0.05
|
||||
bearing_seat = scad.make_cylinder_rsolid(
|
||||
radius=bearing_seat_radius,
|
||||
height=GEAR_HEIGHT + 2.0,
|
||||
bottom_face_center=(0.0, 0.0, -1.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
planet = scad.cut_rsolid(planet, bearing_seat, skip_non_intersecting=False)
|
||||
planet = apply_tags(
|
||||
shape=planet,
|
||||
tags=(f"role.{stage.stage_id}.planet_gear", "role.planet_bearing_seat", "group.two_stage_reducer"),
|
||||
)
|
||||
root_radius = stage.planet_pitch_radius - stage.module * (ADDENDUM_FACTOR + CLEARANCE_FACTOR)
|
||||
print(
|
||||
f"{stage.stage_id}_planet: teeth={stage.planet_teeth} pitch_r={stage.planet_pitch_radius:.3f} "
|
||||
f"bearing_seat_r={bearing_seat_radius:.3f} root_ligament={root_radius - bearing_seat_radius:.3f}"
|
||||
)
|
||||
return make_axis_part_rpart(
|
||||
part_id=f"{stage.stage_id}_reusable_planet",
|
||||
body=planet,
|
||||
name=f"{stage.label} reusable bearing-supported planet",
|
||||
material=material,
|
||||
connectors=(
|
||||
("axis", (0.0, 0.0, GEAR_HEIGHT / 2.0), "Planet spin axis"),
|
||||
("bearing_axis", (0.0, 0.0, GEAR_HEIGHT / 2.0), "Planet bearing outer-ring axis"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def make_stage1_carrier_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create the first carrier and integral second-stage sun/shaft."""
|
||||
|
||||
carrier = _make_carrier_body_rsolid(
|
||||
stage=STAGE_1,
|
||||
plate_bottom_z=STAGE1_CARRIER_BOTTOM_Z,
|
||||
plate_thickness=STAGE1_CARRIER_THICKNESS,
|
||||
pin_bottom_z=STAGE1_PIN_BOTTOM_Z,
|
||||
pin_radius=STAGE1_PIN_RADIUS,
|
||||
hub_radius=STAGE1_HUB_RADIUS,
|
||||
arm_width=STAGE1_ARM_WIDTH,
|
||||
pad_radius=STAGE1_PAD_RADIUS,
|
||||
)
|
||||
shaft = scad.make_cylinder_rsolid(
|
||||
radius=INTERSTAGE_SHAFT_RADIUS,
|
||||
height=STAGE_2.top_z - STAGE1_CARRIER_BOTTOM_Z + 0.1,
|
||||
bottom_face_center=(0.0, 0.0, STAGE1_CARRIER_BOTTOM_Z - 0.05),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
stage2_sun = scad.std.gear.make_herringbone_gear_rsolid(
|
||||
n_teeth=STAGE_2.sun_teeth,
|
||||
module=STAGE_2.module,
|
||||
pressure_angle=PRESSURE_ANGLE,
|
||||
helix_angle=HELIX_ANGLE,
|
||||
gear_height=GEAR_HEIGHT,
|
||||
addendum_factor=ADDENDUM_FACTOR,
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
backlash=BACKLASH,
|
||||
)
|
||||
stage2_sun = scad.translate_shape(shape=stage2_sun, vector=(0.0, 0.0, STAGE_2.bottom_z))
|
||||
carrier = scad.union_rsolid(carrier, shaft, stage2_sun, glue=False)
|
||||
carrier = apply_tags(
|
||||
shape=carrier,
|
||||
tags=("role.stage1.planet_carrier", "role.stage2.sun_gear", "role.integral_interstage_drive", "group.two_stage_reducer"),
|
||||
)
|
||||
connectors = [
|
||||
("carrier_axis", (0.0, 0.0, INTERSTAGE_BEARING_CENTER_Z), "Stage 1 carrier bearing axis"),
|
||||
(
|
||||
"interstage_bearing_axis",
|
||||
(0.0, 0.0, INTERSTAGE_BEARING_CENTER_Z),
|
||||
"Interstage bearing inner-ring seat",
|
||||
),
|
||||
("stage2_sun_axis", (0.0, 0.0, STAGE_2.mid_z), "Integral stage 2 sun axis"),
|
||||
]
|
||||
for index in range(PLANET_COUNT):
|
||||
center = planet_center_xy(stage=STAGE_1, index=index)
|
||||
connectors.extend(
|
||||
(
|
||||
(f"planet_{index + 1}_axis", (*center, STAGE_1.mid_z), f"Stage 1 planet {index + 1} axis"),
|
||||
(f"planet_{index + 1}_bearing_axis", (*center, STAGE_1.mid_z), f"Stage 1 planet {index + 1} bearing pin"),
|
||||
)
|
||||
)
|
||||
print(
|
||||
f"stage1_carrier_sun: pins={PLANET_COUNT} shaft_d={INTERSTAGE_SHAFT_RADIUS * 2.0:.2f} "
|
||||
f"stage2_sun_teeth={STAGE_2.sun_teeth}"
|
||||
)
|
||||
return make_axis_part_rpart(
|
||||
part_id="stage1_carrier_integral_stage2_sun",
|
||||
body=carrier,
|
||||
name="Stage 1 carrier with integral stage-2 sun shaft",
|
||||
material=material,
|
||||
connectors=connectors,
|
||||
)
|
||||
|
||||
|
||||
def make_output_carrier_flange_rpart(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
material: scad.Material,
|
||||
) -> scad.Part:
|
||||
"""Create the second carrier, 16 mm bearing land, and output flange."""
|
||||
|
||||
carrier = _make_carrier_body_rsolid(
|
||||
stage=stage,
|
||||
plate_bottom_z=STAGE2_CARRIER_BOTTOM_Z,
|
||||
plate_thickness=STAGE2_CARRIER_THICKNESS,
|
||||
pin_bottom_z=STAGE2_PIN_BOTTOM_Z,
|
||||
pin_radius=STAGE2_PIN_RADIUS,
|
||||
hub_radius=STAGE2_HUB_RADIUS,
|
||||
arm_width=STAGE2_ARM_WIDTH,
|
||||
pad_radius=STAGE2_PAD_RADIUS,
|
||||
)
|
||||
shaft = scad.make_cylinder_rsolid(
|
||||
radius=OUTPUT_SHAFT_RADIUS,
|
||||
height=(
|
||||
OUTPUT_FLANGE_TOP_Z
|
||||
+ OUTPUT_REGISTER_HEIGHT
|
||||
- STAGE2_CARRIER_BOTTOM_Z
|
||||
+ 0.05
|
||||
),
|
||||
bottom_face_center=(0.0, 0.0, STAGE2_CARRIER_BOTTOM_Z - 0.05),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
flange = scad.make_cylinder_rsolid(
|
||||
radius=OUTPUT_FLANGE_RADIUS,
|
||||
height=OUTPUT_FLANGE_TOP_Z - OUTPUT_FLANGE_BOTTOM_Z,
|
||||
bottom_face_center=(0.0, 0.0, OUTPUT_FLANGE_BOTTOM_Z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
output = scad.union_rsolid(carrier, shaft, flange, glue=False)
|
||||
output = scad.cut_rsolid(
|
||||
output,
|
||||
make_axial_hole_cutters_rsolids(
|
||||
count=OUTPUT_LINK_BOLT_COUNT,
|
||||
pcd=OUTPUT_LINK_HOLE_PCD,
|
||||
hole_radius=OUTPUT_LINK_TAP_RADIUS,
|
||||
bottom_z=OUTPUT_FLANGE_TOP_Z - OUTPUT_LINK_THREAD_DEPTH,
|
||||
height=OUTPUT_LINK_THREAD_DEPTH + 1.0,
|
||||
angle_offset=OUTPUT_LINK_BOLT_ANGLES_DEGREES[0],
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
)
|
||||
output = apply_tags(
|
||||
shape=output,
|
||||
tags=("role.stage2.output_carrier", "role.output_bearing_land", "role.output_link_flange", "group.two_stage_reducer"),
|
||||
)
|
||||
connectors = [
|
||||
("carrier_axis", (0.0, 0.0, STAGE2_CARRIER_BOTTOM_Z + STAGE2_CARRIER_THICKNESS / 2.0), "Stage 2 output carrier axis"),
|
||||
("bearing_1_axis", (0.0, 0.0, OUTPUT_BEARING_1_CENTER_Z), "Rear output bearing inner-ring seat"),
|
||||
("bearing_2_axis", (0.0, 0.0, OUTPUT_BEARING_2_CENTER_Z), "Front output bearing inner-ring seat"),
|
||||
("output_link_axis", (0.0, 0.0, OUTPUT_FLANGE_TOP_Z), "Six-hole driven-link flange"),
|
||||
]
|
||||
for index in range(PLANET_COUNT):
|
||||
center = planet_center_xy(stage=stage, index=index)
|
||||
connectors.extend(
|
||||
(
|
||||
(f"planet_{index + 1}_axis", (*center, stage.mid_z), f"Stage 2 planet {index + 1} axis"),
|
||||
(f"planet_{index + 1}_bearing_axis", (*center, stage.mid_z), f"Stage 2 planet {index + 1} bearing pin"),
|
||||
)
|
||||
)
|
||||
radial_ligament = OUTPUT_FLANGE_RADIUS - (OUTPUT_LINK_HOLE_PCD / 2.0 + OUTPUT_LINK_TAP_RADIUS)
|
||||
print(
|
||||
f"output_carrier_flange: shaft_d={OUTPUT_SHAFT_RADIUS * 2.0:.2f} "
|
||||
f"pilot_h={OUTPUT_REGISTER_HEIGHT:.1f} tapped_holes={OUTPUT_LINK_BOLT_COUNT} "
|
||||
f"pcd={OUTPUT_LINK_HOLE_PCD:.1f} thread_depth={OUTPUT_LINK_THREAD_DEPTH:.1f} "
|
||||
f"radial_ligament={radial_ligament:.2f}"
|
||||
)
|
||||
return make_axis_part_rpart(
|
||||
part_id="stage2_output_carrier_flange",
|
||||
body=output,
|
||||
name="Stage 2 carrier with paired-bearing shaft and output flange",
|
||||
material=material,
|
||||
connectors=connectors,
|
||||
)
|
||||
|
||||
|
||||
def make_planet_rplacement(*, stage: StageSpec, index: int) -> scad.Placement:
|
||||
"""Place and visually phase one planet at its pitch center."""
|
||||
|
||||
center = planet_center_xy(stage=stage, index=index)
|
||||
carrier_angle = 360.0 * index / PLANET_COUNT
|
||||
spin = carrier_angle + 180.0 - 180.0 / stage.planet_teeth
|
||||
print(
|
||||
f"{stage.stage_id}_planet_{index + 1}_placement: center="
|
||||
f"({center[0]:.3f},{center[1]:.3f},{stage.bottom_z:.3f}) spin={spin:.2f}"
|
||||
)
|
||||
return make_z_rotation_rplacement(
|
||||
origin=(center[0], center[1], stage.bottom_z),
|
||||
angle_degrees=spin,
|
||||
)
|
||||
|
||||
|
||||
def planet_center_xy(*, stage: StageSpec, index: int) -> tuple[float, float]:
|
||||
"""Return one equally spaced planet pitch center."""
|
||||
|
||||
angle = math.radians(360.0 * index / PLANET_COUNT)
|
||||
return (
|
||||
stage.planet_center_radius * math.cos(angle),
|
||||
stage.planet_center_radius * math.sin(angle),
|
||||
)
|
||||
|
||||
|
||||
def _make_carrier_body_rsolid(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
plate_bottom_z: float,
|
||||
plate_thickness: float,
|
||||
pin_bottom_z: float,
|
||||
pin_radius: float,
|
||||
hub_radius: float,
|
||||
arm_width: float,
|
||||
pad_radius: float,
|
||||
) -> scad.Solid:
|
||||
hub = scad.make_cylinder_rsolid(
|
||||
radius=hub_radius,
|
||||
height=plate_thickness,
|
||||
bottom_face_center=(0.0, 0.0, plate_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
solids = [hub]
|
||||
pin_height = plate_bottom_z + plate_thickness - pin_bottom_z
|
||||
arm_inner_radius = hub_radius - 1.25
|
||||
arm_outer_radius = stage.planet_center_radius + pad_radius - 0.25
|
||||
arm_length = arm_outer_radius - arm_inner_radius
|
||||
arm_center_radius = (arm_inner_radius + arm_outer_radius) / 2.0
|
||||
for index in range(PLANET_COUNT):
|
||||
angle = 360.0 * index / PLANET_COUNT
|
||||
center = planet_center_xy(stage=stage, index=index)
|
||||
arm = scad.make_box_rsolid(
|
||||
width=arm_length,
|
||||
height=arm_width,
|
||||
depth=plate_thickness,
|
||||
bottom_face_center=(arm_center_radius, 0.0, plate_bottom_z),
|
||||
)
|
||||
solids.append(
|
||||
scad.rotate_shape(
|
||||
shape=arm,
|
||||
angle=angle,
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
origin=(0.0, 0.0, 0.0),
|
||||
)
|
||||
)
|
||||
solids.append(
|
||||
scad.make_cylinder_rsolid(
|
||||
radius=pad_radius,
|
||||
height=plate_thickness,
|
||||
bottom_face_center=(center[0], center[1], plate_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
)
|
||||
solids.append(
|
||||
scad.make_cylinder_rsolid(
|
||||
radius=pin_radius,
|
||||
height=pin_height,
|
||||
bottom_face_center=(center[0], center[1], pin_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
)
|
||||
)
|
||||
carrier = scad.union_rsolid(solids, glue=False)
|
||||
print(
|
||||
f"{stage.stage_id}_carrier_body: arm_length={arm_length:.3f} "
|
||||
f"hub_embed={hub_radius - arm_inner_radius:.3f} pin_height={pin_height:.3f}"
|
||||
)
|
||||
return carrier
|
||||
Reference in New Issue
Block a user