cosplay: Touhou/Houjuu Nue #4
|
@ -390,6 +390,8 @@ class Flexor:
|
||||||
pos = (target_length - self.actuator.conn_length) / self.actuator.stroke_length
|
pos = (target_length - self.actuator.conn_length) / self.actuator.stroke_length
|
||||||
if tag_prefix:
|
if tag_prefix:
|
||||||
tag_prefix = tag_prefix + "_"
|
tag_prefix = tag_prefix + "_"
|
||||||
|
else:
|
||||||
|
tag_prefix = ""
|
||||||
name_actuator = f"{tag_prefix}actuator"
|
name_actuator = f"{tag_prefix}actuator"
|
||||||
name_bracket_front = f"{tag_prefix}bracket_front"
|
name_bracket_front = f"{tag_prefix}bracket_front"
|
||||||
name_bracket_back = f"{tag_prefix}bracket_back"
|
name_bracket_back = f"{tag_prefix}bracket_back"
|
||||||
|
@ -397,6 +399,7 @@ class Flexor:
|
||||||
name_bolt_back = f"{tag_prefix}back_bolt"
|
name_bolt_back = f"{tag_prefix}back_bolt"
|
||||||
name_nut_front = f"{tag_prefix}front_nut"
|
name_nut_front = f"{tag_prefix}front_nut"
|
||||||
name_nut_back = f"{tag_prefix}back_nut"
|
name_nut_back = f"{tag_prefix}back_nut"
|
||||||
|
print(name_bracket_back)
|
||||||
(
|
(
|
||||||
a
|
a
|
||||||
.add(self.actuator.assembly(pos=pos), name=name_actuator)
|
.add(self.actuator.assembly(pos=pos), name=name_actuator)
|
||||||
|
|
|
@ -208,7 +208,8 @@ class RootJoint(Model):
|
||||||
|
|
||||||
def assembly(self,
|
def assembly(self,
|
||||||
offset: int = 0,
|
offset: int = 0,
|
||||||
fastener_pos: float = 0) -> Cq.Assembly:
|
fastener_pos: float = 0,
|
||||||
|
ignore_fasteners: bool = False) -> Cq.Assembly:
|
||||||
"""
|
"""
|
||||||
Specify knob position to determine the position of the knob from fully
|
Specify knob position to determine the position of the knob from fully
|
||||||
inserted (0) or fully uninserted (1)
|
inserted (0) or fully uninserted (1)
|
||||||
|
@ -223,6 +224,10 @@ class RootJoint(Model):
|
||||||
.addS(self.child(), name="child",
|
.addS(self.child(), name="child",
|
||||||
material=Material.PLASTIC_PLA,
|
material=Material.PLASTIC_PLA,
|
||||||
role=Role.CHILD)
|
role=Role.CHILD)
|
||||||
|
)
|
||||||
|
if not ignore_fasteners:
|
||||||
|
(
|
||||||
|
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)))
|
||||||
|
@ -526,6 +531,7 @@ class ShoulderJoint(Model):
|
||||||
self,
|
self,
|
||||||
fastener_pos: float = 0.0,
|
fastener_pos: float = 0.0,
|
||||||
deflection: float = 0.0,
|
deflection: float = 0.0,
|
||||||
|
ignore_fasteners: bool = False,
|
||||||
) -> Cq.Assembly:
|
) -> Cq.Assembly:
|
||||||
assert deflection <= self.angle_max_deflection
|
assert deflection <= self.angle_max_deflection
|
||||||
directrix = self.directrix_id
|
directrix = self.directrix_id
|
||||||
|
@ -547,6 +553,10 @@ class ShoulderJoint(Model):
|
||||||
.addS(self.parent_bot(),
|
.addS(self.parent_bot(),
|
||||||
name="parent_bot",
|
name="parent_bot",
|
||||||
role=Role.PARENT, material=mat)
|
role=Role.PARENT, material=mat)
|
||||||
|
)
|
||||||
|
if not ignore_fasteners:
|
||||||
|
(
|
||||||
|
result
|
||||||
# Fasteners
|
# Fasteners
|
||||||
.addS(self.bolt.assembly(), name="bolt_top",
|
.addS(self.bolt.assembly(), name="bolt_top",
|
||||||
loc=Cq.Location((0, 0, bolt_z)))
|
loc=Cq.Location((0, 0, bolt_z)))
|
||||||
|
@ -1075,7 +1085,7 @@ class ElbowJoint(Model):
|
||||||
return self.disk_joint.housing_lower()
|
return self.disk_joint.housing_lower()
|
||||||
|
|
||||||
@target(name="parent-upper")
|
@target(name="parent-upper")
|
||||||
def parent_joint_upper(self):
|
def parent_joint_upper(self, generate_mount: bool=False):
|
||||||
axial_offset = Cq.Location((self.parent_arm_radius, 0, 0))
|
axial_offset = Cq.Location((self.parent_arm_radius, 0, 0))
|
||||||
housing_dz = self.disk_joint.housing_upper_dz
|
housing_dz = self.disk_joint.housing_upper_dz
|
||||||
conn_h = self.disk_joint.total_thickness
|
conn_h = self.disk_joint.total_thickness
|
||||||
|
@ -1120,16 +1130,25 @@ class ElbowJoint(Model):
|
||||||
#.solve()
|
#.solve()
|
||||||
)
|
)
|
||||||
if self.flexor:
|
if self.flexor:
|
||||||
|
if generate_mount:
|
||||||
# Orientes the hole surface so it faces +X
|
# Orientes the hole surface so it faces +X
|
||||||
loc_thickness = Cq.Location((-self.lip_thickness, 0, 0), (0, 1, 0), 90)
|
loc_thickness = Cq.Location((-self.lip_thickness, 0, 0), (0, 1, 0), 90)
|
||||||
result.add(
|
result.add(
|
||||||
self.actuator_mount(),
|
self.actuator_mount(),
|
||||||
name="act",
|
name="act",
|
||||||
loc=self.actuator_mount_loc(child=False) * loc_thickness)
|
loc=self.actuator_mount_loc(child=False) * loc_thickness)
|
||||||
|
else:
|
||||||
|
result.add(
|
||||||
|
Cq.Edge.makeLine((-1,0,0), (1,0,0)),
|
||||||
|
name="act",
|
||||||
|
loc=self.actuator_mount_loc(child=False))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@assembly()
|
@assembly()
|
||||||
def assembly(self, angle: float = 0) -> Cq.Assembly:
|
def assembly(self,
|
||||||
|
angle: float = 0,
|
||||||
|
generate_mount: bool = False,
|
||||||
|
ignore_actuators: bool = False) -> Cq.Assembly:
|
||||||
assert 0 <= angle <= self.motion_span
|
assert 0 <= angle <= self.motion_span
|
||||||
result = (
|
result = (
|
||||||
Cq.Assembly()
|
Cq.Assembly()
|
||||||
|
@ -1137,7 +1156,7 @@ class ElbowJoint(Model):
|
||||||
role=Role.CHILD, material=self.material)
|
role=Role.CHILD, material=self.material)
|
||||||
.addS(self.parent_joint_lower(), name="parent_lower",
|
.addS(self.parent_joint_lower(), name="parent_lower",
|
||||||
role=Role.CASING, material=self.material)
|
role=Role.CASING, material=self.material)
|
||||||
.addS(self.parent_joint_upper(), name="parent_upper",
|
.addS(self.parent_joint_upper(generate_mount=generate_mount), name="parent_upper",
|
||||||
role=Role.PARENT, material=self.material)
|
role=Role.PARENT, material=self.material)
|
||||||
#.constrain("child/disk?mate_bot", "Fixed")
|
#.constrain("child/disk?mate_bot", "Fixed")
|
||||||
)
|
)
|
||||||
|
@ -1148,14 +1167,14 @@ class ElbowJoint(Model):
|
||||||
disk="child/disk",
|
disk="child/disk",
|
||||||
angle=angle,
|
angle=angle,
|
||||||
)
|
)
|
||||||
if self.flexor:
|
if not ignore_actuators and self.flexor:
|
||||||
target_length = self.flexor.target_length_at_angle(
|
target_length = self.flexor.target_length_at_angle(
|
||||||
angle=angle,
|
angle=angle,
|
||||||
)
|
)
|
||||||
self.flexor.add_to(
|
self.flexor.add_to(
|
||||||
result,
|
result,
|
||||||
target_length=target_length,
|
target_length=target_length,
|
||||||
tag_hole_back="parent_upper/act?mount",
|
tag_hole_back="parent_upper/act",
|
||||||
tag_hole_front="child/act?mount",
|
tag_hole_front="child/act?mount",
|
||||||
tag_dir="parent_lower?mate",
|
tag_dir="parent_lower?mate",
|
||||||
)
|
)
|
||||||
|
|
|
@ -362,7 +362,9 @@ class WingProfile(Model):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@assembly()
|
@assembly()
|
||||||
def assembly_s0(self, ignore_detail: bool=False) -> Cq.Assembly:
|
def assembly_s0(
|
||||||
|
self,
|
||||||
|
ignore_electronics: bool=False) -> Cq.Assembly:
|
||||||
result = (
|
result = (
|
||||||
Cq.Assembly()
|
Cq.Assembly()
|
||||||
.addS(self.surface_s0(top=True), name="bot",
|
.addS(self.surface_s0(top=True), name="bot",
|
||||||
|
@ -401,7 +403,7 @@ class WingProfile(Model):
|
||||||
.constrain(f"{tag}?{top_tag}", f"top?{tag}", "Plane")
|
.constrain(f"{tag}?{top_tag}", f"top?{tag}", "Plane")
|
||||||
.constrain(f"{tag}?dir", f"top?{tag}_dir", "Axis")
|
.constrain(f"{tag}?dir", f"top?{tag}_dir", "Axis")
|
||||||
)
|
)
|
||||||
if not ignore_detail:
|
if not ignore_electronics:
|
||||||
result.add(self.electronic_board.assembly(), name="electronic_board")
|
result.add(self.electronic_board.assembly(), name="electronic_board")
|
||||||
for hole in self.electronic_board.mount_holes:
|
for hole in self.electronic_board.mount_holes:
|
||||||
assert hole.tag
|
assert hole.tag
|
||||||
|
@ -923,7 +925,9 @@ class WingProfile(Model):
|
||||||
elbow_wrist_deflection: float = 0.0,
|
elbow_wrist_deflection: float = 0.0,
|
||||||
root_offset: int = 5,
|
root_offset: int = 5,
|
||||||
fastener_pos: float = 0.0,
|
fastener_pos: float = 0.0,
|
||||||
ignore_detail: bool = False,
|
ignore_fasteners: bool = False,
|
||||||
|
ignore_electronics: bool = False,
|
||||||
|
ignore_actuators: bool = False,
|
||||||
) -> Cq.Assembly():
|
) -> Cq.Assembly():
|
||||||
if parts is None:
|
if parts is None:
|
||||||
parts = [
|
parts = [
|
||||||
|
@ -944,11 +948,14 @@ class WingProfile(Model):
|
||||||
tag_top, tag_bot = tag_bot, tag_top
|
tag_top, tag_bot = tag_bot, tag_top
|
||||||
|
|
||||||
if "s0" in parts:
|
if "s0" in parts:
|
||||||
result.add(self.assembly_s0(ignore_detail=ignore_detail), name="s0")
|
result.add(self.assembly_s0(
|
||||||
|
ignore_electronics=ignore_electronics
|
||||||
|
), name="s0")
|
||||||
if "root" in parts:
|
if "root" in parts:
|
||||||
result.addS(self.root_joint.assembly(
|
result.addS(self.root_joint.assembly(
|
||||||
offset=root_offset,
|
offset=root_offset,
|
||||||
fastener_pos=fastener_pos,
|
fastener_pos=fastener_pos,
|
||||||
|
ignore_fasteners=ignore_fasteners,
|
||||||
), name="root")
|
), name="root")
|
||||||
result.constrain("root/parent", "Fixed")
|
result.constrain("root/parent", "Fixed")
|
||||||
if "s0" in parts and "root" in parts:
|
if "s0" in parts and "root" in parts:
|
||||||
|
@ -962,7 +969,8 @@ class WingProfile(Model):
|
||||||
angle = shoulder_deflection * self.shoulder_joint.angle_max_deflection
|
angle = shoulder_deflection * self.shoulder_joint.angle_max_deflection
|
||||||
result.add(self.shoulder_joint.assembly(
|
result.add(self.shoulder_joint.assembly(
|
||||||
fastener_pos=fastener_pos,
|
fastener_pos=fastener_pos,
|
||||||
deflection=angle), name="shoulder")
|
deflection=angle,
|
||||||
|
ignore_fasteners=ignore_fasteners), name="shoulder")
|
||||||
if "s0" in parts and "shoulder" in parts:
|
if "s0" in parts and "shoulder" in parts:
|
||||||
for i in range(len(self.shoulder_joint.parent_conn_hole_pos)):
|
for i in range(len(self.shoulder_joint.parent_conn_hole_pos)):
|
||||||
(
|
(
|
||||||
|
@ -984,7 +992,9 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
if "elbow" in parts:
|
if "elbow" in parts:
|
||||||
angle = self.elbow_joint.motion_span * elbow_wrist_deflection
|
angle = self.elbow_joint.motion_span * elbow_wrist_deflection
|
||||||
result.add(self.elbow_joint.assembly(angle=angle), name="elbow")
|
result.add(self.elbow_joint.assembly(
|
||||||
|
angle=angle,
|
||||||
|
ignore_actuators=ignore_actuators), name="elbow")
|
||||||
if "s1" in parts and "elbow" in parts:
|
if "s1" in parts and "elbow" in parts:
|
||||||
(
|
(
|
||||||
result
|
result
|
||||||
|
@ -993,6 +1003,11 @@ class WingProfile(Model):
|
||||||
.constrain("s1/elbow_bot?conn0", "elbow/parent_upper/lip?conn_bot0", "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")
|
.constrain("s1/elbow_bot?conn1", "elbow/parent_upper/lip?conn_bot1", "Plane")
|
||||||
)
|
)
|
||||||
|
if not ignore_actuators:
|
||||||
|
(
|
||||||
|
result
|
||||||
|
.constrain("elbow/bracket_back?conn_side", "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:
|
||||||
|
@ -1005,7 +1020,9 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
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(angle=angle), name="wrist")
|
result.add(self.wrist_joint.assembly(
|
||||||
|
angle=angle,
|
||||||
|
ignore_actuators=ignore_actuators), name="wrist")
|
||||||
wrist_n_holes = len(self.wrist_joint.hole_pos)
|
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 i in range(wrist_n_holes):
|
||||||
|
@ -1023,6 +1040,11 @@ class WingProfile(Model):
|
||||||
.constrain(f"s3/wrist_top?conn{i}", f"wrist/child/lip?conn_top{i}", "Plane")
|
.constrain(f"s3/wrist_top?conn{i}", f"wrist/child/lip?conn_top{i}", "Plane")
|
||||||
.constrain(f"s3/wrist_bot?conn{i}", f"wrist/child/lip?conn_bot{i}", "Plane")
|
.constrain(f"s3/wrist_bot?conn{i}", f"wrist/child/lip?conn_bot{i}", "Plane")
|
||||||
)
|
)
|
||||||
|
if not ignore_actuators:
|
||||||
|
(
|
||||||
|
result
|
||||||
|
.constrain("wrist/bracket_back?conn_side", "s2/wrist_act?conn0", "Plane")
|
||||||
|
)
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
result.solve()
|
result.solve()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue