nx_print_sim_test.nx source
↩ module page · 83 lines · 3474 B
1// nx_print_sim_test.nx -- verify the print simulator's first-stone
2// physics: hotend max-flow check.
3//
4// Closed-form invariants:
5// (a) Null inputs -> null simulator
6// (b) Fresh simulator: position 0, time 0, n_issues 0
7// (c) Reasonable extrude move: NO issues raised
8// (d) Extreme extrusion (wide+thick+fast) EXCEEDS hotend max-flow
9// -> HOTEND_FLOW_CEILING issue raised
10// (e) Issue record contains the right location + magnitude
11// (f) Issue kind is in the sealed-enum range
12// (g) Position advances correctly after move
13//
14// expect_exit: 0
15// license_tier: ORIGINAL
16
17import "nx_syscalls.nx"
18import "nx_machine_graph.nx"
19import "nx_material_profile.nx"
20import "nx_print_sim.nx"
21
22const Q14: i64 = 16384
23
24func main() -> i64 {
25 let qidi: *NxMachineGraph = nx_machine_graph_qidi_xmax3()
26 let pla: *NxMaterialProfile = nx_material_profile_generic_pla()
27
28 // --- (a) Null inputs ---
29 let s_null: *NxPrintSim = nx_print_sim_new(0 as *NxMachineGraph, pla)
30 if (s_null as i64) != 0 { return 10 }
31
32 // --- (b) Fresh simulator state ---
33 let s: *NxPrintSim = nx_print_sim_new(qidi, pla)
34 if (s as i64) == 0 { return 20 }
35 if s.cur_x_q14 != 0 { return 21 }
36 if s.cur_y_q14 != 0 { return 22 }
37 if s.cur_z_q14 != 0 { return 23 }
38 if s.n_issues != 0 { return 24 }
39
40 // --- (c) Reasonable extrude: 10mm move at 0.4mm × 0.2mm × 50 mms ---
41 // Flow = 0.4 × 0.2 × 50 = 4 mm³/s.
42 // Qidi max_flow = 35 mm³/s (per nx_machine_graph_qidi_xmax3),
43 // PLA typical_max_flow = 15 mm³/s.
44 // Neither exceeded -> no issues.
45 let lw: i64 = 6554 // 0.4 mm in Q14
46 let lh: i64 = 3277 // 0.2 mm in Q14
47 let dx_10mm: i64 = 10 * Q14
48 let n_issues_c: i64 = nx_print_sim_extrude_move(s, dx_10mm, 0, 0, lw, lh, 50)
49 if n_issues_c != 0 { return 30 }
50 if s.n_issues != 0 { return 31 }
51
52 // --- (d) Extreme extrusion: wide + thick + very fast ---
53 // width 0.8 (Q14 = 13107), height 0.5 (Q14 = 8192), speed 200 mm/s
54 // Flow = 0.8 × 0.5 × 200 = 80 mm³/s.
55 // Qidi max_flow = 35; PLA typ_max = 15. Both exceeded ->
56 // 2 issues raised (HOTEND_FLOW_CEILING + MATERIAL_FLOW_CEILING).
57 let lw_wide: i64 = 13107
58 let lh_thick: i64 = 8192
59 let n_issues_d: i64 = nx_print_sim_extrude_move(s, 5 * Q14, 0, 0,
60 lw_wide, lh_thick, 200)
61 if n_issues_d != 2 { return 40 }
62 if s.n_issues != 2 { return 41 }
63
64 // --- (e) Issue record location matches simulator's current position ---
65 // Position after move = (10 + 5) mm = 15mm × Q14 = 245760.
66 let issue0: *NxPrintSimIssue = nx_print_sim_get_issue(s, 0)
67 if (issue0 as i64) == 0 { return 50 }
68 if issue0.x_q14 != 15 * Q14 { return 51 }
69 if issue0.y_q14 != 0 { return 52 }
70 if issue0.magnitude_q14 <= 0 { return 53 } // some positive excess
71
72 // --- (f) Issue kind in sealed enum range ---
73 if nx_sim_issue_is_valid(issue0.kind) != 1 { return 60 }
74 if issue0.kind != NX_SIM_ISSUE_HOTEND_FLOW_CEILING { return 61 }
75 let issue1: *NxPrintSimIssue = nx_print_sim_get_issue(s, 1)
76 if issue1.kind != NX_SIM_ISSUE_MATERIAL_FLOW_CEILING { return 62 }
77
78 // --- (g) Position state final value matches sum of moves ---
79 // (10 + 5) mm = 245760 Q14.
80 if s.cur_x_q14 != 15 * Q14 { return 70 }
81
82 return 0
83}