feat: integrate SimpleCADAPI 2.0.2 CAD workflows
This commit is contained in:
@@ -88,6 +88,7 @@ except ImportError: # Support direct execution from this example directory.
|
||||
from motor import make_bldc_rotor_rassembly, make_bldc_stator_rassembly
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_integrated_bldc_joint_actuator_rassembly(
|
||||
*, materials: dict[str, scad.Material]
|
||||
) -> scad.Assembly:
|
||||
@@ -116,6 +117,7 @@ def make_integrated_bldc_joint_actuator_rassembly(
|
||||
return actuator
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_integrated_bldc_joint_actuator_components_rtuple(
|
||||
*, materials: dict[str, scad.Material]
|
||||
) -> tuple[tuple[str, scad.Part | scad.Assembly, scad.Placement, str], ...]:
|
||||
@@ -258,6 +260,7 @@ def make_integrated_bldc_joint_actuator_components_rtuple(
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _add_public_connectors_rassembly(*, assembly: scad.Assembly) -> scad.Assembly:
|
||||
forwarded = (
|
||||
("case_clamp_axis", "reducer_housing", "case_clamp_axis", "External split-clamp datum"),
|
||||
@@ -279,6 +282,7 @@ def _add_public_connectors_rassembly(*, assembly: scad.Assembly) -> scad.Assembl
|
||||
return assembly
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _add_constraints_rassembly(*, assembly: scad.Assembly) -> scad.Assembly:
|
||||
assembly = scad.ground_component_rassembly(assembly=assembly, component_id="reducer_housing")
|
||||
assembly = scad.ground_component_rassembly(assembly=assembly, component_id="stage1_ring")
|
||||
@@ -339,6 +343,7 @@ def _add_constraints_rassembly(*, assembly: scad.Assembly) -> scad.Assembly:
|
||||
return assembly
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _add_stage_constraints_rassembly(
|
||||
*,
|
||||
assembly: scad.Assembly,
|
||||
@@ -386,6 +391,7 @@ def _add_stage_constraints_rassembly(
|
||||
return assembly
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _add_bearing_constraints_rassembly(*, assembly: scad.Assembly) -> scad.Assembly:
|
||||
interfaces = (
|
||||
("rear_bearing_outer_to_spider", "rear_bearing_spider", "bearing_axis", "rear_motor_bearing", "outer_axis"),
|
||||
@@ -437,5 +443,6 @@ def _add_bearing_constraints_rassembly(*, assembly: scad.Assembly) -> scad.Assem
|
||||
return assembly
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _stage_rplacement(*, stage: StageSpec) -> scad.Placement:
|
||||
return scad.make_placement_rplacement(origin=(0.0, 0.0, stage.bottom_z))
|
||||
|
||||
@@ -14,6 +14,7 @@ else:
|
||||
from gears import planet_center_xy
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_standard_planet_bearing_rassembly(
|
||||
*,
|
||||
bearing_id: str,
|
||||
@@ -34,6 +35,7 @@ def make_standard_planet_bearing_rassembly(
|
||||
return bearing
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_main_bearing_rassembly(
|
||||
*,
|
||||
bearing_id: str,
|
||||
@@ -48,11 +50,16 @@ def make_main_bearing_rassembly(
|
||||
pitch_radius = (bore_radius + outer_radius) / 2.0
|
||||
inner_outer_radius = pitch_radius - ball_radius * 0.55
|
||||
outer_inner_radius = pitch_radius + ball_radius * 0.55
|
||||
bearing_tag_prefix = ".".join(
|
||||
f"size{token}" if token[0].isdigit() else token
|
||||
for token in bearing_id.split("_")
|
||||
)
|
||||
inner_ring = make_annulus_rsolid(
|
||||
outer_radius=inner_outer_radius,
|
||||
inner_radius=bore_radius,
|
||||
bottom_z=-spec.width / 2.0,
|
||||
height=spec.width,
|
||||
tag_prefix=f"bearing.{bearing_tag_prefix}.inner.ring",
|
||||
tags=("role.bearing_inner_ring",),
|
||||
)
|
||||
outer_ring = make_annulus_rsolid(
|
||||
@@ -60,12 +67,17 @@ def make_main_bearing_rassembly(
|
||||
inner_radius=outer_inner_radius,
|
||||
bottom_z=-spec.width / 2.0,
|
||||
height=spec.width,
|
||||
tag_prefix=f"bearing.{bearing_tag_prefix}.outer.ring",
|
||||
tags=("role.bearing_outer_ring",),
|
||||
)
|
||||
ball = scad.make_sphere_rsolid(
|
||||
radius=ball_radius,
|
||||
center=(pitch_radius, 0.0, 0.0),
|
||||
)
|
||||
ball = scad.apply_tag(
|
||||
shape=ball,
|
||||
tag=f"solid.bearing.{bearing_tag_prefix}.rolling.element",
|
||||
)
|
||||
inner_part = make_axis_part_rpart(
|
||||
part_id=f"{bearing_id}_inner_ring",
|
||||
body=inner_ring,
|
||||
@@ -148,12 +160,14 @@ def make_main_bearing_rassembly(
|
||||
return bearing
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_coaxial_bearing_rplacement(*, center_z: float) -> scad.Placement:
|
||||
"""Place a standard bearing center plane on the actuator Z axis."""
|
||||
|
||||
return make_z_rotation_rplacement(origin=(0.0, 0.0, center_z), angle_degrees=0.0)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_planet_bearing_rplacement(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
|
||||
@@ -9,6 +9,7 @@ import simplecadapi as scad
|
||||
from simplecadapi import ql
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def apply_tags(*, shape: scad.Solid, tags: Iterable[str]) -> scad.Solid:
|
||||
"""Apply semantic tags through the public functional API."""
|
||||
|
||||
@@ -18,12 +19,14 @@ def apply_tags(*, shape: scad.Solid, tags: Iterable[str]) -> scad.Solid:
|
||||
return tagged
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_annulus_rsolid(
|
||||
*,
|
||||
outer_radius: float,
|
||||
inner_radius: float,
|
||||
bottom_z: float,
|
||||
height: float,
|
||||
tag_prefix: str,
|
||||
tags: Iterable[str],
|
||||
) -> scad.Solid:
|
||||
"""Create a strict single-solid annular cylinder."""
|
||||
@@ -33,17 +36,22 @@ def make_annulus_rsolid(
|
||||
height=height,
|
||||
bottom_face_center=(0.0, 0.0, bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"{tag_prefix}.outer",
|
||||
result_tag=f"feature.{tag_prefix}.outer",
|
||||
)
|
||||
bore = scad.make_cylinder_rsolid(
|
||||
radius=inner_radius,
|
||||
height=height + 2.0,
|
||||
bottom_face_center=(0.0, 0.0, bottom_z - 1.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"{tag_prefix}.bore",
|
||||
result_tag=f"tool.{tag_prefix}.bore",
|
||||
)
|
||||
annulus = scad.cut_rsolid(outer, bore, skip_non_intersecting=False)
|
||||
return apply_tags(shape=annulus, tags=tags)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_axis_part_rpart(
|
||||
*,
|
||||
part_id: str,
|
||||
@@ -70,6 +78,7 @@ def make_axis_part_rpart(
|
||||
return part
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_z_rotation_rplacement(
|
||||
*,
|
||||
origin: tuple[float, float, float],
|
||||
@@ -94,6 +103,7 @@ def radial_centers(*, count: int, radius: float, angle_offset: float = 0.0):
|
||||
yield index, angle_degrees, (radius * math.cos(angle), radius * math.sin(angle))
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_axial_hole_cutters_rsolids(
|
||||
*,
|
||||
count: int,
|
||||
@@ -101,12 +111,13 @@ def make_axial_hole_cutters_rsolids(
|
||||
hole_radius: float,
|
||||
bottom_z: float,
|
||||
height: float,
|
||||
tag_prefix: str,
|
||||
angle_offset: float = 0.0,
|
||||
) -> list[scad.Solid]:
|
||||
"""Create equally spaced axial hole cutters."""
|
||||
|
||||
cutters = []
|
||||
for _index, _angle, center in radial_centers(
|
||||
for index, _angle, center in radial_centers(
|
||||
count=count,
|
||||
radius=pcd / 2.0,
|
||||
angle_offset=angle_offset,
|
||||
@@ -117,6 +128,8 @@ def make_axial_hole_cutters_rsolids(
|
||||
height=height,
|
||||
bottom_face_center=(center[0], center[1], bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"{tag_prefix}.hole{index + 1}",
|
||||
result_tag=f"tool.{tag_prefix}.hole{index + 1}",
|
||||
)
|
||||
)
|
||||
return cutters
|
||||
@@ -126,9 +139,13 @@ def ground_solid(*, label: str, solid: scad.Solid) -> None:
|
||||
"""Print a concise QL-backed solid summary."""
|
||||
|
||||
faces = ql.select(items=solid.get_faces()).all()
|
||||
role_faces = ql.select(items=faces).where(ql.tag(pattern="role.*")).all()
|
||||
local_roles = [
|
||||
tag
|
||||
for tag in scad.list_tags(shape=solid, scope="local")
|
||||
if tag.startswith("role.")
|
||||
]
|
||||
print(
|
||||
f"{label}: faces={len(faces)} role_faces={len(role_faces)} "
|
||||
f"{label}: faces={len(faces)} local_roles={len(local_roles)} "
|
||||
f"volume={solid.get_volume():.3f} tags={','.join(scad.list_tags(shape=solid))}"
|
||||
)
|
||||
|
||||
@@ -142,6 +159,7 @@ def ground_compound(*, label: str, compound: scad.Compound) -> None:
|
||||
print(f"{label}: solids={len(solids)} faces={faces} volume={volume:.3f}")
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def connector_ref(*, component_id: str, connector_id: str) -> scad.ConnectorRef:
|
||||
"""Create a component-scoped connector reference."""
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ POWER_CAN_TERMINAL_CENTER = (11.0, 0.0)
|
||||
MOSFET_ANGLES = (22.5, 67.5, 112.5, 202.5, 247.5, 292.5)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_integrated_controller_rassembly(
|
||||
*,
|
||||
pcb_material: scad.Material,
|
||||
@@ -139,12 +140,15 @@ def make_integrated_controller_rassembly(
|
||||
return controller
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_controller_pcb_rpart(*, material: scad.Material) -> scad.Part:
|
||||
board = scad.make_cylinder_rsolid(
|
||||
radius=PCB_RADIUS,
|
||||
height=PCB_THICKNESS,
|
||||
bottom_face_center=(0.0, 0.0, PCB_BOTTOM_Z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="controller.pcb.board",
|
||||
result_tag="feature.controller.pcb.board",
|
||||
)
|
||||
cutters: list[scad.Solid] = [
|
||||
scad.make_cylinder_rsolid(
|
||||
@@ -152,6 +156,8 @@ def _make_controller_pcb_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=PCB_THICKNESS + 2.0,
|
||||
bottom_face_center=(0.0, 0.0, PCB_BOTTOM_Z - 1.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="controller.pcb.center.bore",
|
||||
result_tag="tool.controller.pcb.center.bore",
|
||||
)
|
||||
]
|
||||
cutters.extend(
|
||||
@@ -161,6 +167,7 @@ def _make_controller_pcb_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=PCB_MOUNT_HOLE_RADIUS,
|
||||
bottom_z=PCB_BOTTOM_Z - 1.0,
|
||||
height=PCB_THICKNESS + 2.0,
|
||||
tag_prefix="controller.pcb.mount.hole",
|
||||
angle_offset=45.0,
|
||||
)
|
||||
)
|
||||
@@ -171,9 +178,13 @@ def _make_controller_pcb_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=3.45,
|
||||
bottom_z=PCB_BOTTOM_Z - 1.0,
|
||||
height=PCB_THICKNESS + 2.0,
|
||||
tag_prefix="controller.pcb.rear.column.clearance",
|
||||
)
|
||||
)
|
||||
for x, count in ((PHASE_TERMINAL_CENTER[0], 3), (POWER_CAN_TERMINAL_CENTER[0], 4)):
|
||||
for terminal_id, x, count in (
|
||||
("phase", PHASE_TERMINAL_CENTER[0], 3),
|
||||
("power.can", POWER_CAN_TERMINAL_CENTER[0], 4),
|
||||
):
|
||||
for pin in range(count):
|
||||
y = (pin - (count - 1) / 2.0) * 1.8
|
||||
cutters.append(
|
||||
@@ -182,6 +193,8 @@ def _make_controller_pcb_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=PCB_THICKNESS + 2.0,
|
||||
bottom_face_center=(x, y, PCB_BOTTOM_Z - 1.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"controller.pcb.terminal.{terminal_id}.pin{pin + 1}",
|
||||
result_tag=f"tool.controller.pcb.terminal.{terminal_id}.pin{pin + 1}",
|
||||
)
|
||||
)
|
||||
board = scad.cut_rsolid(board, cutters, skip_non_intersecting=False)
|
||||
@@ -216,12 +229,15 @@ def _make_controller_pcb_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_mosfet_package_rpart(*, material: scad.Material) -> scad.Part:
|
||||
package = scad.make_box_rsolid(
|
||||
width=4.0,
|
||||
height=3.0,
|
||||
depth=1.4,
|
||||
bottom_face_center=(0.0, 0.0, 0.0),
|
||||
tag_prefix="controller.mosfet.package",
|
||||
result_tag="feature.controller.mosfet.package",
|
||||
)
|
||||
package = apply_tags(shape=package, tags=("role.power_mosfet", "group.three_phase_bridge"))
|
||||
return make_axis_part_rpart(
|
||||
@@ -233,6 +249,7 @@ def _make_mosfet_package_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_terminal_block_rpart(
|
||||
*,
|
||||
part_id: str,
|
||||
@@ -241,11 +258,14 @@ def _make_terminal_block_rpart(
|
||||
pin_count: int,
|
||||
material: scad.Material,
|
||||
) -> scad.Part:
|
||||
terminal_tag_prefix = part_id.replace("_", ".")
|
||||
body = scad.make_box_rsolid(
|
||||
width=width,
|
||||
height=6.0,
|
||||
depth=4.9,
|
||||
bottom_face_center=(0.0, 0.0, 0.0),
|
||||
tag_prefix=f"controller.terminal.{terminal_tag_prefix}.body",
|
||||
result_tag=f"feature.controller.terminal.{terminal_tag_prefix}.body",
|
||||
)
|
||||
access_cutters = []
|
||||
for pin in range(pin_count):
|
||||
@@ -256,6 +276,8 @@ def _make_terminal_block_rpart(
|
||||
height=width + 2.0,
|
||||
bottom_face_center=(-width / 2.0 - 1.0, y, 2.45),
|
||||
axis=(1.0, 0.0, 0.0),
|
||||
tag_prefix=f"controller.terminal.{terminal_tag_prefix}.access{pin + 1}",
|
||||
result_tag=f"tool.controller.terminal.{terminal_tag_prefix}.access{pin + 1}",
|
||||
)
|
||||
)
|
||||
body = scad.cut_rsolid(body, access_cutters, skip_non_intersecting=False)
|
||||
|
||||
@@ -110,6 +110,7 @@ except ImportError: # Support direct execution from this example directory.
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_stage_ring_gear_rpart(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
@@ -128,17 +129,25 @@ def make_stage_ring_gear_rpart(
|
||||
addendum_factor=ADDENDUM_FACTOR,
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
)
|
||||
ring = scad.apply_tag(
|
||||
shape=ring,
|
||||
tag=f"solid.stdlib.{stage.stage_id}.fixed.herringbone.ring.gear",
|
||||
)
|
||||
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),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.ring.support",
|
||||
result_tag=f"feature.reducer.{stage.stage_id}.ring.support",
|
||||
)
|
||||
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),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.ring.support.bore",
|
||||
result_tag=f"tool.reducer.{stage.stage_id}.ring.support.bore",
|
||||
)
|
||||
support = scad.cut_rsolid(support, support_bore, skip_non_intersecting=False)
|
||||
ring = scad.union_rsolid(ring, support, glue=False)
|
||||
@@ -159,6 +168,7 @@ def make_stage_ring_gear_rpart(
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_stage_planet_gear_rpart(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
@@ -176,12 +186,18 @@ def make_stage_planet_gear_rpart(
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
backlash=BACKLASH,
|
||||
)
|
||||
planet = scad.apply_tag(
|
||||
shape=planet,
|
||||
tag=f"solid.stdlib.{stage.stage_id}.reusable.herringbone.planet.gear",
|
||||
)
|
||||
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),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.planet.bearing.seat",
|
||||
result_tag=f"tool.reducer.{stage.stage_id}.planet.bearing.seat",
|
||||
)
|
||||
planet = scad.cut_rsolid(planet, bearing_seat, skip_non_intersecting=False)
|
||||
planet = apply_tags(
|
||||
@@ -205,6 +221,7 @@ def make_stage_planet_gear_rpart(
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_stage1_carrier_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create the first carrier and integral second-stage sun/shaft."""
|
||||
|
||||
@@ -223,6 +240,8 @@ def make_stage1_carrier_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
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),
|
||||
tag_prefix="reducer.stage1.carrier.interstage.shaft",
|
||||
result_tag="feature.reducer.stage1.carrier.interstage.shaft",
|
||||
)
|
||||
stage2_sun = scad.std.gear.make_herringbone_gear_rsolid(
|
||||
n_teeth=STAGE_2.sun_teeth,
|
||||
@@ -234,6 +253,10 @@ def make_stage1_carrier_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
backlash=BACKLASH,
|
||||
)
|
||||
stage2_sun = scad.apply_tag(
|
||||
shape=stage2_sun,
|
||||
tag="solid.stdlib.stage2.integral.herringbone.sun.gear",
|
||||
)
|
||||
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(
|
||||
@@ -270,6 +293,7 @@ def make_stage1_carrier_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_output_carrier_flange_rpart(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
@@ -297,12 +321,16 @@ def make_output_carrier_flange_rpart(
|
||||
),
|
||||
bottom_face_center=(0.0, 0.0, STAGE2_CARRIER_BOTTOM_Z - 0.05),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="reducer.stage2.output.shaft",
|
||||
result_tag="feature.reducer.stage2.output.shaft",
|
||||
)
|
||||
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),
|
||||
tag_prefix="reducer.stage2.output.flange",
|
||||
result_tag="feature.reducer.stage2.output.flange",
|
||||
)
|
||||
output = scad.union_rsolid(carrier, shaft, flange, glue=False)
|
||||
output = scad.cut_rsolid(
|
||||
@@ -313,6 +341,7 @@ def make_output_carrier_flange_rpart(
|
||||
hole_radius=OUTPUT_LINK_TAP_RADIUS,
|
||||
bottom_z=OUTPUT_FLANGE_TOP_Z - OUTPUT_LINK_THREAD_DEPTH,
|
||||
height=OUTPUT_LINK_THREAD_DEPTH + 1.0,
|
||||
tag_prefix="reducer.stage2.output.flange.thread",
|
||||
angle_offset=OUTPUT_LINK_BOLT_ANGLES_DEGREES[0],
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
@@ -351,6 +380,7 @@ def make_output_carrier_flange_rpart(
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_planet_rplacement(*, stage: StageSpec, index: int) -> scad.Placement:
|
||||
"""Place and visually phase one planet at its pitch center."""
|
||||
|
||||
@@ -377,6 +407,7 @@ def planet_center_xy(*, stage: StageSpec, index: int) -> tuple[float, float]:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_carrier_body_rsolid(
|
||||
*,
|
||||
stage: StageSpec,
|
||||
@@ -393,6 +424,8 @@ def _make_carrier_body_rsolid(
|
||||
height=plate_thickness,
|
||||
bottom_face_center=(0.0, 0.0, plate_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.carrier.hub",
|
||||
result_tag=f"feature.reducer.{stage.stage_id}.carrier.hub",
|
||||
)
|
||||
solids = [hub]
|
||||
pin_height = plate_bottom_z + plate_thickness - pin_bottom_z
|
||||
@@ -408,6 +441,8 @@ def _make_carrier_body_rsolid(
|
||||
height=arm_width,
|
||||
depth=plate_thickness,
|
||||
bottom_face_center=(arm_center_radius, 0.0, plate_bottom_z),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.carrier.arm{index + 1}",
|
||||
result_tag=f"feature.reducer.{stage.stage_id}.carrier.arm{index + 1}",
|
||||
)
|
||||
solids.append(
|
||||
scad.rotate_shape(
|
||||
@@ -423,6 +458,8 @@ def _make_carrier_body_rsolid(
|
||||
height=plate_thickness,
|
||||
bottom_face_center=(center[0], center[1], plate_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.carrier.pad{index + 1}",
|
||||
result_tag=f"feature.reducer.{stage.stage_id}.carrier.pad{index + 1}",
|
||||
)
|
||||
)
|
||||
solids.append(
|
||||
@@ -431,6 +468,8 @@ def _make_carrier_body_rsolid(
|
||||
height=pin_height,
|
||||
bottom_face_center=(center[0], center[1], pin_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"reducer.{stage.stage_id}.carrier.pin{index + 1}",
|
||||
result_tag=f"feature.reducer.{stage.stage_id}.carrier.pin{index + 1}",
|
||||
)
|
||||
)
|
||||
carrier = scad.union_rsolid(solids, glue=False)
|
||||
|
||||
@@ -102,6 +102,7 @@ except ImportError: # Support direct execution from this example directory.
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_motor_shell_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create the stator sleeve, front attachment land, and rear columns."""
|
||||
|
||||
@@ -110,6 +111,7 @@ def make_motor_shell_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=MOTOR_SHELL_INNER_RADIUS,
|
||||
bottom_z=MOTOR_SHELL_BOTTOM_Z,
|
||||
height=MOTOR_SHELL_TOP_Z - MOTOR_SHELL_BOTTOM_Z,
|
||||
tag_prefix="housing.motor.shell.sleeve",
|
||||
tags=("role.motor_shell", "role.stator_thermal_path"),
|
||||
)
|
||||
front_land = make_annulus_rsolid(
|
||||
@@ -117,16 +119,19 @@ def make_motor_shell_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=HOUSING_INTERFACE_LAND_INNER_RADIUS,
|
||||
bottom_z=MOTOR_SHELL_TOP_Z - 1.4,
|
||||
height=1.4,
|
||||
tag_prefix="housing.motor.shell.front.land",
|
||||
tags=("role.motor_reducer_mount",),
|
||||
)
|
||||
columns = []
|
||||
for _index, _angle, center in radial_centers(count=4, radius=REAR_COLUMN_PCD / 2.0):
|
||||
for index, _angle, center in radial_centers(count=4, radius=REAR_COLUMN_PCD / 2.0):
|
||||
columns.append(
|
||||
scad.make_cylinder_rsolid(
|
||||
radius=REAR_COLUMN_RADIUS,
|
||||
height=REAR_SPIDER_BOTTOM_Z - MOTOR_SHELL_BOTTOM_Z,
|
||||
bottom_face_center=(center[0], center[1], MOTOR_SHELL_BOTTOM_Z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"housing.motor.shell.rear.column{index + 1}",
|
||||
result_tag=f"feature.housing.motor.shell.rear.column{index + 1}",
|
||||
)
|
||||
)
|
||||
shell = scad.union_rsolid(sleeve, front_land, columns, glue=False)
|
||||
@@ -138,6 +143,7 @@ def make_motor_shell_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=M3_CLEARANCE_RADIUS,
|
||||
bottom_z=MOTOR_SHELL_TOP_Z - 2.8,
|
||||
height=3.6,
|
||||
tag_prefix="housing.motor.shell.interface.clearance",
|
||||
angle_offset=30.0,
|
||||
),
|
||||
make_axial_hole_cutters_rsolids(
|
||||
@@ -146,6 +152,7 @@ def make_motor_shell_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=REAR_FASTENER_HOLE_RADIUS,
|
||||
bottom_z=MOTOR_SHELL_BOTTOM_Z - 1.0,
|
||||
height=10.4,
|
||||
tag_prefix="housing.motor.shell.rear.fastener.clearance",
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
)
|
||||
@@ -175,6 +182,7 @@ def make_motor_shell_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create the reducer sleeve and front motor-bearing bulkhead."""
|
||||
|
||||
@@ -183,6 +191,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=REDUCER_HOUSING_INNER_RADIUS,
|
||||
bottom_z=REDUCER_HOUSING_BOTTOM_Z,
|
||||
height=REDUCER_HOUSING_FRONT_Z - REDUCER_HOUSING_BOTTOM_Z,
|
||||
tag_prefix="housing.reducer.sleeve",
|
||||
tags=("role.reducer_housing_sleeve",),
|
||||
)
|
||||
bulkhead = make_annulus_rsolid(
|
||||
@@ -190,6 +199,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=FRONT_MOTOR_BEARING.outer_diameter / 2.0 + 0.05,
|
||||
bottom_z=REDUCER_HOUSING_BOTTOM_Z,
|
||||
height=STAGE_1.bottom_z - REDUCER_HOUSING_BOTTOM_Z,
|
||||
tag_prefix="housing.reducer.front.bulkhead",
|
||||
tags=("role.motor_front_bearing_bulkhead",),
|
||||
)
|
||||
interstage_divider = make_annulus_rsolid(
|
||||
@@ -197,6 +207,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=INTERSTAGE_BEARING.outer_diameter / 2.0 + 0.05,
|
||||
bottom_z=INTERSTAGE_BEARING_CENTER_Z - INTERSTAGE_BEARING.width / 2.0,
|
||||
height=INTERSTAGE_BEARING.width,
|
||||
tag_prefix="housing.reducer.interstage.divider",
|
||||
tags=("role.interstage_bearing_divider",),
|
||||
)
|
||||
output_mount_land = make_annulus_rsolid(
|
||||
@@ -204,6 +215,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=HOUSING_INTERFACE_LAND_INNER_RADIUS,
|
||||
bottom_z=REDUCER_HOUSING_FRONT_Z - 2.2,
|
||||
height=2.2,
|
||||
tag_prefix="housing.reducer.output.mount.land",
|
||||
tags=("role.output_cap_mount_land",),
|
||||
)
|
||||
housing = scad.union_rsolid(
|
||||
@@ -221,6 +233,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=M3_CLEARANCE_RADIUS,
|
||||
bottom_z=REDUCER_HOUSING_BOTTOM_Z - 1.0,
|
||||
height=STAGE_1.bottom_z - REDUCER_HOUSING_BOTTOM_Z + 2.0,
|
||||
tag_prefix="housing.reducer.motor.interface.clearance",
|
||||
angle_offset=30.0,
|
||||
),
|
||||
make_axial_hole_cutters_rsolids(
|
||||
@@ -229,6 +242,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=M3_CLEARANCE_RADIUS,
|
||||
bottom_z=REDUCER_HOUSING_FRONT_Z - 2.2,
|
||||
height=3.2,
|
||||
tag_prefix="housing.reducer.output.interface.clearance",
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
)
|
||||
@@ -265,6 +279,7 @@ def make_reducer_housing_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_rear_bearing_spider_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create a four-arm removable rear motor-bearing support."""
|
||||
|
||||
@@ -274,15 +289,18 @@ def make_rear_bearing_spider_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=8.05,
|
||||
bottom_z=bottom_z,
|
||||
height=5.0,
|
||||
tag_prefix="housing.rear.spider.bearing.hub",
|
||||
tags=("role.rear_motor_bearing_seat",),
|
||||
)
|
||||
solids = [hub]
|
||||
for _index, angle, center in radial_centers(count=4, radius=REAR_COLUMN_PCD / 2.0):
|
||||
for index, angle, center in radial_centers(count=4, radius=REAR_COLUMN_PCD / 2.0):
|
||||
arm = scad.make_box_rsolid(
|
||||
width=12.0,
|
||||
height=3.0,
|
||||
depth=5.0,
|
||||
bottom_face_center=(14.5, 0.0, bottom_z),
|
||||
tag_prefix=f"housing.rear.spider.arm{index + 1}",
|
||||
result_tag=f"feature.housing.rear.spider.arm{index + 1}",
|
||||
)
|
||||
solids.append(
|
||||
scad.rotate_shape(
|
||||
@@ -298,6 +316,8 @@ def make_rear_bearing_spider_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=5.0,
|
||||
bottom_face_center=(center[0], center[1], bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"housing.rear.spider.boss{index + 1}",
|
||||
result_tag=f"feature.housing.rear.spider.boss{index + 1}",
|
||||
)
|
||||
)
|
||||
spider = scad.union_rsolid(solids, glue=False)
|
||||
@@ -309,6 +329,7 @@ def make_rear_bearing_spider_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=REAR_FASTENER_HOLE_RADIUS,
|
||||
bottom_z=bottom_z - 1.0,
|
||||
height=7.0,
|
||||
tag_prefix="housing.rear.spider.fastener.clearance",
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
)
|
||||
@@ -329,6 +350,7 @@ def make_rear_bearing_spider_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_rear_electronics_cover_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create the rear cover with PCB standoffs and terminal apertures."""
|
||||
|
||||
@@ -337,15 +359,23 @@ def make_rear_electronics_cover_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=REAR_COVER_THICKNESS,
|
||||
bottom_face_center=(0.0, 0.0, REAR_COVER_BOTTOM_Z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="housing.rear.cover.plate",
|
||||
result_tag="feature.housing.rear.cover.plate",
|
||||
)
|
||||
standoffs = []
|
||||
for _index, _angle, center in radial_centers(count=4, radius=PCB_STANDOFF_PCD / 2.0, angle_offset=45.0):
|
||||
for index, _angle, center in radial_centers(
|
||||
count=4,
|
||||
radius=PCB_STANDOFF_PCD / 2.0,
|
||||
angle_offset=45.0,
|
||||
):
|
||||
standoffs.append(
|
||||
scad.make_cylinder_rsolid(
|
||||
radius=2.4,
|
||||
height=PCB_BOTTOM_Z - REAR_COVER_BOTTOM_Z - REAR_COVER_THICKNESS + 0.1,
|
||||
bottom_face_center=(center[0], center[1], REAR_COVER_BOTTOM_Z + REAR_COVER_THICKNESS - 0.1),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix=f"housing.rear.cover.pcb.standoff{index + 1}",
|
||||
result_tag=f"feature.housing.rear.cover.pcb.standoff{index + 1}",
|
||||
)
|
||||
)
|
||||
cover = scad.union_rsolid(cover, standoffs, glue=False)
|
||||
@@ -354,18 +384,24 @@ def make_rear_electronics_cover_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=7.2,
|
||||
depth=REAR_COVER_THICKNESS + 2.0,
|
||||
bottom_face_center=(-11.0, 0.0, REAR_COVER_BOTTOM_Z - 1.0),
|
||||
tag_prefix="housing.rear.cover.phase.aperture",
|
||||
result_tag="tool.housing.rear.cover.phase.aperture",
|
||||
)
|
||||
power_aperture = scad.make_box_rsolid(
|
||||
width=9.2,
|
||||
height=7.2,
|
||||
depth=REAR_COVER_THICKNESS + 2.0,
|
||||
bottom_face_center=(11.0, 0.0, REAR_COVER_BOTTOM_Z - 1.0),
|
||||
tag_prefix="housing.rear.cover.power.can.aperture",
|
||||
result_tag="tool.housing.rear.cover.power.can.aperture",
|
||||
)
|
||||
center_service = scad.make_cylinder_rsolid(
|
||||
radius=3.2,
|
||||
height=REAR_COVER_THICKNESS + 2.0,
|
||||
bottom_face_center=(0.0, 0.0, REAR_COVER_BOTTOM_Z - 1.0),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="housing.rear.cover.center.service",
|
||||
result_tag="tool.housing.rear.cover.center.service",
|
||||
)
|
||||
cover = scad.cut_rsolid(
|
||||
cover,
|
||||
@@ -378,6 +414,7 @@ def make_rear_electronics_cover_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=REAR_FASTENER_HOLE_RADIUS,
|
||||
bottom_z=REAR_COVER_BOTTOM_Z - 1.0,
|
||||
height=REAR_COVER_THICKNESS + 2.0,
|
||||
tag_prefix="housing.rear.cover.column.fastener.clearance",
|
||||
),
|
||||
make_axial_hole_cutters_rsolids(
|
||||
count=4,
|
||||
@@ -385,6 +422,7 @@ def make_rear_electronics_cover_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=1.1,
|
||||
bottom_z=REAR_COVER_BOTTOM_Z - 1.0,
|
||||
height=PCB_BOTTOM_Z - REAR_COVER_BOTTOM_Z + 2.0,
|
||||
tag_prefix="housing.rear.cover.pcb.fastener.clearance",
|
||||
angle_offset=45.0,
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
@@ -408,6 +446,7 @@ def make_rear_electronics_cover_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_output_bearing_cap_rpart(*, material: scad.Material) -> scad.Part:
|
||||
"""Create the removable paired-bearing cartridge and front cap."""
|
||||
|
||||
@@ -417,6 +456,7 @@ def make_output_bearing_cap_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=bearing_clearance_radius,
|
||||
bottom_z=OUTPUT_CAP_BOTTOM_Z,
|
||||
height=3.0,
|
||||
tag_prefix="housing.output.cap.rear.flange",
|
||||
tags=("role.output_cap_mount_flange",),
|
||||
)
|
||||
cartridge = make_annulus_rsolid(
|
||||
@@ -424,6 +464,7 @@ def make_output_bearing_cap_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=bearing_clearance_radius,
|
||||
bottom_z=OUTPUT_CAP_BOTTOM_Z,
|
||||
height=OUTPUT_CAP_CARTRIDGE_TOP_Z - OUTPUT_CAP_BOTTOM_Z + 0.1,
|
||||
tag_prefix="housing.output.cap.bearing.cartridge",
|
||||
tags=("role.paired_output_bearing_seat",),
|
||||
)
|
||||
bearing_retainer = make_annulus_rsolid(
|
||||
@@ -431,6 +472,7 @@ def make_output_bearing_cap_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=8.10,
|
||||
bottom_z=OUTPUT_CAP_CARTRIDGE_TOP_Z - 0.1,
|
||||
height=0.5,
|
||||
tag_prefix="housing.output.cap.bearing.retainer",
|
||||
tags=("role.output_axial_retainer",),
|
||||
)
|
||||
outer_lip = make_annulus_rsolid(
|
||||
@@ -438,6 +480,7 @@ def make_output_bearing_cap_rpart(*, material: scad.Material) -> scad.Part:
|
||||
inner_radius=OUTPUT_FLANGE_RADIUS + 0.30,
|
||||
bottom_z=OUTPUT_CAP_CARTRIDGE_TOP_Z - 0.1,
|
||||
height=OUTPUT_CAP_TOP_Z - OUTPUT_CAP_CARTRIDGE_TOP_Z + 0.1,
|
||||
tag_prefix="housing.output.cap.labyrinth.lip",
|
||||
tags=("role.output_labyrinth_lip",),
|
||||
)
|
||||
cap = scad.union_rsolid(rear_flange, cartridge, bearing_retainer, outer_lip, glue=False)
|
||||
@@ -449,6 +492,7 @@ def make_output_bearing_cap_rpart(*, material: scad.Material) -> scad.Part:
|
||||
hole_radius=M3_CLEARANCE_RADIUS,
|
||||
bottom_z=OUTPUT_CAP_BOTTOM_Z - 1.0,
|
||||
height=OUTPUT_CAP_TOP_Z - OUTPUT_CAP_BOTTOM_Z + 2.0,
|
||||
tag_prefix="housing.output.cap.interface.clearance",
|
||||
),
|
||||
skip_non_intersecting=False,
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Build, validate, replay, and export the integrated BLDC joint actuator."""
|
||||
"""Build and export the integrated BLDC joint actuator."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -8,19 +8,34 @@ from pathlib import Path
|
||||
|
||||
import simplecadapi as scad
|
||||
|
||||
from assembly import make_integrated_bldc_joint_actuator_rassembly
|
||||
from common import ground_compound
|
||||
from dimensions import (
|
||||
MOTOR_AIR_GAP,
|
||||
MOTOR_POLE_COUNT,
|
||||
MOTOR_SLOT_COUNT,
|
||||
PACKAGE_RADIUS,
|
||||
PACKAGE_STRUCTURAL_BOTTOM_Z,
|
||||
PACKAGE_TOP_Z,
|
||||
TOTAL_REDUCTION,
|
||||
validate_design_dimensions,
|
||||
)
|
||||
from materials import make_actuator_materials_rdict
|
||||
try:
|
||||
from .assembly import make_integrated_bldc_joint_actuator_rassembly
|
||||
from .common import ground_compound
|
||||
from .dimensions import (
|
||||
MOTOR_AIR_GAP,
|
||||
MOTOR_POLE_COUNT,
|
||||
MOTOR_SLOT_COUNT,
|
||||
PACKAGE_RADIUS,
|
||||
PACKAGE_STRUCTURAL_BOTTOM_Z,
|
||||
PACKAGE_TOP_Z,
|
||||
TOTAL_REDUCTION,
|
||||
validate_design_dimensions,
|
||||
)
|
||||
from .materials import make_actuator_materials_rdict
|
||||
except ImportError: # Support direct execution from this example directory.
|
||||
from assembly import make_integrated_bldc_joint_actuator_rassembly
|
||||
from common import ground_compound
|
||||
from dimensions import (
|
||||
MOTOR_AIR_GAP,
|
||||
MOTOR_POLE_COUNT,
|
||||
MOTOR_SLOT_COUNT,
|
||||
PACKAGE_RADIUS,
|
||||
PACKAGE_STRUCTURAL_BOTTOM_Z,
|
||||
PACKAGE_TOP_Z,
|
||||
TOTAL_REDUCTION,
|
||||
validate_design_dimensions,
|
||||
)
|
||||
from materials import make_actuator_materials_rdict
|
||||
|
||||
|
||||
sys.setrecursionlimit(30000)
|
||||
@@ -28,18 +43,21 @@ sys.setrecursionlimit(30000)
|
||||
OUT_DIR = Path("examples/out/integrated_bldc_joint_actuator")
|
||||
|
||||
|
||||
@scad.model(graph_id="integrated_50mm_bldc_joint_actuator")
|
||||
def build_integrated_bldc_joint_actuator():
|
||||
"""Build the replayable actuator and return product and interchange outputs."""
|
||||
|
||||
validate_design_dimensions()
|
||||
materials = make_actuator_materials_rdict()
|
||||
with scad.GraphSession(graph_id="integrated_50mm_bldc_joint_actuator") as session:
|
||||
assembly = make_integrated_bldc_joint_actuator_rassembly(materials=materials)
|
||||
preview = scad.make_compound_from_assembly_rcompound(assembly=assembly)
|
||||
ground_compound(label="integrated_actuator_preview", compound=preview)
|
||||
session_json = scad.export_session_json(session=session, indent=2)
|
||||
model_json = scad.export_model_json(session=session, indent=2)
|
||||
return assembly, preview, model_json, session_json
|
||||
assembly = make_integrated_bldc_joint_actuator_rassembly(materials=materials)
|
||||
preview = scad.make_compound_from_assembly_rcompound(assembly=assembly)
|
||||
preview = scad.apply_tag(
|
||||
shape=preview,
|
||||
tag="scene.integrated.bldc.joint.actuator.preview",
|
||||
)
|
||||
ground_compound(label="integrated_actuator_preview", compound=preview)
|
||||
scad.capture_result(value=(assembly, preview))
|
||||
return assembly, preview
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -53,19 +71,18 @@ def main() -> None:
|
||||
if fcstd_path.exists():
|
||||
fcstd_path.unlink()
|
||||
|
||||
assembly, preview, model_json, session_json = build_integrated_bldc_joint_actuator()
|
||||
model_path.write_text(model_json, encoding="utf-8")
|
||||
session_path.write_text(session_json, encoding="utf-8")
|
||||
result = build_integrated_bldc_joint_actuator()
|
||||
assembly, preview = result.value
|
||||
model_path.write_text(result.model_json, encoding="utf-8")
|
||||
session_path.write_text(result.session_json, encoding="utf-8")
|
||||
scad.export_step(shapes=preview, filename=str(step_path))
|
||||
|
||||
imported = scad.import_model_json(json_str=model_json)
|
||||
replayed = scad.replay_model_json(json_str=model_json, strict=True)
|
||||
payload = json.loads(model_json)
|
||||
payload = json.loads(result.model_json)
|
||||
|
||||
fcstd_status = "not attempted"
|
||||
try:
|
||||
scad.translator.freecad_translator.translate_model_json_to_fcstd(
|
||||
json_str=model_json,
|
||||
json_str=result.model_json,
|
||||
output_path=str(fcstd_path.resolve()),
|
||||
document_name="Integrated50mmBLDCJointActuator",
|
||||
freecad_cmd=None,
|
||||
@@ -84,9 +101,6 @@ def main() -> None:
|
||||
print(f"constraints={len(assembly.constraint_ids())}")
|
||||
print(f"preview_solids={len(preview.get_solids())}")
|
||||
print(f"preview_volume={preview.get_volume():.3f}")
|
||||
print(f"imported_keys={','.join(sorted(imported.keys()))}")
|
||||
print(f"replay_outputs={len(replayed)}")
|
||||
print("replay_types=" + ",".join(type(item).__name__ for item in replayed))
|
||||
print(f"graph_nodes={len(payload['graph']['nodes'])}")
|
||||
print(f"model={model_path}")
|
||||
print(f"session={session_path}")
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
import simplecadapi as scad
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_actuator_materials_rdict() -> dict[str, scad.Material]:
|
||||
"""Create the materials used by Case 20."""
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ except ImportError: # Support direct execution from this example directory.
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_bldc_stator_rassembly(
|
||||
*,
|
||||
steel_material: scad.Material,
|
||||
@@ -130,6 +131,7 @@ def make_bldc_stator_rassembly(
|
||||
return stator
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def make_bldc_rotor_rassembly(
|
||||
*,
|
||||
steel_material: scad.Material,
|
||||
@@ -190,23 +192,27 @@ def make_bldc_rotor_rassembly(
|
||||
return rotor
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_stator_core_rpart(*, material: scad.Material) -> scad.Part:
|
||||
yoke = make_annulus_rsolid(
|
||||
outer_radius=MOTOR_STATOR_OUTER_RADIUS,
|
||||
inner_radius=MOTOR_STATOR_YOKE_INNER_RADIUS,
|
||||
bottom_z=MOTOR_STATOR_BOTTOM_Z,
|
||||
height=MOTOR_STATOR_TOP_Z - MOTOR_STATOR_BOTTOM_Z,
|
||||
tag_prefix="motor.stator.back.iron",
|
||||
tags=("role.stator_back_iron",),
|
||||
)
|
||||
tooth_length = MOTOR_STATOR_YOKE_INNER_RADIUS - MOTOR_STATOR_TOOTH_INNER_RADIUS + 0.40
|
||||
tooth_center_radius = MOTOR_STATOR_TOOTH_INNER_RADIUS + tooth_length / 2.0
|
||||
teeth = []
|
||||
for _index, angle, _center in radial_centers(count=MOTOR_SLOT_COUNT, radius=0.0):
|
||||
for index, angle, _center in radial_centers(count=MOTOR_SLOT_COUNT, radius=0.0):
|
||||
tooth = scad.make_box_rsolid(
|
||||
width=tooth_length,
|
||||
height=MOTOR_STATOR_TOOTH_WIDTH,
|
||||
depth=MOTOR_STATOR_TOP_Z - MOTOR_STATOR_BOTTOM_Z,
|
||||
bottom_face_center=(tooth_center_radius, 0.0, MOTOR_STATOR_BOTTOM_Z),
|
||||
tag_prefix=f"motor.stator.tooth{index + 1}",
|
||||
result_tag=f"feature.motor.stator.tooth{index + 1}",
|
||||
)
|
||||
teeth.append(
|
||||
scad.rotate_shape(
|
||||
@@ -255,6 +261,7 @@ def _make_stator_core_rpart(*, material: scad.Material) -> scad.Part:
|
||||
return part
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_winding_pack_rpart(*, material: scad.Material) -> scad.Part:
|
||||
side_depth = MOTOR_STATOR_TOP_Z - MOTOR_STATOR_BOTTOM_Z + 0.4
|
||||
side_bottom_z = MOTOR_STATOR_BOTTOM_Z - 0.2
|
||||
@@ -263,24 +270,32 @@ def _make_winding_pack_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=1.2,
|
||||
depth=side_depth,
|
||||
bottom_face_center=(17.55, 2.1, side_bottom_z),
|
||||
tag_prefix="motor.winding.side.positive",
|
||||
result_tag="feature.motor.winding.side.positive",
|
||||
)
|
||||
side_negative = scad.make_box_rsolid(
|
||||
width=4.2,
|
||||
height=1.2,
|
||||
depth=side_depth,
|
||||
bottom_face_center=(17.55, -2.1, side_bottom_z),
|
||||
tag_prefix="motor.winding.side.negative",
|
||||
result_tag="feature.motor.winding.side.negative",
|
||||
)
|
||||
rear_end_turn = scad.make_box_rsolid(
|
||||
width=4.2,
|
||||
height=5.4,
|
||||
depth=0.9,
|
||||
bottom_face_center=(17.55, 0.0, MOTOR_STATOR_BOTTOM_Z - 1.0),
|
||||
tag_prefix="motor.winding.rear.end.turn",
|
||||
result_tag="feature.motor.winding.rear.end.turn",
|
||||
)
|
||||
front_end_turn = scad.make_box_rsolid(
|
||||
width=4.2,
|
||||
height=5.4,
|
||||
depth=0.9,
|
||||
bottom_face_center=(17.55, 0.0, MOTOR_STATOR_TOP_Z + 0.1),
|
||||
tag_prefix="motor.winding.front.end.turn",
|
||||
result_tag="feature.motor.winding.front.end.turn",
|
||||
)
|
||||
winding = scad.union_rsolid(
|
||||
side_positive,
|
||||
@@ -302,6 +317,7 @@ def _make_winding_pack_rpart(*, material: scad.Material) -> scad.Part:
|
||||
)
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_rotor_shaft_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
shaft_bottom_z = REAR_BEARING_CENTER_Z - 3.0
|
||||
shaft = scad.make_cylinder_rsolid(
|
||||
@@ -309,12 +325,16 @@ def _make_rotor_shaft_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=STAGE_1.top_z - shaft_bottom_z,
|
||||
bottom_face_center=(0.0, 0.0, shaft_bottom_z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="motor.rotor.drive.shaft",
|
||||
result_tag="feature.motor.rotor.drive.shaft",
|
||||
)
|
||||
back_iron = scad.make_cylinder_rsolid(
|
||||
radius=MOTOR_ROTOR_BACKIRON_RADIUS,
|
||||
height=MOTOR_ROTOR_TOP_Z - MOTOR_ROTOR_BOTTOM_Z,
|
||||
bottom_face_center=(0.0, 0.0, MOTOR_ROTOR_BOTTOM_Z),
|
||||
axis=(0.0, 0.0, 1.0),
|
||||
tag_prefix="motor.rotor.back.iron",
|
||||
result_tag="feature.motor.rotor.back.iron",
|
||||
)
|
||||
sun = scad.std.gear.make_herringbone_gear_rsolid(
|
||||
n_teeth=STAGE_1.sun_teeth,
|
||||
@@ -326,6 +346,10 @@ def _make_rotor_shaft_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
clearance_factor=CLEARANCE_FACTOR,
|
||||
backlash=BACKLASH,
|
||||
)
|
||||
sun = scad.apply_tag(
|
||||
shape=sun,
|
||||
tag="solid.stdlib.stage1.integral.herringbone.sun.gear",
|
||||
)
|
||||
sun = scad.translate_shape(shape=sun, vector=(0.0, 0.0, STAGE_1.bottom_z))
|
||||
rotor = scad.union_rsolid(shaft, back_iron, sun, glue=False)
|
||||
rotor = apply_tags(
|
||||
@@ -354,6 +378,7 @@ def _make_rotor_shaft_sun_rpart(*, material: scad.Material) -> scad.Part:
|
||||
return part
|
||||
|
||||
|
||||
@scad.requires_session
|
||||
def _make_rotor_magnet_rpart(*, material: scad.Material) -> scad.Part:
|
||||
half_width = MOTOR_MAGNET_TANGENTIAL_WIDTH / 2.0
|
||||
outer_x = (MOTOR_MAGNET_OUTER_RADIUS**2 - half_width**2) ** 0.5
|
||||
@@ -363,6 +388,8 @@ def _make_rotor_magnet_rpart(*, material: scad.Material) -> scad.Part:
|
||||
height=MOTOR_MAGNET_TANGENTIAL_WIDTH,
|
||||
depth=MOTOR_ROTOR_TOP_Z - MOTOR_ROTOR_BOTTOM_Z,
|
||||
bottom_face_center=(outer_x - radial_depth / 2.0, 0.0, MOTOR_ROTOR_BOTTOM_Z),
|
||||
tag_prefix="motor.rotor.reusable.magnet",
|
||||
result_tag="feature.motor.rotor.reusable.magnet",
|
||||
)
|
||||
magnet = apply_tags(shape=magnet, tags=("role.rotor_magnet", "group.rotor_magnets"))
|
||||
print(
|
||||
|
||||
Reference in New Issue
Block a user