nx_rot_health_test.nx source
↩ module page · 90 lines · 4477 B
1// nx_rot_health_test.nx -- gate for the rotating-machine health kernel.
2//
3// Proves each verdict from canned vibration windows, and the MEASURED EXCEED:
4// the bearing-wear window and the healthy window have nearly identical RMS
5// (both well below the ISO warning) -- so an overall-amplitude reading calls
6// BOTH healthy -- but the CREST factor (392 vs 141) correctly flags the
7// incipient bearing fault. Crest catches what RMS misses (the liar-kill).
8//
9// expect_exit: 0
10//
11// license_tier: ORIGINAL
12
13import "nx_syscalls_x86_64.nx"
14import "nx_rot_health.nx"
15
16func main() -> i64 {
17 // ---- isqrt KAT ----
18 if nx_rot_isqrt(2334375) != 1527 { return 1 }
19 if nx_rot_isqrt(0) != 0 { return 2 }
20 if nx_rot_isqrt(4) != 2 { return 3 }
21 // ---- sealed-enum ----
22 if nx_rot_verdict_is_valid(NX_ROT_BEARING_WEAR) != 1 { return 4 }
23 if nx_rot_verdict_is_valid(NX_ROT_N) != 0 { return 5 }
24
25 let vib: *i64 = sys_mmap(256) as *i64
26 let out: *RotEff = sys_mmap(64) as *RotEff
27 let spec: *RotSpec = sys_mmap(64) as *RotSpec
28 spec.iso_warn_um_s = 2800 // ISO zone B/C (small machine class)
29 spec.iso_alarm_um_s = 7100 // ISO zone C/D
30 spec.crest_warn_x100 = 300 // 3.0 crest ceiling
31 spec.temp_rise_warn_mC = 40000 // 40 C bearing temp-rise ceiling
32
33 // ===== HEALTHY: smooth low vibration (crest ~141, RMS ~1414) =====
34 vib[0]=2000; vib[1]=0; vib[2]=0-2000; vib[3]=0; vib[4]=2000; vib[5]=0; vib[6]=0-2000; vib[7]=0
35 nx_rot_analyze(vib, 8, 25000, 25000, 1, spec, out)
36 if out.verdict != NX_ROT_HEALTHY { return 10 }
37 if out.crest_x100 != 141 { return 11 }
38
39 // ===== ROUGH_WARNING: elevated amplitude into ISO zone B/C =======
40 vib[0]=4000; vib[1]=0; vib[2]=0-4000; vib[3]=0; vib[4]=4000; vib[5]=0; vib[6]=0-4000; vib[7]=0
41 nx_rot_analyze(vib, 8, 25000, 25000, 1, spec, out)
42 if out.verdict != NX_ROT_ROUGH_WARNING { return 20 }
43
44 // ===== ROUGH_ALARM: ISO zone C/D (unacceptable) =================
45 vib[0]=11000; vib[1]=0; vib[2]=0-11000; vib[3]=0; vib[4]=11000; vib[5]=0; vib[6]=0-11000; vib[7]=0
46 nx_rot_analyze(vib, 8, 25000, 25000, 1, spec, out)
47 if out.verdict != NX_ROT_ROUGH_ALARM { return 30 }
48
49 // ===== BEARING_WEAR: low RMS but high crest (impact spike) =======
50 vib[0]=6000
51 vib[1]=300; vib[2]=0-300; vib[3]=300; vib[4]=0-300; vib[5]=300; vib[6]=0-300; vib[7]=300
52 vib[8]=0-300; vib[9]=300; vib[10]=0-300; vib[11]=300; vib[12]=0-300; vib[13]=300; vib[14]=0-300; vib[15]=300
53 nx_rot_analyze(vib, 16, 25000, 25000, 1, spec, out)
54 if out.verdict != NX_ROT_BEARING_WEAR { return 40 }
55 if out.crest_x100 != 392 { return 41 }
56 if out.rms_um_s >= spec.iso_warn_um_s { return 42 } // proves RMS alone would NOT flag it
57 let crest_bearing: i64 = out.crest_x100
58 let rms_bearing: i64 = out.rms_um_s
59
60 // ===== OVERHEAT: normal vibration but bearing temp-rise high =====
61 vib[0]=2000; vib[1]=0; vib[2]=0-2000; vib[3]=0; vib[4]=2000; vib[5]=0; vib[6]=0-2000; vib[7]=0
62 nx_rot_analyze(vib, 8, 75000, 25000, 1, spec, out) // 50 C rise
63 if out.verdict != NX_ROT_OVERHEAT { return 50 }
64
65 // ===== IDLE: not running =========================================
66 nx_rot_analyze(vib, 8, 25000, 25000, 0, spec, out)
67 if out.verdict != NX_ROT_IDLE { return 60 }
68
69 // ===== INSUFFICIENT_DATA: empty window ==========================
70 nx_rot_analyze(vib, 0, 25000, 25000, 1, spec, out)
71 if out.verdict != NX_ROT_INSUFFICIENT_DATA { return 70 }
72
73 // ===== BAD_ARG: invalid running flag ============================
74 nx_rot_analyze(vib, 8, 25000, 25000, 5, spec, out)
75 if out.verdict != NX_ROT_BAD_ARG { return 80 }
76
77 // ===== LIAR-KILL: crest catches what RMS misses ==================
78 // Healthy window: same-order RMS as the bearing window, but low crest.
79 vib[0]=2000; vib[1]=0; vib[2]=0-2000; vib[3]=0; vib[4]=2000; vib[5]=0; vib[6]=0-2000; vib[7]=0
80 nx_rot_analyze(vib, 8, 25000, 25000, 1, spec, out)
81 if out.verdict != NX_ROT_HEALTHY { return 90 }
82 let crest_healthy: i64 = out.crest_x100
83 let rms_healthy: i64 = out.rms_um_s
84 if rms_healthy >= spec.iso_warn_um_s { return 91 } // healthy RMS also below warning
85 if crest_bearing == crest_healthy { return 92 } // crest provably differs
86 if crest_bearing <= spec.crest_warn_x100 { return 93 } // bearing crest is the discriminator
87 if crest_healthy > spec.crest_warn_x100 { return 94 } // healthy crest is NOT
88
89 return 0
90}