plasmac.comp
1 component plasmac; 2 3 description 4 """ 5 6 A plasma cutting table control component for use with the LinuxCNC V2.8 or later. 7 8 LinuxCNC V2.9 or later is required to use the "Paused Motion" feature. 9 10 .I VERSION: 11 .br 12 0.100 - 19 Feb 2020 13 14 .I SUMMARY: 15 .br 16 Usage of this component is demonstrated in the PlasmaC example configurations included with LinuxCNC. 17 18 .I DISCLAIMER: 19 .br 20 THE AUTHOR OF THIS SOFTWARE ACCEPTS ABSOLUTELY NO LIABILITY FOR ANY HARM OR LOSS RESULTING FROM ITS USE. 21 22 IT IS EXTREMELY UNWISE TO RELY ON SOFTWARE ALONE FOR SAFETY. 23 24 Any machinery capable of harming persons must have provisions for completely stopping all motors and moving parts etc. before persons enter any danger area. 25 26 All machinery must be designed to comply with local and national safety codes, and the author of this software can not, and does not, take any responsibility for such compliance. 27 """; 28 29 /* INPUT PINS */ 30 pin in float arc_fail_delay "arc failure timeout (seconds)"; 31 pin in float arc_ok_high "maximum voltage level for Arc OK signal [mode 0] (volts)"; 32 pin in bit arc_ok_in "external arc ok input signal [mode 1 & mode 2]"; 33 pin in float arc_ok_low "minimum voltage level for Arc OK signal [mode 0] (volts)"; 34 pin in s32 arc_max_starts "maximum attempts at starting the arc"; 35 pin in float arc_voltage_in "arc voltage input [mode 0 & mode 1] see Notes above"; 36 pin in float arc_voltage_offset "offset to set arc voltage to 0 at 0 volts"; 37 pin in float arc_voltage_scale "scale to convert arc_voltage input to actual volts"; 38 pin in float axis_z_min_limit "axis z minimum limit, connect to ini.z.min-limit"; 39 pin in float axis_z_max_limit "axis z maximum limit, connect to ini.z.max-limit"; 40 pin in float axis_z_position "current z axis position, connect to joint.N.pos-fb"; 41 pin in float axis_x_position "current x axis position, connect to axis.x.pos-cmd"; 42 pin in float axis_y_position "current y axis position, connect to axis.y.pos-cmd"; 43 pin in bit breakaway "torch breakaway switch (optional, see float_switch)"; 44 pin in bit spotting_start "start a new spot, connect to spindle.2.on"; 45 pin in float spotting_threshold "threshold voltage to start spotting delay"; 46 pin in float spotting_time "torch off delay after spotting threshold reached"; 47 pin in bit consumable_change "change consumables in torch"; 48 pin in bit cornerlock_enable "enable corner lock"; 49 pin in float cornerlock_threshold "corner lock threshold (% of requested feed rate), speeds below this disable THC"; 50 pin in float current_velocity "current machine velocity , connect to motion.current-vel"; 51 pin in float cut_feed_rate "cut feed rate, set to 0 to use feed rate from gcod file (machine units per minute)"; 52 pin in float cut_height "cut height (machine units)"; 53 pin in float cut_volts "cut voltage (volts)"; 54 pin in bit cutting_start "start a new cut, connect to spindle.0.on"; 55 pin in bit external_estop "external estop input"; 56 pin in float feed_reduction "reduce adaptive feed to this percentage (connect to motion.analog-out-03)"; 57 pin in float feed_override "feed override value from gui (connect to halui.feed-override.value)"; 58 pin in bit float_switch "float switch input (can also act as breakaway if it actuates when torch breaks away)"; 59 pin in float float_switch_travel "float switch travel (machine units)"; 60 pin in float height_override "height override adjustment (volts)"; 61 pin in float height_per_volt "torch height change per volt (machine units)"; 62 pin in bit homed "machine is homed"; 63 pin in bit kerfcross_enable "enable kerf crossing [mode 0 & mode 1]"; 64 pin in float kerfcross_override "kerf crossing threshold override as a percentage"; 65 pin in float lowpass_frequency "lowpass cutoff frequency for arc voltage output"; 66 pin in s32 mode "operating mode"; 67 pin in bit move_down "external thc down switch [mode 2])"; 68 pin in bit move_up "external thc up switch [mode 2]"; 69 pin in bit multi_tool "allows the use of multiple tools"; 70 pin in float offset_current "current z axis offset, connect to axis.z.eoffset"; 71 pin in bit ohmic_probe_enable "ohmic probe enable input"; 72 pin in float ohmic_probe_offset "Z axis offset for ohmic probe (machine units)"; 73 pin in s32 ohmic_max_attempts "maximum ohmic probe attempts before fallback to float switch"; 74 pin in bit ohmic_probe "ohmic probe input"; 75 pin in bit ohmic_test "test for shorted torch"; 76 pin in float paused_motion_speed "multiplier for speed of motion when paused, from -1 to 1"; 77 pin in float pause_at_end "time to pause at end of cut"; 78 pin in float pid_d_gain "derivative gain input [mode 0 & mode 1]"; 79 pin in float pid_i_gain "integral gain input [mode 0 & mode 1]"; 80 pin in float pid_p_gain "proportional gain input [mode 0 & mode 1]"; 81 pin in float pierce_delay "time required to pierce stock (seconds)"; 82 pin in float pierce_height "pierce height (machine units)"; 83 pin in float probe_feed_rate "probe down velocity (machine units per minute)"; 84 pin in bit probe_test "probe test only"; 85 pin in float probe_start_height "probe starting height"; 86 pin in bit program_is_idle "program is idle, connect to halui.program.is-idle"; 87 pin in bit program_is_paused "program is paused, connect to halui.program.is-paused"; 88 pin in bit program_is_running "program is running, connect to halui.program.is-running"; 89 pin in float puddle_jump_delay "delay move from pierce height to cut height (seconds), leave disconnected if not required"; 90 pin in float puddle_jump_height "puddle jump height (percentage of pierce height), leave disconnected if not required"; 91 pin in float requested_velocity "requested velocity, set by a known requested velocity or connect to motion.requested-vel"; 92 pin in float restart_delay "time from arc failure till next restart attempt"; 93 pin in float safe_height "requested safe traverse height (machine units)"; 94 pin in float scribe_arm_delay "delay from scribe arm to scribe on"; 95 pin in float scribe_on_delay "delay from scribe on to motion beginning"; 96 pin in bit scribe_start "start a new scribe, connect to spindle.1.on"; 97 pin in float setup_feed_rate "feed rate for moves to pierce and cut heights (machine units per minute)"; 98 pin in float skip_ihs_distance "skip IHS if less than this distance from last cut"; 99 pin in bit thc_enable "enable/disable thc and set the IHS skip type"; 100 pin in bit thc_disable "thc disable"; 101 pin in float thc_delay "delay from start of cut to THC enable (seconds)"; 102 pin in float thc_feed_rate "maximum feed rate for thc (machine units per minute)"; 103 pin in float thc_threshold "thc threshold (volts), changes below this have no effect"; 104 pin in bit torch_enable "enable torch"; 105 pin in bit torch_off "turn torch off"; 106 pin in bit torch_pulse_start "torch pulse start"; 107 pin in float torch_pulse_time "torch pulse time (seconds)"; 108 pin in float units_per_mm "for scale calcs, connect to halui.machine.units-per-mm"; 109 pin in bit use_auto_volts "use calculated voltage for thc baseline"; 110 pin in s32 x_y_velocity "velocity for consumable change"; 111 pin in float x_offset "offest to apply to axis x for consumable change"; 112 pin in float y_offset "offest to apply to axis y for consumable change"; 113 114 /* OUTPUT PINS */ 115 pin out float adaptive_feed "for reverse-run, connect to motion.adaptive-feed"; 116 pin out bit arc_ok_out "arc ok output"; 117 pin out float arc_voltage_out "arc voltage output [mode 0 & mode 1]"; 118 pin out bit cornerlock_is_locked "corner locked indicator"; 119 pin out float cut_length "length of current cut job"; 120 pin out float cut_time "time of current cut job"; 121 pin out bit feed_hold "feed hold, connect to motion.feed_hold"; 122 pin out bit kerfcross_is_locked "kerf crossing locked indicator [mode 0 & mode 1]"; 123 pin out bit led_down "thc move down indicator"; 124 pin out bit led_up "thc move up indicator"; 125 pin out s32 offset_counts "number of counts to offset, connect to axis.z.eoffset-counts"; 126 pin out bit offset_enable "enable offsets, connect to axis.z.eoffset-enable"; 127 pin out float offset_scale "offset scale, connect to axis.z.eoffset-scale"; 128 pin out bit ohmic_enable "on only while probing"; 129 pin out s32 pierce_count "number of pierce attempts"; 130 pin out bit program_pause "pause the current program, connect to halui.program.pause"; 131 pin out bit program_resume "resume the currently paused program, connect to halui.program.resume"; 132 pin out bit program_run "run the currently loaded program, connect to halui.program.run"; 133 pin out bit program_stop "stop current program, connect to halui.program.stop"; 134 pin out bit safe_height_is_limited "safe height is limited indicator"; 135 pin out bit scribe_arm "arm the scribe"; 136 pin out bit scribe_on "turn scribe on"; 137 pin out bit thc_active "thc status output"; 138 pin out bit thc_enabled "thc is enabled"; 139 pin out bit torch_on "turn torch on, connect to your torch on input"; 140 pin out s32 x_offset_counts "x offset for consumable change, connect to axis.x.eoffset-counts"; 141 pin out s32 y_offset_counts "y offset for consumable change, connect to axis.y.eoffset-counts"; 142 pin out float z_relative "distance of Z from last probed height"; 143 144 /* VARIABLES */ 145 variable double angle_x_y; /* angle for x/y velocity calcs in radians*/ 146 variable int arc_starts; /* number of attempts to start torch */ 147 variable float arc_fail_timer; /* arc failure timer */ 148 variable float arc_voltage; /* calculated arc voltage before lowpass filter*/ 149 variable float axis_x_finish; /* axis x position at end of cut */ 150 variable float axis_x_start; /* axis x position at start of cut */ 151 variable float axis_y_finish; /* axis y position at end of cut */ 152 variable float axis_y_start; /* axis y position at start of cut */ 153 variable bool auto_cut; /* auto cut mode is active */ 154 variable float spotting_timer; /* spotting timer */ 155 variable bool spotting; /* spotting flag */ 156 variable bool consumable_changing; /* consumables are being changed */ 157 variable int count; /* for counting */ 158 variable int cut_height_first; /* cut height at start of cut */ 159 variable int cut_height_last; /* cut height at end of cut */ 160 variable float cut_offset; /* offset from last cut end to this cut start */ 161 variable bool cut_started; /* cut has started */ 162 variable int cut_target; /* cut height target offset */ 163 variable bool error_message; /* 1 if error message has been sent */ 164 variable bool first_cut_finished; /* first cut is complete */ 165 variable bool float_detected; /* float switch detected */ 166 variable int height_ovr_counts; /* number of counts to change height via override */ 167 variable float height_ovr_old; /* old height override value */ 168 variable bool initialized; /* initialization flag */ 169 variable float kerf_ratio; /* kerf crossing height to distance ratio */ 170 variable float kerf_threshold; /* kerf crossing threshold voltage */ 171 variable float last_arc_voltage; /* last sensed arc voltage */ 172 variable bool manual_cut; /* manual cut mode is active */ 173 variable int offset_datum; /* datum for safe height calcs */ 174 variable int offset_min; /* minimum allowed offset */ 175 variable int offset_max; /* maximum allowed offset */ 176 variable int ohmic_attempts; /* current ohmic probe attempts */ 177 variable bool ohmic_detected; /* true if ohmic probe detected */ 178 variable int setup_velocity; /* velocity for setup moves */ 179 variable float pause_at_end_timer; /* pause at end of cut timer */ 180 variable bool paused_motion; /* paused motion flag */ 181 variable float paused_motion_timer; /* minimum run timer for paused motion */ 182 variable float pid_error_now; /* current error for pid calcs */ 183 variable float pid_error_old; /* old error for pid calcs */ 184 variable float pid_output; /* calculated pid output value */ 185 variable float pierce_timer; /* pierce delay timer */ 186 variable int pierce_target; /* pierce height target offset */ 187 variable int probe_force; /* extra movement of probe after first contact */ 188 variable int probe_force_val; /* distance for probe_force */ 189 variable bool probe_inhibit; /* inhibit probing */ 190 variable int probe_offset; /* offset for active probe */ 191 variable bool probe_required = 1; /* a probe sequence is required */ 192 variable int probe_start_target; /* probe start height target */ 193 variable bool probe_testing; /* probe test active */ 194 variable int probe_velocity; /* probe down velocity */ 195 variable int puddle_jump_percent; /* puddle jump height as percentage of pierce height */ 196 variable int puddle_jump_target; /* puddle jump height target offset */ 197 variable float puddle_jump_timer; /* puddle jump delay timer */ 198 variable float requested_feed_rate; /* requested feed rate */ 199 variable float restart_timer; /* time between torch on attempts*/ 200 variable int safe_min; /* minimum safe height allowed */ 201 variable int safe_preferred; /* preferred safe height offset */ 202 variable int safe_target; /* safe height target offset */ 203 variable bool scribe_pause; /* scribe pause flag */ 204 variable float scribe_arm_timer; /* scribe timer from arm to on*/ 205 variable float scribe_on_timer; /* scribe timer from on to motion*/ 206 variable bool target_sensed; /* sensed top of stock */ 207 variable int target_samples = 6; /* number of samples for setting target_volts */ 208 variable float target_total; /* total voltage of samples for setting target_volts */ 209 variable float target_volts; /* target voltage for thc, set by arc voltage at cut height */ 210 variable float thc_delay_timer; /* thc delay timer */ 211 variable int thc_velocity; /* velocity for thc moves */ 212 variable float torch_off_timer; /* arc off delay timer */ 213 variable bool torch_pulse; /* torch pulse flag */ 214 variable float torch_pulse_timer; /* torch pulse timer */ 215 variable float velocity_scale; /* the velocity multipler */ 216 variable int x_velocity; /* velocity for x motion for consumable change */ 217 variable int y_velocity; /* velocity for y motion for consumable change */ 218 variable int zero_target; /* zero height target offset */ 219 220 /* DEBUGGING PINS */ 221 pin out s32 state_out "current state"; 222 pin out s32 stop_type_out "current stop type"; 223 224 function _; 225 226 author "Phillip A Carter"; 227 228 license "GPLv2 or greater"; 229 230 option singleton yes; 231 232 ;; 233 234 #include "rtapi_math.h" 235 236 typedef enum{IDLE, 237 PROBE_HEIGHT, 238 PROBE_DOWN, 239 PROBE_UP, 240 ZERO_HEIGHT, 241 PIERCE_HEIGHT, 242 TORCH_ON, 243 ARC_OK, 244 PIERCE_DELAY, 245 PUDDLE_JUMP, 246 CUT_HEIGHT, 247 CUT, 248 PAUSE_AT_END, 249 SAFE_HEIGHT, 250 MAX_HEIGHT, 251 FINISH, 252 TORCHPULSE, 253 PAUSED_MOTION, 254 OHMIC_TEST, 255 PROBE_TEST, 256 SCRIBING, 257 CONSUMABLE_CHANGE_ON, 258 CONSUMABLE_CHANGE_OFF, 259 DEBUG} state_t; 260 261 typedef enum{NONE, 262 STOP, 263 WAIT, 264 PAUSE} stop_type_t; 265 266 typedef enum{ZERO, 267 UP, 268 DOWN} move_direction_t; 269 270 typedef enum{FLOAT, 271 OHMIC} probe_type_t; 272 273 typedef enum{EMPTY, 274 CUTTING, 275 SCRIBE, 276 SPOTTING} tool_t; 277 278 state_t state = IDLE; 279 stop_type_t stop_type = NONE; 280 move_direction_t move_direction = ZERO; 281 probe_type_t probe_type = FLOAT; 282 tool_t tool = EMPTY; 283 284 FUNCTION(_) { 285 286 /* do these first run only */ 287 if(!initialized && units_per_mm){ 288 offset_scale = units_per_mm * fperiod; 289 velocity_scale = 1 / units_per_mm / 60; 290 offset_enable = TRUE; 291 adaptive_feed = 1; 292 initialized = TRUE; 293 probe_force_val = 0.125 * units_per_mm / offset_scale; 294 } 295 296 /* set the active tool */ 297 if(cutting_start){ // this allows M3 for cutting as well as M3 $0 298 tool = CUTTING; 299 }else if(multi_tool && scribe_start && !cutting_start && !spotting_start){ 300 tool = SCRIBE; 301 }else if(multi_tool && spotting_start && !cutting_start && !scribe_start){ 302 tool = SPOTTING; 303 }else{ 304 tool = EMPTY; 305 } 306 307 /* output the relative Z height */ 308 if(zero_target){ 309 z_relative = offset_current - zero_target * offset_scale; 310 }else{ 311 z_relative = axis_z_position - axis_z_min_limit; 312 } 313 314 /* convert feed rates to velocity */ 315 setup_velocity = setup_feed_rate * velocity_scale; 316 if(probe_feed_rate < setup_feed_rate){ 317 probe_velocity = probe_feed_rate * velocity_scale; 318 }else{ 319 probe_velocity = setup_velocity; 320 } 321 if(mode == 2){ 322 thc_velocity = thc_feed_rate * velocity_scale * pid_p_gain / 100; 323 }else{ 324 thc_velocity = thc_feed_rate * velocity_scale; 325 } 326 if(thc_velocity < 1){ 327 thc_velocity = 1; 328 } 329 330 /* turn torch off if torch off timer completed */ 331 if(torch_off_timer > 0){ 332 torch_off_timer -= fperiod; 333 if(torch_off_timer <= 0){ 334 torch_on = FALSE; 335 torch_off_timer = 0; 336 } 337 } 338 339 /* turn torch off from external input */ 340 if(torch_off){ 341 torch_on = FALSE; 342 } 343 344 /* set THC state */ 345 thc_enabled = (thc_enable && !thc_disable ? 1:0); 346 347 /* set THC status */ 348 thc_active = (state == CUT) && target_volts && thc_enabled && !cornerlock_is_locked && !kerfcross_is_locked ? 1:0; 349 350 /* set ohmic probe state */ 351 ohmic_detected = ohmic_probe && ohmic_probe_enable; 352 353 /* set adaptive feed reduction if no paused motion */ 354 if(state != PAUSED_MOTION){ 355 if(feed_reduction < 10 && state == CUT){ 356 adaptive_feed = 1; 357 }else if(feed_reduction < 100 && state == CUT){ 358 adaptive_feed = feed_reduction * 0.01; 359 }else{ 360 adaptive_feed = 1; 361 } 362 } 363 364 /* check for a manual cut */ 365 if(tool == CUTTING && !auto_cut){ 366 manual_cut = TRUE; 367 } 368 369 /* check for an abort */ 370 /* or for a pause or wait while active */ 371 if(auto_cut){ 372 if(!probe_test && (external_estop || program_is_idle) && cut_started && !program_run){ 373 auto_cut = FALSE; 374 if(!pause_at_end){ 375 torch_on = FALSE; 376 } 377 stop_type = STOP; 378 program_stop = TRUE; 379 cut_started = FALSE; 380 probe_required = TRUE; 381 axis_x_finish = 0; 382 axis_y_finish = 0; 383 if(!external_estop){ 384 pause_at_end_timer = pause_at_end; 385 state = PAUSE_AT_END; 386 }else{ 387 state = MAX_HEIGHT; 388 } 389 }else if(!probe_test && state > IDLE && state <= CUT && stop_type == NONE && cut_started){ 390 if(program_is_paused){ 391 torch_on = FALSE; 392 stop_type = PAUSE; 393 probe_required = TRUE; 394 pause_at_end_timer = pause_at_end; 395 state = MAX_HEIGHT; 396 }else if(tool == EMPTY){ 397 if(!pause_at_end){ 398 torch_on = FALSE; 399 } 400 stop_type = WAIT; 401 if(thc_enabled && ((!use_auto_volts || (use_auto_volts && target_volts)) || !torch_enable)){ 402 axis_x_finish = axis_x_position; 403 axis_y_finish = axis_y_position; 404 }else{ 405 axis_x_finish = 0; 406 axis_y_finish = 0; 407 } 408 pause_at_end_timer = pause_at_end; 409 state = PAUSE_AT_END; 410 }else if(breakaway){ 411 torch_on = FALSE; 412 program_pause = TRUE; 413 stop_type = PAUSE; 414 probe_required = TRUE; 415 rtapi_print_msg(RTAPI_MSG_ERR,"breakaway switch activated\n" 416 "program is paused.\n"); 417 probe_inhibit = TRUE; 418 state = MAX_HEIGHT; 419 }else if(state > PIERCE_HEIGHT && float_switch){ 420 torch_on = FALSE; 421 program_pause = TRUE; 422 stop_type = PAUSE; 423 probe_required = TRUE; 424 rtapi_print_msg(RTAPI_MSG_ERR,"float switch activated\n" 425 "program is paused.\n"); 426 probe_inhibit = TRUE; 427 state = MAX_HEIGHT; 428 }else if(state > PIERCE_HEIGHT && ohmic_detected){ 429 torch_on = FALSE; 430 program_pause = TRUE; 431 stop_type = PAUSE; 432 probe_required = TRUE; 433 rtapi_print_msg(RTAPI_MSG_ERR,"ohmic probe activated\n" 434 "program is paused.\n"); 435 probe_inhibit = TRUE; 436 state = MAX_HEIGHT; 437 }else if(state > ARC_OK && !arc_ok_out && torch_enable && !torch_off){ ; 438 torch_on = FALSE; 439 program_pause = TRUE; 440 stop_type = PAUSE; 441 probe_required = TRUE; 442 rtapi_print_msg(RTAPI_MSG_ERR,"valid arc lost\n" 443 "program is paused.\n"); 444 state = MAX_HEIGHT; 445 } 446 } 447 }else if(manual_cut){ 448 if(tool == EMPTY){ 449 manual_cut = FALSE; 450 torch_on = FALSE; 451 stop_type = STOP; 452 program_stop = TRUE; 453 cut_started = FALSE; 454 probe_required = TRUE; 455 axis_x_finish = 0; 456 axis_y_finish = 0; 457 state = MAX_HEIGHT; 458 } 459 } 460 461 /* calculate arc voltage */ 462 arc_voltage = (arc_voltage_in - arc_voltage_offset) * arc_voltage_scale; 463 if(lowpass_frequency){ 464 arc_voltage_out += (arc_voltage - arc_voltage_out) * (1 - pow(2.71828, -(2 * M_PI * lowpass_frequency) * fperiod)); 465 }else{ 466 arc_voltage_out = arc_voltage; 467 } 468 469 /* set arc ok from either arc ok input of from actual arc voltage 470 * if using arc ok input, set arc_ok_low_in and/or arc_ok_high_in to 0 */ 471 if(mode > 0){ 472 arc_ok_out = arc_ok_in; 473 }else if(arc_voltage_out >= arc_ok_low && arc_voltage_out <= arc_ok_high){ 474 arc_ok_out = TRUE; 475 }else{ 476 arc_ok_out = FALSE; 477 } 478 479 /* reset program states */ 480 if(program_is_idle){ 481 program_stop = FALSE; 482 program_resume = FALSE; 483 }else if(program_is_paused){ 484 program_pause = FALSE; 485 }else if(program_is_running){ 486 program_run = FALSE; 487 program_resume = FALSE; 488 auto_cut = TRUE; 489 } 490 491 /* if puddlejump height is 0 then set it to 100 */ 492 if(puddle_jump_height == 0){ 493 puddle_jump_percent = 100; 494 }else{ 495 puddle_jump_percent = puddle_jump_height; 496 } 497 498 /* state machine */ 499 switch(state){ 500 case IDLE: 501 if(probe_inhibit && !float_switch && !breakaway && !ohmic_detected){ 502 probe_inhibit = FALSE; 503 }else if(!probe_inhibit){ 504 /* if we get a paused motion request and we are paused */ 505 if(paused_motion_speed && stop_type == PAUSE){ 506 state = PAUSED_MOTION; 507 /* if we get a consumable change start request and we are paused */ 508 }else if(consumable_change && stop_type == PAUSE && !consumable_changing){ 509 state = CONSUMABLE_CHANGE_ON; 510 511 /* if we get a consumable change stop request and we are changing consumables */ 512 }else if(!consumable_change && stop_type == PAUSE && consumable_changing){ 513 state = CONSUMABLE_CHANGE_OFF; 514 515 /* if we get a torch start request and we are stopped or waiting for a restart */ 516 }else if((tool == CUTTING || tool == SPOTTING || probe_test) && (stop_type == NONE || stop_type == WAIT) && homed){ 517 feed_hold = TRUE; 518 stop_type = NONE; 519 //touchdown = FALSE; 520 if(!probe_test){ 521 cut_started = TRUE; 522 }else{ 523 probe_testing = TRUE; 524 } 525 if(!thc_enabled && first_cut_finished){ 526 cut_offset = sqrt(pow(axis_x_start - axis_x_position, 2) + pow(axis_y_start - axis_y_position, 2)); 527 }else if((axis_x_finish || axis_y_finish) && first_cut_finished){ 528 cut_offset = sqrt(pow(axis_x_finish - axis_x_position, 2) + pow(axis_y_finish - axis_y_position, 2)); 529 axis_x_finish = 0; 530 axis_y_finish = 0; 531 } 532 if(cut_offset && cut_offset < skip_ihs_distance && !probe_required){ 533 if(thc_enabled){ 534 cut_target = cut_target + cut_height_last - cut_height_first; 535 pierce_target = pierce_target + cut_height_last - cut_height_first; 536 puddle_jump_target = puddle_jump_target + cut_height_last - cut_height_first; 537 cut_height_first = cut_height_last; 538 } 539 cut_offset = 0; 540 state = PIERCE_HEIGHT; 541 }else{ 542 ohmic_enable = TRUE; 543 if(ohmic_detected && !probe_inhibit){ 544 ohmic_enable = FALSE; 545 probe_inhibit = TRUE; 546 if(probe_testing){ 547 rtapi_print_msg(RTAPI_MSG_ERR,"ohmic probe detected before moving to probe height."); 548 }else{ 549 stop_type = PAUSE; 550 program_pause = TRUE; 551 rtapi_print_msg(RTAPI_MSG_ERR,"ohmic probe detected before moving to probe height.\n" 552 "program is paused.\n"); 553 } 554 }else if(float_switch && !probe_inhibit){ 555 probe_inhibit = TRUE; 556 if(probe_testing){ 557 rtapi_print_msg(RTAPI_MSG_ERR,"float switch detected before moving to probe height."); 558 }else{ 559 stop_type = PAUSE; 560 program_pause = TRUE; 561 rtapi_print_msg(RTAPI_MSG_ERR,"float switch detected before moving to probe height.\n" 562 "program is paused.\n"); 563 } 564 }else if(breakaway && !probe_inhibit){ 565 probe_inhibit = TRUE; 566 if(probe_testing){ 567 rtapi_print_msg(RTAPI_MSG_ERR,"breakaway switch detected before moving to probe height."); 568 }else{ 569 stop_type = PAUSE; 570 program_pause = TRUE; 571 rtapi_print_msg(RTAPI_MSG_ERR,"breakaway switch detected before moving to probe height.\n" 572 "program is paused.\n"); 573 } 574 }else if (!program_is_paused){ 575 if(!first_cut_finished){ 576 if(probe_start_height){ 577 probe_start_target = offset_counts - ((axis_z_position - axis_z_min_limit - probe_start_height) / offset_scale); 578 }else{ 579 probe_start_target = offset_counts; 580 } 581 } 582 cut_offset = 0; 583 state = PROBE_HEIGHT; 584 } 585 } 586 /* if we get a resume request and we are paused */ 587 }else if(!program_is_paused && stop_type == PAUSE){ 588 if(consumable_changing){ 589 state = CONSUMABLE_CHANGE_OFF; 590 } 591 feed_hold = TRUE; 592 stop_type = NONE; 593 /* if torch pulse requested */ 594 }else if(torch_pulse_start){ 595 feed_hold = TRUE; 596 state = TORCHPULSE; 597 /* if ohmic probe shorted test requested */ 598 }else if(ohmic_test){ 599 feed_hold = TRUE; 600 ohmic_enable = TRUE; 601 state = OHMIC_TEST; 602 /* if we get a air-scribe start request */ 603 }else if(tool == SCRIBE && !probe_test && homed){ 604 state = SCRIBING; 605 scribe_arm_timer = scribe_arm_delay; 606 scribe_pause = FALSE; 607 }else if(!cut_started){ 608 feed_hold = FALSE; 609 } 610 } 611 break; 612 case PROBE_HEIGHT: 613 /* move to probe height at setup speed */ 614 if(probe_testing && !probe_test){ 615 state = PROBE_TEST; 616 break; 617 } 618 if(float_switch && !float_detected){ 619 if(probe_testing){ 620 rtapi_print_msg(RTAPI_MSG_ERR,"float switch detected while moving to probe height."); 621 state = PROBE_TEST; 622 }else{ 623 stop_type = PAUSE; 624 program_pause = TRUE; 625 state = MAX_HEIGHT; 626 rtapi_print_msg(RTAPI_MSG_ERR,"float switch detected while moving to probe height.\n" 627 "program is paused.\n"); 628 } 629 }else if(ohmic_detected){ 630 if(probe_testing){ 631 rtapi_print_msg(RTAPI_MSG_ERR,"ohmic probe detected while moving to probe height."); 632 state = PROBE_TEST; 633 }else{ 634 stop_type = PAUSE; 635 program_pause = TRUE; 636 state = MAX_HEIGHT; 637 rtapi_print_msg(RTAPI_MSG_ERR,"ohmic probe detected while moving to probe height.\n" 638 "program is paused.\n"); 639 } 640 }else if(offset_counts - setup_velocity > probe_start_target){ 641 offset_counts -= setup_velocity; 642 }else if(offset_counts + setup_velocity < probe_start_target){ 643 offset_counts += setup_velocity; 644 }else if(offset_counts > probe_start_target || offset_counts < probe_start_target){ 645 offset_counts = probe_start_target; 646 }else{ 647 if(float_detected){ 648 if(!float_switch){ 649 float_detected = FALSE; 650 } 651 }else{ 652 state = PROBE_DOWN; 653 } 654 } 655 break; 656 case PROBE_DOWN: 657 /* probe down to top of stock at probe speed, then push a little further for good contact */ 658 feed_hold = TRUE; 659 if(probe_testing && !probe_test){ 660 state = PROBE_TEST; 661 break; 662 } 663 if(target_sensed){ 664 if(probe_force > 0){ 665 probe_force -= 21; 666 offset_counts -= probe_velocity; 667 }else{ 668 target_sensed = FALSE; 669 if(float_switch || ohmic_detected){ 670 state = PROBE_UP; 671 }else{ 672 rtapi_print_msg(RTAPI_MSG_ERR,"probe trip error while probing."); 673 state = IDLE; 674 } 675 } 676 }else if(!float_switch && !ohmic_detected){ 677 if(axis_z_position - (probe_velocity * offset_scale) <= axis_z_min_limit){ 678 if(!probe_test){ 679 rtapi_print_msg(RTAPI_MSG_ERR,"bottom limit reached while probing down.\n" 680 "program is paused.\n"); 681 stop_type = PAUSE; 682 program_pause = TRUE; 683 }else{ 684 rtapi_print_msg(RTAPI_MSG_ERR,"bottom limit reached while probe testing.\n"); 685 } 686 state = MAX_HEIGHT; 687 }else{ 688 offset_counts -= probe_velocity; 689 } 690 }else if(float_switch && !float_detected){ 691 if(ohmic_attempts == ohmic_max_attempts){ 692 probe_type = FLOAT; 693 target_sensed = TRUE; 694 probe_force = probe_force_val; 695 ohmic_attempts = 0; 696 float_detected = FALSE; 697 }else{ 698 state = PROBE_HEIGHT; 699 ohmic_attempts += 1; 700 float_detected = TRUE; 701 } 702 }else if(ohmic_detected){ 703 probe_type = OHMIC; 704 target_sensed = TRUE; 705 probe_force = probe_force_val; 706 ohmic_attempts = 0; 707 } 708 break; 709 case PROBE_UP: 710 /* probe up at minimum speed to find top of stock */ 711 if(probe_testing && !probe_test){ 712 state = PROBE_TEST; 713 break; 714 } 715 if(float_switch || ohmic_detected){ 716 offset_counts += 1; 717 }else{ 718 if(probe_type == OHMIC){ 719 probe_offset = ohmic_probe_offset / offset_scale; 720 }else{ 721 probe_offset = float_switch_travel / offset_scale; 722 } 723 zero_target = offset_counts + probe_offset; 724 cut_target = cut_height_first = offset_datum = offset_counts + probe_offset + (cut_height / offset_scale); 725 pierce_target = offset_counts + probe_offset + (pierce_height / offset_scale); 726 puddle_jump_target = offset_counts + probe_offset + (pierce_height * (puddle_jump_percent / 100) / offset_scale); 727 safe_min = (pierce_height + (1 * units_per_mm)) / offset_scale; 728 safe_preferred = safe_height / offset_scale; 729 offset_min = offset_counts - ((axis_z_position - axis_z_min_limit) / offset_scale); 730 offset_max = offset_counts + (axis_z_max_limit - axis_z_position - (1 * units_per_mm)) / offset_scale; 731 if(safe_height == 0){ 732 safe_target = offset_max; 733 ohmic_enable = FALSE; 734 // state = ZERO_HEIGHT; 735 state = PIERCE_HEIGHT; 736 }else if(offset_counts + safe_min >= offset_max){ 737 safe_target = offset_max; 738 rtapi_print_msg(RTAPI_MSG_ERR, "material too high for safe traverse.\n" 739 "program is paused.\n"); 740 stop_type = PAUSE; 741 program_pause = TRUE; 742 state = MAX_HEIGHT; 743 }else if(offset_counts + safe_preferred >= offset_max && !safe_height_is_limited){ 744 rtapi_print_msg(RTAPI_MSG_ERR, "safe traverse height has been reduced.\n"); 745 safe_target = offset_max; 746 safe_height_is_limited = TRUE; 747 ohmic_enable = FALSE; 748 // state = ZERO_HEIGHT; 749 state = PIERCE_HEIGHT; 750 }else{ 751 safe_target = offset_counts + safe_preferred; 752 ohmic_enable = FALSE; 753 // state = ZERO_HEIGHT; 754 state = PIERCE_HEIGHT; 755 } 756 } 757 break; 758 case ZERO_HEIGHT: 759 probe_required = FALSE; 760 if(probe_testing && !probe_test){ 761 state = PROBE_TEST; 762 break; 763 } 764 if(offset_counts - setup_velocity > zero_target){ 765 offset_counts -= setup_velocity; 766 }else if(offset_counts + setup_velocity < zero_target){ 767 offset_counts += setup_velocity; 768 }else{ 769 offset_counts = zero_target; 770 axis_x_start = axis_x_position; 771 axis_y_start = axis_y_position; 772 state = PIERCE_HEIGHT; 773 } 774 break; 775 case PIERCE_HEIGHT: 776 /* move up to pierce height */ 777 if(probe_testing && !probe_test){ 778 state = PROBE_TEST; 779 break; 780 } 781 if(pierce_height && cut_height && (use_auto_volts || (!use_auto_volts && cut_volts))){ 782 feed_hold = TRUE; 783 if(offset_counts - setup_velocity > pierce_target){ 784 offset_counts -= setup_velocity; 785 }else if(offset_counts + setup_velocity < pierce_target){ 786 offset_counts += setup_velocity; 787 }else{ 788 offset_counts = pierce_target; 789 arc_starts = 0; 790 if(probe_testing){ 791 state = PROBE_TEST; 792 }else if(!torch_enable){ 793 pierce_timer = pierce_delay; 794 state = PIERCE_DELAY; 795 }else if(tool == CUTTING || tool == SPOTTING){ 796 state = TORCH_ON; 797 } 798 } 799 }else if(!probe_testing){ 800 stop_type = PAUSE; 801 program_pause = TRUE; 802 state = MAX_HEIGHT; 803 rtapi_print_msg(RTAPI_MSG_ERR,"invalid pierce height.\n" 804 "or invalid cut height.\n" 805 "or invalid cut volts."); 806 } 807 break; 808 case TORCH_ON: 809 /* turn torch on and start arc fail timer 810 * if too many attempts then turn torch off, pause program and return to idle state */ 811 feed_hold = TRUE; 812 if(arc_starts > arc_max_starts - 1){ 813 program_pause = TRUE; 814 restart_timer = 0; 815 if (!error_message){ 816 rtapi_print_msg(RTAPI_MSG_ERR,"no arc detected after %d start attempts\nprogram is paused.\n", arc_max_starts); 817 error_message = 1; 818 } 819 }else{ 820 error_message = 0; 821 restart_timer -= fperiod; 822 if(restart_timer <= 0){ 823 restart_timer = 0; 824 arc_fail_timer = arc_fail_delay; 825 if(torch_enable){ 826 torch_on = TRUE; 827 pierce_count += 1; 828 } 829 spotting = FALSE; 830 state = ARC_OK; 831 } 832 } 833 break; 834 case ARC_OK: 835 /* wait for arc ok 836 * if timeout occurs turn torch off then return to TORCH_ON for another attempt */ 837 feed_hold = TRUE; 838 if(tool == SPOTTING){ 839 if(!spotting){ 840 if(arc_voltage >= spotting_threshold){ 841 spotting = TRUE; 842 spotting_timer = spotting_time * 0.001; 843 } 844 }else{ 845 spotting_timer -= fperiod; 846 if(spotting_timer <= 0){ 847 spotting = FALSE; 848 spotting_timer = 0; 849 torch_on = FALSE; 850 stop_type = WAIT; 851 state = SAFE_HEIGHT; 852 } 853 } 854 } 855 arc_fail_timer -= fperiod; 856 if(arc_fail_timer <= 0){ 857 torch_on = FALSE; 858 restart_timer = restart_delay; 859 arc_starts += 1; 860 state = TORCH_ON; 861 }else if(arc_ok_out && tool != SPOTTING){ 862 pierce_timer = pierce_delay; 863 state = PIERCE_DELAY; 864 } 865 break; 866 case PIERCE_DELAY: 867 /* wait for arc to pierce stock */ 868 feed_hold = TRUE; 869 if(pierce_timer > 0){ 870 pierce_timer -= fperiod; 871 }else{ 872 puddle_jump_timer = puddle_jump_delay; 873 state = PUDDLE_JUMP; 874 } 875 break; 876 case PUDDLE_JUMP: 877 /* move to puddle_jump height */ 878 feed_hold = TRUE; 879 if(offset_counts - setup_velocity > puddle_jump_target){ 880 offset_counts -= setup_velocity; 881 }else if(offset_counts + setup_velocity < puddle_jump_target){ 882 offset_counts += setup_velocity; 883 }else{ 884 offset_counts = puddle_jump_target; 885 count = 0; 886 if(puddle_jump_timer > 0){ 887 feed_hold = FALSE; 888 puddle_jump_timer -= fperiod; 889 }else{ 890 puddle_jump_timer = 0; 891 feed_hold = TRUE; 892 state = CUT_HEIGHT; 893 } 894 } 895 break; 896 case CUT_HEIGHT: 897 /* move to cut height */ 898 feed_hold = TRUE; 899 if(offset_counts - setup_velocity > cut_target){ 900 offset_counts -= setup_velocity; 901 }else if(offset_counts + setup_velocity < cut_target){ 902 offset_counts += setup_velocity; 903 }else{ 904 offset_counts = cut_target; 905 if((int)floor(offset_current / offset_scale) <= cut_target + 1 && 906 (int)floor(offset_current / offset_scale) >= cut_target - 1){ 907 count = 0; 908 /* set feed rate for this cut */ 909 if(cut_feed_rate > 0){ 910 requested_feed_rate = cut_feed_rate; 911 }else{ 912 requested_feed_rate = requested_velocity; 913 } 914 feed_hold = FALSE; 915 thc_delay_timer = thc_delay; 916 state = CUT; 917 } 918 } 919 break; 920 case CUT: 921 /* while cutting and it is not a dry run: 922 * if thc is enabled then vary the torch height to keep the arc voltage constant 923 * if corner lock enabled, only allow THC if current velocity is greater than the threshold percentage of requested velocity 924 * if kerf crossing is enabled, only allow THC if the voltage change is less than the threshold voltage (modes 0 & 1 only) 925 * adjust torch height and target voltage to suit if height override requested (modes 0 & 1 only)*/ 926 if(torch_on){ 927 // if(torch_enable){ 928 /* thc control by arc voltage */ 929 if(mode < 2){ 930 thc_delay_timer -= fperiod; 931 if(thc_delay_timer <= 0){ 932 /* set target voltage */ 933 if(target_volts == 0){ 934 if(use_auto_volts){ 935 /* wait until velocity is at least 99.9% of requested velocity before sampling arc voltage */ 936 if(current_velocity * 60 > requested_feed_rate * feed_override * 0.999){ 937 count += 1; 938 target_total += arc_voltage_out; 939 if(count == target_samples){ 940 target_volts = target_total / target_samples; 941 last_arc_voltage = target_volts; 942 count = 0; 943 target_total = 0; 944 } 945 } 946 if(target_volts == 0){ 947 cornerlock_is_locked = TRUE; 948 }else{ 949 cornerlock_is_locked = FALSE; 950 } 951 }else{ 952 target_volts = cut_volts; 953 } 954 /* height override setup*/ 955 }else if(fabs(height_override - height_ovr_old) > 0.05){ 956 height_ovr_counts -= (height_override - height_ovr_old) / 10 * units_per_mm / offset_scale; 957 height_ovr_old = height_override; 958 /* height override z motion */ 959 }else if(height_ovr_counts != 0){ 960 if((setup_velocity) < height_ovr_counts){ 961 offset_counts -= setup_velocity; 962 height_ovr_counts -= setup_velocity; 963 }else{ 964 offset_counts -= height_ovr_counts; 965 height_ovr_counts = 0; 966 } 967 /* torch height control */ 968 }else if(thc_enabled){ 969 /* lock thc if velocity < requested velocity * cornerlock threshold percentage */ 970 if(cornerlock_enable){ 971 if(current_velocity * 60 < requested_feed_rate * feed_override * cornerlock_threshold * 0.01){ 972 cornerlock_is_locked = TRUE; 973 }else if(cornerlock_is_locked && current_velocity * 60 > requested_feed_rate * feed_override * 0.99){ 974 cornerlock_is_locked = FALSE; 975 } 976 }else{ 977 cornerlock_is_locked = FALSE; 978 } 979 /* unlock kerfcross lock if voltage reduced to safe level */ 980 if(kerfcross_is_locked){ 981 // if(arc_voltage_out < last_arc_voltage + (kerf_threshold * 0.05)){ 982 if(arc_voltage_out < target_volts + (kerf_threshold * 0.5)){ 983 kerfcross_is_locked = FALSE; 984 last_arc_voltage = arc_voltage_out; 985 } 986 /* set kerfcross lock if voltage change > kerfcross threshold volts */ 987 }else if(kerfcross_enable){ 988 if(thc_feed_rate < current_velocity * 60){ 989 kerf_ratio = thc_feed_rate / (current_velocity * 60); 990 }else{ 991 kerf_ratio = 1; /* 45 degree ramp */ 992 } 993 kerf_threshold = ((kerf_ratio * current_velocity * fperiod) / height_per_volt) * (kerfcross_override * 0.01); 994 // if(arc_voltage_out > last_arc_voltage + kerf_threshold){ 995 if(arc_voltage_out > target_volts + kerf_threshold){ 996 kerfcross_is_locked = TRUE; 997 }else{ 998 last_arc_voltage = arc_voltage_out; 999 } 1000 } 1001 /* do thc if ok to go */ 1002 if(!cornerlock_is_locked && !kerfcross_is_locked){ 1003 pid_error_now = (target_volts + height_override - arc_voltage_out) * 0.1; 1004 if(fabs(pid_error_now) < fabs(thc_threshold * 0.1)){ 1005 pid_error_now = 0; 1006 } 1007 pid_output = pid_error_now * pid_p_gain; 1008 pid_output += pid_error_now * pid_i_gain * fperiod; 1009 pid_output += (pid_error_now - pid_error_old) * pid_d_gain / fperiod; 1010 pid_error_old = pid_error_now; 1011 if(pid_output > thc_velocity){ 1012 pid_output = thc_velocity; 1013 }else if(pid_output < -thc_velocity){ 1014 pid_output = -thc_velocity; 1015 } 1016 /* if we hit a soft limit during thc*/ 1017 if(offset_counts + pid_output <= offset_min || offset_counts + pid_output >= offset_max){ 1018 torch_on = FALSE; 1019 stop_type = PAUSE; 1020 program_pause = TRUE; 1021 if(offset_counts + pid_output <= offset_min){ 1022 rtapi_print_msg(RTAPI_MSG_ERR,"bottom limit reached while THC moving down.\n" 1023 "program is paused.\n"); 1024 }else{ 1025 rtapi_print_msg(RTAPI_MSG_ERR,"top limit reached while THC moving up.\n" 1026 "program is paused.\n"); 1027 } 1028 pid_output = 0; 1029 state = MAX_HEIGHT; 1030 1031 } 1032 offset_counts += pid_output; 1033 } 1034 } 1035 if(pid_output > 0){ 1036 led_up = TRUE; 1037 }else if((pid_output) < 0){ 1038 led_down = TRUE; 1039 }else{ 1040 led_down = FALSE; 1041 led_up = FALSE; 1042 } 1043 pid_output = 0; 1044 } 1045 }else{ /* thc control by move-up and move-down inputs (no kerf crossing in this mode) */ 1046 if(thc_enabled){ 1047 /* lock thc if velocity < requested velocity * cornerlock threshold percentage */ 1048 if(cornerlock_enable){ 1049 if(current_velocity * 60 < requested_feed_rate * feed_override * cornerlock_threshold * 0.01){ 1050 cornerlock_is_locked = TRUE; 1051 }else if(cornerlock_is_locked && current_velocity * 60 > requested_feed_rate * feed_override * 0.99){ 1052 cornerlock_is_locked = FALSE; 1053 } 1054 }else{ 1055 cornerlock_is_locked = FALSE; 1056 } 1057 if(move_down && !cornerlock_is_locked){ 1058 if(offset_counts - thc_velocity <= offset_min){ 1059 torch_on = FALSE; 1060 stop_type = PAUSE; 1061 program_pause = TRUE; 1062 rtapi_print_msg(RTAPI_MSG_ERR,"bottom limit reached while THC moving down.\n" 1063 "program is paused.\n"); 1064 state = MAX_HEIGHT; 1065 }else{ /* move down at requested velocity */ 1066 offset_counts -= thc_velocity; 1067 led_down = TRUE; 1068 } 1069 }else if(move_up && !cornerlock_is_locked){ 1070 if(offset_counts + thc_velocity + safe_min >= offset_max){ 1071 torch_on = FALSE; 1072 stop_type = PAUSE; 1073 program_pause = TRUE; 1074 rtapi_print_msg(RTAPI_MSG_ERR,"top limit reached while THC moving up.\n" 1075 "program is paused.\n"); 1076 state = MAX_HEIGHT; 1077 }else{ /* move up at requested velocity */ 1078 offset_counts += thc_velocity; 1079 led_up = TRUE; 1080 } 1081 }else{ 1082 led_down = FALSE; 1083 led_up = FALSE; 1084 } 1085 } 1086 } 1087 /* check if safe height is below maximium offset */ 1088 if(offset_counts > offset_datum){ 1089 safe_target += offset_counts - offset_datum; 1090 offset_datum = offset_counts; 1091 if(safe_target > offset_max){ 1092 safe_target = offset_max; 1093 if(!safe_height_is_limited){ 1094 safe_height_is_limited = TRUE; 1095 rtapi_print_msg(RTAPI_MSG_ERR, "safe traverse height has been reduced."); 1096 } 1097 } 1098 } 1099 } 1100 cut_height_last = offset_counts; 1101 cut_length = cut_length + current_velocity * fperiod; 1102 cut_time = cut_time + fperiod; 1103 break; 1104 case PAUSE_AT_END: 1105 feed_hold = TRUE; 1106 pause_at_end_timer -= fperiod; 1107 if(pause_at_end_timer <= 0){ 1108 pause_at_end_timer = 0; 1109 torch_on = FALSE; 1110 if(program_is_idle){ 1111 state = MAX_HEIGHT; 1112 }else{ 1113 state = SAFE_HEIGHT; 1114 } 1115 } 1116 break; 1117 case SAFE_HEIGHT: 1118 /* move to safe height */ 1119 feed_hold = TRUE; 1120 if(!torch_off_timer || !torch_on){ 1121 cornerlock_is_locked = FALSE; 1122 if(!probe_test){ 1123 if(offset_counts - setup_velocity > safe_target){ 1124 offset_counts -= setup_velocity; 1125 }else if(offset_counts + setup_velocity < safe_target){ 1126 offset_counts += setup_velocity; 1127 }else{ 1128 offset_counts = safe_target; 1129 if(stop_type == WAIT){ 1130 feed_hold = FALSE; 1131 } 1132 first_cut_finished = TRUE; 1133 /* do height override here for for remainder of job */ 1134 height_ovr_old = 0; 1135 state = FINISH; 1136 } 1137 } 1138 } 1139 break; 1140 case MAX_HEIGHT: 1141 /* move to maximum height */ 1142 feed_hold = TRUE; 1143 cornerlock_is_locked = FALSE; 1144 if(!probe_test){ 1145 if(offset_counts - setup_velocity > offset_max){ 1146 offset_counts -= setup_velocity; 1147 }else if(offset_counts + setup_velocity < offset_max){ 1148 offset_counts += setup_velocity; 1149 }else{ 1150 offset_counts = offset_max; 1151 if(stop_type == WAIT){ 1152 feed_hold = FALSE; 1153 } 1154 /* do height override here for remainder of job */ 1155 height_ovr_old = 0; 1156 state = FINISH; 1157 } 1158 } 1159 break; 1160 case FINISH: 1161 /* clean up and return to idle state */ 1162 target_volts = 0; 1163 cornerlock_is_locked = FALSE; 1164 kerfcross_is_locked = FALSE; 1165 led_down = FALSE; 1166 led_up = FALSE; 1167 ohmic_enable = FALSE; 1168 cut_length = 0; 1169 cut_time = 0; 1170 if(stop_type == STOP){ 1171 auto_cut = FALSE; 1172 manual_cut = FALSE; 1173 program_run = FALSE; 1174 paused_motion = FALSE; 1175 adaptive_feed = 1; 1176 if(program_is_idle){ 1177 first_cut_finished = FALSE; 1178 if(offset_counts - setup_velocity > 0){ 1179 offset_counts -= setup_velocity; 1180 }else if(offset_counts + setup_velocity < 0){ 1181 offset_counts += setup_velocity; 1182 }else{ 1183 offset_counts = 0; 1184 stop_type = NONE; 1185 safe_height_is_limited = FALSE; 1186 cut_started = FALSE; 1187 /* do height override here for one cut only */ 1188 /* height_ovr_old = 0; */ 1189 if(consumable_changing){ 1190 state = CONSUMABLE_CHANGE_OFF; 1191 } 1192 } 1193 } 1194 }else{ 1195 state = IDLE; 1196 } 1197 break; 1198 case TORCHPULSE: 1199 /* single pulse the torch on and off */ 1200 if(!torch_pulse){ 1201 torch_pulse_timer = torch_pulse_time; 1202 if(torch_enable){ 1203 torch_on = TRUE; 1204 } 1205 torch_pulse = TRUE; 1206 }else{ 1207 if(torch_pulse_timer > 0){ 1208 torch_pulse_timer -= fperiod; 1209 }else{ 1210 torch_on = FALSE; 1211 if(!torch_pulse_start){ 1212 torch_pulse = FALSE; 1213 state = IDLE; 1214 } 1215 } 1216 } 1217 break; 1218 case PAUSED_MOTION: 1219 /* a bit kludgy but we need a timer here for a minimum run 1220 * time to give the GUI time to poll the status channel */ 1221 if(paused_motion_speed){ 1222 if(!paused_motion){ 1223 paused_motion_timer = 0.2; /* 0.2 seconds */ 1224 paused_motion = TRUE; 1225 adaptive_feed = paused_motion_speed; 1226 feed_hold = FALSE; 1227 program_resume = TRUE; 1228 }else{ 1229 paused_motion_timer -= fperiod; 1230 } 1231 }else{ 1232 paused_motion_timer -= fperiod; 1233 feed_hold = TRUE; 1234 program_pause = TRUE; 1235 if(program_is_paused && paused_motion_timer <= 0){ 1236 paused_motion = FALSE; 1237 adaptive_feed = 1; 1238 state = IDLE; 1239 } 1240 } 1241 break; 1242 case OHMIC_TEST: 1243 /* wait here until ohmic_test input released */ 1244 if (!ohmic_test){ 1245 ohmic_enable = FALSE; 1246 state = IDLE; 1247 } 1248 break; 1249 case PROBE_TEST: 1250 /* wait here until probe_test input released */ 1251 if(!probe_test){ 1252 probe_testing = FALSE; 1253 if(offset_counts - setup_velocity > 0){ 1254 offset_counts -= setup_velocity; 1255 }else if(offset_counts + setup_velocity < 0){ 1256 offset_counts += setup_velocity; 1257 }else{ 1258 offset_counts = 0; 1259 state = FINISH; 1260 } 1261 } 1262 break; 1263 case SCRIBING: 1264 if(tool == SCRIBE){ 1265 if(!program_is_paused){ 1266 scribe_arm = TRUE; 1267 1268 if(scribe_arm_timer){ 1269 feed_hold = TRUE; 1270 scribe_arm_timer -= fperiod; 1271 if(scribe_arm_timer < 0){ 1272 scribe_arm_timer = 0; 1273 } 1274 }else if(scribe_on_timer){ 1275 feed_hold = TRUE; 1276 scribe_on_timer -= fperiod; 1277 if(scribe_on_timer < 0){ 1278 scribe_on_timer = 0; 1279 } 1280 }else if(scribe_arm && !scribe_arm_timer && !scribe_on){ 1281 feed_hold = TRUE; 1282 scribe_on_timer = scribe_on_delay; 1283 scribe_on = TRUE; 1284 }else if(scribe_on && !scribe_on_timer){ 1285 feed_hold = FALSE; 1286 } 1287 }else{ 1288 scribe_arm = FALSE; 1289 scribe_on = FALSE; 1290 scribe_arm_timer = scribe_arm_delay; 1291 scribe_on_timer = 0; 1292 } 1293 }else{ 1294 scribe_arm = FALSE; 1295 scribe_on = FALSE; 1296 scribe_arm_timer = 0; 1297 scribe_on_timer = 0; 1298 state = IDLE; 1299 } 1300 break; 1301 case CONSUMABLE_CHANGE_ON: 1302 if(!consumable_changing){ 1303 if(x_offset == 0 && y_offset == 0){ 1304 x_velocity = 0; 1305 y_velocity = 0; 1306 }else if(x_offset == 0){ 1307 x_velocity = 0; 1308 if(y_offset > 0){ 1309 y_velocity = x_y_velocity; 1310 }else{ 1311 y_velocity = x_y_velocity * -1; 1312 } 1313 }else if(y_offset == 0){ 1314 if(x_offset > 0){ 1315 x_velocity = x_y_velocity; 1316 }else{ 1317 x_velocity = x_y_velocity * -1; 1318 } 1319 }else{ 1320 angle_x_y = atan2(y_offset, x_offset); 1321 x_velocity = x_y_velocity * cos(angle_x_y); 1322 y_velocity = x_y_velocity * sin(angle_x_y); 1323 } 1324 consumable_changing = TRUE; 1325 }else{ 1326 if(x_velocity && x_offset_counts != x_offset){ 1327 if(fabs(x_offset_counts) + fabs(x_velocity) < fabs(x_offset)){ 1328 x_offset_counts += x_velocity; 1329 }else{ 1330 x_offset_counts = x_offset; 1331 } 1332 } 1333 if(y_velocity && y_offset_counts != y_offset){ 1334 if(fabs(y_offset_counts) + fabs(y_velocity) < fabs(y_offset)){ 1335 y_offset_counts += y_velocity; 1336 }else{ 1337 y_offset_counts = y_offset; 1338 } 1339 } 1340 } 1341 if(x_offset_counts == x_offset && y_offset_counts == y_offset){ 1342 state = IDLE; 1343 } 1344 break; 1345 case CONSUMABLE_CHANGE_OFF: 1346 if(x_velocity){ 1347 if(fabs(x_offset_counts) - fabs(x_velocity) > 0){ 1348 x_offset_counts -= x_velocity; 1349 }else{ 1350 x_offset_counts = 0; 1351 } 1352 } 1353 if(y_velocity){ 1354 if(fabs(y_offset_counts) - fabs(y_velocity) > 0){ 1355 y_offset_counts -= y_velocity; 1356 }else{ 1357 y_offset_counts = 0; 1358 } 1359 } 1360 if(!x_offset_counts && !y_offset_counts){ 1361 consumable_changing = FALSE; 1362 state = IDLE; 1363 } 1364 break; 1365 case DEBUG: 1366 /* holding state for debugging */ 1367 rtapi_print_msg(RTAPI_MSG_ERR, "I have no idea how we got here...\n"); 1368 break; 1369 } 1370 1371 /* set debugging pins */ 1372 state_out = state; 1373 stop_type_out = stop_type; 1374 1375 }