code wiki / (root) / nx_robot_step_gate.nx

nx_robot_step_gate.nx source

↩ module page · 111 lines · 4934 B

1// nx_robot_step_gate.nx -- R-ROBO-1 GATE: multi-axis stepper step generation (the actuation 2// primitive). Commands a synchronized 3-axis move (X=+20, Y=+8, Z=-5 steps), generates the pulse 3// plan via nx_robot_step, and VERIFIES: each axis emits EXACTLY |delta| pulses, directions are 4// correct, the final reconstructed position equals the target EXACTLY (integer, no drift), and the 5// Bresenham invariant holds on every minor axis (max deviation == 0..nt, i.e. evenly distributed). 6// NEGATIVE CONTROL: a deliberately front-loaded (non-Bresenham) sequence VIOLATES the invariant 7// (deviation > nt), proving the evenness check has teeth. 100% sovereign, integer-only. 8// license_tier: ORIGINAL expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_robot_step.nx" 11 12func sw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 13func sn(v: i64) -> i64 { 14 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 15 var m: i64 = v 16 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 17 let d: *u8 = sys_mmap(24); var k: i64 = 0 18 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 19 let o: *u8 = sys_mmap(24); var i: i64 = 0 20 while i < k { o[i] = d[k - 1 - i]; i = i + 1 } 21 sys_write(1, o, k); return 0 22} 23 24func check(name: *u8, cond: i64, tot: *i64) -> i64 { 25 if cond == 1 { sw(" ok " as *u8); tot[0] = tot[0] + 1 } 26 else { sw(" FAIL " as *u8); tot[1] = tot[1] + 1 } 27 sw(name); sw("\n" as *u8) 28 return 0 29} 30 31func abs_i(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 32 33func main() -> i64 { 34 let tot: *i64 = sys_mmap(16) as *i64 35 tot[0] = 0; tot[1] = 0 36 37 sw("=== nx_robot_step_gate R-ROBO-1 -- multi-axis stepper step generation (integer Bresenham) ===\n" as *u8) 38 39 let naxes: i64 = 3 40 let delta: *i64 = sys_mmap(64) as *i64 41 delta[0] = 20; delta[1] = 8; delta[2] = 0 - 5 // X=+20, Y=+8, Z=-5 42 let dir: *i64 = sys_mmap(64) as *i64 43 let max_ticks: i64 = 256 44 let puls: *i64 = sys_mmap(max_ticks * naxes * 8) as *i64 45 46 let nt: i64 = robot_step_plan(delta, naxes, dir, puls, max_ticks) 47 sw(" n_ticks=" as *u8); sn(nt); sw(" (=max|delta|, the major axis)\n" as *u8) 48 49 // directions 50 var okdir: i64 = 0 51 if dir[0] == 1 { if dir[1] == 1 { if dir[2] == (0 - 1) { okdir = 1 } } } 52 check("directions correct (X+ Y+ Z-)" as *u8, okdir, tot) 53 54 // exact pulse counts per axis 55 var i: i64 = 0 56 var okcount: i64 = 1 57 while i < naxes { 58 let c: i64 = robot_step_count(puls, naxes, nt, i) 59 if c != abs_i(delta[i]) { okcount = 0 } 60 sw(" axis " as *u8); sn(i); sw(" pulses=" as *u8); sn(c); sw(" expected=" as *u8); sn(abs_i(delta[i])); sw("\n" as *u8) 61 i = i + 1 62 } 63 check("each axis emits EXACTLY |delta| pulses" as *u8, okcount, tot) 64 65 // final reconstructed position == target (exact integer, no drift) 66 var okpos: i64 = 1 67 i = 0 68 while i < naxes { 69 let c: i64 = robot_step_count(puls, naxes, nt, i) 70 let pos: i64 = c * dir[i] 71 if pos != delta[i] { okpos = 0 } 72 i = i + 1 73 } 74 check("final reconstructed position == commanded target (exact)" as *u8, okpos, tot) 75 76 // major axis pulses every tick 77 var cmaj: i64 = robot_step_count(puls, naxes, nt, 0) 78 var okmaj: i64 = 0 79 if cmaj == nt { okmaj = 1 } 80 check("major axis X pulses every tick (cmaj==nt)" as *u8, okmaj, tot) 81 82 // Bresenham invariant on minor axes: max deviation must be <= nt (evenly distributed) 83 let devY: i64 = robot_step_max_dev(puls, naxes, nt, 1, abs_i(delta[1])) 84 let devZ: i64 = robot_step_max_dev(puls, naxes, nt, 2, abs_i(delta[2])) 85 sw(" Bresenham maxdev Y=" as *u8); sn(devY); sw(" Z=" as *u8); sn(devZ); sw(" bound=" as *u8); sn(nt); sw("\n" as *u8) 86 var okbres: i64 = 0 87 if devY <= nt { if devZ <= nt { okbres = 1 } } 88 check("Bresenham invariant holds on minor axes (maxdev <= nt)" as *u8, okbres, tot) 89 90 // NEGATIVE CONTROL: front-load Y's 8 pulses into the first 8 ticks -> must VIOLATE the invariant 91 let bad: *i64 = sys_mmap(max_ticks * naxes * 8) as *i64 92 var t: i64 = 0 93 while t < nt { 94 bad[t * naxes + 0] = 1 // X every tick (fine) 95 var py: i64 = 0 96 if t < 8 { py = 1 } // all 8 Y pulses crammed up front 97 bad[t * naxes + 1] = py 98 bad[t * naxes + 2] = 0 99 t = t + 1 100 } 101 let baddev: i64 = robot_step_max_dev(bad, naxes, nt, 1, abs_i(delta[1])) 102 sw(" front-loaded Y maxdev=" as *u8); sn(baddev); sw(" (must exceed bound " as *u8); sn(nt); sw(")\n" as *u8) 103 var negok: i64 = 0 104 if baddev > nt { negok = 1 } 105 check("NEG-CONTROL: front-loaded sequence VIOLATES invariant (check has teeth)" as *u8, negok, tot) 106 107 sw("=== VERDICT pass=" as *u8); sn(tot[0]); sw(" fail=" as *u8); sn(tot[1]); sw(" ===\n" as *u8) 108 if tot[1] == 0 { sys_exit(0) } 109 sys_exit(1) 110 return 1 111}