cosplay: Touhou/Houjuu Nue #4
|
@ -1050,6 +1050,8 @@ class ElbowJoint(Model):
|
||||||
parent_arm_radius: float = 40.0
|
parent_arm_radius: float = 40.0
|
||||||
|
|
||||||
lip_thickness: float = 5.0
|
lip_thickness: float = 5.0
|
||||||
|
# Extra bit on top of the lip to connect to actuator mount
|
||||||
|
child_lip_extra_length: float = 1.0
|
||||||
lip_length: float = 60.0
|
lip_length: float = 60.0
|
||||||
hole_pos: list[float] = field(default_factory=lambda: [15, 25])
|
hole_pos: list[float] = field(default_factory=lambda: [15, 25])
|
||||||
parent_arm_width: float = 10.0
|
parent_arm_width: float = 10.0
|
||||||
|
@ -1069,8 +1071,9 @@ class ElbowJoint(Model):
|
||||||
flexor: Optional[Flexor] = None
|
flexor: Optional[Flexor] = None
|
||||||
# Rotates the entire flexor
|
# Rotates the entire flexor
|
||||||
flexor_offset_angle: float = 0
|
flexor_offset_angle: float = 0
|
||||||
# Rotates the surface of the mount
|
# Rotates the surface of the mount relative to radially inwards
|
||||||
flexor_mount_rot: float = 0
|
flexor_mount_angle_parent: float = 0
|
||||||
|
flexor_mount_angle_child: float = -90
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
assert self.child_arm_radius > self.disk_joint.radius_housing
|
assert self.child_arm_radius > self.disk_joint.radius_housing
|
||||||
|
@ -1133,7 +1136,8 @@ class ElbowJoint(Model):
|
||||||
) -> Cq.Location:
|
) -> Cq.Location:
|
||||||
# Moves the hole so the axle of the mount is perpendicular to it
|
# Moves the hole so the axle of the mount is perpendicular to it
|
||||||
loc_mount = Cq.Location.from2d(self.flexor.mount_height, 0) * Cq.Location.rot2d(180)
|
loc_mount = Cq.Location.from2d(self.flexor.mount_height, 0) * Cq.Location.rot2d(180)
|
||||||
loc_mount_orient = Cq.Location.rot2d(self.flexor_mount_rot * (-1 if child else 1))
|
mount_angle = self.flexor_mount_angle_child if child else self.flexor_mount_angle_parent
|
||||||
|
loc_mount_orient = Cq.Location.rot2d(mount_angle)
|
||||||
# Moves the hole to be some distance apart from 0
|
# Moves the hole to be some distance apart from 0
|
||||||
mount_r, mount_loc_angle, mount_parent_r = self.flexor.open_pos()
|
mount_r, mount_loc_angle, mount_parent_r = self.flexor.open_pos()
|
||||||
loc_span = Cq.Location.from2d(mount_r if child else mount_parent_r, 0)
|
loc_span = Cq.Location.from2d(mount_r if child else mount_parent_r, 0)
|
||||||
|
@ -1182,12 +1186,23 @@ class ElbowJoint(Model):
|
||||||
loc_cut_rel = Cq.Location((0, self.disk_joint.spring.radius_inner, -self.disk_joint.disk_bot_thickness))
|
loc_cut_rel = Cq.Location((0, self.disk_joint.spring.radius_inner, -self.disk_joint.disk_bot_thickness))
|
||||||
disk_cut = self.disk_joint._disk_cut().located(
|
disk_cut = self.disk_joint._disk_cut().located(
|
||||||
loc_lip.inverse * loc_cut_rel * loc_disk)
|
loc_lip.inverse * loc_cut_rel * loc_disk)
|
||||||
|
lip_extra = Cq.Solid.makeBox(
|
||||||
|
length=self.child_lip_extra_length,
|
||||||
|
width=self.total_thickness,
|
||||||
|
height=self.lip_thickness,
|
||||||
|
).located(Cq.Location((
|
||||||
|
self.lip_length / 2,
|
||||||
|
-self.total_thickness / 2,
|
||||||
|
0,
|
||||||
|
)))
|
||||||
result = (
|
result = (
|
||||||
Cq.Assembly()
|
Cq.Assembly()
|
||||||
.add(self.disk_joint.disk(), name="disk",
|
.add(self.disk_joint.disk(), name="disk",
|
||||||
loc=loc_rot_neutral * Cq.Location((0, 0, -dz), (0,0,1), angle))
|
loc=loc_rot_neutral * Cq.Location((0, 0, -dz), (0,0,1), angle))
|
||||||
.add(self.lip().cut(disk_cut), name="lip",
|
.add(self.lip().cut(disk_cut), name="lip",
|
||||||
loc=loc_rot_neutral * loc_disk.inverse * loc_lip)
|
loc=loc_rot_neutral * loc_disk.inverse * loc_lip)
|
||||||
|
.add(lip_extra, name="lip_extra",
|
||||||
|
loc=loc_rot_neutral * loc_disk.inverse * loc_lip)
|
||||||
)
|
)
|
||||||
# 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)
|
||||||
|
|
|
@ -64,6 +64,7 @@ class WingProfile(Model):
|
||||||
actuator=LINEAR_ACTUATOR_50,
|
actuator=LINEAR_ACTUATOR_50,
|
||||||
flexor_offset_angle=30,
|
flexor_offset_angle=30,
|
||||||
parent_arm_width=15,
|
parent_arm_width=15,
|
||||||
|
child_lip_extra_length=8,
|
||||||
flip=False,
|
flip=False,
|
||||||
))
|
))
|
||||||
# Distance between the two spacers on the elbow, halved
|
# Distance between the two spacers on the elbow, halved
|
||||||
|
@ -99,12 +100,12 @@ class WingProfile(Model):
|
||||||
wrist_bot_loc: Cq.Location
|
wrist_bot_loc: Cq.Location
|
||||||
wrist_height: float
|
wrist_height: float
|
||||||
elbow_rotate: float = 10.0
|
elbow_rotate: float = 10.0
|
||||||
elbow_joint_overlap_median: float = 0.3
|
|
||||||
wrist_joint_overlap_median: float = 0.5
|
|
||||||
wrist_rotate: float = -30.0
|
wrist_rotate: float = -30.0
|
||||||
# Position of the elbow axle with 0 being bottom and 1 being top (flipped on the left side)
|
# Position of the elbow axle with 0 being bottom and 1 being top (flipped on the left side)
|
||||||
elbow_axle_pos: float = 0.5
|
elbow_axle_pos: float
|
||||||
wrist_axle_pos: float = 0.0
|
wrist_axle_pos: float
|
||||||
|
elbow_joint_overlap_median: float
|
||||||
|
wrist_joint_overlap_median: float
|
||||||
|
|
||||||
# False for the right side, True for the left side
|
# False for the right side, True for the left side
|
||||||
flip: bool
|
flip: bool
|
||||||
|
@ -1089,6 +1090,10 @@ class WingR(WingProfile):
|
||||||
ring_radius_inner: float = 22.0
|
ring_radius_inner: float = 22.0
|
||||||
|
|
||||||
flip: bool = False
|
flip: bool = False
|
||||||
|
elbow_axle_pos: float = 0.4
|
||||||
|
wrist_axle_pos: float = 0.0
|
||||||
|
elbow_joint_overlap_median: float = 0.35
|
||||||
|
wrist_joint_overlap_median: float = 0.5
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
|
@ -1099,6 +1104,8 @@ class WingR(WingProfile):
|
||||||
* Cq.Location.rot2d(self.arrow_angle) \
|
* Cq.Location.rot2d(self.arrow_angle) \
|
||||||
* Cq.Location.from2d(0, self.arrow_height + self.wrist_height)
|
* Cq.Location.from2d(0, self.arrow_height + self.wrist_height)
|
||||||
self.ring_loc = self.wrist_top_loc * self.ring_rel_loc
|
self.ring_loc = self.wrist_top_loc * self.ring_rel_loc
|
||||||
|
self.elbow_joint.flexor_offset_angle = 15
|
||||||
|
self.elbow_joint.flexor_mount_angle_child = -75
|
||||||
assert self.ring_radius > self.ring_radius_inner
|
assert self.ring_radius > self.ring_radius_inner
|
||||||
|
|
||||||
assert 0 > self.blade_overlap_angle > self.arrow_angle
|
assert 0 > self.blade_overlap_angle > self.arrow_angle
|
||||||
|
@ -1316,7 +1323,6 @@ class WingL(WingProfile):
|
||||||
flip: bool = True
|
flip: bool = True
|
||||||
elbow_axle_pos: float = 0.4
|
elbow_axle_pos: float = 0.4
|
||||||
wrist_axle_pos: float = 0.5
|
wrist_axle_pos: float = 0.5
|
||||||
|
|
||||||
elbow_joint_overlap_median: float = 0.5
|
elbow_joint_overlap_median: float = 0.5
|
||||||
wrist_joint_overlap_median: float = 0.5
|
wrist_joint_overlap_median: float = 0.5
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue