code wiki / (root) / nx_print_sim_spaghetti_test.nx

nx_print_sim_spaghetti_test.nx source

↩ module page · 139 lines · 5783 B

1// nx_print_sim_spaghetti_test.nx -- verify the simulator predicts 2// spaghetti / halfway-failure progenitors with real physics: 3// ENVELOPE_VIOLATION move past machine build volume 4// BED_CRASH Z below 0 (nozzle into bed) 5// TIPOVER_RISK tall-narrow geometry vs machine accel 6// 7// Operator directive 2026-05-20: "i want especially spaghetti or 8// where it prints halfway and fails etc to be predicted and to get 9// the loop really really hammered out" 10// 11// Each predictor: NO heuristic threshold; the substrate's existing 12// machine + material fields supply the physical limit. 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 let lw: i64 = 6554 // 0.4mm Q14 28 let lh: i64 = 3277 // 0.2mm Q14 29 30 // ===== (a) ENVELOPE_VIOLATION ===== 31 let s_env: *NxPrintSim = nx_print_sim_new(qidi, pla) 32 // Qidi build_x_mm = 325. Move to X = 400 mm = past envelope. 33 // Move first to safe spot, then drive past x bound. 34 nx_print_sim_extrude_move(s_env, 100 * Q14, 100 * Q14, Q14, 35 lw, lh, 50) 36 if s_env.n_issues != 0 { return 10 } // safe move = no issues 37 38 // Now drive 400mm in X (past 325 build volume). 39 nx_print_sim_extrude_move(s_env, 400 * Q14, 0, 0, 40 lw, lh, 50) 41 if s_env.n_issues < 1 { return 11 } 42 var saw_env: i64 = 0 43 var i_e: i64 = 0 44 while i_e < s_env.n_issues { 45 let ip: *NxPrintSimIssue = nx_print_sim_get_issue(s_env, i_e) 46 if ip.kind == NX_SIM_ISSUE_ENVELOPE_VIOLATION { saw_env = 1 } 47 i_e = i_e + 1 48 } 49 if saw_env != 1 { return 12 } 50 51 // ===== (b) BED_CRASH ===== 52 let s_bed: *NxPrintSim = nx_print_sim_new(qidi, pla) 53 // Move XY safely first, then drive Z negative. 54 nx_print_sim_extrude_move(s_bed, 50 * Q14, 50 * Q14, Q14, 55 lw, lh, 50) 56 if s_bed.n_issues != 0 { return 20 } 57 58 // Drive Z to -2mm. 59 nx_print_sim_extrude_move(s_bed, 0, 0, 0 - 3 * Q14, 60 lw, lh, 50) 61 if s_bed.n_issues < 1 { return 21 } 62 var saw_crash: i64 = 0 63 var i_c: i64 = 0 64 while i_c < s_bed.n_issues { 65 let ip2: *NxPrintSimIssue = nx_print_sim_get_issue(s_bed, i_c) 66 if ip2.kind == NX_SIM_ISSUE_BED_CRASH { 67 saw_crash = 1 68 if ip2.magnitude_q14 <= 0 { return 22 } // positive depth 69 } 70 i_c = i_c + 1 71 } 72 if saw_crash != 1 { return 23 } 73 74 // ===== (c) TIPOVER_RISK -- tall narrow geometry ===== 75 // 76 // Simulate a 10mm × 10mm base × 200mm tall column. 77 // base_radius = 5mm, z_height = 200mm. Ratio z_height/base_r = 40. 78 // 2g/accel = 2 × 9810 / 5000 = 3.92. 40 > 3.92 -> TIPOVER. 79 let s_tall: *NxPrintSim = nx_print_sim_new(qidi, pla) 80 // Move to (50, 50, 0) start; then build bbox via 4 corner moves at 81 // various z heights to establish a 10x10x200 footprint. 82 nx_print_sim_extrude_move(s_tall, 50 * Q14, 50 * Q14, Q14, 83 lw, lh, 50) 84 nx_print_sim_extrude_move(s_tall, 10 * Q14, 0, 0, 85 lw, lh, 50) 86 nx_print_sim_extrude_move(s_tall, 0, 10 * Q14, 0, 87 lw, lh, 50) 88 nx_print_sim_extrude_move(s_tall, 0 - 10 * Q14, 0, 0, 89 lw, lh, 50) 90 // Now Z up 200mm 91 nx_print_sim_extrude_move(s_tall, 0, 0 - 10 * Q14, 200 * Q14, 92 lw, lh, 50) 93 let n_before: i64 = s_tall.n_issues 94 nx_print_sim_finalize(s_tall) 95 let n_after: i64 = s_tall.n_issues 96 if n_after <= n_before { return 30 } // finalize raised at least 1 issue 97 var saw_tip: i64 = 0 98 var i_t: i64 = 0 99 while i_t < s_tall.n_issues { 100 let ip3: *NxPrintSimIssue = nx_print_sim_get_issue(s_tall, i_t) 101 if ip3.kind == NX_SIM_ISSUE_TIPOVER_RISK { 102 saw_tip = 1 103 if ip3.magnitude_q14 <= 0 { return 31 } 104 } 105 i_t = i_t + 1 106 } 107 if saw_tip != 1 { return 32 } 108 109 // ===== (d) Safe geometry: WIDE base, short height -- no TIPOVER ===== 110 // 111 // Qidi max_accel = 20000 mm/s² (aggressive CoreXY). Threshold: 112 // z_height < 2g × base_radius / accel = base_radius × 0.981 113 // 114 // 200mm × 200mm base × 50mm tall: 115 // base_radius = 100mm; threshold = 98.1mm; z_height = 50mm < 98.1 -> SAFE 116 let s_safe: *NxPrintSim = nx_print_sim_new(qidi, pla) 117 nx_print_sim_extrude_move(s_safe, 50 * Q14, 50 * Q14, Q14, 118 lw, lh, 50) 119 nx_print_sim_extrude_move(s_safe, 200 * Q14, 0, 0, 120 lw, lh, 50) 121 nx_print_sim_extrude_move(s_safe, 0, 200 * Q14, 0, 122 lw, lh, 50) 123 nx_print_sim_extrude_move(s_safe, 0 - 200 * Q14, 0, 0, 124 lw, lh, 50) 125 nx_print_sim_extrude_move(s_safe, 0, 0 - 200 * Q14, 50 * Q14, 126 lw, lh, 50) 127 let n_safe_before: i64 = s_safe.n_issues 128 nx_print_sim_finalize(s_safe) 129 let n_safe_after: i64 = s_safe.n_issues 130 // 50mm tall on 100mm base_radius @ 20000 accel -> ratio 0.5 < 0.981 -> SAFE 131 if n_safe_after != n_safe_before { return 40 } 132 133 // ===== (e) Sealed-enum range checks for ALL new constants ===== 134 if nx_sim_issue_is_valid(NX_SIM_ISSUE_ENVELOPE_VIOLATION) != 1 { return 50 } 135 if nx_sim_issue_is_valid(NX_SIM_ISSUE_BED_CRASH) != 1 { return 51 } 136 if nx_sim_issue_is_valid(NX_SIM_ISSUE_TIPOVER_RISK) != 1 { return 52 } 137 138 return 0 139}