code wiki / (root) / nx_print_runtime_shift_test.nx

nx_print_runtime_shift_test.nx source

↩ module page · 88 lines · 3444 B

1// nx_print_runtime_shift_test.nx -- layer-shift / lost-steps detection. 2// 3// Closed-form invariants: 4// (a) Perfect cmd == act on both axes: no fire 5// (b) Sub-tolerance drift: no fire 6// (c) X drift > tolerance: fires LAYER_SHIFT 7// (d) Y drift > tolerance: fires LAYER_SHIFT 8// (e) Negative drift (actual ahead of commanded): fires too (abs) 9// (f) Setter rejects negative tolerance + null monitor 10// (g) Tighter tolerance catches smaller drift 11// (h) n_issues_total tracks fires 12// 13// expect_exit: 0 14// license_tier: ORIGINAL 15 16import "nx_syscalls.nx" 17import "nx_print_runtime_monitor.nx" 18 19const Q14: i64 = 16384 20 21func main() -> i64 { 22 let m: *NxRuntimeMonitor = nx_runtime_monitor_new(5000, 3, 5 * Q14, 2 * Q14) 23 if (m as i64) == 0 { return 5 } 24 25 // Default tolerance is 0.5mm = Q14/2. 26 27 // ===== (a) Perfect cmd == act: no fire ===== 28 let v0: i64 = nx_runtime_monitor_step_layer_shift(m, 29 100 * Q14, 100 * Q14, 30 200 * Q14, 200 * Q14) 31 if v0 != NX_RT_ISSUE_NONE { return 10 } 32 33 // ===== (b) Sub-tolerance drift (0.3mm on X): no fire ===== 34 // 0.3mm = 3*Q14/10 35 let small_drift: i64 = (3 * Q14) / 10 36 let v1: i64 = nx_runtime_monitor_step_layer_shift(m, 37 100 * Q14, 100 * Q14 - small_drift, 38 200 * Q14, 200 * Q14) 39 if v1 != NX_RT_ISSUE_NONE { return 20 } 40 41 // ===== (c) X drift > tolerance (0.8mm): fires ===== 42 let big_drift: i64 = (8 * Q14) / 10 // 0.8mm > 0.5mm tol 43 let v2: i64 = nx_runtime_monitor_step_layer_shift(m, 44 100 * Q14, 100 * Q14 - big_drift, 45 200 * Q14, 200 * Q14) 46 if v2 != NX_RT_ISSUE_LAYER_SHIFT { return 30 } 47 if m.n_issues_total != 1 { return 31 } 48 49 // ===== (d) Y drift > tolerance: fires ===== 50 let v3: i64 = nx_runtime_monitor_step_layer_shift(m, 51 100 * Q14, 100 * Q14, 52 200 * Q14, 200 * Q14 - big_drift) 53 if v3 != NX_RT_ISSUE_LAYER_SHIFT { return 40 } 54 if m.n_issues_total != 2 { return 41 } 55 56 // ===== (e) Negative drift (actual ahead of commanded): also fires ===== 57 let v4: i64 = nx_runtime_monitor_step_layer_shift(m, 58 100 * Q14, 100 * Q14 + big_drift, // act 0.8mm AHEAD 59 200 * Q14, 200 * Q14) 60 if v4 != NX_RT_ISSUE_LAYER_SHIFT { return 50 } 61 if m.n_issues_total != 3 { return 51 } 62 63 // ===== (f) Setter guards ===== 64 if nx_runtime_monitor_set_layer_shift_tolerance(m, -1) != NX_RT_BAD_INPUT { return 60 } 65 if nx_runtime_monitor_set_layer_shift_tolerance(0 as *NxRuntimeMonitor, 1) != NX_RT_BAD_INPUT { return 61 } 66 67 // ===== (g) Tighter tolerance catches smaller drift ===== 68 let m2: *NxRuntimeMonitor = nx_runtime_monitor_new(5000, 3, 5 * Q14, 2 * Q14) 69 // Tighten to 0.1mm 70 if nx_runtime_monitor_set_layer_shift_tolerance(m2, Q14 / 10) != NX_RT_OK { return 70 } 71 // 0.2mm drift now fires (would NOT have fired at default 0.5mm) 72 let drift_02: i64 = (2 * Q14) / 10 73 let v_tight: i64 = nx_runtime_monitor_step_layer_shift(m2, 74 100 * Q14, 100 * Q14 - drift_02, 75 200 * Q14, 200 * Q14) 76 if v_tight != NX_RT_ISSUE_LAYER_SHIFT { return 71 } 77 78 // Same drift on m (default 0.5mm) should NOT fire 79 let v_loose: i64 = nx_runtime_monitor_step_layer_shift(m, 80 100 * Q14, 100 * Q14 - drift_02, 81 200 * Q14, 200 * Q14) 82 if v_loose != NX_RT_ISSUE_NONE { return 72 } 83 84 // ===== (h) Issue count tracking ===== 85 if m.n_issues_total != 3 { return 80 } // c + d + e 86 87 return 0 88}