cosplay: Touhou/Houjuu Nue #4
|
@ -219,6 +219,8 @@ class TorsionJoint:
|
|||
assert self.groove_radius_inner > self.spring.radius > self.radius_axle
|
||||
assert self.spring.height > self.groove_depth, "Groove is too deep"
|
||||
assert self.groove_depth < self.spring.height - self.spring.thickness * 2
|
||||
if self.rider_n_slots == 1:
|
||||
assert self.rider_slot_span == 0.0, "Non-zero span is impossible with multiple riders"
|
||||
|
||||
@property
|
||||
def total_height(self):
|
||||
|
@ -373,7 +375,9 @@ class TorsionJoint:
|
|||
)
|
||||
theta_begin = -math.radians(rider_slot_begin)
|
||||
theta_span = math.radians(self.rider_slot_span)
|
||||
if abs(math.remainder(self.rider_slot_span, 360)) < TOL:
|
||||
if self.rider_n_slots <= 1:
|
||||
theta_step = 0
|
||||
elif abs(math.remainder(self.rider_slot_span, 360)) < TOL:
|
||||
theta_step = theta_span / self.rider_n_slots
|
||||
else:
|
||||
theta_step = theta_span / (self.rider_n_slots - 1)
|
||||
|
|
|
@ -50,14 +50,14 @@ class Parameters(Model):
|
|||
|
||||
wing_r1: MW.WingR = field(default_factory=lambda: MW.WingR(
|
||||
name="r1",
|
||||
shoulder_joint=MJ.ShoulderJoint(directrix_id=1),
|
||||
shoulder_angle_bias = 15.0,
|
||||
))
|
||||
wing_r2: MW.WingR = field(default_factory=lambda: MW.WingR(
|
||||
name="r2",
|
||||
))
|
||||
wing_r3: MW.WingR = field(default_factory=lambda: MW.WingR(
|
||||
name="r3",
|
||||
shoulder_joint=MJ.ShoulderJoint(directrix_id=1),
|
||||
shoulder_angle_bias = 15.0,
|
||||
))
|
||||
wing_l1: MW.WingL = field(default_factory=lambda: MW.WingL(
|
||||
name="l1",
|
||||
|
@ -66,7 +66,7 @@ class Parameters(Model):
|
|||
wing_l2: MW.WingL = field(default_factory=lambda: MW.WingL(
|
||||
name="l2",
|
||||
wrist_angle=-30.0,
|
||||
shoulder_joint=MJ.ShoulderJoint(directrix_id=1),
|
||||
shoulder_angle_bias = 15.0,
|
||||
))
|
||||
wing_l3: MW.WingL = field(default_factory=lambda: MW.WingL(
|
||||
name="l3",
|
||||
|
@ -84,6 +84,8 @@ class Parameters(Model):
|
|||
self.wing_l2.base_joint = self.harness.hs_hirth_joint
|
||||
self.wing_l3.base_joint = self.harness.hs_hirth_joint
|
||||
|
||||
self.wing_r1.shoulder_joint.torsion_joint
|
||||
|
||||
assert self.wing_r1.hs_joint_axis_diam == self.harness.hs_joint_axis_diam
|
||||
assert self.wing_r2.hs_joint_axis_diam == self.harness.hs_joint_axis_diam
|
||||
assert self.wing_r3.hs_joint_axis_diam == self.harness.hs_joint_axis_diam
|
||||
|
|
|
@ -32,8 +32,8 @@ class ShoulderJoint(Model):
|
|||
height=7.5,
|
||||
),
|
||||
rider_slot_begin=0,
|
||||
rider_n_slots=2,
|
||||
rider_slot_span=15,
|
||||
rider_n_slots=1,
|
||||
rider_slot_span=0,
|
||||
))
|
||||
|
||||
# On the parent side, drill vertical holes
|
||||
|
|
|
@ -10,11 +10,21 @@ class TestJoints(unittest.TestCase):
|
|||
j = MJ.ShoulderJoint()
|
||||
assembly = j.torsion_joint.rider_track_assembly()
|
||||
self.assertEqual(pairwise_intersection(assembly), [])
|
||||
|
||||
def test_shoulder_collision_0(self):
|
||||
j = MJ.ShoulderJoint()
|
||||
assembly = j.assembly()
|
||||
self.assertEqual(pairwise_intersection(assembly), [])
|
||||
|
||||
def test_shoulder_align(self):
|
||||
j = MJ.ShoulderJoint()
|
||||
a = j.assembly()
|
||||
l_t_c0 = a.get_abs_location("parent_top/lip?conn0")
|
||||
l_b_c0 = a.get_abs_location("parent_bot/lip?conn0")
|
||||
v = l_t_c0 - l_b_c0
|
||||
self.assertAlmostEqual(v.x, 0)
|
||||
self.assertAlmostEqual(v.y, 0)
|
||||
|
||||
def test_shoulder_joint_dist(self):
|
||||
"""
|
||||
Tests the arm radius
|
||||
|
|
|
@ -39,6 +39,7 @@ class WingProfile(Model):
|
|||
|
||||
shoulder_joint: ShoulderJoint = field(default_factory=lambda: ShoulderJoint(
|
||||
))
|
||||
shoulder_angle_bias: float = 0.0
|
||||
shoulder_width: float = 36.0
|
||||
shoulder_tip_x: float = -200.0
|
||||
shoulder_tip_y: float = 160.0
|
||||
|
@ -94,7 +95,7 @@ class WingProfile(Model):
|
|||
self.elbow_top_loc = self.elbow_bot_loc * Cq.Location.from2d(0, self.elbow_height)
|
||||
self.wrist_top_loc = self.wrist_bot_loc * Cq.Location.from2d(0, self.wrist_height)
|
||||
|
||||
self.shoulder_joint.angle_neutral = -self.shoulder_angle_neutral
|
||||
self.shoulder_joint.angle_neutral = -self.shoulder_angle_neutral - self.shoulder_angle_bias
|
||||
|
||||
@submodel(name="shoulder-joint")
|
||||
def submodel_shoulder_joint(self) -> Model:
|
||||
|
@ -287,14 +288,14 @@ class WingProfile(Model):
|
|||
sw = self.shoulder_width
|
||||
|
||||
axle_dist = self.shoulder_joint.parent_lip_ext
|
||||
theta = math.radians(self.shoulder_joint.angle_neutral)
|
||||
c, s = math.cos(-theta), math.sin(-theta)
|
||||
theta = math.radians(self.shoulder_angle_neutral)
|
||||
c, s = math.cos(theta), math.sin(theta)
|
||||
tags = [
|
||||
# transforms [axle_dist, -sw/2] about the centre (tip_x, tip_y - sw/2)
|
||||
("shoulder", Cq.Location.from2d(
|
||||
self.shoulder_tip_x + axle_dist * c + (-sw/2) * s,
|
||||
self.shoulder_tip_y - sw / 2 - axle_dist * s + (-sw/2) * c,
|
||||
self.shoulder_joint.angle_neutral)),
|
||||
-self.shoulder_angle_neutral)),
|
||||
("base", Cq.Location.from2d(base_dx, base_dy, 90)),
|
||||
]
|
||||
result = extrude_with_markers(
|
||||
|
|
Loading…
Reference in New Issue