nx_torque_test.nx source
↩ module page · 90 lines · 3315 B
1// nx_torque_test.nx -- torque vector ops + cross-primitive
2// composition demo with nx_force.
3//
4// Closed-form invariants (Q14 N·m unless noted):
5// (a) Zero torque magnitude = 0.
6// (b) Unit +Z torque magnitude = Q14.
7// (c) (3, 4, 0) Q14 N·m -> magnitude 5 Q14 (3-4-5).
8// (d) Add: (1, 2, 3) + (4, 5, 6) = (5, 7, 9).
9// (e) τ = r × F demo: r = (1, 0, 0) m, F = (0, 1, 0) N
10// → τ = +Z 1 N·m (right-hand rule).
11// (f) τ = r × F: r = (0, 2, 0) m, F = (3, 0, 0) N
12// → τ = (0*0 - 0*0, 0*3 - 0*0, 2*0 - 0*3 - oh wait
13//
14// Let me recompute by formula:
15//
16// τ_x = r_y*F_z - r_z*F_y = 2*0 - 0*0 = 0
17//
18// τ_y = r_z*F_x - r_x*F_z = 0*3 - 0*0 = 0
19//
20// τ_z = r_x*F_y - r_y*F_x = 0*0 - 2*3 = -6
21//
22// → (0, 0, -6) Q14 N·m
23// (g) τ from r=0, F=anything → zero torque (no lever arm).
24// (h) Verdict name lookup non-NULL for every verdict.
25//
26// expect_exit: 0
27// license_tier: ORIGINAL
28
29import "nx_syscalls.nx"
30import "nx_force.nx"
31import "nx_torque.nx"
32
33const Q14: i64 = 16384
34
35func near(actual: i64, expected: i64, tol: i64) -> i64 {
36 let diff: i64 = actual - expected
37 if diff < 0 { if -diff <= tol { return 1 } }
38 if diff >= 0 { if diff <= tol { return 1 } }
39 return 0
40}
41
42func main() -> i64 {
43 // --- (a) Zero ---
44 let t0: *NxTorque = nx_torque_zero()
45 if nx_torque_magnitude_q14(t0) != 0 { return 10 }
46
47 // --- (b) Unit +Z ---
48 let tz: *NxTorque = nx_torque_new(0, 0, Q14)
49 if near(nx_torque_magnitude_q14(tz), Q14, 1) != 1 { return 20 }
50
51 // --- (c) 3-4-5 ---
52 let t345: *NxTorque = nx_torque_new(3 * Q14, 4 * Q14, 0)
53 if near(nx_torque_magnitude_q14(t345), 5 * Q14, 1) != 1 { return 30 }
54
55 // --- (d) Add ---
56 let a: *NxTorque = nx_torque_new(1, 2, 3)
57 let b: *NxTorque = nx_torque_new(4, 5, 6)
58 let s: *NxTorque = nx_torque_add(a, b)
59 if s.tx_q14 != 5 { return 40 }
60 if s.ty_q14 != 7 { return 41 }
61 if s.tz_q14 != 9 { return 42 }
62
63 // --- (e) τ = r × F right-hand rule: r=+X (1m), F=+Y (1N) → τ=+Z (1 N·m) ---
64 let f_pos_y: *NxForce = nx_force_new(0, Q14, 0)
65 let tau_z: *NxTorque = nx_torque_from_position_force(Q14, 0, 0, f_pos_y)
66 if tau_z.tx_q14 != 0 { return 50 }
67 if tau_z.ty_q14 != 0 { return 51 }
68 if near(tau_z.tz_q14, Q14, 1) != 1 { return 52 }
69
70 // --- (f) τ = r × F: r=(0,2,0)m, F=(3,0,0)N → τ=(0,0,-6) N·m ---
71 let f_px: *NxForce = nx_force_new(3 * Q14, 0, 0)
72 let tau_neg_z: *NxTorque = nx_torque_from_position_force(0, 2 * Q14, 0, f_px)
73 if tau_neg_z.tx_q14 != 0 { return 60 }
74 if tau_neg_z.ty_q14 != 0 { return 61 }
75 if near(tau_neg_z.tz_q14, -6 * Q14, 1) != 1 { return 62 }
76
77 // --- (g) Zero lever arm → zero torque ---
78 let f_any: *NxForce = nx_force_new(100 * Q14, 200 * Q14, 300 * Q14)
79 let tau_zero: *NxTorque = nx_torque_from_position_force(0, 0, 0, f_any)
80 if tau_zero.tx_q14 != 0 { return 70 }
81 if tau_zero.ty_q14 != 0 { return 71 }
82 if tau_zero.tz_q14 != 0 { return 72 }
83
84 // --- (h) Verdict names ---
85 if (nx_torque_verdict_name(NX_TORQUE_OK) as i64) == 0 { return 80 }
86 if (nx_torque_verdict_name(NX_TORQUE_ERR_NULL_INPUT) as i64) == 0 { return 81 }
87 if (nx_torque_verdict_name(NX_TORQUE_ERR_NULL_FORCE) as i64) == 0 { return 82 }
88
89 return 0
90}