cosplay: Touhou/Houjuu Nue #4
|
@ -76,8 +76,8 @@ class RootJoint(Model):
|
||||||
hirth_joint: HirthJoint = field(default_factory=lambda: HirthJoint(
|
hirth_joint: HirthJoint = field(default_factory=lambda: HirthJoint(
|
||||||
radius=25.0,
|
radius=25.0,
|
||||||
radius_inner=15.0,
|
radius_inner=15.0,
|
||||||
tooth_height=7.0,
|
tooth_height=5.60,
|
||||||
base_height=5.0,
|
base_height=4.0,
|
||||||
n_tooth=24,
|
n_tooth=24,
|
||||||
))
|
))
|
||||||
parent_width: float = 85
|
parent_width: float = 85
|
||||||
|
@ -100,6 +100,10 @@ class RootJoint(Model):
|
||||||
child_width: float = 50.0
|
child_width: float = 50.0
|
||||||
child_mount_thickness: float = 25.4 / 4
|
child_mount_thickness: float = 25.4 / 4
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
assert self.child_extra_thickness > 0.0
|
||||||
|
assert self.parent_thickness >= self.hex_nut.thickness
|
||||||
|
|
||||||
def corner_pos(self) -> list[tuple[int, int]]:
|
def corner_pos(self) -> list[tuple[int, int]]:
|
||||||
"""
|
"""
|
||||||
Generates a set of points corresponding to the connectorss
|
Generates a set of points corresponding to the connectorss
|
||||||
|
@ -113,8 +117,15 @@ class RootJoint(Model):
|
||||||
]
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total_height(self) -> float:
|
def child_extra_thickness(self) -> float:
|
||||||
return self.parent_thickness + self.hirth_joint.total_height
|
"""
|
||||||
|
Extra thickness allocated to child for padding
|
||||||
|
"""
|
||||||
|
return self.knob.height_thread - self.hirth_joint.joint_height - self.child_mount_thickness - self.parent_thickness
|
||||||
|
|
||||||
|
@property
|
||||||
|
def base_to_surface_thickness(self) -> float:
|
||||||
|
return self.hirth_joint.joint_height + self.child_extra_thickness
|
||||||
|
|
||||||
@target(name="parent")
|
@target(name="parent")
|
||||||
def parent(self):
|
def parent(self):
|
||||||
|
@ -127,9 +138,9 @@ class RootJoint(Model):
|
||||||
result = (
|
result = (
|
||||||
Cq.Workplane('XY')
|
Cq.Workplane('XY')
|
||||||
.box(
|
.box(
|
||||||
self.parent_width,
|
length=self.parent_width,
|
||||||
self.parent_width,
|
width=self.parent_width,
|
||||||
self.parent_thickness,
|
height=self.parent_thickness,
|
||||||
centered=(True, True, False))
|
centered=(True, True, False))
|
||||||
.translate((0, 0, -self.parent_thickness))
|
.translate((0, 0, -self.parent_thickness))
|
||||||
.edges("|Z")
|
.edges("|Z")
|
||||||
|
@ -177,11 +188,11 @@ class RootJoint(Model):
|
||||||
result = (
|
result = (
|
||||||
Cq.Workplane('XY')
|
Cq.Workplane('XY')
|
||||||
.box(
|
.box(
|
||||||
self.child_height,
|
length=self.child_height,
|
||||||
self.child_width,
|
width=self.child_width,
|
||||||
self.hirth_joint.base_height,
|
height=self.child_extra_thickness + self.hirth_joint.base_height,
|
||||||
centered=(True, True, False))
|
centered=(True, True, False))
|
||||||
#.translate((0, 0, -self.base_joint.base_height))
|
.translate((0, 0, -self.child_extra_thickness))
|
||||||
#.edges("|Z")
|
#.edges("|Z")
|
||||||
#.fillet(self.hs_joint_corner_fillet)
|
#.fillet(self.hs_joint_corner_fillet)
|
||||||
.faces(">Z")
|
.faces(">Z")
|
||||||
|
@ -190,7 +201,7 @@ class RootJoint(Model):
|
||||||
.hole(self.corner_hole_diam)
|
.hole(self.corner_hole_diam)
|
||||||
)
|
)
|
||||||
# Creates a plane parallel to the holes but shifted to the base
|
# Creates a plane parallel to the holes but shifted to the base
|
||||||
plane = result.faces(">Z").workplane(offset=-self.hirth_joint.base_height)
|
plane = result.copyWorkplane(Cq.Workplane('XY', origin=(0, 0, -self.child_extra_thickness)))
|
||||||
|
|
||||||
for i, (px, py) in enumerate(conn):
|
for i, (px, py) in enumerate(conn):
|
||||||
plane.moveTo(px, py).tagPlane(f"conn{i}")
|
plane.moveTo(px, py).tagPlane(f"conn{i}")
|
||||||
|
@ -232,7 +243,7 @@ class RootJoint(Model):
|
||||||
result
|
result
|
||||||
.addS(self.hex_nut.assembly(), name="hex_nut")
|
.addS(self.hex_nut.assembly(), name="hex_nut")
|
||||||
.addS(self.knob.assembly(), name="knob",
|
.addS(self.knob.assembly(), name="knob",
|
||||||
loc=Cq.Location((0, 0, knob_h * fastener_pos)))
|
loc=Cq.Location((0, 0, knob_h * fastener_pos - self.parent_thickness)))
|
||||||
.constrain("knob/thread", "Fixed")
|
.constrain("knob/thread", "Fixed")
|
||||||
.constrain("hex_nut?bot", "parent?base", "Plane", param=0)
|
.constrain("hex_nut?bot", "parent?base", "Plane", param=0)
|
||||||
.constrain("hex_nut?dirX", "parent@faces@>X", "Axis", param=0)
|
.constrain("hex_nut?dirX", "parent@faces@>X", "Axis", param=0)
|
||||||
|
@ -1071,6 +1082,14 @@ class ElbowJoint(Model):
|
||||||
motion_span=self.motion_span
|
motion_span=self.motion_span
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def hole_loc_tags(self):
|
||||||
|
"""
|
||||||
|
An iterator which iterates through positions of the hole and tags
|
||||||
|
"""
|
||||||
|
for i, x in enumerate(self.hole_pos):
|
||||||
|
yield x, f"conn_top{i}"
|
||||||
|
yield -x, f"conn_bot{i}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total_thickness(self):
|
def total_thickness(self):
|
||||||
return self.disk_joint.total_thickness
|
return self.disk_joint.total_thickness
|
||||||
|
|
|
@ -63,6 +63,7 @@ class WingProfile(Model):
|
||||||
angle_neutral=10.0,
|
angle_neutral=10.0,
|
||||||
actuator=LINEAR_ACTUATOR_50,
|
actuator=LINEAR_ACTUATOR_50,
|
||||||
flexor_offset_angle=30,
|
flexor_offset_angle=30,
|
||||||
|
parent_arm_width=15,
|
||||||
flip=False,
|
flip=False,
|
||||||
))
|
))
|
||||||
# Distance between the two spacers on the elbow, halved
|
# Distance between the two spacers on the elbow, halved
|
||||||
|
@ -353,7 +354,7 @@ class WingProfile(Model):
|
||||||
|
|
||||||
def surface_s0(self, top: bool = False) -> Cq.Workplane:
|
def surface_s0(self, top: bool = False) -> Cq.Workplane:
|
||||||
base_dx = -(self.base_width - self.root_joint.child_width) / 2 - 10
|
base_dx = -(self.base_width - self.root_joint.child_width) / 2 - 10
|
||||||
base_dy = self.root_joint.hirth_joint.joint_height
|
base_dy = self.root_joint.base_to_surface_thickness
|
||||||
#mid_spacer_loc = (
|
#mid_spacer_loc = (
|
||||||
# Cq.Location.from2d(0, -self.shoulder_width/2) *
|
# Cq.Location.from2d(0, -self.shoulder_width/2) *
|
||||||
# self.shoulder_axle_loc *
|
# self.shoulder_axle_loc *
|
||||||
|
@ -593,6 +594,25 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
return mbox
|
return mbox
|
||||||
|
|
||||||
|
def _spacer_from_disk_joint(
|
||||||
|
self,
|
||||||
|
joint: ElbowJoint,
|
||||||
|
segment_thickness: float,
|
||||||
|
) -> MountingBox:
|
||||||
|
holes = [
|
||||||
|
Hole(x, tag=tag)
|
||||||
|
for x, tag in joint.hole_loc_tags()
|
||||||
|
]
|
||||||
|
mbox = MountingBox(
|
||||||
|
length=joint.lip_length,
|
||||||
|
width=segment_thickness,
|
||||||
|
thickness=self.spacer_thickness,
|
||||||
|
holes=holes,
|
||||||
|
hole_diam=joint.hole_diam,
|
||||||
|
centred=(True, True),
|
||||||
|
centre_left_right_tags=True,
|
||||||
|
)
|
||||||
|
return mbox
|
||||||
|
|
||||||
@target(name="profile-s1", kind=TargetKind.DXF)
|
@target(name="profile-s1", kind=TargetKind.DXF)
|
||||||
def profile_s1(self) -> Cq.Sketch:
|
def profile_s1(self) -> Cq.Sketch:
|
||||||
|
@ -615,23 +635,17 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
return profile
|
return profile
|
||||||
def surface_s1(self, front: bool = True) -> Cq.Workplane:
|
def surface_s1(self, front: bool = True) -> Cq.Workplane:
|
||||||
tags_shoulder = [
|
rot_elbow = Cq.Location.rot2d(self.elbow_rotate)
|
||||||
|
loc_elbow = rot_elbow * self.elbow_joint.parent_arm_loc()
|
||||||
|
tags = [
|
||||||
("shoulder",
|
("shoulder",
|
||||||
Cq.Location((0, self.shoulder_height / 2, 0)) *
|
Cq.Location((0, self.shoulder_height / 2, 0)) *
|
||||||
self.shoulder_joint.child_lip_loc()),
|
self.shoulder_joint.child_lip_loc()),
|
||||||
]
|
("elbow", self.elbow_axle_loc * loc_elbow),
|
||||||
rot_elbow = Cq.Location.rot2d(self.elbow_rotate)
|
|
||||||
loc_elbow = rot_elbow * self.elbow_joint.parent_arm_loc()
|
|
||||||
tags_elbow = [
|
|
||||||
("elbow_bot", self.elbow_axle_loc * loc_elbow *
|
|
||||||
Cq.Location.from2d(0, -self.elbow_h2)),
|
|
||||||
("elbow_top", self.elbow_axle_loc * loc_elbow *
|
|
||||||
Cq.Location.from2d(0, self.elbow_h2)),
|
|
||||||
("elbow_act", self.elbow_axle_loc * rot_elbow *
|
("elbow_act", self.elbow_axle_loc * rot_elbow *
|
||||||
self.elbow_joint.actuator_mount_loc()),
|
self.elbow_joint.actuator_mount_loc()),
|
||||||
]
|
]
|
||||||
profile = self.profile_s1()
|
profile = self.profile_s1()
|
||||||
tags = tags_shoulder + tags_elbow
|
|
||||||
return extrude_with_markers(
|
return extrude_with_markers(
|
||||||
profile, self.panel_thickness, tags, reverse=front)
|
profile, self.panel_thickness, tags, reverse=front)
|
||||||
@submodel(name="spacer-s1-shoulder")
|
@submodel(name="spacer-s1-shoulder")
|
||||||
|
@ -653,10 +667,9 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
@submodel(name="spacer-s1-elbow")
|
@submodel(name="spacer-s1-elbow")
|
||||||
def spacer_s1_elbow(self) -> MountingBox:
|
def spacer_s1_elbow(self) -> MountingBox:
|
||||||
return self.spacer_of_joint(
|
return self._spacer_from_disk_joint(
|
||||||
joint=self.elbow_joint,
|
joint=self.elbow_joint,
|
||||||
segment_thickness=self.s1_thickness,
|
segment_thickness=self.s1_thickness,
|
||||||
dx=self.elbow_h2,
|
|
||||||
)
|
)
|
||||||
@submodel(name="spacer-s1-elbow-act")
|
@submodel(name="spacer-s1-elbow-act")
|
||||||
def spacer_s1_elbow_act(self) -> MountingBox:
|
def spacer_s1_elbow_act(self) -> MountingBox:
|
||||||
|
@ -683,16 +696,14 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
for o, t in [
|
for o, t in [
|
||||||
(self.spacer_s1_shoulder(), "shoulder"),
|
(self.spacer_s1_shoulder(), "shoulder"),
|
||||||
(self.spacer_s1_elbow(), "elbow_top"),
|
(self.spacer_s1_elbow(), "elbow"),
|
||||||
(self.spacer_s1_elbow(), "elbow_bot"),
|
|
||||||
(self.spacer_s1_elbow_act(), "elbow_act"),
|
(self.spacer_s1_elbow_act(), "elbow_act"),
|
||||||
]:
|
]:
|
||||||
is_top = t.endswith("_top")
|
|
||||||
self._assembly_insert_spacer(
|
self._assembly_insert_spacer(
|
||||||
result,
|
result,
|
||||||
o.generate(),
|
o.generate(),
|
||||||
point_tag=t,
|
point_tag=t,
|
||||||
flipped=not is_top,
|
flipped=True,
|
||||||
)
|
)
|
||||||
return result.solve()
|
return result.solve()
|
||||||
|
|
||||||
|
@ -743,24 +754,21 @@ class WingProfile(Model):
|
||||||
return profile
|
return profile
|
||||||
def surface_s2(self, front: bool = True) -> Cq.Workplane:
|
def surface_s2(self, front: bool = True) -> Cq.Workplane:
|
||||||
loc_elbow = Cq.Location.rot2d(self.elbow_rotate) * self.elbow_joint.child_arm_loc()
|
loc_elbow = Cq.Location.rot2d(self.elbow_rotate) * self.elbow_joint.child_arm_loc()
|
||||||
tags_elbow = [
|
|
||||||
("elbow_bot", self.elbow_axle_loc * loc_elbow *
|
|
||||||
Cq.Location.from2d(0, self.elbow_h2)),
|
|
||||||
("elbow_top", self.elbow_axle_loc * loc_elbow *
|
|
||||||
Cq.Location.from2d(0, -self.elbow_h2)),
|
|
||||||
]
|
|
||||||
rot_wrist = Cq.Location.rot2d(self.wrist_rotate)
|
rot_wrist = Cq.Location.rot2d(self.wrist_rotate)
|
||||||
loc_wrist = rot_wrist * self.wrist_joint.parent_arm_loc()
|
loc_wrist = rot_wrist * self.wrist_joint.parent_arm_loc()
|
||||||
tags_wrist = [
|
tags = [
|
||||||
|
("elbow", self.elbow_axle_loc * loc_elbow),
|
||||||
|
("wrist", self.wrist_axle_loc * loc_wrist),
|
||||||
|
("wrist_act", self.wrist_axle_loc * rot_wrist *
|
||||||
|
self.wrist_joint.actuator_mount_loc()),
|
||||||
|
|
||||||
|
# for mounting the bridge only
|
||||||
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
||||||
Cq.Location.from2d(0, -self.wrist_h2)),
|
Cq.Location.from2d(0, -self.wrist_h2)),
|
||||||
("wrist_top", self.wrist_axle_loc * loc_wrist *
|
("wrist_top", self.wrist_axle_loc * loc_wrist *
|
||||||
Cq.Location.from2d(0, self.wrist_h2)),
|
Cq.Location.from2d(0, self.wrist_h2)),
|
||||||
("wrist_act", self.wrist_axle_loc * rot_wrist *
|
|
||||||
self.wrist_joint.actuator_mount_loc()),
|
|
||||||
]
|
]
|
||||||
profile = self.profile_s2()
|
profile = self.profile_s2()
|
||||||
tags = tags_elbow + tags_wrist
|
|
||||||
return extrude_with_markers(profile, self.panel_thickness, tags, reverse=front)
|
return extrude_with_markers(profile, self.panel_thickness, tags, reverse=front)
|
||||||
def surface_s2_bridge(self, front: bool = True) -> Optional[Cq.Workplane]:
|
def surface_s2_bridge(self, front: bool = True) -> Optional[Cq.Workplane]:
|
||||||
profile = self.profile_s2_bridge()
|
profile = self.profile_s2_bridge()
|
||||||
|
@ -777,17 +785,15 @@ class WingProfile(Model):
|
||||||
profile, self.panel_thickness, tags, reverse=not front)
|
profile, self.panel_thickness, tags, reverse=not front)
|
||||||
@submodel(name="spacer-s2-elbow")
|
@submodel(name="spacer-s2-elbow")
|
||||||
def spacer_s2_elbow(self) -> MountingBox:
|
def spacer_s2_elbow(self) -> MountingBox:
|
||||||
return self.spacer_of_joint(
|
return self._spacer_from_disk_joint(
|
||||||
joint=self.elbow_joint,
|
joint=self.elbow_joint,
|
||||||
segment_thickness=self.s2_thickness,
|
segment_thickness=self.s2_thickness,
|
||||||
dx=self.elbow_h2,
|
|
||||||
)
|
)
|
||||||
@submodel(name="spacer-s2-wrist")
|
@submodel(name="spacer-s2-wrist")
|
||||||
def spacer_s2_wrist(self) -> MountingBox:
|
def spacer_s2_wrist(self) -> MountingBox:
|
||||||
return self.spacer_of_joint(
|
return self._spacer_from_disk_joint(
|
||||||
joint=self.wrist_joint,
|
joint=self.wrist_joint,
|
||||||
segment_thickness=self.s2_thickness,
|
segment_thickness=self.s2_thickness,
|
||||||
dx=self.wrist_h2,
|
|
||||||
)
|
)
|
||||||
@submodel(name="spacer-s2-wrist-act")
|
@submodel(name="spacer-s2-wrist-act")
|
||||||
def spacer_s2_wrist_act(self) -> MountingBox:
|
def spacer_s2_wrist_act(self) -> MountingBox:
|
||||||
|
@ -831,20 +837,16 @@ class WingProfile(Model):
|
||||||
.constrain("back?wrist_top", "bridge_back?wrist_top", "Plane")
|
.constrain("back?wrist_top", "bridge_back?wrist_top", "Plane")
|
||||||
)
|
)
|
||||||
for o, t in [
|
for o, t in [
|
||||||
(self.spacer_s2_elbow(), "elbow_bot"),
|
(self.spacer_s2_elbow(), "elbow"),
|
||||||
(self.spacer_s2_elbow(), "elbow_top"),
|
(self.spacer_s2_wrist(), "wrist"),
|
||||||
(self.spacer_s2_wrist(), "wrist_bot"),
|
|
||||||
(self.spacer_s2_wrist(), "wrist_top"),
|
|
||||||
(self.spacer_s2_wrist_act(), "wrist_act"),
|
(self.spacer_s2_wrist_act(), "wrist_act"),
|
||||||
]:
|
]:
|
||||||
is_top = t.endswith("_top")
|
|
||||||
is_parent = t.startswith("elbow")
|
is_parent = t.startswith("elbow")
|
||||||
self._assembly_insert_spacer(
|
self._assembly_insert_spacer(
|
||||||
result,
|
result,
|
||||||
o.generate(),
|
o.generate(),
|
||||||
point_tag=t,
|
point_tag=t,
|
||||||
flipped=is_top == is_parent,
|
flipped=is_parent,
|
||||||
#rotate=not is_parent,
|
|
||||||
)
|
)
|
||||||
return result.solve()
|
return result.solve()
|
||||||
|
|
||||||
|
@ -878,6 +880,7 @@ class WingProfile(Model):
|
||||||
front: bool = True) -> Cq.Workplane:
|
front: bool = True) -> Cq.Workplane:
|
||||||
loc_wrist = Cq.Location.rot2d(self.wrist_rotate) * self.wrist_joint.child_arm_loc()
|
loc_wrist = Cq.Location.rot2d(self.wrist_rotate) * self.wrist_joint.child_arm_loc()
|
||||||
tags = [
|
tags = [
|
||||||
|
("wrist", self.wrist_axle_loc * loc_wrist),
|
||||||
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
||||||
Cq.Location.from2d(0, self.wrist_h2)),
|
Cq.Location.from2d(0, self.wrist_h2)),
|
||||||
("wrist_top", self.wrist_axle_loc * loc_wrist *
|
("wrist_top", self.wrist_axle_loc * loc_wrist *
|
||||||
|
@ -900,10 +903,9 @@ class WingProfile(Model):
|
||||||
return extrude_with_markers(profile, self.panel_thickness, tags, reverse=not front)
|
return extrude_with_markers(profile, self.panel_thickness, tags, reverse=not front)
|
||||||
@submodel(name="spacer-s3-wrist")
|
@submodel(name="spacer-s3-wrist")
|
||||||
def spacer_s3_wrist(self) -> MountingBox:
|
def spacer_s3_wrist(self) -> MountingBox:
|
||||||
return self.spacer_of_joint(
|
return self._spacer_from_disk_joint(
|
||||||
joint=self.wrist_joint,
|
joint=self.wrist_joint,
|
||||||
segment_thickness=self.s3_thickness,
|
segment_thickness=self.s3_thickness,
|
||||||
dx=self.wrist_h2,
|
|
||||||
)
|
)
|
||||||
@assembly()
|
@assembly()
|
||||||
def assembly_s3(self) -> Cq.Assembly:
|
def assembly_s3(self) -> Cq.Assembly:
|
||||||
|
@ -929,19 +931,17 @@ class WingProfile(Model):
|
||||||
.constrain("back?wrist_bot", "extra_back?wrist_bot", "Plane")
|
.constrain("back?wrist_bot", "extra_back?wrist_bot", "Plane")
|
||||||
.constrain("back?wrist_top", "extra_back?wrist_top", "Plane")
|
.constrain("back?wrist_top", "extra_back?wrist_top", "Plane")
|
||||||
)
|
)
|
||||||
for t in ["wrist_bot", "wrist_top"]:
|
|
||||||
is_top = t.endswith("_top")
|
|
||||||
o = self.spacer_s3_wrist()
|
|
||||||
self._assembly_insert_spacer(
|
self._assembly_insert_spacer(
|
||||||
result,
|
result,
|
||||||
o.generate(),
|
self.spacer_s3_wrist().generate(),
|
||||||
point_tag=t,
|
point_tag="wrist",
|
||||||
flipped=is_top,
|
flipped=True,
|
||||||
)
|
)
|
||||||
return result.solve()
|
return result.solve()
|
||||||
|
|
||||||
@assembly()
|
@assembly()
|
||||||
def assembly(self,
|
def assembly(
|
||||||
|
self,
|
||||||
parts: Optional[list[str]] = None,
|
parts: Optional[list[str]] = None,
|
||||||
shoulder_deflection: float = 0.0,
|
shoulder_deflection: float = 0.0,
|
||||||
elbow_wrist_deflection: float = 0.0,
|
elbow_wrist_deflection: float = 0.0,
|
||||||
|
@ -1013,55 +1013,44 @@ class WingProfile(Model):
|
||||||
angle=angle,
|
angle=angle,
|
||||||
ignore_actuators=ignore_actuators), name="elbow")
|
ignore_actuators=ignore_actuators), name="elbow")
|
||||||
if "s1" in parts and "elbow" in parts:
|
if "s1" in parts and "elbow" in parts:
|
||||||
(
|
for _, tag in self.elbow_joint.hole_loc_tags():
|
||||||
result
|
result.constrain(
|
||||||
.constrain("s1/elbow_top?conn0", "elbow/parent_upper/lip?conn_top0", "Plane")
|
f"s1/elbow?{tag}",
|
||||||
.constrain("s1/elbow_top?conn1", "elbow/parent_upper/lip?conn_top1", "Plane")
|
f"elbow/parent_upper/lip?{tag}", "Plane")
|
||||||
.constrain("s1/elbow_bot?conn0", "elbow/parent_upper/lip?conn_bot0", "Plane")
|
|
||||||
.constrain("s1/elbow_bot?conn1", "elbow/parent_upper/lip?conn_bot1", "Plane")
|
|
||||||
)
|
|
||||||
if not ignore_actuators:
|
if not ignore_actuators:
|
||||||
(
|
result.constrain(
|
||||||
result
|
"elbow/bracket_back?conn_side",
|
||||||
.constrain("elbow/bracket_back?conn_side", "s1/elbow_act?conn0", "Plane")
|
"s1/elbow_act?conn0",
|
||||||
)
|
"Plane")
|
||||||
if "s2" in parts:
|
if "s2" in parts:
|
||||||
result.add(self.assembly_s2(), name="s2")
|
result.add(self.assembly_s2(), name="s2")
|
||||||
if "s2" in parts and "elbow" in parts:
|
if "s2" in parts and "elbow" in parts:
|
||||||
(
|
for _, tag in self.elbow_joint.hole_loc_tags():
|
||||||
result
|
result.constrain(
|
||||||
.constrain("s2/elbow_top?conn0", "elbow/child/lip?conn_top0", "Plane")
|
f"s2/elbow?{tag}",
|
||||||
.constrain("s2/elbow_top?conn1", "elbow/child/lip?conn_top1", "Plane")
|
f"elbow/child/lip?{tag}", "Plane")
|
||||||
.constrain("s2/elbow_bot?conn0", "elbow/child/lip?conn_bot0", "Plane")
|
|
||||||
.constrain("s2/elbow_bot?conn1", "elbow/child/lip?conn_bot1", "Plane")
|
|
||||||
)
|
|
||||||
if "wrist" in parts:
|
if "wrist" in parts:
|
||||||
angle = self.wrist_joint.motion_span * elbow_wrist_deflection
|
angle = self.wrist_joint.motion_span * elbow_wrist_deflection
|
||||||
result.add(self.wrist_joint.assembly(
|
result.add(self.wrist_joint.assembly(
|
||||||
angle=angle,
|
angle=angle,
|
||||||
ignore_actuators=ignore_actuators), name="wrist")
|
ignore_actuators=ignore_actuators), name="wrist")
|
||||||
wrist_n_holes = len(self.wrist_joint.hole_pos)
|
|
||||||
if "s2" in parts and "wrist" in parts:
|
if "s2" in parts and "wrist" in parts:
|
||||||
for i in range(wrist_n_holes):
|
for _, tag in self.wrist_joint.hole_loc_tags():
|
||||||
(
|
result.constrain(
|
||||||
result
|
f"s2/wrist?{tag}",
|
||||||
.constrain(f"s2/wrist_top?conn{i}", f"wrist/parent_upper/lip?conn_top{i}", "Plane")
|
f"wrist/parent_upper/lip?{tag}", "Plane")
|
||||||
.constrain(f"s2/wrist_bot?conn{i}", f"wrist/parent_upper/lip?conn_bot{i}", "Plane")
|
|
||||||
)
|
|
||||||
if "s3" in parts:
|
if "s3" in parts:
|
||||||
result.add(self.assembly_s3(), name="s3")
|
result.add(self.assembly_s3(), name="s3")
|
||||||
if "s3" in parts and "wrist" in parts:
|
if "s3" in parts and "wrist" in parts:
|
||||||
for i in range(wrist_n_holes):
|
for _, tag in self.wrist_joint.hole_loc_tags():
|
||||||
(
|
result.constrain(
|
||||||
result
|
f"s3/wrist?{tag}",
|
||||||
.constrain(f"s3/wrist_top?conn{i}", f"wrist/child/lip?conn_top{i}", "Plane")
|
f"wrist/child/lip?{tag}", "Plane")
|
||||||
.constrain(f"s3/wrist_bot?conn{i}", f"wrist/child/lip?conn_bot{i}", "Plane")
|
|
||||||
)
|
|
||||||
if not ignore_actuators:
|
if not ignore_actuators:
|
||||||
(
|
result.constrain(
|
||||||
result
|
"wrist/bracket_back?conn_side",
|
||||||
.constrain("wrist/bracket_back?conn_side", "s2/wrist_act?conn0", "Plane")
|
"s2/wrist_act?conn0",
|
||||||
)
|
"Plane")
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
result.solve()
|
result.solve()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue