feat: Extension profile on both sides
This commit is contained in:
parent
f75375e384
commit
82d8cf9599
|
@ -62,7 +62,7 @@ class WingProfile(Model):
|
||||||
child_arm_radius=23.0,
|
child_arm_radius=23.0,
|
||||||
parent_arm_radius=30.0,
|
parent_arm_radius=30.0,
|
||||||
hole_diam=4.0,
|
hole_diam=4.0,
|
||||||
angle_neutral=-20.0,
|
angle_neutral=-30.0,
|
||||||
))
|
))
|
||||||
# Distance between the two spacers on the elbow, halved
|
# Distance between the two spacers on the elbow, halved
|
||||||
wrist_h2: float = 5.0
|
wrist_h2: float = 5.0
|
||||||
|
@ -80,7 +80,7 @@ class WingProfile(Model):
|
||||||
wrist_bot_loc: Cq.Location
|
wrist_bot_loc: Cq.Location
|
||||||
wrist_height: float
|
wrist_height: float
|
||||||
elbow_rotate: float = -5.0
|
elbow_rotate: float = -5.0
|
||||||
wrist_rotate: float = -20.0
|
wrist_rotate: float = -30.0
|
||||||
|
|
||||||
# False for the right side, True for the left side
|
# False for the right side, True for the left side
|
||||||
flip: bool
|
flip: bool
|
||||||
|
@ -385,6 +385,36 @@ class WingProfile(Model):
|
||||||
for p in points
|
for p in points
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
def _joint_extension_profile(
|
||||||
|
self,
|
||||||
|
axle_loc: Cq.Location,
|
||||||
|
radius: float,
|
||||||
|
angle_span: float,
|
||||||
|
bot: bool = False) -> Cq.Sketch:
|
||||||
|
sign = -1 if bot else 1
|
||||||
|
#sign = -1
|
||||||
|
axle_loc = axle_loc * Cq.Location.rot2d(180 if bot else 0)
|
||||||
|
loc_h = Cq.Location.from2d(0, radius)
|
||||||
|
start = axle_loc * loc_h
|
||||||
|
mid = axle_loc * Cq.Location.rot2d(-sign * angle_span/2) * loc_h
|
||||||
|
end = axle_loc * Cq.Location.rot2d(-sign * angle_span) * loc_h
|
||||||
|
return (
|
||||||
|
Cq.Sketch()
|
||||||
|
.segment(
|
||||||
|
axle_loc.to2d_pos(),
|
||||||
|
start.to2d_pos(),
|
||||||
|
)
|
||||||
|
.arc(
|
||||||
|
start.to2d_pos(),
|
||||||
|
mid.to2d_pos(),
|
||||||
|
end.to2d_pos(),
|
||||||
|
)
|
||||||
|
.segment(
|
||||||
|
end.to2d_pos(),
|
||||||
|
axle_loc.to2d_pos(),
|
||||||
|
)
|
||||||
|
.assemble()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _assembly_insert_spacer(
|
def _assembly_insert_spacer(
|
||||||
|
@ -480,6 +510,35 @@ class WingProfile(Model):
|
||||||
tags = tags_shoulder + tags_elbow
|
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)
|
||||||
|
@target(name="profile-s1-bridge", kind=TargetKind.DXF)
|
||||||
|
def profile_s1_bridge(self) -> Cq.Workplane:
|
||||||
|
return (
|
||||||
|
self.profile()
|
||||||
|
#.reset()
|
||||||
|
#.polygon(self._mask_elbow(), mode='i')
|
||||||
|
.reset()
|
||||||
|
.push([self.elbow_axle_loc])
|
||||||
|
.each(self._elbow_joint_retract_cut_polygon, mode='i')
|
||||||
|
.reset()
|
||||||
|
.push([self.elbow_axle_loc])
|
||||||
|
.each(lambda loc: self._joint_extension_profile(
|
||||||
|
axle_loc=self.elbow_axle_loc,
|
||||||
|
radius=self.elbow_height / 2,
|
||||||
|
angle_span=self.elbow_joint.motion_span,
|
||||||
|
bot=True,
|
||||||
|
), mode='a')
|
||||||
|
)
|
||||||
|
def surface_s1_bridge(self, front: bool = True) -> Cq.Workplane:
|
||||||
|
profile = self.profile_s1_bridge()
|
||||||
|
loc_elbow = Cq.Location.rot2d(self.elbow_rotate) * self.elbow_joint.parent_arm_loc()
|
||||||
|
tags = [
|
||||||
|
("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)),
|
||||||
|
]
|
||||||
|
return extrude_with_markers(
|
||||||
|
profile, self.panel_thickness, tags, reverse=not front)
|
||||||
@submodel(name="spacer-s1-shoulder")
|
@submodel(name="spacer-s1-shoulder")
|
||||||
def spacer_s1_shoulder(self) -> MountingBox:
|
def spacer_s1_shoulder(self) -> MountingBox:
|
||||||
holes = [
|
holes = [
|
||||||
|
@ -511,6 +570,14 @@ class WingProfile(Model):
|
||||||
material=self.mat_panel, role=self.role_panel)
|
material=self.mat_panel, role=self.role_panel)
|
||||||
.constrain("front@faces@>Z", "back@faces@<Z", "Point",
|
.constrain("front@faces@>Z", "back@faces@<Z", "Point",
|
||||||
param=self.s1_thickness)
|
param=self.s1_thickness)
|
||||||
|
.addS(self.surface_s1_bridge(front=True), name="bridge_front",
|
||||||
|
material=self.mat_panel, role=self.role_panel)
|
||||||
|
.constrain("front?elbow_bot", "bridge_front?elbow_bot", "Plane")
|
||||||
|
.constrain("front?elbow_top", "bridge_front?elbow_top", "Plane")
|
||||||
|
.addS(self.surface_s1_bridge(front=False), name="bridge_back",
|
||||||
|
material=self.mat_panel, role=self.role_panel)
|
||||||
|
.constrain("back?elbow_bot", "bridge_back?elbow_bot", "Plane")
|
||||||
|
.constrain("back?elbow_top", "bridge_back?elbow_top", "Plane")
|
||||||
)
|
)
|
||||||
for t in ["shoulder_bot", "shoulder_top", "elbow_bot", "elbow_top"]:
|
for t in ["shoulder_bot", "shoulder_top", "elbow_bot", "elbow_top"]:
|
||||||
is_top = t.endswith("_top")
|
is_top = t.endswith("_top")
|
||||||
|
@ -545,7 +612,6 @@ 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:
|
||||||
h = self.elbow_height / 2
|
|
||||||
loc_elbow = Cq.Location.rot2d(self.elbow_rotate) * self.elbow_joint.child_arm_loc(flip=self.flip)
|
loc_elbow = Cq.Location.rot2d(self.elbow_rotate) * self.elbow_joint.child_arm_loc(flip=self.flip)
|
||||||
tags_elbow = [
|
tags_elbow = [
|
||||||
("elbow_bot", self.elbow_axle_loc * loc_elbow *
|
("elbow_bot", self.elbow_axle_loc * loc_elbow *
|
||||||
|
@ -553,7 +619,6 @@ class WingProfile(Model):
|
||||||
("elbow_top", self.elbow_axle_loc * loc_elbow *
|
("elbow_top", self.elbow_axle_loc * loc_elbow *
|
||||||
Cq.Location.from2d(0, -self.elbow_h2)),
|
Cq.Location.from2d(0, -self.elbow_h2)),
|
||||||
]
|
]
|
||||||
h = self.wrist_height / 2
|
|
||||||
loc_wrist = Cq.Location.rot2d(self.wrist_rotate) * self.wrist_joint.parent_arm_loc()
|
loc_wrist = Cq.Location.rot2d(self.wrist_rotate) * self.wrist_joint.parent_arm_loc()
|
||||||
tags_wrist = [
|
tags_wrist = [
|
||||||
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
||||||
|
@ -564,6 +629,40 @@ class WingProfile(Model):
|
||||||
profile = self.profile_s2()
|
profile = self.profile_s2()
|
||||||
tags = tags_elbow + tags_wrist
|
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)
|
||||||
|
@target(name="profile-s2-bridge", kind=TargetKind.DXF)
|
||||||
|
def profile_s2_bridge(self) -> Cq.Workplane:
|
||||||
|
# Generates the extension profile, which is required on both sides
|
||||||
|
profile = self._joint_extension_profile(
|
||||||
|
axle_loc=self.wrist_axle_loc,
|
||||||
|
radius=self.wrist_height * (0.5 if self.flip else 1),
|
||||||
|
angle_span=self.wrist_joint.motion_span,
|
||||||
|
bot=False,
|
||||||
|
)
|
||||||
|
# Generates the contraction (cut) profile. only required on the left
|
||||||
|
if self.flip:
|
||||||
|
extra = (
|
||||||
|
self.profile()
|
||||||
|
.reset()
|
||||||
|
.push([self.wrist_axle_loc])
|
||||||
|
.each(self._wrist_joint_retract_cut_polygon, mode='i')
|
||||||
|
)
|
||||||
|
profile = (
|
||||||
|
profile
|
||||||
|
.push([self.wrist_axle_loc])
|
||||||
|
.each(lambda _: extra, mode='a')
|
||||||
|
)
|
||||||
|
return profile
|
||||||
|
def surface_s2_bridge(self, front: bool = True) -> Cq.Workplane:
|
||||||
|
profile = self.profile_s2_bridge()
|
||||||
|
loc_wrist = Cq.Location.rot2d(self.wrist_rotate) * self.wrist_joint.parent_arm_loc()
|
||||||
|
tags = [
|
||||||
|
("wrist_bot", self.wrist_axle_loc * loc_wrist *
|
||||||
|
Cq.Location.from2d(0, -self.wrist_h2)),
|
||||||
|
("wrist_top", self.wrist_axle_loc * loc_wrist *
|
||||||
|
Cq.Location.from2d(0, self.wrist_h2)),
|
||||||
|
]
|
||||||
|
return extrude_with_markers(
|
||||||
|
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_of_joint(
|
||||||
|
@ -589,6 +688,14 @@ class WingProfile(Model):
|
||||||
material=self.mat_panel, role=self.role_panel)
|
material=self.mat_panel, role=self.role_panel)
|
||||||
.constrain("front@faces@>Z", "back@faces@<Z", "Point",
|
.constrain("front@faces@>Z", "back@faces@<Z", "Point",
|
||||||
param=self.s1_thickness)
|
param=self.s1_thickness)
|
||||||
|
.addS(self.surface_s2_bridge(front=True), name="bridge_front",
|
||||||
|
material=self.mat_panel, role=self.role_panel)
|
||||||
|
.constrain("front?wrist_bot", "bridge_front?wrist_bot", "Plane")
|
||||||
|
.constrain("front?wrist_top", "bridge_front?wrist_top", "Plane")
|
||||||
|
.addS(self.surface_s2_bridge(front=False), name="bridge_back",
|
||||||
|
material=self.mat_panel, role=self.role_panel)
|
||||||
|
.constrain("back?wrist_bot", "bridge_back?wrist_bot", "Plane")
|
||||||
|
.constrain("back?wrist_top", "bridge_back?wrist_top", "Plane")
|
||||||
)
|
)
|
||||||
for t in ["elbow_bot", "elbow_top", "wrist_bot", "wrist_top"]:
|
for t in ["elbow_bot", "elbow_top", "wrist_bot", "wrist_top"]:
|
||||||
is_top = t.endswith("_top")
|
is_top = t.endswith("_top")
|
||||||
|
|
Loading…
Reference in New Issue