cosplay: Touhou/Houjuu Nue #4

Open
aniva wants to merge 189 commits from touhou/houjuu-nue into main
5 changed files with 27 additions and 10 deletions
Showing only changes of commit e73c6c0fed - Show all commits

View File

@ -219,6 +219,8 @@ class TorsionJoint:
assert self.groove_radius_inner > self.spring.radius > self.radius_axle assert self.groove_radius_inner > self.spring.radius > self.radius_axle
assert self.spring.height > self.groove_depth, "Groove is too deep" assert self.spring.height > self.groove_depth, "Groove is too deep"
assert self.groove_depth < self.spring.height - self.spring.thickness * 2 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 @property
def total_height(self): def total_height(self):
@ -373,7 +375,9 @@ class TorsionJoint:
) )
theta_begin = -math.radians(rider_slot_begin) theta_begin = -math.radians(rider_slot_begin)
theta_span = math.radians(self.rider_slot_span) 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 theta_step = theta_span / self.rider_n_slots
else: else:
theta_step = theta_span / (self.rider_n_slots - 1) theta_step = theta_span / (self.rider_n_slots - 1)

View File

@ -50,14 +50,14 @@ class Parameters(Model):
wing_r1: MW.WingR = field(default_factory=lambda: MW.WingR( wing_r1: MW.WingR = field(default_factory=lambda: MW.WingR(
name="r1", name="r1",
shoulder_joint=MJ.ShoulderJoint(directrix_id=1), shoulder_angle_bias = 15.0,
)) ))
wing_r2: MW.WingR = field(default_factory=lambda: MW.WingR( wing_r2: MW.WingR = field(default_factory=lambda: MW.WingR(
name="r2", name="r2",
)) ))
wing_r3: MW.WingR = field(default_factory=lambda: MW.WingR( wing_r3: MW.WingR = field(default_factory=lambda: MW.WingR(
name="r3", name="r3",
shoulder_joint=MJ.ShoulderJoint(directrix_id=1), shoulder_angle_bias = 15.0,
)) ))
wing_l1: MW.WingL = field(default_factory=lambda: MW.WingL( wing_l1: MW.WingL = field(default_factory=lambda: MW.WingL(
name="l1", name="l1",
@ -66,7 +66,7 @@ class Parameters(Model):
wing_l2: MW.WingL = field(default_factory=lambda: MW.WingL( wing_l2: MW.WingL = field(default_factory=lambda: MW.WingL(
name="l2", name="l2",
wrist_angle=-30.0, 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( wing_l3: MW.WingL = field(default_factory=lambda: MW.WingL(
name="l3", name="l3",
@ -84,6 +84,8 @@ class Parameters(Model):
self.wing_l2.base_joint = self.harness.hs_hirth_joint self.wing_l2.base_joint = self.harness.hs_hirth_joint
self.wing_l3.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_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_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 assert self.wing_r3.hs_joint_axis_diam == self.harness.hs_joint_axis_diam

View File

@ -32,8 +32,8 @@ class ShoulderJoint(Model):
height=7.5, height=7.5,
), ),
rider_slot_begin=0, rider_slot_begin=0,
rider_n_slots=2, rider_n_slots=1,
rider_slot_span=15, rider_slot_span=0,
)) ))
# On the parent side, drill vertical holes # On the parent side, drill vertical holes

View File

@ -10,11 +10,21 @@ class TestJoints(unittest.TestCase):
j = MJ.ShoulderJoint() j = MJ.ShoulderJoint()
assembly = j.torsion_joint.rider_track_assembly() assembly = j.torsion_joint.rider_track_assembly()
self.assertEqual(pairwise_intersection(assembly), []) self.assertEqual(pairwise_intersection(assembly), [])
def test_shoulder_collision_0(self): def test_shoulder_collision_0(self):
j = MJ.ShoulderJoint() j = MJ.ShoulderJoint()
assembly = j.assembly() assembly = j.assembly()
self.assertEqual(pairwise_intersection(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): def test_shoulder_joint_dist(self):
""" """
Tests the arm radius Tests the arm radius

View File

@ -39,6 +39,7 @@ class WingProfile(Model):
shoulder_joint: ShoulderJoint = field(default_factory=lambda: ShoulderJoint( shoulder_joint: ShoulderJoint = field(default_factory=lambda: ShoulderJoint(
)) ))
shoulder_angle_bias: float = 0.0
shoulder_width: float = 36.0 shoulder_width: float = 36.0
shoulder_tip_x: float = -200.0 shoulder_tip_x: float = -200.0
shoulder_tip_y: float = 160.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.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.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") @submodel(name="shoulder-joint")
def submodel_shoulder_joint(self) -> Model: def submodel_shoulder_joint(self) -> Model:
@ -287,14 +288,14 @@ class WingProfile(Model):
sw = self.shoulder_width sw = self.shoulder_width
axle_dist = self.shoulder_joint.parent_lip_ext axle_dist = self.shoulder_joint.parent_lip_ext
theta = math.radians(self.shoulder_joint.angle_neutral) theta = math.radians(self.shoulder_angle_neutral)
c, s = math.cos(-theta), math.sin(-theta) c, s = math.cos(theta), math.sin(theta)
tags = [ tags = [
# transforms [axle_dist, -sw/2] about the centre (tip_x, tip_y - sw/2) # transforms [axle_dist, -sw/2] about the centre (tip_x, tip_y - sw/2)
("shoulder", Cq.Location.from2d( ("shoulder", Cq.Location.from2d(
self.shoulder_tip_x + axle_dist * c + (-sw/2) * s, self.shoulder_tip_x + axle_dist * c + (-sw/2) * s,
self.shoulder_tip_y - sw / 2 - axle_dist * s + (-sw/2) * c, 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)), ("base", Cq.Location.from2d(base_dx, base_dy, 90)),
] ]
result = extrude_with_markers( result = extrude_with_markers(