feat: P01/P02阶梯榫卯面承载+P03侧开式托架/P04加长避让重构,精简零件显示名并同步重建模型数据与查看器,清理历史文档
This commit is contained in:
+15
-275
@@ -1,14 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""60 mm gearmotor -> 5-DOF printable robot arm (J1 yaw, J2 shoulder, J3 elbow,
|
||||
J4 wrist pitch, J5 gripper).
|
||||
"""Shared geometry / assembly / export library for the robot arm build.
|
||||
|
||||
Joint recipe (measured, see docs/interfaces.md):
|
||||
proximal link holds the motor in a Ø60.3 slip bore + 64.4 square PCBA pocket +
|
||||
4 radial M3 pinch screws; motor rear datum + 65.0 = the driven link's hub mating
|
||||
plane, whose face replicates the motor output (Ø36x1.0 neck, Ø6.5x4.0 centre,
|
||||
3x M2 on Ø29) so the existing face-spline halves + split clamp bolt straight on.
|
||||
No layout of its own: the joint frames and station positions live in
|
||||
human_layout.py and arm_model.py, which import this module. What lives here is
|
||||
the measured motor interface (docs/interfaces.md), the Joint class (motor slip
|
||||
bore + PCBA pocket + pinch screws; driven hub mating plane at motor rear datum
|
||||
+65.0 replicating the Ø36x1.0 neck / Ø6.5x4.0 centre / 3x M2 on Ø29 output so
|
||||
the existing face-spline halves + split clamp bolt straight on), the part
|
||||
registry, and the STEP/STL/mesh/BOM/collision export pipeline.
|
||||
|
||||
Run: python arm_build.py -> out/, web/mesh_arm.json, docs/
|
||||
Run: python arm_model.py -> out/, web/mesh_arm.json, docs/
|
||||
"""
|
||||
import math
|
||||
import os
|
||||
@@ -50,30 +51,6 @@ HUB_M2_CLOCK = [(360.0 - a) % 360.0 for a in M["m2_clock"]] # phase of the mir
|
||||
HUB_PILOT_D = M["neck_d"] - 0.4 # 35.6 -> the half's pilot lands in a Ø36 recess
|
||||
PINCH_D = 2.6 # M3 clearance in printed material
|
||||
|
||||
# ---------------------------------------------------------------- layout (ground X fwd, Y left, Z up)
|
||||
PLATE_T = 9.0
|
||||
ARM_L1, ARM_L2 = 175.0, 165.0
|
||||
EL_A, FA_A = 58.0, 8.0
|
||||
SH = (0.0, 125.0)
|
||||
EL = (SH[0] + ARM_L1 * math.cos(EL_A * D2R), SH[1] + ARM_L1 * math.sin(EL_A * D2R))
|
||||
WR = (EL[0] + ARM_L2 * math.cos(FA_A * D2R), EL[1] + ARM_L2 * math.sin(FA_A * D2R))
|
||||
DIR_U = (math.cos(EL_A * D2R), math.sin(EL_A * D2R))
|
||||
DIR_F = (math.cos(FA_A * D2R), math.sin(FA_A * D2R))
|
||||
PERP_F = (-DIR_F[1], DIR_F[0]) # "up" in the arm plane for the wrist
|
||||
|
||||
Y0 = -26.0
|
||||
Y_UP_IN = Y0 + HUB_FACE_Z
|
||||
Y_UP_OUT = Y_UP_IN + PLATE_T
|
||||
Y3_REAR = Y_UP_IN
|
||||
Y_FA_OUT = Y3_REAR - HUB_FACE_Z - PLATE_T
|
||||
Y_FA_IN = Y_FA_OUT + PLATE_T
|
||||
Y4_REAR = Y_FA_IN
|
||||
Y_WM_IN = Y4_REAR + HUB_FACE_Z
|
||||
Y_WM_OUT = Y_WM_IN + PLATE_T
|
||||
Y_M5, S0_M5 = -2.0, 58.0
|
||||
BRACKET_BOLT = [(-26.0, Y0 - 3.0), (0.0, Y0 - 3.0), (26.0, Y0 - 3.0)] # turret <-> shoulder wall
|
||||
COLUMN_BOLT = [(35.0 * math.cos(a * D2R), 35.0 * math.sin(a * D2R)) for a in (30, 150, 270)]
|
||||
|
||||
PARTS = []
|
||||
CENTS = {}
|
||||
|
||||
@@ -287,7 +264,7 @@ class Joint:
|
||||
cuts.append(cyl(M["m2_tap_d"] / 2.0, H - 0.05, H + M["m2_depth"], u, v))
|
||||
return shape.cut(*[self.L(s) for s in cuts])
|
||||
|
||||
def hub_island(self, shape, r=30.0, t=PLATE_T + 0.5):
|
||||
def hub_island(self, shape, r=30.0, t=9.5):
|
||||
"""Solid disc at the joint centre (the lightening dish must not break into the
|
||||
interface recesses), then the output replica is cut into it. Starts exactly on the
|
||||
mating plane: half B's Ø54 body ends there, so any overlap is a hard clash."""
|
||||
@@ -321,185 +298,10 @@ class Joint:
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- printed part builders
|
||||
def p_base_plate():
|
||||
s = cyl(76, 0, 8).cut(cyl(25, -0.01, 8.01))
|
||||
for a in (45, 135, 225, 315):
|
||||
u, v = 58 * math.cos(a * D2R), 58 * math.sin(a * D2R)
|
||||
s = s.cut(cyl(2.75, -0.01, 8.01, u, v)).cut(cyl(5.5, -0.01, 2.8, u, v))
|
||||
for a in range(0, 360, 45):
|
||||
u, v = 68 * math.cos(a * D2R), 68 * math.sin(a * D2R)
|
||||
s = s.cut(cyl(4.0, -0.01, 3.0, u, v))
|
||||
return s
|
||||
|
||||
|
||||
def p_column(j1):
|
||||
"""Ø88 column z 8..64 holding M1; open at the bottom so it slides over the motor."""
|
||||
s = cyl(44, 8, 64)
|
||||
for a in (0, 90, 180, 270):
|
||||
blk = box(21, 45, -12, 12, 22, 50)
|
||||
blk = place(blk, R(a, 0, 0, 1))
|
||||
s = s.cut(blk)
|
||||
s = j1.pocket(s, front_pad=0.0)
|
||||
s = j1.pinch(s, n=2)
|
||||
# J1 hub must be able to pull up: top face keeps a Ø61 recess ring for the cover
|
||||
s = s.cut(ring(30.6, 36.0, 63.4, 64.01))
|
||||
# cable duct from the base to the turret
|
||||
duct = box(-9, 9, -46, -30, 20, 64)
|
||||
s = s.cut(duct)
|
||||
return s
|
||||
|
||||
|
||||
def p_turret(j1):
|
||||
"""J1 driven hub: mating face at z=73, plate 73..82, carries the shoulder bracket."""
|
||||
face = j1.hub_face()
|
||||
zf = 73.0
|
||||
s = cyl(52, zf, zf + PLATE_T)
|
||||
s = s.cut(ring(38.5, 52.0, zf - 0.01, zf + 2.2)) # dish the underside for the clamp
|
||||
for a in range(30, 360, 60): # lightening (off the bolt lines)
|
||||
u, v = 40 * math.cos(a * D2R), 40 * math.sin(a * D2R)
|
||||
s = s.cut(cyl(7.0, zf + 2.4, zf + PLATE_T - 2.4, u, v))
|
||||
s = j1.hub_island(s, 30.0, PLATE_T - 0.02)
|
||||
for (u, v) in COLUMN_BOLT: # 3x M3 down into the column
|
||||
s = s.cut(cyl(1.6, zf - 0.01, zf + PLATE_T + 0.01, u, v))
|
||||
for (u, v) in BRACKET_BOLT: # 3x M3 up for the shoulder wall
|
||||
s = s.cut(cyl(1.55, zf + PLATE_T - 6.0, zf + PLATE_T + 0.01, u, v))
|
||||
return s
|
||||
|
||||
|
||||
def p_shoulder_bracket(j2):
|
||||
"""Wall on the turret top + motor sleeve; holds M2 (axis +Y at SH)."""
|
||||
zt = 82.0
|
||||
y0, y1 = Y0 - 6.0, Y0
|
||||
s = Ybox(SH[0] - 40, SH[0] + 40, y0, y1, zt + 0.02, SH[1] + 39.0)
|
||||
s = s.fuse(Ycyl(38.0, Y0, Y0 + COVER_Z - 3.0, SH[0], SH[1]))
|
||||
s = s.fuse(Ybox(SH[0] - 38, SH[0] + 38, Y0, Y0 + 6.0, SH[1] - 20, SH[1] + 20))
|
||||
for sx in (-1, 1): # feet down onto the turret
|
||||
s = s.fuse(Ybox(sx * 26 - 6, sx * 26 + 6, y0, y1, zt + 0.02, zt + 30.0))
|
||||
s = j2.pocket(s) # relieve AFTER every fuse
|
||||
s = j2.pinch(s, n=2)
|
||||
for (bx_, by_) in BRACKET_BOLT: # 3x M3 down into the turret
|
||||
s = s.cut(cyl(1.7, zt + 0.01, zt + 8.0, bx_, by_))
|
||||
return s
|
||||
|
||||
|
||||
def p_upper_arm(j2, j3):
|
||||
"""Plate normal Y, y 39..48. J2 hub at the shoulder end; holds M3 at the elbow (axis -Y,
|
||||
so its boss reaches toward -Y from the plate)."""
|
||||
pts = dogbone(EL, SH, 41.0, 41.0)
|
||||
s = Yplate(pts, Y_UP_IN, Y_UP_OUT)
|
||||
s = s.fuse(Ycyl(38.0, Y3_REAR - 22.0, Y_UP_OUT, EL[0], EL[1])) # elbow motor boss
|
||||
inner = dogbone(EL, SH, 41.0 - 10.0, 41.0 - 10.0)
|
||||
s = s.cut(Yplate(inner, Y_UP_IN + 2.6, Y_UP_OUT - 2.6)) # lightening dish
|
||||
for k in range(1, 4): # web ribs in the dish
|
||||
t = k / 4.0
|
||||
cx = SH[0] + (EL[0] - SH[0]) * t
|
||||
cz = SH[1] + (EL[1] - SH[1]) * t
|
||||
s = s.fuse(Ybox(cx - 3.5, cx + 3.5, Y_UP_IN + 2.6, Y_UP_OUT - 2.6, cz - 20, cz + 20))
|
||||
s = j2.hub_island(s, 30.0, PLATE_T + 0.5)
|
||||
s = j3.pocket(s)
|
||||
s = j3.pinch(s, n=2)
|
||||
return s
|
||||
|
||||
|
||||
def p_forearm(j3, j4):
|
||||
"""Plate normal Y, y -35..-26. J3 hub at the elbow end; holds M4 at the wrist (axis +Y,
|
||||
boss reaches toward +Y)."""
|
||||
pts = dogbone(WR, EL, 40.0, 40.0)
|
||||
s = Yplate(pts, Y_FA_OUT, Y_FA_IN)
|
||||
s = s.fuse(Ycyl(37.0, Y_FA_OUT, Y4_REAR + 22.0, WR[0], WR[1])) # wrist motor boss
|
||||
inner = dogbone(WR, EL, 40.0 - 10.0, 40.0 - 10.0)
|
||||
s = s.cut(Yplate(inner, Y_FA_OUT + 2.6, Y_FA_IN - 2.6))
|
||||
for k in range(1, 3):
|
||||
t = k / 3.0
|
||||
cx = EL[0] + (WR[0] - EL[0]) * t
|
||||
cz = EL[1] + (WR[1] - EL[1]) * t
|
||||
s = s.fuse(Ybox(cx - 3.5, cx + 3.5, Y_FA_OUT + 2.6, Y_FA_IN - 2.6, cz - 16, cz + 16))
|
||||
s = j3.hub_island(s, 30.0, PLATE_T + 0.5)
|
||||
s = j4.pocket(s)
|
||||
s = j4.pinch(s, n=2)
|
||||
return s
|
||||
|
||||
|
||||
def p_wrist_plate(j4):
|
||||
"""J4 driven hub + round palm disc with the joint shrouds; bolts to the gripper housing."""
|
||||
zf = Y_WM_IN
|
||||
s = Ycyl(41.0, zf, zf + PLATE_T, WR[0], WR[1])
|
||||
s = j4.hub_island(s, 30.0, PLATE_T + 0.5)
|
||||
for a in range(0, 360, 60): # lightening, clear of the hub island
|
||||
u, v = 34 * math.cos(a * D2R), 34 * math.sin(a * D2R)
|
||||
if math.hypot(u, v) > 31.0:
|
||||
s = s.cut(Ycyl(6.5, zf + 2.6, zf + PLATE_T - 2.6, WR[0] + u, WR[1] + v))
|
||||
for a in (0, 120, 240): # 3x M3 forward into the housing
|
||||
u, v = 30 * math.cos(a * D2R), 30 * math.sin(a * D2R)
|
||||
s = s.cut(Ycyl(1.7, zf + PLATE_T - 6.0, zf + PLATE_T + 0.01, WR[0] + u, WR[1] + v))
|
||||
return s
|
||||
|
||||
|
||||
def p_shell(j4, j5):
|
||||
"""Tapered gripper housing: holds M5, carries the finger guides and the crank window."""
|
||||
zf = Y_WM_IN + PLATE_T
|
||||
rear = j5.L(bx(-41, 41, -38, 38, -14.0, 30.0))
|
||||
fore = j5.L(bx(-41, 41, -38, 38, 30.0, 62.0))
|
||||
body = rear.fuse(fore)
|
||||
# cavity must stay inside both sections: it was ±35.5/±29.5 against a ±34/±26 shell,
|
||||
# which ate the side walls and left the guide blocks as three disconnected solids
|
||||
cav = j5.L(bx(-32.6, 32.6, -32.6, 32.6, -9.0, 54.0))
|
||||
s = body.cut(cav)
|
||||
# mounting flange overlapping the shell by 6 mm: a thin 0.1 mm land would fuse into two
|
||||
# disconnected solids, which would print as two pieces
|
||||
s = s.fuse(j5.L(bx(-41, 41, -35, 35, -16.0, -8.0)))
|
||||
s = j5.pocket(s)
|
||||
s = j5.pinch(s, n=2)
|
||||
s = s.cut(j5.L(cyl(22.5, 53.9, 62.01))) # crank pocket in the front wall
|
||||
for sd in (-1, 1):
|
||||
for sy in (-1, 1): # y-guides, rooted in the side wall
|
||||
s = s.fuse(j5.L(bx(33.0 * sd, 41.0 * sd, 11.6 * sy, 14.2 * sy, 55.0, 66.0)))
|
||||
s = s.cut(j5.L(bx(10.0 * sd, 30.0 * sd, -12.5, 12.5, 53.9, 66.01))) # cam clearance
|
||||
s = s.cut(j5.L(bx(29.5 * sd, 40.5 * sd, -12.6, 12.6, 44.0, 66.01))) # finger arm exit
|
||||
for a in (0, 120, 240): # M3 pilots back into the palm
|
||||
u, v = 30 * math.cos(a * D2R), 30 * math.sin(a * D2R)
|
||||
s = s.cut(j5.L(cyl(1.55, -16.0, -8.0, u, v)))
|
||||
return s
|
||||
|
||||
|
||||
def bx(x0, x1, y0, y1, z0, z1):
|
||||
return box(min(x0, x1), max(x0, x1), min(y0, y1), max(y0, y1), min(z0, z1), max(z0, z1))
|
||||
|
||||
|
||||
def p_finger(j5, side=+1):
|
||||
"""Prismatic finger: arm riding the y-guides, 45 deg cam ramp on the inner face, inward pad.
|
||||
The crank's two opposed pins bear on the two ramps and push both jaws open together."""
|
||||
u = side
|
||||
arm = bx(30.0 * u, 40.0 * u, -10.5, 10.5, 50.0, 140.0)
|
||||
arm = arm.fuse(bx(20.0 * u, 30.0 * u, -10.0, 10.0, 60.0, 78.0)) # cam heel block
|
||||
ramp = bx(-9, 9, -12, 12, 58.0, 80.0)
|
||||
ramp = place(ramp, R(45 if u > 0 else -45, 0, 0, 1))
|
||||
ramp = place(ramp, T(17.0 * u, 0, 0))
|
||||
arm = arm.cut(ramp)
|
||||
foot = bx(8.0 * u, 30.0 * u, -12.0, 12.0, 96.0, 124.0)
|
||||
for k in range(3): # 2 mm grooves cut INTO the contact face
|
||||
foot = foot.cut(bx(6.0 * u, 8.2 * u, -10.5 + 7.0 * k, -7.5 + 7.0 * k, 98.0, 122.0))
|
||||
arm = arm.fuse(foot).fuse(bx(30.0 * u, 37.0 * u, -8.0, 8.0, 140.0, 147.0))
|
||||
return j5.L(arm)
|
||||
|
||||
|
||||
def p_crank(j5):
|
||||
"""Printed disc bolted onto the M5 output: spigot + pilot + disc + 2 opposed pins at R14."""
|
||||
fz = FLANGE_Z
|
||||
s = j5.L(cyl(3.15, fz - 2.7, fz + 0.5)) # into the Ø6.5 bore
|
||||
s = s.fuse(j5.L(cyl(17.8, fz + 0.06, COVER_Z))) # into the Ø36 neck
|
||||
s = s.fuse(j5.L(cyl(20.0, COVER_Z, 62.0))) # disc
|
||||
for a in (0.0, 180.0):
|
||||
u, v = 14.0 * math.cos(a * D2R), 14.0 * math.sin(a * D2R)
|
||||
s = s.fuse(j5.L(cyl(2.9, 62.0, 78.0, u, v)))
|
||||
s = s.fuse(j5.L(cyl(4.6, 62.0, 64.4, u, v)))
|
||||
for a in M["m2_clock"]: # M2 into the motor
|
||||
u, v = M["m2_bcd"] / 2.0 * math.cos(a * D2R), M["m2_bcd"] / 2.0 * math.sin(a * D2R)
|
||||
s = s.cut(j5.L(cyl(M["m2_clear_d"] / 2.0, fz - 0.01, 59.2, u, v)))
|
||||
s = s.cut(j5.L(cyl(M["m2_cb_d"] / 2.0, 59.2, 62.01, u, v)))
|
||||
return s
|
||||
|
||||
|
||||
GRP = { # part -> the joint group that carries it (kinematic tree)
|
||||
"P01_底座板": "root", "P02_立柱": "root", "M1_J1": "root",
|
||||
"J1_半联轴器A": "root", "J1_抱箍A": "root", "J1_抱箍B": "root",
|
||||
@@ -533,48 +335,6 @@ def explode_vec(p, JS, cents, gmean):
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- assembly
|
||||
def build():
|
||||
global MOTOR, HALF, CLAMP
|
||||
MOTOR = cq.importers.importStep(SRC_STEP).val()
|
||||
MOTOR = place(MOTOR, T(0, 0, -2.57))
|
||||
motor = MOTOR
|
||||
half = HALF = solids_of(cq.importers.importStep(HALF_STEP).val())[0]
|
||||
clamp = CLAMP = solids_of(cq.importers.importStep(CLAMP_STEP).val())[0]
|
||||
|
||||
j1 = Joint("J1", "底座回转", (0, 0, 8.0), (0, 0, 1), (1, 0, 0), lug_phase=45)
|
||||
j2 = Joint("J2", "肩俯仰", (SH[0], Y0, SH[1]), (0, 1, 0), (1, 0, 0), lug_phase=90)
|
||||
j3 = Joint("J3", "肘俯仰", (EL[0], Y3_REAR, EL[1]), (0, -1, 0), (1, 0, 0), lug_phase=90)
|
||||
j4 = Joint("J4", "腕俯仰", (WR[0], Y4_REAR, WR[1]), (0, 1, 0), (1, 0, 0), lug_phase=90)
|
||||
j5 = Joint("J5", "夹爪", (WR[0] + S0_M5 * DIR_F[0], Y_M5, WR[1] + S0_M5 * DIR_F[1]),
|
||||
(DIR_F[0], 0, DIR_F[1]), (0, 1, 0), lug_phase=0)
|
||||
JS = dict(J1=j1, J2=j2, J3=j3, J4=j4, J5=j5)
|
||||
|
||||
add("P01_底座板", "底座安装板 Ø152x8", p_base_plate(), 0x4b5563, note="4x M5 地脚,中心 Ø50 走线")
|
||||
add("P02_立柱", "立柱,装 M1", p_column(j1), 0x4b5563, note="Ø60.3 滑配 + 64.4 方 Pocket + 2x M3 顶丝")
|
||||
add("P03_转塔", "J1 从动盘 + 转塔", p_turret(j1), 0x2563eb, note="底面复刻电机输出:Ø36x1.0 / Ø6.5x4 / 3xM2@Ø29")
|
||||
add("P04_肩支架", "肩支架,装 M2", p_shoulder_bracket(j2), 0x4b5563, note="立式抱紧 M2,底面 3x M3 接转塔")
|
||||
add("P05_大臂", "大臂板 y39..48", p_upper_arm(j2, j3), 0x059669, note="根部和肘部各一次接口;肘部装 M3")
|
||||
add("P06_小臂", "小臂板 y-35..-26", p_forearm(j3, j4), 0x059669, note="肘部从动盘 + 腕部装 M4")
|
||||
add("P07_腕板", "J4 从动盘 + 掌盘", p_wrist_plate(j4), 0xd97706,
|
||||
note="含关节包壳弧段;正面 3x M3 接爪壳")
|
||||
add("P11_爪壳", "夹爪壳体,装 M5", p_shell(j4, j5), 0xb45309,
|
||||
note="锥形壳 + 两根指导轨 + 曲柄过孔;后端 3x M3 锁在掌盘上")
|
||||
add("P08_指A", "夹爪指 A", p_finger(j5, +1), 0xdc2626, note="45° 斜槽 + 导轨舌")
|
||||
add("P09_指B", "夹爪指 B(与 A 镜像)", p_finger(j5, -1), 0xdc2626, note="打印 2 件时镜像即可")
|
||||
add("P10_曲柄", "夹爪曲柄盘", p_crank(j5), 0x7c3aed, note="双销 R14,直接锁在 M5 输出上")
|
||||
|
||||
for k, (jid, cn) in enumerate([("J1", "底座回转"), ("J2", "肩俯仰"), ("J3", "肘俯仰"),
|
||||
("J4", "腕俯仰"), ("J5", "夹爪电机")]):
|
||||
j = JS[jid]
|
||||
add("M%d_%s" % (k + 1, jid), "%s 电机模组" % jid, place(motor, j.t), 0x9ca3af,
|
||||
printed=False, note="复用 装配体2.STEP:Ø60 机座 + 两级 0.5M 行星减速")
|
||||
if jid != "J5":
|
||||
for nm, sh in j.place_hardware(half, clamp, jid):
|
||||
add(nm, "%s 端面齿联轴器/抱箍" % jid, sh, 0xeab308, printed=False,
|
||||
note="沿用 配件/ 现有 v9 零件,打印件")
|
||||
return JS
|
||||
|
||||
|
||||
def write_step(items, path):
|
||||
w = STEPControl_Writer()
|
||||
for nm, sh in items:
|
||||
@@ -664,8 +424,11 @@ def export(JS):
|
||||
|
||||
joints = [dict(id=k, cn=JS[k].cn, rear=JS[k].rear, d=JS[k].d, xdir=JS[k].xdir, hub=JS[k].hub_face())
|
||||
for k in JS]
|
||||
json.dump(dict(parts=parts, joints=joints, layout=dict(SH=SH, EL=EL, WR=WR,
|
||||
L1=ARM_L1, L2=ARM_L2, ver=VERSION, it=ITER),
|
||||
d3 = lambda a, b: math.sqrt(sum((a[i] - b[i]) ** 2 for i in range(3)))
|
||||
json.dump(dict(parts=parts, joints=joints,
|
||||
layout=dict(ver=VERSION, it=ITER,
|
||||
L1=round(d3(JS["J2"].rear, JS["J4"].rear), 1),
|
||||
L2=round(d3(JS["J4"].rear, JS["J5"].rear), 1)),
|
||||
measured=dict(M=M, C=C, HUB_FACE_Z=HUB_FACE_Z, CLAMP_SPAN=list(CLAMP_SPAN))),
|
||||
open(WEB + "/mesh_arm.json", "w", encoding="utf-8"), ensure_ascii=False)
|
||||
bom = [dict(件号=p["name"], 名称=p["cn"], 类型="3D打印" if p["printed"] else "已有/电机",
|
||||
@@ -777,26 +540,3 @@ def verify_interfaces(half, clamp, JS):
|
||||
spigot_proud=round(b[1] - HUB_FACE_Z, 3),
|
||||
clamp_clear=round(c[0] - COVER_Z, 3)))
|
||||
return rows
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
JS = build()
|
||||
vi = verify_interfaces(HALF, CLAMP, JS)
|
||||
bom = export(JS)
|
||||
cl = collide()
|
||||
with open(DOCS + "/collision.txt", "w", encoding="utf-8") as fh:
|
||||
fh.write("干涉对(体积 mm3,>2 才算数)\n")
|
||||
for r in cl:
|
||||
fh.write(" %-16s x %-16s %10.1f %s\n" % r)
|
||||
fh.write("total pairs: %d\n" % len(cl))
|
||||
print("parts %d printed %d" % (len(PARTS), sum(1 for p in PARTS if p["printed"])))
|
||||
for p in PARTS:
|
||||
print(" %-22s %9.1f cm3 %s" % (p["name"], p["vol"] / 1000.0, p["bb"]))
|
||||
print("JOINT STACK (hub_face=%.3f cover=%.3f)" % (HUB_FACE_Z, COVER_Z))
|
||||
for r in vi:
|
||||
print(" %-3s halfA=%s halfB=%s clamp=%s B销钉伸出hub面=%+.3f(应+4.06) 抱箍起点离盖板=%+.3f" %
|
||||
(r["jid"], r["halfA"], r["halfB"], r["clamp"], r["spigot_proud"], r["clamp_clear"]))
|
||||
print("COLLISION pairs=%d" % len(cl))
|
||||
for r in cl[:18]:
|
||||
print(" %-16s x %-16s %9.1f mm3 %s" % r)
|
||||
print("WROTE", OUT + "/assembly/ROBOT_ARM_%s.stp" % VERSION)
|
||||
|
||||
Reference in New Issue
Block a user