Motor seat and coupler
This commit is contained in:
parent
2d6d65235d
commit
e94546b017
|
@ -3,10 +3,23 @@ from nhf.materials import Role, Material
|
||||||
import nhf.utils
|
import nhf.utils
|
||||||
from nhf.parts.fasteners import FlatHeadBolt, HexNut, Washer
|
from nhf.parts.fasteners import FlatHeadBolt, HexNut, Washer
|
||||||
|
|
||||||
|
from typing import Optional, Union
|
||||||
import math
|
import math
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
import cadquery as Cq
|
import cadquery as Cq
|
||||||
|
|
||||||
|
def has_part(li: Optional[list[str]], name: Union[str, list[str]]) -> bool:
|
||||||
|
"""
|
||||||
|
Check if a part exists in a name list
|
||||||
|
"""
|
||||||
|
if li:
|
||||||
|
if isinstance(name, list):
|
||||||
|
return all(n in li for n in name)
|
||||||
|
else:
|
||||||
|
return name in li
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
NUT_COMMON = HexNut(
|
NUT_COMMON = HexNut(
|
||||||
# FIXME: measure
|
# FIXME: measure
|
||||||
mass=0.0,
|
mass=0.0,
|
||||||
|
@ -227,6 +240,8 @@ class Onbashira(Model):
|
||||||
barrel_diam: float = 25.4 * 1.5
|
barrel_diam: float = 25.4 * 1.5
|
||||||
barrel_wall_thickness: float = 25.4 / 8
|
barrel_wall_thickness: float = 25.4 / 8
|
||||||
barrel_length: float = 25.4 * 12
|
barrel_length: float = 25.4 * 12
|
||||||
|
# Longitudinal shift
|
||||||
|
barrel_shift: float = -20.0
|
||||||
|
|
||||||
# Gap between the stator edge and the inner face of the barrel
|
# Gap between the stator edge and the inner face of the barrel
|
||||||
stator_gap: float = 3.0
|
stator_gap: float = 3.0
|
||||||
|
@ -267,6 +282,16 @@ class Onbashira(Model):
|
||||||
flange_coupler: FlangeCoupler = FlangeCoupler()
|
flange_coupler: FlangeCoupler = FlangeCoupler()
|
||||||
auxiliary_thickness: float = 25.4 / 8
|
auxiliary_thickness: float = 25.4 / 8
|
||||||
|
|
||||||
|
# Distance between bind point and motor's mount points
|
||||||
|
motor_driver_radius: float = 110.0
|
||||||
|
motor_seat_depth: float = 95.0
|
||||||
|
motor_seat_radius: float = 45.0
|
||||||
|
motor_coupler_flange_thickness: float = 10.0
|
||||||
|
motor_coupler_flange_radius: float = 8.0
|
||||||
|
motor_coupler_height: float = 100.0
|
||||||
|
motor_coupler_conn_dx: float = 30.0
|
||||||
|
motor_coupler_wall_thickness: float = 5.0
|
||||||
|
motor_coupler_inner_gap: float = 1.0
|
||||||
turning_bar_width: float = 15.0
|
turning_bar_width: float = 15.0
|
||||||
electronic_mount_dx: float = 50.0
|
electronic_mount_dx: float = 50.0
|
||||||
|
|
||||||
|
@ -365,29 +390,70 @@ class Onbashira(Model):
|
||||||
.extrude(self.side_width * 1.5)
|
.extrude(self.side_width * 1.5)
|
||||||
)
|
)
|
||||||
|
|
||||||
@target(name="motor-driver-shaft")
|
@target(name="motor-coupler")
|
||||||
def motor_driver_shaft(self) -> Cq.Workplane:
|
def motor_coupler(self) -> Cq.Workplane:
|
||||||
"""
|
"""
|
||||||
Driver shaft which connects to each barrel to move them.
|
Coupler which connects to each barrel to move them.
|
||||||
|
|
||||||
The driver shaft reaches
|
|
||||||
"""
|
"""
|
||||||
return (
|
x = self.motor_coupler_conn_dx
|
||||||
|
y0 = self.barrel_diam/2 + self.motor_coupler_wall_thickness
|
||||||
|
y = self.motor_coupler_flange_radius
|
||||||
|
t = self.motor_coupler_flange_thickness
|
||||||
|
flange = (
|
||||||
|
Cq.Workplane()
|
||||||
|
.sketch()
|
||||||
|
.polygon([
|
||||||
|
(x, y),
|
||||||
|
(0, y0),
|
||||||
|
(-x, y),
|
||||||
|
(-x, -y),
|
||||||
|
(0, -y0),
|
||||||
|
(x, -y),
|
||||||
|
])
|
||||||
|
.reset()
|
||||||
|
.push([
|
||||||
|
(x, 0), (-x, 0)
|
||||||
|
])
|
||||||
|
.circle(y, mode="a")
|
||||||
|
.circle(BOLT_BEARING.diam_thread/2, mode="s")
|
||||||
|
.reset()
|
||||||
|
.circle(self.barrel_diam/2, mode="s")
|
||||||
|
.finalize()
|
||||||
|
.extrude(t)
|
||||||
|
)
|
||||||
|
body = (
|
||||||
Cq.Workplane()
|
Cq.Workplane()
|
||||||
.cylinder(
|
.cylinder(
|
||||||
radius=self.barrel_diam/2,
|
radius=self.barrel_diam/2 + self.motor_coupler_wall_thickness,
|
||||||
height=20.0
|
height=self.motor_coupler_height,
|
||||||
|
centered=(True, True, False)
|
||||||
)
|
)
|
||||||
|
.faces(">Z")
|
||||||
|
.hole(self.barrel_diam + self.motor_coupler_inner_gap*2)
|
||||||
)
|
)
|
||||||
|
result = body + flange
|
||||||
|
result.tagAbsolute("holeT1", (x, 0, t), direction="+Z")
|
||||||
|
result.tagAbsolute("holeT2", (-x, 0, t), direction="+Z")
|
||||||
|
result.tagAbsolute("holeB1", (x, 0, 0), direction="-Z")
|
||||||
|
result.tagAbsolute("holeB2", (-x, 0, 0), direction="-Z")
|
||||||
|
return result
|
||||||
|
|
||||||
@target(name="motor-driver-disk", kind=TargetKind.DXF)
|
@target(name="motor-driver-disk", kind=TargetKind.DXF)
|
||||||
def profile_motor_driver_disk(self) -> Cq.Sketch:
|
def profile_motor_driver_disk(self) -> Cq.Sketch:
|
||||||
"""
|
"""
|
||||||
A drive disk mounts onto the motor, and extends into gun barrels to turn them.
|
A drive disk mounts onto the motor, and extends into gun barrels to turn them.
|
||||||
"""
|
"""
|
||||||
|
hole_diam = self.barrel_diam - self.barrel_wall_thickness * 2
|
||||||
|
|
||||||
|
coupler_holes = [
|
||||||
|
Cq.Location.rot2d(i * 360 / self.n_side) *
|
||||||
|
Cq.Location.from2d(self.rotation_radius + sx * self.motor_coupler_conn_dx, 0)
|
||||||
|
for i in range(self.n_side)
|
||||||
|
for sx in (-1, 1)
|
||||||
|
]
|
||||||
return (
|
return (
|
||||||
Cq.Sketch()
|
Cq.Sketch()
|
||||||
.circle(self.rotor_radius)
|
.circle(self.motor_driver_radius)
|
||||||
# Drill out the centre which will accomodate the motor shaft
|
# Drill out the centre which will accomodate the motor shaft
|
||||||
.circle(self.motor.diam_shaft/2, mode="s")
|
.circle(self.motor.diam_shaft/2, mode="s")
|
||||||
# Drill out couplers
|
# Drill out couplers
|
||||||
|
@ -404,11 +470,19 @@ class Onbashira(Model):
|
||||||
.regularPolygon(
|
.regularPolygon(
|
||||||
self.rotation_radius,
|
self.rotation_radius,
|
||||||
self.n_side,
|
self.n_side,
|
||||||
|
angle=180 / self.n_side,
|
||||||
mode="c",
|
mode="c",
|
||||||
tag="const",
|
tag="const",
|
||||||
)
|
)
|
||||||
.vertices(tag="const")
|
.vertices(tag="const")
|
||||||
.circle(BOLT_COMMON.diam_thread/2, mode="s")
|
.circle(hole_diam/2, mode="s")
|
||||||
|
.reset()
|
||||||
|
# Create coupler holes
|
||||||
|
.push([
|
||||||
|
loc.to2d_pos()
|
||||||
|
for loc in coupler_holes
|
||||||
|
])
|
||||||
|
.circle(BOLT_BEARING.diam_thread /2, mode="s")
|
||||||
)
|
)
|
||||||
def motor_driver_disk(self) -> Cq.Workplane:
|
def motor_driver_disk(self) -> Cq.Workplane:
|
||||||
result = (
|
result = (
|
||||||
|
@ -421,19 +495,26 @@ class Onbashira(Model):
|
||||||
loc = Cq.Location.rot2d(i * 360 / n) * Cq.Location(self.flange_coupler.r_hole_flange, 0)
|
loc = Cq.Location.rot2d(i * 360 / n) * Cq.Location(self.flange_coupler.r_hole_flange, 0)
|
||||||
result.tagAbsolute(f"holeT{i}", loc * Cq.Location(0, 0, self.auxiliary_thickness), direction="+Z")
|
result.tagAbsolute(f"holeT{i}", loc * Cq.Location(0, 0, self.auxiliary_thickness), direction="+Z")
|
||||||
result.tagAbsolute(f"holeB{i}", loc, direction="-Z")
|
result.tagAbsolute(f"holeB{i}", loc, direction="-Z")
|
||||||
|
loc_z = Cq.Location(0, 0, self.auxiliary_thickness)
|
||||||
|
loc_outer = Cq.Location.from2d(self.rotation_radius + self.motor_coupler_conn_dx, 0)
|
||||||
|
loc_inner = Cq.Location.from2d(self.rotation_radius - self.motor_coupler_conn_dx, 0)
|
||||||
|
for i in range(self.n_side):
|
||||||
|
loc_rot = Cq.Location.rot2d(i * 360 / self.n_side)
|
||||||
|
p_outer, _ = (loc_z * loc_rot * loc_outer).toTuple()
|
||||||
|
p_inner, _ = (loc_z * loc_rot * loc_inner).toTuple()
|
||||||
|
result.tagAbsolute(f"holeCOF{i}", p_outer, direction="+Z")
|
||||||
|
result.tagAbsolute(f"holeCIF{i}", p_inner, direction="+Z")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@target(name="motor-mount-plate", kind=TargetKind.DXF)
|
@target(name="motor-mount-plate", kind=TargetKind.DXF)
|
||||||
def profile_motor_mount_plate(self) -> Cq.Sketch:
|
def profile_motor_mount_plate(self) -> Cq.Sketch:
|
||||||
assert self.n_side == 6
|
r = self.motor_seat_radius
|
||||||
bx, by = self.angle_joint_bind_pos.to2d_pos()
|
|
||||||
gap = 10.0
|
gap = 10.0
|
||||||
hole_dx = self.motor.dx_anchor
|
hole_dx = self.motor.dx_anchor
|
||||||
return (
|
return (
|
||||||
Cq.Sketch()
|
Cq.Sketch()
|
||||||
.rect((bx + gap) * 2, (by + gap) * 2)
|
.circle(r + gap)
|
||||||
.reset()
|
.regularPolygon(r, self.n_side, mode="c", tag="corner")
|
||||||
.rect(bx * 2, by * 2, mode="c", tag="corner")
|
|
||||||
.vertices(tag="corner")
|
.vertices(tag="corner")
|
||||||
.circle(BOLT_COMMON.diam_thread/2, mode="s")
|
.circle(BOLT_COMMON.diam_thread/2, mode="s")
|
||||||
.reset()
|
.reset()
|
||||||
|
@ -451,12 +532,10 @@ class Onbashira(Model):
|
||||||
)
|
)
|
||||||
result.tagAbsolute("anchor1", (self.motor.dx_anchor, 0, 0), direction="-Z")
|
result.tagAbsolute("anchor1", (self.motor.dx_anchor, 0, 0), direction="-Z")
|
||||||
result.tagAbsolute("anchor2", (-self.motor.dx_anchor, 0, 0), direction="-Z")
|
result.tagAbsolute("anchor2", (-self.motor.dx_anchor, 0, 0), direction="-Z")
|
||||||
bp = self.angle_joint_bind_pos
|
r = self.motor_seat_radius
|
||||||
for i in range(self.n_side):
|
for i in range(self.n_side):
|
||||||
if i in {1, 4}:
|
|
||||||
continue
|
|
||||||
angle = i * 360 / self.n_side
|
angle = i * 360 / self.n_side
|
||||||
x, y = (Cq.Location.rot2d(angle) * bp).to2d_pos()
|
x, y = (Cq.Location.rot2d(angle) * Cq.Location.from2d(0, r)).to2d_pos()
|
||||||
result.tagAbsolute(f"holeF{i}", (x, y, self.auxiliary_thickness), direction="+Z")
|
result.tagAbsolute(f"holeF{i}", (x, y, self.auxiliary_thickness), direction="+Z")
|
||||||
result.tagAbsolute(f"holeB{i}", (x, -y, 0), direction="-Z")
|
result.tagAbsolute(f"holeB{i}", (x, -y, 0), direction="-Z")
|
||||||
return result
|
return result
|
||||||
|
@ -510,6 +589,49 @@ class Onbashira(Model):
|
||||||
f"driver_disk?holeB{i}",
|
f"driver_disk?holeB{i}",
|
||||||
"Plane",
|
"Plane",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add the motor seats
|
||||||
|
assert self.n_side % 2 == 0
|
||||||
|
for i in range(self.n_side // 2):
|
||||||
|
name_seat = f"seat{i}"
|
||||||
|
a = (
|
||||||
|
a.addS(
|
||||||
|
self.motor_seat(),
|
||||||
|
name=name_seat,
|
||||||
|
role=Role.STRUCTURE,
|
||||||
|
material=self.material_brace
|
||||||
|
)
|
||||||
|
.constrain(
|
||||||
|
f"{name_seat}?holeMF1",
|
||||||
|
f"mount_plate?holeB{i*2}",
|
||||||
|
"Plane"
|
||||||
|
)
|
||||||
|
.constrain(
|
||||||
|
f"{name_seat}?holeMF2",
|
||||||
|
f"mount_plate?holeB{i*2+1}",
|
||||||
|
"Plane"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for i in range(self.n_side):
|
||||||
|
name_coupler = f"coupler{i}"
|
||||||
|
a = (
|
||||||
|
a.addS(
|
||||||
|
self.motor_coupler(),
|
||||||
|
name=name_coupler,
|
||||||
|
role=Role.CONNECTION,
|
||||||
|
material=self.material_brace,
|
||||||
|
)
|
||||||
|
.constrain(
|
||||||
|
f"{name_coupler}?holeB1",
|
||||||
|
f"driver_disk?holeCOF{i}",
|
||||||
|
"Plane",
|
||||||
|
)
|
||||||
|
.constrain(
|
||||||
|
f"{name_coupler}?holeB2",
|
||||||
|
f"driver_disk?holeCIF{i}",
|
||||||
|
"Plane",
|
||||||
|
)
|
||||||
|
)
|
||||||
return a.solve()
|
return a.solve()
|
||||||
|
|
||||||
@target(name="stator-coupler")
|
@target(name="stator-coupler")
|
||||||
|
@ -784,7 +906,7 @@ class Onbashira(Model):
|
||||||
da_bind_rotor_minor = 360 / self.n_side / (1 + self.rotor_bind_extra)
|
da_bind_rotor_minor = 360 / self.n_side / (1 + self.rotor_bind_extra)
|
||||||
for i in range(self.n_side):
|
for i in range(self.n_side):
|
||||||
loc_barrel = Cq.Location.rot2d((i+1/2) * 360/self.n_side) * \
|
loc_barrel = Cq.Location.rot2d((i+1/2) * 360/self.n_side) * \
|
||||||
Cq.Location(self.rotation_radius, 0, -self.barrel_length/2)
|
Cq.Location(self.rotation_radius, 0, self.barrel_shift-self.barrel_length/2)
|
||||||
a = a.addS(
|
a = a.addS(
|
||||||
self.barrel(),
|
self.barrel(),
|
||||||
name=f"barrel{i}",
|
name=f"barrel{i}",
|
||||||
|
@ -877,30 +999,172 @@ class Onbashira(Model):
|
||||||
result.tagAbsolute("holeMO1", (dxe, 0, t))
|
result.tagAbsolute("holeMO1", (dxe, 0, t))
|
||||||
result.tagAbsolute("holeMO2", (-dxe, 0, t))
|
result.tagAbsolute("holeMO2", (-dxe, 0, t))
|
||||||
return result
|
return result
|
||||||
@target(name="raising-bar")
|
|
||||||
def raising_bar(self) -> Cq.Workplane:
|
@target(name="motor-seat")
|
||||||
|
def motor_seat(self) -> Cq.Workplane:
|
||||||
"""
|
"""
|
||||||
Create new longitudinal mount points closer to the centre axis, and a
|
Create new longitudinal mount points closer to the centre axis, and a
|
||||||
ring for mounting lights
|
ring for mounting lights
|
||||||
"""
|
"""
|
||||||
_, dx = self.angle_joint_bind_pos.to2d_pos()
|
bx, by = self.angle_joint_bind_pos.to2d_pos()
|
||||||
gap = 10
|
gap = 10
|
||||||
t1 = 5
|
t1 = 10
|
||||||
|
base_w = 17.0
|
||||||
theta = math.pi / self.n_side
|
theta = math.pi / self.n_side
|
||||||
|
theta2 = theta * 0.5
|
||||||
|
track_width = 7.0
|
||||||
r0 = self.bulk_radius
|
r0 = self.bulk_radius
|
||||||
result = (
|
r1 = self.rotation_radius + gap
|
||||||
Cq.Workplane()
|
r2 = self.rotation_radius - gap
|
||||||
.sketch()
|
profile_arc = (
|
||||||
.circle(self.rotation_radius + gap)
|
Cq.Sketch()
|
||||||
.circle(self.rotation_radius - gap, mode="s")
|
.circle(r1)
|
||||||
|
.circle(r2, mode="s")
|
||||||
.polygon([
|
.polygon([
|
||||||
(0, 0),
|
(0, 0),
|
||||||
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
||||||
(r0 * math.cos(theta), -r0 * math.sin(theta)),
|
(r0 * math.cos(theta), -r0 * math.sin(theta)),
|
||||||
], mode="i")
|
], mode="i")
|
||||||
|
)
|
||||||
|
profile_base = (
|
||||||
|
profile_arc
|
||||||
|
.reset()
|
||||||
|
.polygon([
|
||||||
|
(bx - base_w/2, by),
|
||||||
|
(bx + base_w/2, by),
|
||||||
|
(bx + base_w/2, -by),
|
||||||
|
(bx - base_w/2, -by),
|
||||||
|
])
|
||||||
|
.reset()
|
||||||
|
.polygon([
|
||||||
|
(r1 * math.cos(theta), r1 * math.sin(theta)),
|
||||||
|
(r1 * math.cos(theta2), r1 * math.sin(theta2)),
|
||||||
|
(r0 * math.cos(theta2), r0 * math.sin(theta2)),
|
||||||
|
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
||||||
|
])
|
||||||
|
.polygon([
|
||||||
|
(r1 * math.cos(theta), -r1 * math.sin(theta)),
|
||||||
|
(r1 * math.cos(theta2), -r1 * math.sin(theta2)),
|
||||||
|
(r0 * math.cos(theta2), -r0 * math.sin(theta2)),
|
||||||
|
(r0 * math.cos(theta), -r0 * math.sin(theta)),
|
||||||
|
])
|
||||||
|
.reset()
|
||||||
|
.push([
|
||||||
|
(bx, by), (bx, -by),
|
||||||
|
])
|
||||||
|
.circle(base_w/2, mode="a")
|
||||||
|
.reset()
|
||||||
|
.push([
|
||||||
|
(bx, by), (bx, -by),
|
||||||
|
])
|
||||||
|
.circle(BOLT_COMMON.diam_thread/2, mode="s")
|
||||||
|
)
|
||||||
|
base = (
|
||||||
|
Cq.Workplane()
|
||||||
|
.placeSketch(profile_base)
|
||||||
|
.extrude(t1)
|
||||||
|
)
|
||||||
|
r3 = self.motor_seat_radius
|
||||||
|
r2_5 = r3 + BOLT_COMMON.diam_thread/2
|
||||||
|
mount_x = r3 * math.cos(theta)
|
||||||
|
mount_y = r3 * math.sin(theta)
|
||||||
|
front = (
|
||||||
|
Cq.Workplane()
|
||||||
|
.sketch()
|
||||||
|
.circle(r1)
|
||||||
|
.circle(self.rotation_radius+track_width/2, mode="s")
|
||||||
|
.circle(self.rotation_radius-track_width/2)
|
||||||
|
.circle(r2_5, mode="s")
|
||||||
|
.polygon([
|
||||||
|
(0, 0),
|
||||||
|
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
||||||
|
(r0 * math.cos(theta), -r0 * math.sin(theta)),
|
||||||
|
], mode="i")
|
||||||
|
.push([
|
||||||
|
(mount_x, mount_y),
|
||||||
|
(mount_x, -mount_y),
|
||||||
|
])
|
||||||
|
.circle(base_w/2)
|
||||||
|
.circle(BOLT_COMMON.diam_thread/2, mode="s")
|
||||||
.finalize()
|
.finalize()
|
||||||
.extrude(t1)
|
.extrude(t1)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Construct the connection between the front and back
|
||||||
|
|
||||||
|
profile_bridge_outer_base = (
|
||||||
|
Cq.Sketch()
|
||||||
|
.polygon([
|
||||||
|
(bx - base_w/2, by - base_w/2),
|
||||||
|
(bx + base_w/2, by - base_w/2),
|
||||||
|
(bx + base_w/2, by - base_w*1.5),
|
||||||
|
(bx - base_w/2, by - base_w*1.5),
|
||||||
|
])
|
||||||
|
.wires()
|
||||||
|
.val()
|
||||||
|
.moved(0, 0, t1)
|
||||||
|
)
|
||||||
|
profile_bridge_outer_top = (
|
||||||
|
Cq.Sketch()
|
||||||
|
.circle(r1)
|
||||||
|
.circle(self.rotation_radius+track_width/2, mode="s")
|
||||||
|
.polygon([
|
||||||
|
(0, 0),
|
||||||
|
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
||||||
|
(r0 * math.cos(theta2), r0 * math.sin(theta2)),
|
||||||
|
], mode="i")
|
||||||
|
.wires()
|
||||||
|
.val()
|
||||||
|
.moved(0, 0, self.motor_seat_depth)
|
||||||
|
)
|
||||||
|
profile_bridge_inner_base = (
|
||||||
|
Cq.Sketch()
|
||||||
|
.circle(r1)
|
||||||
|
.circle(r2, mode="s")
|
||||||
|
.polygon([
|
||||||
|
(0, 0),
|
||||||
|
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
||||||
|
(r0 * math.cos(theta2), r0 * math.sin(theta2)),
|
||||||
|
], mode="i")
|
||||||
|
.wires()
|
||||||
|
.val()
|
||||||
|
)
|
||||||
|
profile_bridge_inner_top = (
|
||||||
|
Cq.Sketch()
|
||||||
|
.circle(r1)
|
||||||
|
.circle(r2, mode="s")
|
||||||
|
.polygon([
|
||||||
|
(0, 0),
|
||||||
|
(r0 * math.cos(theta), r0 * math.sin(theta)),
|
||||||
|
(r0 * math.cos(theta2), r0 * math.sin(theta2)),
|
||||||
|
], mode="i")
|
||||||
|
.wires()
|
||||||
|
.val()
|
||||||
|
.moved(0, 0, self.motor_seat_depth - t1)
|
||||||
|
)
|
||||||
|
bridge_outer = Cq.Solid.makeLoft([profile_bridge_outer_base, profile_bridge_outer_top])
|
||||||
|
bridge_inner = Cq.Solid.makeLoft([profile_bridge_inner_base, profile_bridge_inner_top])
|
||||||
|
hole_subtractor = Cq.Solid.makeCylinder(
|
||||||
|
radius=BOLT_COMMON.diam_thread/2,
|
||||||
|
height=t1,
|
||||||
|
pnt=((r1+r2)/2, 0, 0)
|
||||||
|
)
|
||||||
|
result = (
|
||||||
|
base
|
||||||
|
+ front.translate((0, 0, self.motor_seat_depth - t1))
|
||||||
|
+ bridge_outer
|
||||||
|
+ bridge_outer.mirror("XZ")
|
||||||
|
+ bridge_inner
|
||||||
|
+ bridge_inner.mirror("XZ")
|
||||||
|
- hole_subtractor
|
||||||
|
)
|
||||||
|
|
||||||
|
# Mark the mount points
|
||||||
|
result.tagAbsolute("holeBB1", (bx, +by, 0), direction="-Z")
|
||||||
|
result.tagAbsolute("holeBB2", (bx, -by, 0), direction="-Z")
|
||||||
|
result.tagAbsolute("holeMF1", (mount_x, +mount_y, self.motor_seat_depth), direction="+Z")
|
||||||
|
result.tagAbsolute("holeMF2", (mount_x, -mount_y, self.motor_seat_depth), direction="+Z")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -1676,81 +1940,107 @@ class Onbashira(Model):
|
||||||
result.tagAbsolute(f"holeRSI{i}", (-x, -y, -t), direction="-Z")
|
result.tagAbsolute(f"holeRSI{i}", (-x, -y, -t), direction="-Z")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@assembly()
|
@assembly()
|
||||||
def assembly(self) -> Cq.Assembly:
|
def assembly(self, parts: Optional[list[str]] = None) -> Cq.Assembly:
|
||||||
a = Cq.Assembly()
|
a = Cq.Assembly()
|
||||||
a = (
|
if has_part(parts, "section1"):
|
||||||
a
|
a = a.add(
|
||||||
.add(
|
|
||||||
self.assembly_section1(),
|
self.assembly_section1(),
|
||||||
name="section1",
|
name="section1",
|
||||||
)
|
)
|
||||||
.add(
|
if has_part(parts, "ring1"):
|
||||||
|
a = a.add(
|
||||||
self.assembly_ring(self.angle_joint()),
|
self.assembly_ring(self.angle_joint()),
|
||||||
name="ring1",
|
name="ring1",
|
||||||
)
|
)
|
||||||
.add(
|
if has_part(parts, "section2"):
|
||||||
|
a = a.add(
|
||||||
self.assembly_section(length=self.side_length2, hasFrontHole=True, hasBackHole=True),
|
self.assembly_section(length=self.side_length2, hasFrontHole=True, hasBackHole=True),
|
||||||
name="section2",
|
name="section2",
|
||||||
)
|
)
|
||||||
.add(
|
if has_part(parts, "ring2"):
|
||||||
|
a = a.add(
|
||||||
self.assembly_ring(self.angle_joint()),
|
self.assembly_ring(self.angle_joint()),
|
||||||
name="ring2",
|
name="ring2",
|
||||||
)
|
)
|
||||||
.add(
|
a = a.addS(
|
||||||
self.assembly_section(length=self.side_length3, hasFrontHole=True, hasBackHole=True),
|
|
||||||
name="section3",
|
|
||||||
)
|
|
||||||
.add(
|
|
||||||
self.assembly_ring(self.angle_joint_chamber_front()),
|
|
||||||
name="ring3",
|
|
||||||
)
|
|
||||||
.add(
|
|
||||||
self.assembly_chamber(),
|
|
||||||
name="chamber",
|
|
||||||
)
|
|
||||||
.add(
|
|
||||||
self.assembly_ring(self.angle_joint_chamber_back()),
|
|
||||||
name="ring4",
|
|
||||||
)
|
|
||||||
.addS(
|
|
||||||
self.chamber_back(),
|
|
||||||
name="chamber_back",
|
|
||||||
material=self.material_side,
|
|
||||||
role=Role.STRUCTURE | Role.DECORATION,
|
|
||||||
)
|
|
||||||
.addS(
|
|
||||||
self.handle(),
|
self.handle(),
|
||||||
name="handle",
|
name="handle",
|
||||||
material=self.material_brace,
|
material=self.material_brace,
|
||||||
role=Role.HANDLE,
|
role=Role.HANDLE,
|
||||||
)
|
)
|
||||||
.add(self.assembly_motor(), name="motor")
|
# Handle constrain
|
||||||
.add(self.assembly_machine(), name="machine")
|
for ih, (x, y) in enumerate(self.angle_joint_bolt_position):
|
||||||
.add(self.turning_bar(), name="turning_bar1")
|
a = a.constrain(
|
||||||
)
|
f"handle?holeLPI{ih}",
|
||||||
a = a.constrain(
|
f"ring2/side0?holeLPO{ih}",
|
||||||
f"turning_bar1?holeBO2",
|
"Plane",
|
||||||
f"ring3/side0?holeStatorL",
|
)
|
||||||
"Plane",
|
a = a.constrain(
|
||||||
)
|
f"handle?holeRPI{ih}",
|
||||||
a = a.constrain(
|
f"ring2/side0?holeRPO{ih}",
|
||||||
f"turning_bar1?holeBO1",
|
"Plane",
|
||||||
f"ring3/side1?holeStatorL",
|
)
|
||||||
"Plane",
|
if has_part(parts, "section3"):
|
||||||
)
|
a = a.add(
|
||||||
# Add handle
|
self.assembly_section(length=self.side_length3, hasFrontHole=True, hasBackHole=True),
|
||||||
for ih, (x, y) in enumerate(self.angle_joint_bolt_position):
|
name="section3",
|
||||||
|
)
|
||||||
|
if has_part(parts, "ring3"):
|
||||||
|
a = a.add(
|
||||||
|
self.assembly_ring(self.angle_joint_chamber_front()),
|
||||||
|
name="ring3",
|
||||||
|
)
|
||||||
|
if has_part(parts, "chamber"):
|
||||||
|
a = a.add(
|
||||||
|
self.assembly_chamber(),
|
||||||
|
name="chamber",
|
||||||
|
)
|
||||||
|
if has_part(parts, "ring4"):
|
||||||
|
a = a.add(
|
||||||
|
self.assembly_ring(self.angle_joint_chamber_back()),
|
||||||
|
name="ring4",
|
||||||
|
)
|
||||||
|
if has_part(parts, "chamber_back"):
|
||||||
|
a = a.addS(
|
||||||
|
self.chamber_back(),
|
||||||
|
name="chamber_back",
|
||||||
|
material=self.material_side,
|
||||||
|
role=Role.STRUCTURE | Role.DECORATION,
|
||||||
|
)
|
||||||
|
if has_part(parts, "motor"):
|
||||||
|
a = a.add(self.assembly_motor(), name="motor")
|
||||||
|
if has_part(parts, "machine"):
|
||||||
|
a = a.add(self.assembly_machine(), name="machine")
|
||||||
|
if has_part(parts, "turning_bar"):
|
||||||
|
a = a.add(self.turning_bar(), name="turning_bar1")
|
||||||
|
if has_part(parts, ["turning_bar", "ring3"]):
|
||||||
a = a.constrain(
|
a = a.constrain(
|
||||||
f"handle?holeLPI{ih}",
|
f"turning_bar1?holeBO2",
|
||||||
f"ring2/side0?holeLPO{ih}",
|
f"ring3/side0?holeStatorL",
|
||||||
"Plane",
|
"Plane",
|
||||||
)
|
)
|
||||||
a = a.constrain(
|
a = a.constrain(
|
||||||
f"handle?holeRPI{ih}",
|
f"turning_bar1?holeBO1",
|
||||||
f"ring2/side0?holeRPO{ih}",
|
f"ring3/side1?holeStatorL",
|
||||||
"Plane",
|
"Plane",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# FIXME: Filter
|
||||||
|
if has_part(parts, ["motor", "ring2"]):
|
||||||
|
for i in range(self.n_side // 2):
|
||||||
|
j = self.n_side // 2 - 1 - i
|
||||||
|
a = a.constrain(
|
||||||
|
f"motor/seat{j}?holeBB1",
|
||||||
|
f"ring2/side{i*2}?holeStatorL",
|
||||||
|
"Plane",
|
||||||
|
)
|
||||||
|
#a = a.constrain(
|
||||||
|
# f"motor/seat{j}?holeBB2",
|
||||||
|
# f"ring2/side{i*2+1}?holeStatorL",
|
||||||
|
# "Plane",
|
||||||
|
#)
|
||||||
for i in range(self.n_side):
|
for i in range(self.n_side):
|
||||||
j = (i + 1) % self.n_side
|
j = (i + 1) % self.n_side
|
||||||
ir = (self.n_side - i) % self.n_side
|
ir = (self.n_side - i) % self.n_side
|
||||||
|
@ -1772,12 +2062,6 @@ class Onbashira(Model):
|
||||||
f"machine/stator2?holeB{ir}",
|
f"machine/stator2?holeB{ir}",
|
||||||
"Plane",
|
"Plane",
|
||||||
)
|
)
|
||||||
if i not in {1, 4}:
|
|
||||||
a = a.constrain(
|
|
||||||
f"motor/mount_plate?holeF{i}",
|
|
||||||
f"ring2/side{(ir+2)%self.n_side}?holeStatorR",
|
|
||||||
"Plane",
|
|
||||||
)
|
|
||||||
|
|
||||||
name_bolt =f"stator_outer_bolt{i}"
|
name_bolt =f"stator_outer_bolt{i}"
|
||||||
a = a.addS(
|
a = a.addS(
|
||||||
|
|
Loading…
Reference in New Issue