|
|
我尝试用WorkBuddy自己写NX后处理,在一问一答间自动生成后处理文件,不知成功不成功,大家感觉怎么样- """
- AC双摆头五轴后处理运动学验证脚本
- 用法: python verify_kinematics.py
- """
- import math
- PI = math.pi
- RAD = 180.0 / PI
- def calc_angles(ax, ay, az):
- """刀轴矢量(I,J,K) -> A角, C角"""
- # A角: 刀轴与-Z的夹角
- # az=-1 -> A=0(向下), az=0 -> A=90(水平)
- a_rad = math.acos(-az)
- a_ang = a_rad * RAD
- # C角: atan2(-ax, ay)
- if abs(a_ang) < 0.5:
- c_ang = 0.0 # 奇异区冻结
- else:
- c_ang = math.atan2(-ax, ay) * RAD
- return a_ang, c_ang, a_rad
- def calc_machine_pos(Xp, Yp, Zp, L, a_ang, c_ang, a_rad):
- """编程坐标 -> 机床坐标"""
- c_rad = c_ang / RAD
- sinA = math.sin(a_rad)
- cosA = math.cos(a_rad)
- sinC = math.sin(c_rad)
- cosC = math.cos(c_rad)
- Xm = Xp + L * sinA * sinC
- Ym = Yp - L * sinA * cosC
- Zm = Zp + L * cosA
- return Xm, Ym, Zm
- def verify(name, ax, ay, az, Xp, Yp, Zp, L,
- exp_X, exp_Y, exp_Z, exp_A, exp_C, tol=0.01):
- """验证单个测试用例"""
- a_ang, c_ang, a_rad = calc_angles(ax, ay, az)
- Xm, Ym, Zm = calc_machine_pos(Xp, Yp, Zp, L, a_ang, c_ang, a_rad)
- ok = (abs(Xm - exp_X) < tol and abs(Ym - exp_Y) < tol and
- abs(Zm - exp_Z) < tol and abs(a_ang - exp_A) < tol and
- abs(c_ang - exp_C) < tol)
- status = "PASS" if ok else "FAIL"
- print(f"\n{'='*60}")
- print(f" 测试: {name} [{status}]")
- print(f"{'='*60}")
- print(f" 刀轴矢量: I={ax:.4f} J={ay:.4f} K={az:.4f}")
- print(f" 编程坐标: X={Xp:.3f} Y={Yp:.3f} Z={Zp:.3f}")
- print(f" 摆长 L: {L:.3f}")
- print(f" ---")
- print(f" A角: 计算={a_ang:.4f}° 期望={exp_A:.4f}° {'OK' if abs(a_ang-exp_A)<tol else 'MISMATCH'}")
- print(f" C角: 计算={c_ang:.4f}° 期望={exp_C:.4f}° {'OK' if abs(c_ang-exp_C)<tol else 'MISMATCH'}")
- print(f" X轴: 计算={Xm:.4f} 期望={exp_X:.4f} {'OK' if abs(Xm-exp_X)<tol else 'MISMATCH'}")
- print(f" Y轴: 计算={Ym:.4f} 期望={exp_Y:.4f} {'OK' if abs(Ym-exp_Y)<tol else 'MISMATCH'}")
- print(f" Z轴: 计算={Zm:.4f} 期望={exp_Z:.4f} {'OK' if abs(Zm-exp_Z)<tol else 'MISMATCH'}")
- return ok
- def main():
- print("=" * 60)
- print(" AC双摆头五轴运动学验证 (非RTCP, 摆心距=0)")
- print("=" * 60)
- L = 150.0
- Xp, Yp, Zp = 100.0, 100.0, -50.0
- all_pass = True
- # 测试1: A=0°, C=0°, 刀轴垂直向下
- all_pass &= verify(
- "A=0 C=0 刀轴向下",
- ax=0, ay=0, az=-1,
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=0, exp_C=0,
- exp_X=100, exp_Y=100, exp_Z=100 # Z = -50 + 150*1 = 100
- )
- # 测试2: A=90°, C=0°, 刀轴指向+Y
- all_pass &= verify(
- "A=90 C=0 刀轴指+Y",
- ax=0, ay=1, az=0,
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=90, exp_C=0,
- exp_X=100, exp_Y=-50, exp_Z=-50 # Y=100-150=-50, Z=-50+0=-50
- )
- # 测试3: A=90°, C=90°, 刀轴指向-X
- all_pass &= verify(
- "A=90 C=90 刀轴指-X",
- ax=-1, ay=0, az=0,
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=90, exp_C=90,
- exp_X=250, exp_Y=100, exp_Z=-50 # C=90: sin(90)=1, X=100+150*1*1=250 # X=100+150=175
- )
- # 测试4: A=90°, C=180°, 刀轴指向-Y
- all_pass &= verify(
- "A=90 C=180 刀轴指-Y",
- ax=0, ay=-1, az=0,
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=90, exp_C=180,
- exp_X=100, exp_Y=250, exp_Z=-50 # Y=100+150=250
- )
- # 测试5: A=90°, C=-90°, 刀轴指向+X
- # C=-90: sin(-90)=-1, X=100+150*1*(-1)=100-150=-50
- all_pass &= verify(
- "A=90 C=-90 刀轴指+X",
- ax=1, ay=0, az=0,
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=90, exp_C=-90,
- exp_X=-50, exp_Y=100, exp_Z=-50
- )
- # 测试6: A=45°, C=0°
- a45 = math.radians(45)
- all_pass &= verify(
- "A=45 C=0",
- ax=0, ay=math.sin(a45), az=-math.cos(a45),
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=45, exp_C=0,
- exp_X=100, exp_Y=100 - L*math.sin(a45),
- exp_Z=-50 + L*math.cos(a45)
- )
- # 测试7: A=45°, C=45°
- all_pass &= verify(
- "A=45 C=45",
- ax=-math.sin(a45)*math.sin(a45),
- ay=math.cos(a45)*math.sin(a45),
- az=-math.cos(a45),
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=45, exp_C=45,
- exp_X=100 + L*math.sin(a45)*math.sin(a45),
- exp_Y=100 - L*math.sin(a45)*math.cos(a45),
- exp_Z=-50 + L*math.cos(a45)
- )
- # 测试8: A=110°(过顶), C=0°
- a110 = math.radians(110)
- all_pass &= verify(
- "A=110 C=0 过顶区域",
- ax=0, ay=math.sin(a110), az=-math.cos(a110),
- Xp=Xp, Yp=Yp, Zp=Zp, L=L,
- exp_A=110, exp_C=0,
- exp_X=100, exp_Y=100 - L*math.sin(a110),
- exp_Z=-50 + L*math.cos(a110) # cos(110)<0, Z会减小
- )
- # 测试9: 刀尖不动验证 (不同A角, 同一编程点)
- print("\n" + "=" * 60)
- print(" 测试9: 刀尖定点不动验证")
- print("=" * 60)
- print(" 编程点固定 (100, 100, -50), L=150")
- print(" 不同刀轴方向, 后处理输出机床坐标应使刀尖不动\n")
- angles = [0, 15, 30, 45, 60, 75, 90, 105, 110]
- for a_deg in angles:
- a_r = math.radians(a_deg)
- ax_t = 0
- ay_t = math.sin(a_r)
- az_t = -math.cos(a_r)
- a_out, c_out, _ = calc_angles(ax_t, ay_t, az_t)
- Xm, Ym, Zm = calc_machine_pos(Xp, Yp, Zp, L, a_out, c_out, math.radians(a_out))
- # 反算刀尖位置: Xm - L*sin(A)*sin(C), Ym + L*sin(A)*cos(C), Zm - L*cos(A)
- tip_x = Xm - L * math.sin(math.radians(a_out)) * math.sin(math.radians(c_out))
- tip_y = Ym + L * math.sin(math.radians(a_out)) * math.cos(math.radians(c_out))
- tip_z = Zm - L * math.cos(math.radians(a_out))
- ok = abs(tip_x - Xp) < 0.01 and abs(tip_y - Yp) < 0.01 and abs(tip_z - Zp) < 0.01
- all_pass &= ok
- print(f" A={a_deg:6.1f}° C={c_out:8.3f}° "
- f"机床X={Xm:9.3f} Y={Ym:9.3f} Z={Zm:9.3f} "
- f"刀尖反算=({tip_x:.3f}, {tip_y:.3f}, {tip_z:.3f}) "
- f"{'OK' if ok else 'FAIL'}")
- print("\n" + "=" * 60)
- if all_pass:
- print(" >>> 所有测试通过! 运动学公式正确 <<<")
- else:
- print(" >>> 部分测试失败, 请检查公式 <<<")
- print("=" * 60)
- if __name__ == "__main__":
- main()
复制代码
|
|