From 5a0a93c70de1cbb8e4eb1e9717cb360e87c9f41b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 08:20:40 -0500 Subject: [PATCH 001/283] Initial motate link commit --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 1540f1af..1e1be74e 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 1540f1af7fd2213a704fc8585513effae041f9f1 +Subproject commit 1e1be74e8b0dac10af1829ea211fef06f594ab7f From ed43317f9fed4db6345bb6251d6dc623ebf7da75 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 08:21:08 -0500 Subject: [PATCH 002/283] minor commit --- g2core/g2core.cppproj | 4 ++-- g2core/stepper.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index c227a946..2b1f1c3d 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800019454 + J41800030015 0x284E0A60 2000000 diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 142153e4..d79e17b1 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -608,6 +608,9 @@ static void _load_move() mp_runtime_command(st_pre.bf); } // else null - WARNING - We cannot printf from here!! Causes crashes. + else { + _debug_trap("_load_move called when it's not needed?"); + } // all other cases drop to here (e.g. Null moves after Mcodes skip to here) st_pre.block_type = BLOCK_TYPE_NULL; From bf3c540f9e5e20aad68efe6040e230b8b00b9b52 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 12:47:26 -0500 Subject: [PATCH 003/283] Checkpoint - generalizing planner buffer handling --- g2core/board/G2v9/hardware.h | 1 + g2core/plan_exec.cpp | 11 ++++++ g2core/plan_line.cpp | 33 ++++++++--------- g2core/planner.cpp | 68 +++++++++++++++++++++++++++++++----- g2core/planner.h | 15 +++++++- g2core/stepper.cpp | 27 +++++++------- g2core/stepper.h | 2 +- 7 files changed, 118 insertions(+), 39 deletions(-) mode change 100755 => 100644 g2core/board/G2v9/hardware.h mode change 100755 => 100644 g2core/planner.cpp mode change 100755 => 100644 g2core/planner.h diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h old mode 100755 new mode 100644 index 835dfc44..17ac7bf3 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -1,5 +1,6 @@ /* * hardware.h - system hardware configuration + * for: /board/g2v9 * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index c21234c7..6882ad9f 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -537,6 +537,17 @@ stat_t mp_exec_aline(mpBuf_t *bf) return (status); } + +/* + * mp_plan_feedhold_move() - plan Z lift moves for feedhold + */ + +stat_t mp_plan_feedhold_move() +{ + + return (STAT_OK); +} + /* * mp_exit_hold_state() - end a feedhold * diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index caf56522..8a5c5031 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -129,16 +129,15 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); } * Controlling jerk smooths transitions between moves and allows for faster feeds while * controlling machine oscillations and other undesirable side-effects. * - * Note All math is done in absolute coordinates using single precision floating point (float). + * Note: All math is done in absolute coordinates using single precision floating point (float). * * Note: Returning a status that is not STAT_OK means the endpoint is NOT advanced. So lines * that are too short to move will accumulate and get executed once the accumulated error * exceeds the minimums. */ -stat_t mp_aline(GCodeState_t* gm_in) +stat_t mp_aline(GCodeState_t* gm_in) { - mpBuf_t* bf; // current move pointer float target_rotated[AXES] = {0, 0, 0, 0, 0, 0}; float axis_square[AXES] = {0, 0, 0, 0, 0, 0}; float axis_length[AXES]; @@ -191,33 +190,35 @@ stat_t mp_aline(GCodeState_t* gm_in) // exit if the move has zero movement. At all. if (fp_ZERO(length)) { - sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL + sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL return (STAT_MINIMUM_LENGTH_MOVE); } // get a cleared buffer and copy in the Gcode model state - if ((bf = mp_get_write_buffer()) == NULL) { // never supposed to fail + mpBuf_t* bf = mp_get_write_buffer(); + if (bf == NULL) { // never supposed to fail +// if ((bf = mp_get_write_buffer()) == NULL) { // never supposed to fail return (cm_panic(STAT_FAILED_GET_PLANNER_BUFFER, "aline()")); } memcpy(&bf->gm, gm_in, sizeof(GCodeState_t)); // Since bf->gm.target is being used all over the place, we'll make it the rotated target - copy_vector(bf->gm.target, target_rotated); // copy the rotated taget in place + copy_vector(bf->gm.target, target_rotated); // copy the rotated taget in place // setup the buffer - bf->bf_func = mp_exec_aline; // register the callback to the exec function - bf->length = length; // record the length - for (uint8_t axis = 0; axis < AXES; axis++) { // compute the unit vector and set flags - if ((bf->axis_flags[axis] = flags[axis])) { // yes, this is supposed to be = and not == - bf->unit[axis] = axis_length[axis] / length; // nb: bf-> unit was cleared by mp_get_write_buffer() + bf->bf_func = mp_exec_aline; // register the callback to the exec function + bf->length = length; // record the length + for (uint8_t axis = 0; axis < AXES; axis++) { // compute the unit vector and set flags + if ((bf->axis_flags[axis] = flags[axis])) { // yes, this is supposed to be = and not == + bf->unit[axis] = axis_length[axis] / length;// nb: bf-> unit was cleared by mp_get_write_buffer() } } - _calculate_jerk(bf); // compute bf->jerk values - _calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax - _set_bf_diagnostics(bf); //+++++DIAGNOSTIC + _calculate_jerk(bf); // compute bf->jerk values + _calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax + _set_bf_diagnostics(bf); //+++++DIAGNOSTIC // Note: these next lines must remain in exact order. Position must update before committing the buffer. - copy_vector(mp.position, bf->gm.target); // set the planner position - mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) + copy_vector(mp.position, bf->gm.target); // set the planner position + mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) return (STAT_OK); } diff --git a/g2core/planner.cpp b/g2core/planner.cpp old mode 100755 new mode 100644 index eb94beb7..de03a894 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -65,9 +65,10 @@ #include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures -mpBufferPool_t mb; // buffer pool management -mpMotionPlannerSingleton_t mp; // context for block planning -mpMotionRuntimeSingleton_t mr; // context for block runtime +mpBufferPool_t mb; // buffer pool management +mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for pool #1 buffers +mpMotionPlannerSingleton_t mp; // context for block planning +mpMotionRuntimeSingleton_t mr; // context for block runtime #define JSON_COMMAND_BUFFER_SIZE 3 @@ -700,15 +701,68 @@ static inline void _clear_buffer(mpBuf_t *bf) bf->clear(); } -void mp_init_buffers(void) +void _init_buffers(mpBuf_t *base, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; - memset(&mb, 0, sizeof(mb)); // clear all values, pointers and status +// memset(base, 0, sizeof(mpBuf_t * size)); // clear all buffers in pool + mb.bf = base; // link the buffer pool first + mb.w = mb.bf; // init all buffer pointers + mb.r = mb.bf; + mb.queue_size = size-1; + mb.buffers_available = size; + + pv = &mb.bf[size-1]; + for (i=0; i < size-1; i++) { + mb.bf[i].buffer_number = i; //+++++ number it for diagnostics only (otherwise not used) + + nx_i = ((imotionStopped(); - // } - // loop unrolled version + + // If there are no moves to load start motor power timeouts + if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) { + // for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { + // Motors[motor]->motionStopped(); + // } + + // loop unrolled version motor_1.motionStopped(); // ...start motor power timeouts - motor_2.motionStopped(); // ...start motor power timeouts + motor_2.motionStopped(); #if (MOTORS > 2) - motor_3.motionStopped(); // ...start motor power timeouts + motor_3.motionStopped(); #endif #if (MOTORS > 3) - motor_4.motionStopped(); // ...start motor power timeouts + motor_4.motionStopped(); #endif #if (MOTORS > 4) - motor_5.motionStopped(); // ...start motor power timeouts + motor_5.motionStopped(); #endif #if (MOTORS > 5) - motor_6.motionStopped(); // ...start motor power timeouts + motor_6.motionStopped(); #endif return; } diff --git a/g2core/stepper.h b/g2core/stepper.h index 6c1967dd..1c185796 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -515,7 +515,7 @@ struct Stepper { } } }; - + virtual void periodicCheck(bool have_actually_stopped) // can be overridden { if (have_actually_stopped && _power_state == MOTOR_RUNNING) { From ba8a139e6af2835cb29f30d9b270cb632ee86993 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 13:38:23 -0500 Subject: [PATCH 004/283] Changed rotate reference to master --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index 1e1be74e..1540f1af 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit 1e1be74e8b0dac10af1829ea211fef06f594ab7f +Subproject commit 1540f1af7fd2213a704fc8585513effae041f9f1 From 0d0fdd9ddb1e4a53964916231c2f3cc98a1a8dda Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 13:38:49 -0500 Subject: [PATCH 005/283] updated planner buffer initialization to work from detached buffer pools --- g2core/planner.cpp | 64 +++++----------------------------------------- g2core/planner.h | 11 -------- 2 files changed, 6 insertions(+), 69 deletions(-) diff --git a/g2core/planner.cpp b/g2core/planner.cpp index de03a894..662d3fd8 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -701,12 +701,12 @@ static inline void _clear_buffer(mpBuf_t *bf) bf->clear(); } -void _init_buffers(mpBuf_t *base, uint8_t size) +void _init_buffer_pool(mpBuf_t *base, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; -// memset(base, 0, sizeof(mpBuf_t * size)); // clear all buffers in pool + memset(base, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool mb.bf = base; // link the buffer pool first mb.w = mb.bf; // init all buffer pointers mb.r = mb.bf; @@ -715,8 +715,7 @@ void _init_buffers(mpBuf_t *base, uint8_t size) pv = &mb.bf[size-1]; for (i=0; i < size-1; i++) { - mb.bf[i].buffer_number = i; //+++++ number it for diagnostics only (otherwise not used) - + mb.bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) nx_i = ((ipv); -} -mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) -{ - return (bf->nx); -} +mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); } +mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } */ mpBuf_t * mp_get_write_buffer() // get & clear a buffer diff --git a/g2core/planner.h b/g2core/planner.h index 04923c3f..f817480c 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -242,18 +242,7 @@ typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for struct mpBuffer *nx; // static pointer to next buffer uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging } mpBuf_t; -/* -typedef struct mpBufferPool { // ring buffer for sub-moves - magic_t magic_start; // magic number to test memory integrity - mpBuf_t *r; // run buffer pointer - mpBuf_t *w; // write buffer pointer - uint8_t buffers_available; // running count of available buffers - mpBuf_t bf[PLANNER_BUFFER_POOL_SIZE];// buffer storage - - magic_t magic_end; -} mpBufferPool_t; -*/ typedef struct mpBufferPool { // one or more planner buffer queues magic_t magic_start; // magic number to test memory integrity From 470923f0f73f39d30f0d46e987967df9b7e97eaa Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 15:47:41 -0500 Subject: [PATCH 006/283] Checkpoint added Primary and Alternate planner queue section from the buffer primitives --- g2core/canonical_machine.cpp | 8 +- g2core/controller.cpp | 4 +- g2core/cycle_jogging.cpp | 4 +- g2core/plan_arc.cpp | 2 +- g2core/plan_exec.cpp | 9 +- g2core/plan_line.cpp | 4 +- g2core/planner.cpp | 175 ++++++++++++++++++++++++++--------- g2core/planner.h | 30 ++++-- g2core/report.cpp | 4 +- 9 files changed, 169 insertions(+), 71 deletions(-) mode change 100755 => 100644 g2core/canonical_machine.cpp mode change 100755 => 100644 g2core/controller.cpp mode change 100755 => 100644 g2core/cycle_jogging.cpp diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp old mode 100755 new mode 100644 index ec7a3cb8..01152b35 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1248,7 +1248,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm.gm); // send the move to the planner cm_finalize_move(); - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer()) { + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { cm_cycle_end(); return (STAT_OK); } @@ -1277,7 +1277,7 @@ stat_t _goto_stored_position(float target2[], const float target[], const bool f target2[i] -= target[i]; } } - while (mp_planner_is_full()); // Make sure you have available buffers + while (mp_planner_is_full(ACTIVE_Q)); // Make sure you have available buffers bool flags2[] = { 1,1,1,1,1,1 }; return (cm_straight_traverse(target2, flags2)); // Go to programmed endpoint @@ -1395,7 +1395,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) cm_finalize_move(); // <-- ONLY safe because we don't care about status... - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer()) { + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { cm_cycle_end(); return (STAT_OK); } @@ -1720,7 +1720,7 @@ bool cm_has_hold() void cm_start_hold() { - if (mp_has_runnable_buffer()) { // meaning there's something running + if (mp_has_runnable_buffer(ACTIVE_Q)) { // meaning there's something running cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected cm_set_motion_state(MOTION_HOLD); diff --git a/g2core/controller.cpp b/g2core/controller.cpp old mode 100755 new mode 100644 index b92b029f..aa4df6e4 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -201,7 +201,7 @@ static stat_t _dispatch_command() { if (cs.controller_state != CONTROLLER_PAUSED) { devflags_t flags = DEV_IS_BOTH; - if ((!mp_planner_is_full()) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { + if ((!mp_planner_is_full(ACTIVE_Q)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { _dispatch_kernel(); } } @@ -350,7 +350,7 @@ static stat_t _sync_to_tx_buffer() static stat_t _sync_to_planner() { - if (mp_planner_is_full()) { // allow up to N planner buffers for this line + if (mp_planner_is_full(ACTIVE_Q)) { // allow up to N planner buffers for this line return (STAT_EAGAIN); } return (STAT_OK); diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp old mode 100755 new mode 100644 index fa2c3e2b..43d8ddd2 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -130,7 +130,7 @@ stat_t cm_jogging_cycle_callback(void) { return (STAT_EAGAIN); // sync to planner move ends } // if (jog.func == _jogging_axis_ramp_jog && mp_get_buffers_available() < PLANNER_BUFFER_HEADROOM) { - if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full()) { + if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(ACTIVE_Q)) { return (STAT_EAGAIN); // prevent flooding the queue with jog moves } return (jog.func(jog.axis)); // execute the current jogging move @@ -142,7 +142,7 @@ static stat_t _set_jogging_func(stat_t (*func)(int8_t axis)) { } static stat_t _jogging_axis_start(int8_t axis) { - // cm_end_hold(); // ends hold if one is in effect +// cm_end_hold(); // ends hold if one is in effect return (_set_jogging_func(_jogging_axis_ramp_jog)); } diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 052a6871..8698c231 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -78,7 +78,7 @@ stat_t cm_arc_callback() if (arc.run_state == BLOCK_INACTIVE) { return (STAT_NOOP); } - if (mp_planner_is_full()) { + if (mp_planner_is_full(ACTIVE_Q)) { return (STAT_EAGAIN); } arc.theta += arc.segment_theta; diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 6882ad9f..8ea3fef7 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -419,8 +419,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (5) - decelerated to zero // Update the run buffer then force a replan of the whole planner queue if (cm.hold_state == FEEDHOLD_DECEL_END) { - mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr.target, mr.position);// reset length //bf->entry_vmax = 0; // set bp+0 as hold point @@ -431,7 +431,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) mp_free_run_buffer(); } - mp_replan_queue(mb.r); // make it replan all the blocks + mp_replan_queue(mp_get_r(ACTIVE_Q)); // make it replan all the blocks +// mp_replan_queue(mb.r); // make it replan all the blocks return (STAT_OK); } @@ -560,7 +561,7 @@ stat_t mp_plan_feedhold_move() void mp_exit_hold_state() { cm.hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer()) { + if (mp_has_runnable_buffer(ACTIVE_Q)) { cm_set_motion_state(MOTION_RUN); sr_request_status_report(SR_REQUEST_IMMEDIATE); } else { diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 8a5c5031..27637acd 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -112,7 +112,9 @@ bool mp_get_runtime_busy() if (cm.cycle_state == CYCLE_OFF) { return (false); } - if ((st_runtime_isbusy() == true) || (mr.block_state == BLOCK_ACTIVE) || (mb.r->buffer_state > MP_BUFFER_EMPTY)) { + if ((st_runtime_isbusy() == true) || + (mr.block_state == BLOCK_ACTIVE) || + (mp_get_r(ACTIVE_Q)->buffer_state > MP_BUFFER_EMPTY)) { return (true); } return (false); diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 662d3fd8..7ef79bb4 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -65,8 +65,9 @@ #include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures -mpBufferPool_t mb; // buffer pool management -mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for pool #1 buffers +mpBufferQueue_t mb; // buffer pool management +mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +mpBuf_t mb_pool1[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers mpMotionPlannerSingleton_t mp; // context for block planning mpMotionRuntimeSingleton_t mr; // context for block runtime @@ -168,11 +169,13 @@ void planner_init_assertions() stat_t planner_test_assertions() { +/* +++++ Fix this if ((BAD_MAGIC(mb.magic_start)) || (BAD_MAGIC(mb.magic_end)) || (BAD_MAGIC(mp.magic_start)) || (BAD_MAGIC(mp.magic_end)) || (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end))) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } +*/ return (STAT_OK); } @@ -433,22 +436,27 @@ stat_t mp_exec_out_of_band_dwell(void) * mp_has_runnable_buffer() - true if next buffer is runnable, indicating motion has not stopped. * mp_is_it_phat_city_time() - test if there is time for non-essential processes */ -uint8_t mp_get_planner_buffers() +uint8_t mp_get_planner_buffers(int8_t q) // which queue are you interested in? { - return (mb.buffers_available); + if (q == ACTIVE_Q) { q = mb.active_q; }; + return (mb.q[q].buffers_available); } -bool mp_planner_is_full() +bool mp_planner_is_full(int8_t q) // which queue are you interested in? { - // We also need to ensure we have room for another JSON command - return ((mb.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0)); + if (q == ACTIVE_Q) { q = mb.active_q; }; + return ((mb.q[q].buffers_available < PLANNER_BUFFER_HEADROOM) + || (jc.available == 0)); // We also need to ensure we have room for another JSON command } -bool mp_has_runnable_buffer() +bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) { - return (mb.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true + if (q == ACTIVE_Q) { q = mb.active_q; }; + return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } + + bool mp_is_phat_city_time() { if(cm.hold_state == FEEDHOLD_HOLD) { @@ -494,7 +502,8 @@ bool mp_is_phat_city_time() stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state - if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state +//+++ if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state + if ((mp_get_planner_buffers(ACTIVE_Q) == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state (cm.motion_state == MOTION_STOP) && (cm.hold_state == FEEDHOLD_OFF)) { mp.planner_state = PLANNER_IDLE; @@ -512,11 +521,12 @@ stat_t mp_planner_callback() // Process a planner request or timeout if (mp.planner_state == PLANNER_IDLE) { - mp.p = mb.r; // initialize planner pointer to run buffer +//++++ mp.p = mb.r; // initialize planner pointer to run buffer + mp.p = mp_get_r(ACTIVE_Q); // initialize planner pointer to run buffer mp.planner_state = PLANNER_STARTUP; } if (mp.planner_state == PLANNER_STARTUP) { - if (!mp_planner_is_full() && !_timed_out) { + if (!mp_planner_is_full(ACTIVE_Q) && !_timed_out) { return (STAT_OK); // remain in STARTUP } mp.planner_state = PLANNER_PRIMING; @@ -534,15 +544,13 @@ stat_t mp_planner_callback() void mp_replan_queue(mpBuf_t *bf) { do { - if (bf->buffer_state >= MP_BUFFER_PLANNED) { - // revert from PLANNED state + if (bf->buffer_state >= MP_BUFFER_PLANNED) { // revert from PLANNED state bf->buffer_state = MP_BUFFER_PREPPED; - } else { - // If it's not "planned" then it's either PREPPED or earlier. - // We don't need to adjust it. - break; + } else { // If it's not "planned" then it's either PREPPED or earlier. + break; // We don't need to adjust it. } - } while ((bf = mp_get_next_buffer(bf)) != mb.r); + } while ((bf = mp_get_next_buffer(bf)) != mp_get_r(ACTIVE_Q)); +//+++ } while ((bf = mp_get_next_buffer(bf)) != mb.r); mp.request_planning = true; } @@ -599,14 +607,16 @@ void mp_end_feed_override(const float ramp_time) void mp_planner_time_accounting() { - mpBuf_t *bf = mb.r; // start with run buffer +//+++ mpBuf_t *bf = mb.r; // start with run buffer + mpBuf_t *bf = mp_get_r(ACTIVE_Q); // start with run buffer // check the run buffer to see if anything is running. Might not be if (bf->buffer_state != MP_BUFFER_RUNNING) { // this is not an error condition return; } mp.plannable_time = 0; //UPDATE_BF_MS(bf); //+++++ - while ((bf = bf->nx) != mb.r) { +//+++ while ((bf = bf->nx) != mb.r) { + while ((bf = bf->nx) != mp_get_r(ACTIVE_Q)) { if (bf->buffer_state == MP_BUFFER_EMPTY || bf->plannable == true) { break; } @@ -701,53 +711,71 @@ static inline void _clear_buffer(mpBuf_t *bf) bf->clear(); } -void _init_buffer_pool(mpBuf_t *base, uint8_t size) +void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; + + memset(&mb.q[q], 0, sizeof(mpQueue_t)); // clear values, pointers and status + mb.q[q].magic_start = MAGICNUM; + mb.q[q].magic_end = MAGICNUM; - memset(base, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool - mb.bf = base; // link the buffer pool first - mb.w = mb.bf; // init all buffer pointers - mb.r = mb.bf; - mb.queue_size = size-1; - mb.buffers_available = size; + memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool + mb.q[q].bf = pool; // link the buffer pool first + mb.q[q].w = pool; // init all buffer pointers + mb.q[q].r = pool; + mb.q[q].queue_size = size-1; + mb.q[q].buffers_available = size; - pv = &mb.bf[size-1]; + pv = &mb.q[q].bf[size-1]; for (i=0; i < size-1; i++) { - mb.bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) + mb.q[q].bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) nx_i = ((ipv); } mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } -*/ + */ + +mpBuf_t * mp_get_w(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].w : mb.q[q].w); } +mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : mb.q[q].r); } mpBuf_t * mp_get_write_buffer() // get & clear a buffer { + mpBuf_t *w = mb.q[mb.active_q].w; + mpQueue_t *q = &mb.q[mb.active_q]; + + if (q->w->buffer_state == MP_BUFFER_EMPTY) { + _clear_buffer(w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer + w->buffer_state = MP_BUFFER_INITIALIZING; + mb.q[mb.active_q].buffers_available--; + + return (mp_get_w(ACTIVE_Q)); + } + // The no buffer condition always causes a panic - invoked by the caller + rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); + return (NULL); +/* if (mb.w->buffer_state == MP_BUFFER_EMPTY) { _clear_buffer(mb.w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer mb.w->buffer_state = MP_BUFFER_INITIALIZING; @@ -758,14 +786,23 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer // The no buffer condition always causes a panic - invoked by the caller rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); return (NULL); +*/ } void mp_unget_write_buffer() // mark buffer as empty and adjust free buffer count { + mpBuf_t *w = mb.q[mb.active_q].w; + + if (w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer + w->buffer_state = MP_BUFFER_EMPTY; + mb.q[mb.active_q].buffers_available++; + } +/* if (mb.w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer mb.w->buffer_state = MP_BUFFER_EMPTY; mb.buffers_available++; } +*/ } /*** WARNING *** @@ -775,6 +812,28 @@ void mp_unget_write_buffer() // mark buffer as empty and adjust free buff void mp_commit_write_buffer(const blockType block_type) { + mpBuf_t *w = mb.q[mb.active_q].w; + + w->block_type = block_type; + w->block_state = BLOCK_INITIAL_ACTION; + + if (block_type == BLOCK_TYPE_ALINE) { + if (cm.motion_state == MOTION_STOP) { + cm_set_motion_state(MOTION_PLANNING); + } + } else { + if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { + // NB: BEWARE! the exec may result in the planner buffer being + // processed IMMEDIATELY and then freed - invalidating the contents + st_request_plan_move(); // request an exec if the runtime is not busy + } + } + w->plannable = true; // enable block for planning + mp.request_planning = true; + mb.q[mb.active_q].w = w->nx; // advance write buffer pointer + mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer + qr_request_queue_report(+1); // request QR and add to "added buffers" count +/* mb.w->block_type = block_type; mb.w->block_state = BLOCK_INITIAL_ACTION; @@ -782,7 +841,7 @@ void mp_commit_write_buffer(const blockType block_type) if (cm.motion_state == MOTION_STOP) { cm_set_motion_state(MOTION_PLANNING); } - } else { + } else { if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { // NB: BEWARE! the exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents @@ -794,11 +853,25 @@ void mp_commit_write_buffer(const blockType block_type) mb.w = mb.w->nx; // advance write buffer pointer mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer qr_request_queue_report(+1); // request QR and add to "added buffers" count + +*/ } // Note: mp_get_run_buffer() is only called by mp_exec_move(), which is inside an interrupt mpBuf_t * mp_get_run_buffer() { + mpBuf_t *r = mb.q[mb.active_q].r; + + // EMPTY is the one case where nothing is returned. This is not an error + if (r->buffer_state == MP_BUFFER_EMPTY) { + return (NULL); + } + // Otherwise return the buffer. Let mp_exec_move() manage the state machine to sort out: + // (1) is the the first time the run buffer has been retrieved? + // (2) is the buffer in error - i.e. not yet ready for running? + return (r); +} +/* // EMPTY is the one case where nothing is returned. This is not an error if (mb.r->buffer_state == MP_BUFFER_EMPTY) { return (NULL); @@ -808,12 +881,23 @@ mpBuf_t * mp_get_run_buffer() // (2) is the buffer in error - i.e. not yet ready for running? return (mb.r); } - +*/ // Note: mp_free_run_buffer() is only called from mp_exec_XXX, which are within an interrupt bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { - _audit_buffers(); // diagnostic audit for buffer chain integrity (only runs in DEBUG mode) + mpBuf_t *r = mb.q[mb.active_q].r; +// _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) + + mb.q[mb.active_q].r = r->nx; // advance to next run buffer + _clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) + + mb.q[mb.active_q].buffers_available++; + qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count + return (mb.q[mb.active_q].w == mb.q[mb.active_q].r); // return true if the queue emptied + +/* + return (mb.w == mb.r); // return true if the queue emptied mpBuf_t *r = mb.r; mb.r = mb.r->nx; // advance to next run buffer _clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) @@ -821,6 +905,7 @@ bool mp_free_run_buffer() // EMPTY current run buffer & advance to the mb.buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count return (mb.w == mb.r); // return true if the queue emptied +*/ } /* UNUSED FUNCTIONS - left in for completeness and for reference diff --git a/g2core/planner.h b/g2core/planner.h index f817480c..40035985 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -124,8 +124,8 @@ typedef enum { /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 -#define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line #define SECONDARY_BUFFER_POOL_SIZE ((uint8_t)4) // Secondary planner queue for feedhold operations +#define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line #define JERK_MULTIPLIER ((float)1000000) // DO NOT CHANGE - must always be 1 million #define JUNCTION_INTEGRATION_MIN (0.05) // minimum allowable setting @@ -172,6 +172,11 @@ typedef enum { //#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; } #define UPDATE_MP_DIAGNOSTICS { mp.plannable_time_ms = mp.plannable_time*60000; } +// Define which queue you are interested in for input args +#define PRIMARY_Q 0 +#define SECONDARY_Q 1 +#define ACTIVE_Q -1 + /* * Planner structures */ @@ -243,17 +248,20 @@ typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging } mpBuf_t; -typedef struct mpBufferPool { // one or more planner buffer queues +typedef struct mpQueue { // a planner buffer queue magic_t magic_start; // magic number to test memory integrity - mpBuf_t *r; // run buffer pointer mpBuf_t *w; // write buffer pointer uint8_t queue_size; // total number of buffers, zero-based (e.g. 47 not 48) - uint8_t buffers_available; // running count of available buffers + uint8_t buffers_available; // running count of available buffers in queue mpBuf_t *bf; // pointer to buffer storage array - magic_t magic_end; -} mpBufferPool_t; +} mpQueue_t; + +typedef struct mpBufferQueue { // one or more planner buffer queues + uint8_t active_q; // index of currently active queue + mpQueue_t q[2]; // number of queues +} mpBufferQueue_t; typedef struct mpMotionPlannerSingleton { // common variables for planning (move master) magic_t magic_start; // magic number to test memory integrity @@ -350,7 +358,7 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables } mpMotionRuntimeSingleton_t; // Reference global scope structures -extern mpBufferPool_t mb; // buffer pool management +extern mpBufferQueue_t mb; // planner buffer queue management extern mpMotionPlannerSingleton_t mp; // context for block planning extern mpMotionRuntimeSingleton_t mr; // context for block runtime @@ -383,9 +391,9 @@ void mp_request_out_of_band_dwell(float seconds); stat_t mp_exec_out_of_band_dwell(void); // planner functions and helpers -uint8_t mp_get_planner_buffers(void); -bool mp_planner_is_full(void); -bool mp_has_runnable_buffer(void); +uint8_t mp_get_planner_buffers(int8_t q); +bool mp_planner_is_full(int8_t q); +bool mp_has_runnable_buffer(int8_t q); bool mp_is_phat_city_time(void); stat_t mp_planner_callback(); @@ -396,6 +404,8 @@ void mp_planner_time_accounting(void); // planner buffer primitives void mp_init_buffers(void); +mpBuf_t * mp_get_w(int8_t q); +mpBuf_t * mp_get_r(int8_t q); //mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf); // Use the following macro instead //mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf); // Use the following macro instead diff --git a/g2core/report.cpp b/g2core/report.cpp index e7fca4eb..7b42cb59 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -491,7 +491,7 @@ void qr_init_queue_report() void qr_request_queue_report(int8_t buffers) { // get buffer depth and added/removed count - qr.buffers_available = mp_get_planner_buffers(); + qr.buffers_available = mp_get_planner_buffers(ACTIVE_Q); if (buffers > 0) { qr.buffers_added += buffers; } else { @@ -574,7 +574,7 @@ stat_t qr_queue_report_callback() // called by controller dispatcher */ stat_t qr_get(nvObj_t *nv) { - nv->value = (float)mp_get_planner_buffers(); // ensure that manually requested QR count is always up to date + nv->value = (float)mp_get_planner_buffers(ACTIVE_Q); // ensure that manually requested QR count is always up to date nv->valuetype = TYPE_INT; return (STAT_OK); } From 7795c3d70f123993332d83e0986e10f043e80e43 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 5 Dec 2016 16:23:15 -0500 Subject: [PATCH 007/283] Some cleanup and testing --- g2core/planner.cpp | 162 +++++++++++++-------------------------------- g2core/planner.h | 11 +-- 2 files changed, 53 insertions(+), 120 deletions(-) diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 7ef79bb4..04714315 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -169,13 +169,14 @@ void planner_init_assertions() stat_t planner_test_assertions() { -/* +++++ Fix this - if ((BAD_MAGIC(mb.magic_start)) || (BAD_MAGIC(mb.magic_end)) || + if ( +// (BAD_MAGIC(mb.q[0].magic_start)) || (BAD_MAGIC(mb.q[0].magic_end)) || // kind of a hack +// (BAD_MAGIC(mb.q[1].magic_start)) || (BAD_MAGIC(mb.q[1].magic_end)) || // this one, too (BAD_MAGIC(mp.magic_start)) || (BAD_MAGIC(mp.magic_end)) || - (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end))) { + (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end)) + ) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } -*/ return (STAT_OK); } @@ -455,8 +456,6 @@ bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } - - bool mp_is_phat_city_time() { if(cm.hold_state == FEEDHOLD_HOLD) { @@ -502,7 +501,6 @@ bool mp_is_phat_city_time() stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state -//+++ if ((mb.buffers_available == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state if ((mp_get_planner_buffers(ACTIVE_Q) == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state (cm.motion_state == MOTION_STOP) && (cm.hold_state == FEEDHOLD_OFF)) { @@ -521,7 +519,6 @@ stat_t mp_planner_callback() // Process a planner request or timeout if (mp.planner_state == PLANNER_IDLE) { -//++++ mp.p = mb.r; // initialize planner pointer to run buffer mp.p = mp_get_r(ACTIVE_Q); // initialize planner pointer to run buffer mp.planner_state = PLANNER_STARTUP; } @@ -550,7 +547,6 @@ void mp_replan_queue(mpBuf_t *bf) break; // We don't need to adjust it. } } while ((bf = mp_get_next_buffer(bf)) != mp_get_r(ACTIVE_Q)); -//+++ } while ((bf = mp_get_next_buffer(bf)) != mb.r); mp.request_planning = true; } @@ -607,7 +603,6 @@ void mp_end_feed_override(const float ramp_time) void mp_planner_time_accounting() { -//+++ mpBuf_t *bf = mb.r; // start with run buffer mpBuf_t *bf = mp_get_r(ACTIVE_Q); // start with run buffer // check the run buffer to see if anything is running. Might not be @@ -615,7 +610,6 @@ void mp_planner_time_accounting() return; } mp.plannable_time = 0; //UPDATE_BF_MS(bf); //+++++ -//+++ while ((bf = bf->nx) != mb.r) { while ((bf = bf->nx) != mp_get_r(ACTIVE_Q)) { if (bf->buffer_state == MP_BUFFER_EMPTY || bf->plannable == true) { break; @@ -715,36 +709,36 @@ void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; - - memset(&mb.q[q], 0, sizeof(mpQueue_t)); // clear values, pointers and status - mb.q[q].magic_start = MAGICNUM; - mb.q[q].magic_end = MAGICNUM; + mpQueue_t *b = &mb.q[q]; + + memset(b, 0, sizeof(mpQueue_t)); // clear values, pointers and status + b->magic_start = MAGICNUM; + b->magic_end = MAGICNUM; memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool - mb.q[q].bf = pool; // link the buffer pool first - mb.q[q].w = pool; // init all buffer pointers - mb.q[q].r = pool; - mb.q[q].queue_size = size-1; - mb.q[q].buffers_available = size; + b->bf = pool; // link the buffer pool first + b->w = pool; // init all buffer pointers + b->r = pool; + b->queue_size = size-1; + b->buffers_available = size; - pv = &mb.q[q].bf[size-1]; + pv = &b->bf[size-1]; for (i=0; i < size-1; i++) { - mb.q[q].bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) + b->bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) nx_i = ((ibf[nx_i]; + b->bf[i].nx = nx; // setup circular list pointers + b->bf[i].pv = pv; + pv = &b->bf[i]; } } void mp_init_buffers(void) { _init_planner_queue(0, mb_pool0, PLANNER_BUFFER_POOL_SIZE); -// _init_planner_queue(1, mb_pool1, SECONDARY_BUFFER_POOL_SIZE); + _init_planner_queue(1, mb_pool1, SECONDARY_BUFFER_POOL_SIZE); - // Now handle the two "stub blocks" in the runtime structure. - mr.bf[0].nx = &mr.bf[1]; + mr.bf[0].nx = &mr.bf[1]; // Now handle the two "stub blocks" in the runtime structure. mr.bf[1].nx = &mr.bf[0]; mr.r = &mr.bf[0]; mr.p = &mr.bf[1]; @@ -762,47 +756,27 @@ mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : m mpBuf_t * mp_get_write_buffer() // get & clear a buffer { - mpBuf_t *w = mb.q[mb.active_q].w; mpQueue_t *q = &mb.q[mb.active_q]; if (q->w->buffer_state == MP_BUFFER_EMPTY) { - _clear_buffer(w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer - w->buffer_state = MP_BUFFER_INITIALIZING; - mb.q[mb.active_q].buffers_available--; - + _clear_buffer(q->w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer + q->w->buffer_state = MP_BUFFER_INITIALIZING; + q->buffers_available--; return (mp_get_w(ACTIVE_Q)); } // The no buffer condition always causes a panic - invoked by the caller rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); return (NULL); -/* - if (mb.w->buffer_state == MP_BUFFER_EMPTY) { - _clear_buffer(mb.w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer - mb.w->buffer_state = MP_BUFFER_INITIALIZING; - mb.buffers_available--; - - return (mb.w); - } - // The no buffer condition always causes a panic - invoked by the caller - rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); - return (NULL); -*/ } void mp_unget_write_buffer() // mark buffer as empty and adjust free buffer count { - mpBuf_t *w = mb.q[mb.active_q].w; + mpQueue_t *q = &mb.q[mb.active_q]; - if (w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer - w->buffer_state = MP_BUFFER_EMPTY; - mb.q[mb.active_q].buffers_available++; + if (q->w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer + q->w->buffer_state = MP_BUFFER_EMPTY; + q->buffers_available++; } -/* - if (mb.w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer - mb.w->buffer_state = MP_BUFFER_EMPTY; - mb.buffers_available++; - } -*/ } /*** WARNING *** @@ -812,10 +786,10 @@ void mp_unget_write_buffer() // mark buffer as empty and adjust free buff void mp_commit_write_buffer(const blockType block_type) { - mpBuf_t *w = mb.q[mb.active_q].w; + mpQueue_t *q = &mb.q[mb.active_q]; - w->block_type = block_type; - w->block_state = BLOCK_INITIAL_ACTION; + q->w->block_type = block_type; + q->w->block_state = BLOCK_INITIAL_ACTION; if (block_type == BLOCK_TYPE_ALINE) { if (cm.motion_state == MOTION_STOP) { @@ -828,90 +802,48 @@ void mp_commit_write_buffer(const blockType block_type) st_request_plan_move(); // request an exec if the runtime is not busy } } - w->plannable = true; // enable block for planning + q->w->plannable = true; // enable block for planning mp.request_planning = true; - mb.q[mb.active_q].w = w->nx; // advance write buffer pointer + q->w = q->w->nx; // advance write buffer pointer mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer qr_request_queue_report(+1); // request QR and add to "added buffers" count -/* - mb.w->block_type = block_type; - mb.w->block_state = BLOCK_INITIAL_ACTION; - - if (block_type == BLOCK_TYPE_ALINE) { - if (cm.motion_state == MOTION_STOP) { - cm_set_motion_state(MOTION_PLANNING); - } - } else { - if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { - // NB: BEWARE! the exec may result in the planner buffer being - // processed IMMEDIATELY and then freed - invalidating the contents - st_request_plan_move(); // request an exec if the runtime is not busy - } - } - mb.w->plannable = true; // enable block for planning - mp.request_planning = true; - mb.w = mb.w->nx; // advance write buffer pointer - mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer - qr_request_queue_report(+1); // request QR and add to "added buffers" count - -*/ } // Note: mp_get_run_buffer() is only called by mp_exec_move(), which is inside an interrupt +// EMPTY is the one case where nothing is returned. This is not an error +// Otherwise return the buffer. Let mp_exec_move() manage the state machine to sort out: +// (1) is the the first time the run buffer has been retrieved? +// (2) is the buffer in error - i.e. not yet ready for running? mpBuf_t * mp_get_run_buffer() { mpBuf_t *r = mb.q[mb.active_q].r; - // EMPTY is the one case where nothing is returned. This is not an error if (r->buffer_state == MP_BUFFER_EMPTY) { return (NULL); } - // Otherwise return the buffer. Let mp_exec_move() manage the state machine to sort out: - // (1) is the the first time the run buffer has been retrieved? - // (2) is the buffer in error - i.e. not yet ready for running? return (r); } -/* - // EMPTY is the one case where nothing is returned. This is not an error - if (mb.r->buffer_state == MP_BUFFER_EMPTY) { - return (NULL); - } - // Otherwise return the buffer. Let mp_exec_move() manage the state machine to sort out: - // (1) is the the first time the run buffer has been retrieved? - // (2) is the buffer in error - i.e. not yet ready for running? - return (mb.r); -} -*/ + // Note: mp_free_run_buffer() is only called from mp_exec_XXX, which are within an interrupt bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { - mpBuf_t *r = mb.q[mb.active_q].r; + mpQueue_t *q = &mb.q[mb.active_q]; -// _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) + _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) - mb.q[mb.active_q].r = r->nx; // advance to next run buffer - _clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) + q->r = q->r->nx; // advance to next run buffer + _clear_buffer(q->r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) - mb.q[mb.active_q].buffers_available++; + q->buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count - return (mb.q[mb.active_q].w == mb.q[mb.active_q].r); // return true if the queue emptied + return (q->w == q->r); // return true if the queue emptied -/* - return (mb.w == mb.r); // return true if the queue emptied - mpBuf_t *r = mb.r; - mb.r = mb.r->nx; // advance to next run buffer - _clear_buffer(r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) - - mb.buffers_available++; - qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count - return (mb.w == mb.r); // return true if the queue emptied -*/ } /* UNUSED FUNCTIONS - left in for completeness and for reference void mp_copy_buffer(mpBuf_t *bf, const mpBuf_t *bp) { - // copy contents of bp to by while preserving pointers in bp + // copy contents of bp to bf while preserving pointers in bp memcpy((void *)(&bf->bf_func), (&bp->bf_func), sizeof(mpBuf_t) - (sizeof(void *) * 2)); } */ diff --git a/g2core/planner.h b/g2core/planner.h index 40035985..471e4940 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -121,6 +121,12 @@ typedef enum { ZOID_EXIT_3a2 } zoidExitPoint; +typedef enum { + ACTIVE_Q = -1, // Must be -1 + PRIMARY_Q, // must line up with structure indexes + SECONDARY_Q +} queueType; + /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 @@ -172,11 +178,6 @@ typedef enum { //#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; } #define UPDATE_MP_DIAGNOSTICS { mp.plannable_time_ms = mp.plannable_time*60000; } -// Define which queue you are interested in for input args -#define PRIMARY_Q 0 -#define SECONDARY_Q 1 -#define ACTIVE_Q -1 - /* * Planner structures */ From 3999533a8bb613349674cfc8c89257991cb6eab8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 8 Dec 2016 07:58:30 -0500 Subject: [PATCH 008/283] Updated AS7 project file for SAM3x part and a different programmer (Editorial gripe: The part and tool selections really should not be in the project file - but the .atsuo file which can be kept local, but we have no control over this. Maybe someone at Atmel/Microchip). --- g2core/g2core.cppproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index f6402809..4669f074 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -5,7 +5,7 @@ 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAMS70N19 + ATSAM3X8C none Executable CPP @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800030015 Atmel-ICE True @@ -100,8 +100,8 @@ True true - J41800019454 - 0xA11D0A00 + J41800030015 + 0x284E0A60 2000000 From dd0ff106ca5b34cfff3c91fd9c53480c4e633276 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 8 Dec 2016 12:27:29 -0500 Subject: [PATCH 009/283] Fixed a couple of stupid bugs in new buffer management; Set make block profile to default to 2 USB ports --- g2core/planner.cpp | 51 +++++----------------- g2core/planner.h | 11 +++-- g2core/settings/settings_default.h | 17 ++++---- g2core/settings/settings_makeblock.h | 65 ++++++++++++++-------------- 4 files changed, 56 insertions(+), 88 deletions(-) mode change 100755 => 100644 g2core/settings/settings_default.h diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 0f17ef13..942c7ec3 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -672,7 +672,7 @@ void mp_planner_time_accounting() * Functions Provided: * _clear_buffer(bf) Zero the contents of a buffer * - * mp_init_buffers() Initialize or reset buffers + * mp_init_buffers() Initialize and reset buffers in all planner queues * * mp_get_prev_buffer(bf) Return pointer to the previous buffer in the linked list * mp_get_next_buffer(bf) Return pointer to the next buffer in the linked list @@ -706,13 +706,10 @@ void mp_planner_time_accounting() // Also clears unlocked, so the buffer cannot be used static inline void _clear_buffer(mpBuf_t *bf) { - // Note: bf->bf_func is the first address we wish to clear as we must preserve - // the pointers and buffer number during interrupts - - // We'll have to figure something else out for C, sorry. - bf->reset(); -} + bf->reset(); // Call a reset method on the buffer object. +} // We'll need something else for C - like bring the method code back into this function. +// initialize a single planner queue void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size) { mpBuf_t *pv, *nx; @@ -731,37 +728,15 @@ void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size) b->buffers_available = size; pv = &b->bf[size-1]; - for (i=0; i < size-1; i++) { + for (i=0; i < size; i++) { b->bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) nx_i = ((ibf[nx_i]; b->bf[i].nx = nx; // setup circular list pointers b->bf[i].pv = pv; pv = &b->bf[i]; - -/*======= - - //memset(&mb, 0, sizeof(mb)); // clear all values, pointers and status - mb.magic_start = MAGICNUM; - mb.magic_end = MAGICNUM; - - mb.w = &mb.bf[0]; // init all buffer pointers - mb.r = &mb.bf[0]; - pv = &mb.bf[PLANNER_BUFFER_POOL_SIZE-1]; - for (uint8_t i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { - _clear_buffer(&mb.bf[i]); - uint8_t nx_i = ((i<(PLANNER_BUFFER_POOL_SIZE-1))?(i+1):0); // buffer incr & wrap - - mb.bf[i].buffer_number = i; //+++++ number it for diagnostics only (otherwise not used) - - nx = &mb.bf[nx_i]; - mb.bf[i].nx = nx; // setup ring pointers - mb.bf[i].pv = pv; - - pv = &mb.bf[i]; ->>refs/heads/dev-168-gquadratic -*/ } + b->bf[size-1].nx = pool; } void mp_init_buffers(void) @@ -777,7 +752,6 @@ void mp_init_buffers(void) /* * These GET functions are defined here but we use the macros in planner.h instead - * mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); } mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } */ @@ -828,9 +802,8 @@ void mp_commit_write_buffer(const blockType block_type) } } else { if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { - // NB: BEWARE! the exec may result in the planner buffer being + // NB: BEWARE! the requested exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents -// st_request_plan_move(); // ++++ request an exec if the runtime is not busy st_request_forward_plan(); // request an exec if the runtime is not busy } } @@ -860,16 +833,16 @@ mpBuf_t * mp_get_run_buffer() bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { mpQueue_t *q = &mb.q[mb.active_q]; - + mpBuf_t *r_now = q->r; // this is to avoid a race condition when clearing the buffer + _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) q->r = q->r->nx; // advance to next run buffer - _clear_buffer(q->r); // clear it out (& reset unlocked and set MP_BUFFER_EMPTY) + _clear_buffer(r_now); // clear out the old buffer (& reset unlocked and set MP_BUFFER_EMPTY) q->buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count return (q->w == q->r); // return true if the queue emptied - } /* UNUSED FUNCTIONS - left in for completeness and for reference @@ -926,8 +899,6 @@ void mp_dump_planner(mpBuf_t *bf_start) // starting at bf #warning DEBUG TRAPS ENABLED -#pragma GCC optimize ("O0") - //static void _planner_report(const char *msg) //{ // rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, msg); @@ -1030,8 +1001,6 @@ static void _audit_buffers() __enable_irq(); } -#pragma GCC reset_options - #else static void _audit_buffers() diff --git a/g2core/planner.h b/g2core/planner.h index 2766af71..42e5a274 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -308,7 +308,6 @@ typedef enum { */ struct mpBuffer_to_clear { - // Note: _clear_buffer() zeros all data from this point down stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function cm_exec_t cm_func; // callback to canonical machine execution function @@ -336,10 +335,9 @@ struct mpBuffer_to_clear { float block_time; // computed move time for entire block (move) float override_factor; // feed rate or rapid override factor for this block ("override" is a reserved word) - // We are removing all entry_* values. - // To get the entry_* values, look at pv->exit_* or mr.exit_* - // *** SEE NOTES ON THESE VARIABLES, in aline() *** + // We removed all entry_* values. + // To get the entry_* values, look at pv->exit_* or mr.exit_* float cruise_velocity; // cruise velocity requested & achieved float exit_velocity; // exit velocity requested for the move // is also the entry velocity of the *next* move @@ -361,9 +359,10 @@ struct mpBuffer_to_clear { GCodeState_t gm; // Gcode model state - passed from model, used by planner and runtime + // cleasr the above structure void reset() { - //memset((void *)(this), 0, sizeof(mpBuffer_to_clear)); - + //memset((void *)(this), 0, sizeof(mpBuffer_to_clear)); // slower on the M3. Test for M7 + bf_func = nullptr; cm_func = nullptr; diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h old mode 100755 new mode 100644 index e0566ae7..3512f0b7 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -58,11 +58,6 @@ // *** Machine configuration settings *** // -#ifndef USB_SERIAL_PORTS_EXPOSED -#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! -#endif - - #ifndef JUNCTION_INTEGRATION_TIME #define JUNCTION_INTEGRATION_TIME 0.75 // {jt: cornering - between 0.05 and 2.00 (max) #endif @@ -129,16 +124,20 @@ // *** Communications and Reporting Settings *** // -#ifndef TEXT_VERBOSITY -#define TEXT_VERBOSITY TV_VERBOSE // {tv: TV_SILENT, TV_VERBOSE +#ifndef USB_SERIAL_PORTS_EXPOSED +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! +#endif + +#ifndef XIO_ENABLE_FLOW_CONTROL +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // {ex: FLOW_CONTROL_OFF, FLOW_CONTROL_XON, FLOW_CONTROL_RTS #endif #ifndef COMM_MODE #define COMM_MODE JSON_MODE // {ej: TEXT_MODE, JSON_MODE #endif -#ifndef XIO_ENABLE_FLOW_CONTROL -#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_XON, FLOW_CONTROL_RTS +#ifndef TEXT_VERBOSITY +#define TEXT_VERBOSITY TV_VERBOSE // {tv: TV_SILENT, TV_VERBOSE #endif #ifndef JSON_VERBOSITY diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 650c3603..02ac216b 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -34,24 +34,25 @@ // Machine configuration settings -#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) -#define CHORDAL_TOLERANCE 0.1 // chordal tolerance for arcs (in mm) +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.1 // chordal tolerance for arcs (in mm) -#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on -#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high -#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high #define SPINDLE_PAUSE_ON_HOLD true #define SPINDLE_DWELL_TIME 1.0 -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high #define COOLANT_PAUSE_ON_HOLD false // Communications and reporting settings +#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE @@ -59,8 +60,8 @@ #define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE #define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum -#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable //#define STATUS_REPORT_DEFAULTS //"line","posx","posy","posz","posa","bcr","feed","vel","unit","coor","dist","admo","frmo","momo","stat" @@ -81,14 +82,14 @@ // *** motor settings ************************************************************************************ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 36.576 // 1tr 2.032mm pitch * 18 teeth per revolution -#define M1_MICROSTEPS 8 // 1mi 1,2,4,8 -#define M1_POLARITY 0 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 36.576 // 1tr 2.032mm pitch * 18 teeth per revolution +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8 +#define M1_POLARITY 0 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled #define M1_POWER_LEVEL 0.4 #define M2_MOTOR_MAP AXIS_Y @@ -99,7 +100,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.4 -#define M3_MOTOR_MAP AXIS_Z // Imaginary Z axis. FOr testing +#define M3_MOTOR_MAP AXIS_Z // Imaginary Z axis. For testing #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 1.25 #define M3_MICROSTEPS 8 @@ -111,19 +112,19 @@ #define JERK_MAX 5000 -#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX 40000 // xvm G0 max velocity in mm/min -#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min -#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits -#define X_TRAVEL_MAX 420 // xtm travel between switches or crashes -#define X_JERK_MAX JERK_MAX // xjm jerk * 1,000,000 -#define X_JERK_HIGH_SPEED 20000 // xjh -#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable -#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive -#define X_SEARCH_VELOCITY 3000 // xsv minus means move to minimum switch -#define X_LATCH_VELOCITY 100 // xlv mm/min -#define X_LATCH_BACKOFF 4 // xlb mm -#define X_ZERO_BACKOFF 2 // xzb mm +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX 40000 // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits +#define X_TRAVEL_MAX 420 // xtm travel between switches or crashes +#define X_JERK_MAX JERK_MAX // xjm jerk * 1,000,000 +#define X_JERK_HIGH_SPEED 20000 // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY 3000 // xsv minus means move to minimum switch +#define X_LATCH_VELOCITY 100 // xlv mm/min +#define X_LATCH_BACKOFF 4 // xlb mm +#define X_ZERO_BACKOFF 2 // xzb mm #define Y_AXIS_MODE AXIS_STANDARD #define Y_VELOCITY_MAX 40000 From e934cfda8e112d9e741c4a57b1f1ad29bbf5b180 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 8 Dec 2016 14:28:52 -0500 Subject: [PATCH 010/283] added switch and return functions --- g2core/config_app.cpp | 36 +++++++++++++++++++----------------- g2core/planner.cpp | 30 +++++++++++++++++++++++++----- g2core/planner.h | 4 ++++ 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 9ddff796..ed913244 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -655,23 +655,25 @@ const cfgItem_t cfgArray[] = { { "", "gc", _f0, 0, tx_print_nul, gc_get_gc,gc_run_gc,(float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports - { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports - { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available - { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue - { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue - { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing - { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush - { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets - { "", "msg", _f0, 0, tx_print_str, get_nul, set_nul, (float *)&cs.null, 0 }, // string for generic messages - { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm - { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic - { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown - { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state - { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" - { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic - { "", "tram", _f0,0, cm_print_tram, cm_get_tram, cm_set_tram, (float *)&cs.null, 0 },// SET to attempt setting rotation matrix from probes - { "", "defa",_f0, 0, tx_print_nul, help_defa, set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen - { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, + { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports + { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available + { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue + { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue + { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing + { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush + { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets + { "", "msg", _f0, 0, tx_print_str, get_nul, set_nul, (float *)&cs.null, 0 }, // string for generic messages + { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm + { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic + { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown + { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state + { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" + { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic + { "", "tram", _f0,0, cm_print_tram, cm_get_tram,cm_set_tram, (float *)&cs.null, 0 },// SET to attempt setting rotation matrix from probes + { "", "defa",_f0, 0, tx_print_nul, help_defa, set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen + { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, + { "", "switch",_f0,0, tx_print_nul, get_nul, mp_switch_q, (float *)&cs.null,0 }, + { "", "return",_f0,0, tx_print_nul, get_nul, mp_return_q, (float *)&cs.null,0 }, #ifdef __HELP_SCREENS { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 942c7ec3..eef111ac 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -627,6 +627,26 @@ void mp_planner_time_accounting() UPDATE_MP_DIAGNOSTICS //+++++ } +/* + * mp_switch_q() - switch planner to different quue + * mp_return_q() - return from a planner queue switch + */ +stat_t mp_switch_q(nvObj_t *nv) +{ + if ((nv->value < PRIMARY_Q) || (nv->value < SECONDARY_Q)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + mb.return_q = mb.active_q; + mb.active_q = (uint8_t)nv->value; + return (STAT_OK); +} + +stat_t mp_return_q(nvObj_t *nv) // if value == true return with offset corrections +{ + mb.active_q = mb.return_q; + return (STAT_OK); +} + /**** PLANNER BUFFER PRIMITIVES ************************************************************ * * Planner buffers are used to queue and operate on Gcode blocks. Each buffer contains @@ -830,16 +850,16 @@ mpBuf_t * mp_get_run_buffer() } // Note: mp_free_run_buffer() is only called from mp_exec_XXX, which are within an interrupt +// Clearing and advancing must be done atomically as other interrupts may be using the run buffer bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { mpQueue_t *q = &mb.q[mb.active_q]; - mpBuf_t *r_now = q->r; // this is to avoid a race condition when clearing the buffer - + mpBuf_t *r_now = q->r; // save this pointer is to avoid a race condition when clearing the buffer + _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) - q->r = q->r->nx; // advance to next run buffer - _clear_buffer(r_now); // clear out the old buffer (& reset unlocked and set MP_BUFFER_EMPTY) - + q->r = q->r->nx; // advance to next run buffer first, + _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) q->buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count return (q->w == q->r); // return true if the queue emptied diff --git a/g2core/planner.h b/g2core/planner.h index 42e5a274..2192bbe5 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -423,6 +423,7 @@ typedef struct mpQueue { // a planner buffer queue typedef struct mpBufferQueue { // one or more planner buffer queues uint8_t active_q; // index of currently active queue + uint8_t return_q; // index of queue to return to mpQueue_t q[2]; // number of queues } mpBufferQueue_t; @@ -565,6 +566,9 @@ void mp_start_feed_override(const float ramp_time, const float override); void mp_end_feed_override(const float ramp_time); void mp_planner_time_accounting(void); +stat_t mp_switch_q(nvObj_t *nv); +stat_t mp_return_q(nvObj_t *nv); + // planner buffer primitives void mp_init_buffers(void); mpBuf_t * mp_get_w(int8_t q); From 58a615358fc460feb751522983c934d57eda4ccd Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 8 Dec 2016 14:33:33 -0500 Subject: [PATCH 011/283] Minor prep --- g2core/canonical_machine.cpp | 2 +- g2core/canonical_machine.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) mode change 100755 => 100644 g2core/canonical_machine.h diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 3899ed89..c285d9af 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -112,7 +112,7 @@ **** STRUCTURE ALLOCATIONS ******************************************************** ***********************************************************************************/ -cmSingleton_t cm; // canonical machine controller singleton +cmMachine_t cm; // canonical machine master structure /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h old mode 100755 new mode 100644 index 509df9d4..ee699091 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -497,7 +497,6 @@ typedef struct cmAxis { float travel_min; // min work envelope for soft limits float jerk_max; // max jerk (Jm) in mm/min^3 divided by 1 million float jerk_high; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million - //float recip_jerk; // stored reciprocal of current jerk value - has the million in it float max_junction_accel; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million float junction_dev; // aka cornering delta -- DEPRICATED! float radius; // radius in mm for rotary axis modes @@ -579,11 +578,11 @@ typedef struct cmSingleton { // struct to manage cm globals and c GCodeFlags_t gf; // gcode input flags - transient magic_t magic_end; -} cmSingleton_t; +} cmMachine_t; /**** Externs - See canonical_machine.c for allocation ****/ -extern cmSingleton_t cm; // canonical machine controller singleton +extern cmMachine_t cm; // canonical machine controller singleton /***************************************************************************** * FUNCTION PROTOTYPES From a4330f42ccab26c65b3b2dbede7689193ee24f89 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 07:41:31 -0500 Subject: [PATCH 012/283] Intermediate commit - changing canonical machine struct to work by pointer - not absolute. Compiles. Does not run. --- g2core/canonical_machine.cpp | 520 ++++++++++++++++++----------------- g2core/canonical_machine.h | 27 +- g2core/config_app.cpp | 346 +++++++++++------------ g2core/controller.cpp | 26 +- g2core/cycle_homing.cpp | 108 ++++---- g2core/cycle_jogging.cpp | 18 +- g2core/cycle_probing.cpp | 68 ++--- g2core/gcode_parser.cpp | 76 ++--- g2core/gpio.cpp | 8 +- g2core/json_parser.cpp | 4 +- g2core/kinematics.cpp | 6 +- g2core/main.cpp | 3 +- g2core/persistence.cpp | 2 +- g2core/plan_arc.cpp | 44 +-- g2core/plan_exec.cpp | 50 ++-- g2core/plan_line.cpp | 58 ++-- g2core/planner.cpp | 12 +- g2core/planner.h | 2 +- g2core/spindle.cpp | 4 +- g2core/temperature.cpp | 2 +- 20 files changed, 704 insertions(+), 680 deletions(-) mode change 100755 => 100644 g2core/cycle_homing.cpp mode change 100755 => 100644 g2core/cycle_probing.cpp mode change 100755 => 100644 g2core/gpio.cpp mode change 100755 => 100644 g2core/json_parser.cpp mode change 100755 => 100644 g2core/kinematics.cpp mode change 100755 => 100644 g2core/main.cpp mode change 100755 => 100644 g2core/persistence.cpp mode change 100755 => 100644 g2core/spindle.cpp mode change 100755 => 100644 g2core/temperature.cpp diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index c285d9af..434102d1 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -112,7 +112,9 @@ **** STRUCTURE ALLOCATIONS ******************************************************** ***********************************************************************************/ -cmMachine_t cm; // canonical machine master structure +cmMachine_t *cm; // pointer to active canonical machine +cmMachine_t cm0; // canonical machine primary machine +cmMachine_t cm1; // canonical machine secondary machine /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** @@ -141,7 +143,7 @@ static int8_t _get_axis_type(const index_t index); */ void cm_set_motion_state(const cmMotionState motion_state) { - cm.motion_state = motion_state; + cm->motion_state = motion_state; switch (motion_state) { case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } @@ -158,11 +160,11 @@ void cm_set_motion_state(const cmMotionState motion_state) * cm_get_hold_state() * cm_get_homing_state() */ -cmMachineState cm_get_machine_state() { return cm.machine_state;} -cmCycleState cm_get_cycle_state() { return cm.cycle_state;} -cmMotionState cm_get_motion_state() { return cm.motion_state;} -cmFeedholdState cm_get_hold_state() { return cm.hold_state;} -cmHomingState cm_get_homing_state() { return cm.homing_state;} +cmMachineState cm_get_machine_state() { return cm->machine_state;} +cmCycleState cm_get_cycle_state() { return cm->cycle_state;} +cmMotionState cm_get_motion_state() { return cm->motion_state;} +cmFeedholdState cm_get_hold_state() { return cm->hold_state;} +cmHomingState cm_get_homing_state() { return cm->homing_state;} /* * cm_get_combined_state() - combines raw states into something a user might want to see @@ -177,20 +179,20 @@ cmHomingState cm_get_homing_state() { return cm.homing_state;} */ cmCombinedState cm_get_combined_state() { - if (cm.machine_state <= MACHINE_PROGRAM_END) { // replaces first 5 cm.machine_state cases - return ((cmCombinedState)cm.machine_state); //...where MACHINE_xxx == COMBINED_xxx + if (cm->machine_state <= MACHINE_PROGRAM_END) { // replaces first 5 cm->machine_state cases + return ((cmCombinedState)cm->machine_state); //...where MACHINE_xxx == COMBINED_xxx } - switch(cm.machine_state) { + switch(cm->machine_state) { case MACHINE_INTERLOCK: { return (COMBINED_INTERLOCK); } case MACHINE_SHUTDOWN: { return (COMBINED_SHUTDOWN); } case MACHINE_PANIC: { return (COMBINED_PANIC); } case MACHINE_CYCLE: { - switch(cm.cycle_state) { + switch(cm->cycle_state) { case CYCLE_HOMING: { return (COMBINED_HOMING); } case CYCLE_PROBE: { return (COMBINED_PROBE); } case CYCLE_JOG: { return (COMBINED_JOG); } case CYCLE_MACHINING: case CYCLE_OFF: { - switch(cm.motion_state) { + switch(cm->motion_state) { case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE_1, above case MOTION_PLANNING: { return (COMBINED_RUN); } case MOTION_RUN: { return (COMBINED_RUN); } @@ -219,10 +221,10 @@ cmCombinedState cm_get_combined_state() ***********************************/ /* These getters and setters will work on any gm model with inputs: - * MODEL (GCodeState_t *)&cm.gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm.am // active model pointer is maintained by state management + * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ uint32_t cm_get_linenum(const GCodeState_t *gcode_state) { return gcode_state->linenum;} cmMotionMode cm_get_motion_mode(const GCodeState_t *gcode_state) { return gcode_state->motion_mode;} @@ -234,7 +236,7 @@ uint8_t cm_get_distance_mode(const GCodeState_t *gcode_state) { return gcode_sta uint8_t cm_get_arc_distance_mode(const GCodeState_t *gcode_state) { return gcode_state->arc_distance_mode;} uint8_t cm_get_feed_rate_mode(const GCodeState_t *gcode_state) { return gcode_state->feed_rate_mode;} uint8_t cm_get_tool(const GCodeState_t *gcode_state) { return gcode_state->tool;} -uint8_t cm_get_block_delete_switch() { return cm.gmx.block_delete_switch;} +uint8_t cm_get_block_delete_switch() { return cm->gmx.block_delete_switch;} uint8_t cm_get_runtime_busy() { return (mp_get_runtime_busy());} float cm_get_feed_rate(const GCodeState_t *gcode_state) { return gcode_state->feed_rate;} @@ -256,7 +258,7 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ void cm_set_model_linenum(const uint32_t linenum) { - cm.gm.linenum = linenum; // you must first set the model line number, + cm->gm.linenum = linenum; // you must first set the model line number, nv_add_object((const char *)"n"); // then add the line number to the nv list } @@ -297,12 +299,12 @@ void cm_set_model_linenum(const uint32_t linenum) float cm_get_active_coord_offset(const uint8_t axis) { - if (cm.gm.absolute_override == ABSOLUTE_OVERRIDE_ON) { // no offset if in absolute override mode + if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON) { // no offset if in absolute override mode return (0.0); } - float offset = cm.offset[cm.gm.coord_system][axis]; - if (cm.gmx.origin_offset_enable == true) { - offset += cm.gmx.origin_offset[axis]; // includes G5x and G92 components + float offset = cm->offset[cm->gm.coord_system][axis]; + if (cm->gmx.origin_offset_enable == true) { + offset += cm->gmx.origin_offset[axis]; // includes G5x and G92 components } return (offset); } @@ -310,10 +312,10 @@ float cm_get_active_coord_offset(const uint8_t axis) /* * cm_get_work_offset() - return a coord offset from the gcode_state * - * MODEL (GCodeState_t *)&cm.gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm.am // active model pointer is maintained by state management + * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) @@ -324,10 +326,10 @@ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) /* * cm_set_work_offsets() - capture coord offsets from the model into absolute values in the gcode_state * - * MODEL (GCodeState_t *)&cm.gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm.am // active model pointer is maintained by state management + * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ void cm_set_work_offsets(GCodeState_t *gcode_state) @@ -341,7 +343,7 @@ void cm_set_work_offsets(GCodeState_t *gcode_state) * cm_get_absolute_position() - get position of axis in absolute coordinates * * This function accepts as input: - * MODEL (GCodeState_t *)&cm.gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct * * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) @@ -351,7 +353,7 @@ void cm_set_work_offsets(GCodeState_t *gcode_state) float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t axis) { if (gcode_state == MODEL) { - return (cm.gmx.position[axis]); + return (cm->gmx.position[axis]); } return (mp_get_runtime_absolute_position(axis)); } @@ -365,7 +367,7 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax * calling cm_get_model_coord_offset_vector() first. * * This function accepts as input: - * MODEL (GCodeState_t *)&cm.gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct * * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) @@ -376,7 +378,7 @@ float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) float position; if (gcode_state == MODEL) { - position = cm.gmx.position[axis] - cm_get_active_coord_offset(axis); + position = cm->gmx.position[axis] - cm_get_active_coord_offset(axis); } else { position = mp_get_runtime_work_position(axis); } @@ -407,12 +409,12 @@ float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) void cm_finalize_move() { - copy_vector(cm.gmx.position, cm.gm.target); // update model position + copy_vector(cm->gmx.position, cm->gm.target); // update model position } void cm_update_model_position_from_runtime() { - copy_vector(cm.gmx.position, mr.gm.target); + copy_vector(cm->gmx.position, mr.gm.target); } /* @@ -424,14 +426,14 @@ void cm_update_model_position_from_runtime() stat_t cm_deferred_write_callback() { - if ((cm.cycle_state == CYCLE_OFF) && (cm.deferred_write_flag == true)) { - cm.deferred_write_flag = false; + if ((cm->cycle_state == CYCLE_OFF) && (cm->deferred_write_flag == true)) { + cm->deferred_write_flag = false; nvObj_t nv; for (uint8_t i=1; i<=COORDS; i++) { for (uint8_t j=0; joffset[i][j]; nv_persist(&nv); // Note: only writes values that have changed } } @@ -461,9 +463,9 @@ stat_t cm_set_tram(nvObj_t *nv) } // check to make sure we have three valid probes in a row - if ((cm.probe_state[0] == PROBE_SUCCEEDED) && - (cm.probe_state[1] == PROBE_SUCCEEDED) && - (cm.probe_state[2] == PROBE_SUCCEEDED)) + if ((cm->probe_state[0] == PROBE_SUCCEEDED) && + (cm->probe_state[1] == PROBE_SUCCEEDED) && + (cm->probe_state[2] == PROBE_SUCCEEDED)) { // Step 1: Get the normal of the plane formed by the three probes @@ -473,12 +475,12 @@ stat_t cm_set_tram(nvObj_t *nv) // n_{xyz} is the unit normal // Step 1a: get the deltas - float d0_x = cm.probe_results[0][0] - cm.probe_results[1][0]; - float d0_y = cm.probe_results[0][1] - cm.probe_results[1][1]; - float d0_z = cm.probe_results[0][2] - cm.probe_results[1][2]; - float d2_x = cm.probe_results[2][0] - cm.probe_results[1][0]; - float d2_y = cm.probe_results[2][1] - cm.probe_results[1][1]; - float d2_z = cm.probe_results[2][2] - cm.probe_results[1][2]; + float d0_x = cm->probe_results[0][0] - cm->probe_results[1][0]; + float d0_y = cm->probe_results[0][1] - cm->probe_results[1][1]; + float d0_z = cm->probe_results[0][2] - cm->probe_results[1][2]; + float d2_x = cm->probe_results[2][0] - cm->probe_results[1][0]; + float d2_y = cm->probe_results[2][1] - cm->probe_results[1][1]; + float d2_z = cm->probe_results[2][2] - cm->probe_results[1][2]; // Step 1b: compute the combined magnitde // since sqrt(a)*sqrt(b) = sqrt(a*b), we can save a sqrt in making the unit normal @@ -522,20 +524,22 @@ stat_t cm_set_tram(nvObj_t *nv) {0, 0, 0, 1} } */ - cm.rotation_matrix[0][0] = 1 - q_yy_2; - cm.rotation_matrix[0][1] = q_xy_2; - cm.rotation_matrix[0][2] = q_wy_2; + cm->rotation_matrix[0][0] = 1 - q_yy_2; + cm->rotation_matrix[0][1] = q_xy_2; + cm->rotation_matrix[0][2] = q_wy_2; - cm.rotation_matrix[1][0] = q_xy_2; - cm.rotation_matrix[1][1] = 1 - q_xx_2; - cm.rotation_matrix[1][2] = -q_wx_2; + cm->rotation_matrix[1][0] = q_xy_2; + cm->rotation_matrix[1][1] = 1 - q_xx_2; + cm->rotation_matrix[1][2] = -q_wx_2; - cm.rotation_matrix[2][0] = -q_wy_2; - cm.rotation_matrix[2][1] = q_wx_2; - cm.rotation_matrix[2][2] = 1 - q_xx_2 - q_yy_2; + cm->rotation_matrix[2][0] = -q_wy_2; + cm->rotation_matrix[2][1] = q_wx_2; + cm->rotation_matrix[2][2] = 1 - q_xx_2 - q_yy_2; // Step 4: compute the z-offset - cm.rotation_z_offset = (n_x*cm.probe_results[1][0] + n_y*cm.probe_results[1][1]) / n_z + cm.probe_results[1][2]; + cm->rotation_z_offset = (n_x*cm->probe_results[1][0] + + n_y*cm->probe_results[1][1]) / + n_z + cm->probe_results[1][2]; } else { return (STAT_COMMAND_NOT_ACCEPTED); } @@ -552,16 +556,16 @@ stat_t cm_get_tram(nvObj_t *nv) { nv->value = true; - if (fp_NOT_ZERO(cm.rotation_z_offset) || - fp_NOT_ZERO(cm.rotation_matrix[0][1]) || - fp_NOT_ZERO(cm.rotation_matrix[0][2]) || - fp_NOT_ZERO(cm.rotation_matrix[1][0]) || - fp_NOT_ZERO(cm.rotation_matrix[1][2]) || - fp_NOT_ZERO(cm.rotation_matrix[2][0]) || - fp_NOT_ZERO(cm.rotation_matrix[2][1]) || - fp_NE(1.0, cm.rotation_matrix[0][0]) || - fp_NE(1.0, cm.rotation_matrix[1][1]) || - fp_NE(1.0, cm.rotation_matrix[2][2])) + if (fp_NOT_ZERO(cm->rotation_z_offset) || + fp_NOT_ZERO(cm->rotation_matrix[0][1]) || + fp_NOT_ZERO(cm->rotation_matrix[0][2]) || + fp_NOT_ZERO(cm->rotation_matrix[1][0]) || + fp_NOT_ZERO(cm->rotation_matrix[1][2]) || + fp_NOT_ZERO(cm->rotation_matrix[2][0]) || + fp_NOT_ZERO(cm->rotation_matrix[2][1]) || + fp_NE(1.0, cm->rotation_matrix[0][0]) || + fp_NE(1.0, cm->rotation_matrix[1][1]) || + fp_NE(1.0, cm->rotation_matrix[2][2])) { nv->value = false; @@ -598,10 +602,10 @@ stat_t cm_get_tram(nvObj_t *nv) static float _calc_ABC(const uint8_t axis, const float target[]) { - if ((cm.a[axis].axis_mode == AXIS_STANDARD) || (cm.a[axis].axis_mode == AXIS_INHIBITED)) { + if ((cm->a[axis].axis_mode == AXIS_STANDARD) || (cm->a[axis].axis_mode == AXIS_INHIBITED)) { return(target[axis]); // no mm conversion - it's in degrees } - return(_to_millimeters(target[axis]) * 360 / (2 * M_PI * cm.a[axis].radius)); + return(_to_millimeters(target[axis]) * 360 / (2 * M_PI * cm->a[axis].radius)); } void cm_set_model_target(const float target[], const bool flags[]) @@ -610,31 +614,31 @@ void cm_set_model_target(const float target[], const bool flags[]) float tmp = 0; // copy position to target so it always starts correctly - copy_vector(cm.gm.target, cm.gmx.position); + copy_vector(cm->gm.target, cm->gmx.position); // process XYZABC for lower modes for (axis=AXIS_X; axis<=AXIS_Z; axis++) { - if (!flags[axis] || cm.a[axis].axis_mode == AXIS_DISABLED) { + if (!flags[axis] || cm->a[axis].axis_mode == AXIS_DISABLED) { continue; // skip axis if not flagged for update or its disabled - } else if ((cm.a[axis].axis_mode == AXIS_STANDARD) || (cm.a[axis].axis_mode == AXIS_INHIBITED)) { - if (cm.gm.distance_mode == ABSOLUTE_MODE) { - cm.gm.target[axis] = cm_get_active_coord_offset(axis) + _to_millimeters(target[axis]); + } else if ((cm->a[axis].axis_mode == AXIS_STANDARD) || (cm->a[axis].axis_mode == AXIS_INHIBITED)) { + if (cm->gm.distance_mode == ABSOLUTE_MODE) { + cm->gm.target[axis] = cm_get_active_coord_offset(axis) + _to_millimeters(target[axis]); } else { - cm.gm.target[axis] += _to_millimeters(target[axis]); + cm->gm.target[axis] += _to_millimeters(target[axis]); } } } // FYI: The ABC loop below relies on the XYZ loop having been run first for (axis=AXIS_A; axis<=AXIS_C; axis++) { - if (!flags[axis] || cm.a[axis].axis_mode == AXIS_DISABLED) { + if (!flags[axis] || cm->a[axis].axis_mode == AXIS_DISABLED) { continue; // skip axis if not flagged for update or its disabled } else { tmp = _calc_ABC(axis, target); } - if (cm.gm.distance_mode == ABSOLUTE_MODE) { - cm.gm.target[axis] = tmp + cm_get_active_coord_offset(axis); // sacidu93's fix to Issue #22 + if (cm->gm.distance_mode == ABSOLUTE_MODE) { + cm->gm.target[axis] = tmp + cm_get_active_coord_offset(axis); // sacidu93's fix to Issue #22 } else { - cm.gm.target[axis] += tmp; + cm->gm.target[axis] += tmp; } } } @@ -652,24 +656,24 @@ void cm_set_model_target(const float target[], const bool flags[]) static stat_t _finalize_soft_limits(const stat_t status) { - cm.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // cancel motion - copy_vector(cm.gm.target, cm.gmx.position); // reset model target + cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // cancel motion + copy_vector(cm->gm.target, cm->gmx.position); // reset model target return (cm_alarm(status, "soft_limits")); // throw an alarm } stat_t cm_test_soft_limits(const float target[]) { - if (cm.soft_limit_enable == true) { + if (cm->soft_limit_enable == true) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - if (cm.homed[axis] != true) { continue; } // skip axis if not homed - if (fp_EQ(cm.a[axis].travel_min, cm.a[axis].travel_max)) { continue; } // skip axis if identical - if (fabs(cm.a[axis].travel_min) > DISABLE_SOFT_LIMIT) { continue; } // skip min test if disabled - if (fabs(cm.a[axis].travel_max) > DISABLE_SOFT_LIMIT) { continue; } // skip max test if disabled + if (cm->homed[axis] != true) { continue; } // skip axis if not homed + if (fp_EQ(cm->a[axis].travel_min, cm->a[axis].travel_max)) { continue; } // skip axis if identical + if (fabs(cm->a[axis].travel_min) > DISABLE_SOFT_LIMIT) { continue; } // skip min test if disabled + if (fabs(cm->a[axis].travel_max) > DISABLE_SOFT_LIMIT) { continue; } // skip max test if disabled - if (target[axis] < cm.a[axis].travel_min) { + if (target[axis] < cm->a[axis].travel_min) { return (_finalize_soft_limits(STAT_SOFT_LIMIT_EXCEEDED_XMIN + 2*axis)); } - if (target[axis] > cm.a[axis].travel_max) { + if (target[axis] > cm->a[axis].travel_max) { return (_finalize_soft_limits(STAT_SOFT_LIMIT_EXCEEDED_XMAX + 2*axis)); } } @@ -697,11 +701,12 @@ stat_t cm_test_soft_limits(const float target[]) void canonical_machine_init() { -// If you can assume all memory has been zeroed by a hard reset you don't need this code: - memset(&cm, 0, sizeof(cm)); // do not reset canonicalMachineSingleton once it's been initialized - memset(&cm.gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status - memset(&cm.gn, 0, sizeof(GCodeInput_t)); - memset(&cm.gf, 0, sizeof(GCodeFlags_t)); + // If you can assume all memory has been zeroed by a hard reset you don't need this code: +// memset(&cm, 0, sizeof(cm)); // do not reset canonicalMachineSingleton once it's been initialized + memset(cm, 0, sizeof(cm0)); // do not reset canonicalMachineSingleton once it's been initialized + memset(&cm->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status + memset(&cm->gn, 0, sizeof(GCodeInput_t)); + memset(&cm->gf, 0, sizeof(GCodeFlags_t)); canonical_machine_init_assertions(); // establish assertions ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer @@ -709,22 +714,22 @@ void canonical_machine_init() } void canonical_machine_reset_rotation() { - memset(&cm.rotation_matrix, 0, sizeof(float)*3*3); + memset(&cm->rotation_matrix, 0, sizeof(float)*3*3); // We must make it an identity matrix for no rotation - cm.rotation_matrix[0][0] = 1.0; - cm.rotation_matrix[1][1] = 1.0; - cm.rotation_matrix[2][2] = 1.0; - cm.rotation_z_offset = 0.0; + cm->rotation_matrix[0][0] = 1.0; + cm->rotation_matrix[1][1] = 1.0; + cm->rotation_matrix[2][2] = 1.0; + cm->rotation_z_offset = 0.0; } void canonical_machine_reset() { // set gcode defaults - cm_set_units_mode(cm.default_units_mode); - cm_set_coord_system(cm.default_coord_system); // NB: queues a block to the planner with the coordinates - cm_select_plane(cm.default_select_plane); - cm_set_path_control(MODEL, cm.default_path_control); - cm_set_distance_mode(cm.default_distance_mode); + cm_set_units_mode(cm->default_units_mode); + cm_set_coord_system(cm->default_coord_system); // NB: queues a block to the planner with the coordinates + cm_select_plane(cm->default_select_plane); + cm_set_path_control(MODEL, cm->default_path_control); + cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_MODE); // always the default cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default cm_reset_overrides(); // set overrides to initial conditions @@ -732,26 +737,26 @@ void canonical_machine_reset() // NOTE: Should unhome axes here // reset request flags - cm.queue_flush_state = FLUSH_OFF; - cm.end_hold_requested = false; - cm.limit_requested = 0; // resets switch closures that occurred during initialization - cm.safety_interlock_disengaged = 0; // ditto - cm.safety_interlock_reengaged = 0; // ditto - cm.shutdown_requested = 0; // ditto + cm->queue_flush_state = FLUSH_OFF; + cm->end_hold_requested = false; + cm->limit_requested = 0; // resets switch closures that occurred during initialization + cm->safety_interlock_disengaged = 0; // ditto + cm->safety_interlock_reengaged = 0; // ditto + cm->shutdown_requested = 0; // ditto // set initial state and signal that the machine is ready for action - cm.cycle_state = CYCLE_OFF; - cm.motion_state = MOTION_STOP; - cm.hold_state = FEEDHOLD_OFF; - cm.esc_boot_timer = SysTickTimer_getValue(); - cm.gmx.block_delete_switch = true; - cm.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode - cm.machine_state = MACHINE_READY; + cm->cycle_state = CYCLE_OFF; + cm->motion_state = MOTION_STOP; + cm->hold_state = FEEDHOLD_OFF; + cm->esc_boot_timer = SysTickTimer_getValue(); + cm->gmx.block_delete_switch = true; + cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode + cm->machine_state = MACHINE_READY; canonical_machine_reset_rotation(); - memset(&cm.probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); - memset(&cm.probe_results, 0, sizeof(float)*PROBES_STORED*AXES); + memset(&cm->probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); + memset(&cm->probe_results, 0, sizeof(float)*PROBES_STORED*AXES); } /* @@ -761,18 +766,18 @@ void canonical_machine_reset() void canonical_machine_init_assertions(void) { - cm.magic_start = MAGICNUM; - cm.magic_end = MAGICNUM; - cm.gmx.magic_start = MAGICNUM; - cm.gmx.magic_end = MAGICNUM; + cm->magic_start = MAGICNUM; + cm->magic_end = MAGICNUM; + cm->gmx.magic_start = MAGICNUM; + cm->gmx.magic_end = MAGICNUM; arc.magic_start = MAGICNUM; arc.magic_end = MAGICNUM; } stat_t canonical_machine_test_assertions(void) { - if ((BAD_MAGIC(cm.magic_start)) || (BAD_MAGIC(cm.magic_end)) || - (BAD_MAGIC(cm.gmx.magic_start)) || (BAD_MAGIC(cm.gmx.magic_end)) || + if ((BAD_MAGIC(cm->magic_start)) || (BAD_MAGIC(cm->magic_end)) || + (BAD_MAGIC(cm->gmx.magic_start)) || (BAD_MAGIC(cm->gmx.magic_end)) || (BAD_MAGIC(arc.magic_start)) || (BAD_MAGIC(arc.magic_end))) { return(cm_panic(STAT_CANONICAL_MACHINE_ASSERTION_FAILURE, "canonical_machine_test_assertions()")); } @@ -827,16 +832,16 @@ stat_t cm_clr(nvObj_t *nv) // clear alarm or shutdown from comman void cm_clear() { - if (cm.machine_state == MACHINE_ALARM) { - cm.machine_state = MACHINE_PROGRAM_STOP; - } else if (cm.machine_state == MACHINE_SHUTDOWN) { - cm.machine_state = MACHINE_READY; + if (cm->machine_state == MACHINE_ALARM) { + cm->machine_state = MACHINE_PROGRAM_STOP; + } else if (cm->machine_state == MACHINE_SHUTDOWN) { + cm->machine_state = MACHINE_READY; } } void cm_parse_clear(const char *s) { - if (cm.machine_state == MACHINE_ALARM) { + if (cm->machine_state == MACHINE_ALARM) { if (toupper(s[0]) == 'M') { if (( (s[1]=='3') && (s[2]=='0') && (s[3]==NUL)) || ((s[1]=='2') && (s[2]==NUL) )) { cm_clear(); @@ -851,9 +856,9 @@ void cm_parse_clear(const char *s) stat_t cm_is_alarmed() { - if (cm.machine_state == MACHINE_ALARM) { return (STAT_COMMAND_REJECTED_BY_ALARM); } - if (cm.machine_state == MACHINE_SHUTDOWN) { return (STAT_COMMAND_REJECTED_BY_SHUTDOWN); } - if (cm.machine_state == MACHINE_PANIC) { return (STAT_COMMAND_REJECTED_BY_PANIC); } + if (cm->machine_state == MACHINE_ALARM) { return (STAT_COMMAND_REJECTED_BY_ALARM); } + if (cm->machine_state == MACHINE_SHUTDOWN) { return (STAT_COMMAND_REJECTED_BY_SHUTDOWN); } + if (cm->machine_state == MACHINE_PANIC) { return (STAT_COMMAND_REJECTED_BY_PANIC); } return (STAT_OK); } @@ -877,9 +882,9 @@ void cm_halt_motion(void) { mp_halt_runtime(); // stop the runtime. Do this immediately. (Reset is in cm_clear) canonical_machine_reset(); // reset Gcode model - cm.cycle_state = CYCLE_OFF; // Note: leaves machine_state alone - cm.motion_state = MOTION_STOP; - cm.hold_state = FEEDHOLD_OFF; + cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone + cm->motion_state = MOTION_STOP; + cm->hold_state = FEEDHOLD_OFF; } /* @@ -907,11 +912,11 @@ void cm_halt_motion(void) stat_t cm_alarm(const stat_t status, const char *msg) { - if ((cm.machine_state == MACHINE_ALARM) || (cm.machine_state == MACHINE_SHUTDOWN) || - (cm.machine_state == MACHINE_PANIC)) { + if ((cm->machine_state == MACHINE_ALARM) || (cm->machine_state == MACHINE_SHUTDOWN) || + (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't alarm if already in an alarm state } - cm.machine_state = MACHINE_ALARM; + cm->machine_state = MACHINE_ALARM; cm_request_feedhold(); // stop motion cm_request_queue_flush(); // do a queue flush once runtime is not busy @@ -945,7 +950,7 @@ stat_t cm_alarm(const stat_t status, const char *msg) stat_t cm_shutdown(const stat_t status, const char *msg) { - if ((cm.machine_state == MACHINE_SHUTDOWN) || (cm.machine_state == MACHINE_PANIC)) { + if ((cm->machine_state == MACHINE_SHUTDOWN) || (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't shutdown if shutdown or panic'd } cm_halt_motion(); // halt motors (may have already been done from GPIO) @@ -955,11 +960,11 @@ stat_t cm_shutdown(const stat_t status, const char *msg) cm_queue_flush(); // flush all queues and reset positions for (uint8_t i = 0; i < HOMING_AXES; i++) { // unhome axes and the machine - cm.homed[i] = false; + cm->homed[i] = false; } - cm.homing_state = HOMING_NOT_HOMED; + cm->homing_state = HOMING_NOT_HOMED; - cm.machine_state = MACHINE_SHUTDOWN; // do this after all other activity + cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity rpt_exception(status, msg); // send exception report return (status); } @@ -978,7 +983,7 @@ stat_t cm_panic(const stat_t status, const char *msg) { _debug_trap(msg); - if (cm.machine_state == MACHINE_PANIC) { // only do this once + if (cm->machine_state == MACHINE_PANIC) { // only do this once return (STAT_OK); } cm_halt_motion(); // halt motors (may have already been done from GPIO) @@ -987,7 +992,7 @@ stat_t cm_panic(const stat_t status, const char *msg) temperature_reset(); // turn off heaters and fans cm_queue_flush(); // flush all queues and reset positions - cm.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable rpt_exception(status, msg); // send panic report return (status); } @@ -1010,25 +1015,25 @@ stat_t cm_panic(const stat_t status, const char *msg) stat_t cm_select_plane(const uint8_t plane) { - cm.gm.select_plane = (cmCanonicalPlane)plane; + cm->gm.select_plane = (cmCanonicalPlane)plane; return (STAT_OK); } stat_t cm_set_units_mode(const uint8_t mode) { - cm.gm.units_mode = (cmUnitsMode)mode; // 0 = inches, 1 = mm. + cm->gm.units_mode = (cmUnitsMode)mode; // 0 = inches, 1 = mm. return(STAT_OK); } stat_t cm_set_distance_mode(const uint8_t mode) { - cm.gm.distance_mode = (cmDistanceMode)mode; // 0 = absolute mode, 1 = incremental + cm->gm.distance_mode = (cmDistanceMode)mode; // 0 = absolute mode, 1 = incremental return (STAT_OK); } stat_t cm_set_arc_distance_mode(const uint8_t mode) { - cm.gm.arc_distance_mode = (cmDistanceMode)mode; // 0 = absolute mode, 1 = incremental + cm->gm.arc_distance_mode = (cmDistanceMode)mode; // 0 = absolute mode, 1 = incremental return (STAT_OK); } @@ -1050,7 +1055,7 @@ stat_t cm_set_coord_offsets(const uint8_t coord_system, if ((coord_system < G54) || (coord_system > COORD_SYSTEM_MAX)) { // you can't set G53 return (STAT_P_WORD_IS_INVALID); } - if (!cm.gf.L_word) { + if (!cm->gf.L_word) { return (STAT_L_WORD_IS_MISSING); } if ((L_word != 2) && (L_word != 20)) { @@ -1059,11 +1064,11 @@ stat_t cm_set_coord_offsets(const uint8_t coord_system, for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { if (L_word == 2) { - cm.offset[coord_system][axis] = _to_millimeters(offset[axis]); + cm->offset[coord_system][axis] = _to_millimeters(offset[axis]); } else { - cm.offset[coord_system][axis] = cm.gmx.position[axis] - _to_millimeters(offset[axis]); + cm->offset[coord_system][axis] = cm->gmx.position[axis] - _to_millimeters(offset[axis]); } - cm.deferred_write_flag = true; // persist offsets once machining cycle is over + cm->deferred_write_flag = true; // persist offsets once machining cycle is over } } return (STAT_OK); @@ -1078,7 +1083,7 @@ stat_t cm_set_coord_offsets(const uint8_t coord_system, */ stat_t cm_set_coord_system(const uint8_t coord_system) { - cm.gm.coord_system = (cmCoordSystem)coord_system; + cm->gm.coord_system = (cmCoordSystem)coord_system; float value[] = { (float)coord_system,0,0,0,0,0 }; // pass coordinate system in value[0] element bool flags[] = { 1,0,0,0,0,0 }; @@ -1091,7 +1096,7 @@ static void _exec_offset(float *value, bool *flag) uint8_t coord_system = ((uint8_t)value[0]); // coordinate system is passed in value[0] element float offsets[AXES]; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - offsets[axis] = cm.offset[coord_system][axis] + (cm.gmx.origin_offset[axis] * cm.gmx.origin_offset_enable); + offsets[axis] = cm->offset[coord_system][axis] + (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); } mp_set_runtime_work_offset(offsets); cm_set_work_offsets(MODEL); // set work offsets in the Gcode model @@ -1119,8 +1124,8 @@ static void _exec_offset(float *value, bool *flag) void cm_set_position(const uint8_t axis, const float position) { // TODO: Interlock involving runtime_busy test - cm.gmx.position[axis] = position; - cm.gm.target[axis] = position; + cm->gmx.position[axis] = position; + cm->gm.target[axis] = position; mp_set_planner_position(axis, position); mp_set_runtime_position(axis, position); mp_set_steps_to_runtime_position(); @@ -1146,10 +1151,10 @@ stat_t cm_set_absolute_origin(const float origin[], bool flag[]) for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { -// REMOVED value[axis] = cm.offset[cm.gm.coord_system][axis] + _to_millimeters(origin[axis]); // G2 Issue #26 +// REMOVED value[axis] = cm->offset[cm->gm.coord_system][axis] + _to_millimeters(origin[axis]); // G2 Issue #26 value[axis] = _to_millimeters(origin[axis]); - cm.gmx.position[axis] = value[axis]; // set model position - cm.gm.target[axis] = value[axis]; // reset model target + cm->gmx.position[axis] = value[axis]; // set model position + cm->gm.target[axis] = value[axis]; // reset model target mp_set_planner_position(axis, value[axis]); // set mm position } } @@ -1162,7 +1167,7 @@ static void _exec_absolute_origin(float *value, bool *flag) for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { mp_set_runtime_position(axis, value[axis]); - cm.homed[axis] = true; // G28.3 is not considered homed until you get here + cm->homed[axis] = true; // G28.3 is not considered homed until you get here } } mp_set_steps_to_runtime_position(); @@ -1181,15 +1186,15 @@ static void _exec_absolute_origin(float *value, bool *flag) stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) { // set offsets in the Gcode model extended context - cm.gmx.origin_offset_enable = true; + cm->gmx.origin_offset_enable = true; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { - cm.gmx.origin_offset[axis] = cm.gmx.position[axis] - - cm.offset[cm.gm.coord_system][axis] - _to_millimeters(offset[axis]); + cm->gmx.origin_offset[axis] = cm->gmx.position[axis] - + cm->offset[cm->gm.coord_system][axis] - _to_millimeters(offset[axis]); } } // now pass the offset to the callback - setting the coordinate system also applies the offsets - float value[] = { (float)cm.gm.coord_system,0,0,0,0,0 }; // pass coordinate system in value[0] element + float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; // pass coordinate system in value[0] element bool flags[] = { 1,0,0,0,0,0 }; mp_queue_command(_exec_offset, value, flags); return (STAT_OK); @@ -1197,11 +1202,11 @@ stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) stat_t cm_reset_origin_offsets() { - cm.gmx.origin_offset_enable = false; + cm->gmx.origin_offset_enable = false; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - cm.gmx.origin_offset[axis] = 0; + cm->gmx.origin_offset[axis] = 0; } - float value[] = { (float)cm.gm.coord_system,0,0,0,0,0 }; + float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; bool flags[] = { 1,0,0,0,0,0 }; mp_queue_command(_exec_offset, value, flags); return (STAT_OK); @@ -1209,8 +1214,8 @@ stat_t cm_reset_origin_offsets() stat_t cm_suspend_origin_offsets() { - cm.gmx.origin_offset_enable = false; - float value[] = { (float)cm.gm.coord_system,0,0,0,0,0 }; + cm->gmx.origin_offset_enable = false; + float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; bool flags[] = { 1,0,0,0,0,0 }; mp_queue_command(_exec_offset, value, flags); return (STAT_OK); @@ -1218,8 +1223,8 @@ stat_t cm_suspend_origin_offsets() stat_t cm_resume_origin_offsets() { - cm.gmx.origin_offset_enable = true; - float value[] = { (float)cm.gm.coord_system,0,0,0,0,0 }; + cm->gmx.origin_offset_enable = true; + float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; bool flags[] = { 1,0,0,0,0,0 }; mp_queue_command(_exec_offset, value, flags); return (STAT_OK); @@ -1234,7 +1239,7 @@ stat_t cm_resume_origin_offsets() stat_t cm_straight_traverse(const float target[], const bool flags[]) { - cm.gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; + cm->gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; // it's legal for a G0 to have no axis words but we don't want to process it if (!(flags[AXIS_X] || flags[AXIS_Y] || flags[AXIS_Z] || @@ -1243,10 +1248,10 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) } cm_set_model_target(target, flags); - ritorno (cm_test_soft_limits(cm.gm.target)); // test soft limits; exit if thrown - cm_set_work_offsets(&cm.gm); // capture the fully resolved offsets to the state + ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown + cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles - stat_t status = mp_aline(&cm.gm); // send the move to the planner + stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_finalize_move(); if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { cm_cycle_end(); @@ -1267,12 +1272,12 @@ stat_t _goto_stored_position(float target2[], const float target[], const bool f cm_straight_traverse(target, flags); // Go through intermediate point if provided cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON);// Position was stored in absolute coords - if (cm.gm.units_mode == INCHES) { // If G28 or G30 are called while in inches mode + if (cm->gm.units_mode == INCHES) { // If G28 or G30 are called while in inches mode for (uint8_t i=0; igm.distance_mode == INCREMENTAL_MODE) { // Subtract out any movement already performed for (uint8_t i=0; igmx.g28_position, cm->gmx.position); // in MM and machine coordinates return (STAT_OK); } stat_t cm_goto_g28_position(const float target[], const bool flags[]) { - return (_goto_stored_position(cm.gmx.g28_position, target, flags)); + return (_goto_stored_position(cm->gmx.g28_position, target, flags)); } stat_t cm_set_g30_position(void) { - copy_vector(cm.gmx.g30_position, cm.gmx.position); // in MM and machine coordinates + copy_vector(cm->gmx.g30_position, cm->gmx.position); // in MM and machine coordinates return (STAT_OK); } stat_t cm_goto_g30_position(const float target[], const bool flags[]) { - return (_goto_stored_position(cm.gmx.g30_position, target, flags)); + return (_goto_stored_position(cm->gmx.g30_position, target, flags)); } /******************************** @@ -1316,13 +1321,13 @@ stat_t cm_goto_g30_position(const float target[], const bool flags[]) stat_t cm_set_feed_rate(const float feed_rate) { - if (cm.gm.feed_rate_mode == INVERSE_TIME_MODE) { + if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) { if (fp_ZERO(feed_rate)) { return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); } - cm.gm.feed_rate = 1/feed_rate; // normalize to minutes (NB: active for this gcode block only) + cm->gm.feed_rate = 1/feed_rate; // normalize to minutes (NB: active for this gcode block only) } else { - cm.gm.feed_rate = _to_millimeters(feed_rate); + cm->gm.feed_rate = _to_millimeters(feed_rate); } return (STAT_OK); } @@ -1337,7 +1342,7 @@ stat_t cm_set_feed_rate(const float feed_rate) stat_t cm_set_feed_rate_mode(const uint8_t mode) { - cm.gm.feed_rate_mode = (cmFeedRateMode)mode; + cm->gm.feed_rate_mode = (cmFeedRateMode)mode; return (STAT_OK); } @@ -1365,7 +1370,7 @@ stat_t cm_set_path_control(GCodeState_t *gcode_state, const uint8_t mode) */ stat_t cm_dwell(const float seconds) { - cm.gm.parameter = seconds; + cm->gm.parameter = seconds; mp_dwell(seconds); return (STAT_OK); } @@ -1376,10 +1381,10 @@ stat_t cm_dwell(const float seconds) stat_t cm_straight_feed(const float target[], const bool flags[]) { // trap zero feed rate condition - if (fp_ZERO(cm.gm.feed_rate)) { + if (fp_ZERO(cm->gm.feed_rate)) { return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); } - cm.gm.motion_mode = MOTION_MODE_STRAIGHT_FEED; + cm->gm.motion_mode = MOTION_MODE_STRAIGHT_FEED; // it's legal for a G1 to have no axis words but we don't want to process it if (!(flags[AXIS_X] || flags[AXIS_Y] || flags[AXIS_Z] || @@ -1388,10 +1393,10 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) } cm_set_model_target(target, flags); - ritorno (cm_test_soft_limits(cm.gm.target)); // test soft limits; exit if thrown - cm_set_work_offsets(&cm.gm); // capture the fully resolved offsets to the state + ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown + cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles - stat_t status = mp_aline(&cm.gm); // send the move to the planner + stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_finalize_move(); // <-- ONLY safe because we don't care about status... @@ -1430,12 +1435,12 @@ stat_t cm_select_tool(const uint8_t tool_select) static void _exec_select_tool(float *value, bool *flag) { - cm.gm.tool_select = (uint8_t)value[0]; + cm->gm.tool_select = (uint8_t)value[0]; } stat_t cm_change_tool(const uint8_t tool_change) { - float value[] = { (float)cm.gm.tool_select,0,0,0,0,0 }; + float value[] = { (float)cm->gm.tool_select,0,0,0,0,0 }; bool flags[] = { 1,0,0,0,0,0 }; mp_queue_command(_exec_change_tool, value, flags); return (STAT_OK); @@ -1443,7 +1448,7 @@ stat_t cm_change_tool(const uint8_t tool_change) static void _exec_change_tool(float *value, bool *flag) { - cm.gm.tool = (uint8_t)value[0]; + cm->gm.tool = (uint8_t)value[0]; } /*********************************** @@ -1466,11 +1471,11 @@ void cm_message(const char *message) void cm_reset_overrides() { - cm.gmx.m48_enable = true; - cm.gmx.mfo_enable = false; // feed rate overrides - cm.gmx.mfo_factor = 1.0; - cm.gmx.mto_enable = false; // traverse overrides - cm.gmx.mto_factor = 1.0; + cm->gmx.m48_enable = true; + cm->gmx.mfo_enable = false; // feed rate overrides + cm->gmx.mfo_factor = 1.0; + cm->gmx.mto_enable = false; // traverse overrides + cm->gmx.mto_factor = 1.0; } /* @@ -1505,7 +1510,7 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 { // handle changes to feed override given new state of m48/m49 - cm.gmx.m48_enable = enable; // update state + cm->gmx.m48_enable = enable; // update state return (STAT_OK); } @@ -1553,33 +1558,33 @@ stat_t cm_mfo_enable(uint8_t enable) // M50 { bool new_enable = true; bool new_override = false; - if (cm.gf.parameter) { // if parameter is present in Gcode block - if (fp_ZERO(cm.gn.parameter)) { + if (cm->gf.parameter) { // if parameter is present in Gcode block + if (fp_ZERO(cm->gn.parameter)) { new_enable = false; // P0 disables override } else { - if (cm.gn.parameter < FEED_OVERRIDE_MIN) { + if (cm->gn.parameter < FEED_OVERRIDE_MIN) { return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (cm.gn.parameter > FEED_OVERRIDE_MAX) { + if (cm->gn.parameter > FEED_OVERRIDE_MAX) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - cm.gmx.mfo_factor = cm.gn.parameter; // it validates - store it. + cm->gmx.mfo_factor = cm->gn.parameter; // it validates - store it. new_override = true; } } - if (cm.gmx.m48_enable) { // if master enable is ON - if (new_enable && (new_override || !cm.gmx.mfo_enable)) { // 3 cases to start a ramp - mp_start_feed_override(FEED_OVERRIDE_RAMP_TIME, cm.gmx.mfo_factor); - } else if (cm.gmx.mfo_enable && !new_enable) { // case to turn off the ramp + if (cm->gmx.m48_enable) { // if master enable is ON + if (new_enable && (new_override || !cm->gmx.mfo_enable)) { // 3 cases to start a ramp + mp_start_feed_override(FEED_OVERRIDE_RAMP_TIME, cm->gmx.mfo_factor); + } else if (cm->gmx.mfo_enable && !new_enable) { // case to turn off the ramp mp_end_feed_override(FEED_OVERRIDE_RAMP_TIME); } } - cm.gmx.mfo_enable = new_enable; // always update the enable state + cm->gmx.mfo_enable = new_enable; // always update the enable state return (STAT_OK); } -// if ((new_enable && new_override) || (new_enable && !cm.gmx.mfo_enable)) { -// if (!(cm.gmx.mfo_enable && new_override)) { +// if ((new_enable && new_override) || (new_enable && !cm->gmx.mfo_enable)) { +// if (!(cm->gmx.mfo_enable && new_override)) { /************************************************ @@ -1603,7 +1608,7 @@ stat_t cm_mfo_enable(uint8_t enable) // M50 * If a queue flush request is also present the queue flush should be done first * * Below the request level, feedholds work like this: - * - The hold is initiated by calling cm_start_hold(). cm.hold_state is set to + * - The hold is initiated by calling cm_start_hold(). cm->hold_state is set to * FEEDHOLD_SYNC, motion_state is set to MOTION_HOLD, and the spindle is turned off * (if it it on). The remainder of feedhold * processing occurs in plan_exec.c in the mp_exec_aline() function. @@ -1667,23 +1672,23 @@ stat_t cm_mfo_enable(uint8_t enable) // M50 */ void cm_request_feedhold(void) { // honor request if not already in a feedhold and you are moving - if ((cm.hold_state == FEEDHOLD_OFF) && (cm.motion_state != MOTION_STOP)) { - cm.hold_state = FEEDHOLD_REQUESTED; + if ((cm->hold_state == FEEDHOLD_OFF) && (cm->motion_state != MOTION_STOP)) { + cm->hold_state = FEEDHOLD_REQUESTED; } } void cm_request_end_hold(void) { - if (cm.hold_state != FEEDHOLD_OFF) { - cm.end_hold_requested = true; + if (cm->hold_state != FEEDHOLD_OFF) { + cm->end_hold_requested = true; } } void cm_request_queue_flush() { - if ((cm.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm.queue_flush_state == FLUSH_OFF)) { // ...and only once - cm.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + if ((cm->hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold + (cm->queue_flush_state == FLUSH_OFF)) { // ...and only once + cm->queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now } @@ -1694,14 +1699,14 @@ void cm_request_queue_flush() */ stat_t cm_feedhold_sequencing_callback() { - if (cm.hold_state == FEEDHOLD_REQUESTED) { + if (cm->hold_state == FEEDHOLD_REQUESTED) { cm_start_hold(); // feed won't run unless the machine is moving } - if (cm.queue_flush_state == FLUSH_REQUESTED) { + if (cm->queue_flush_state == FLUSH_REQUESTED) { cm_queue_flush(); // queue flush won't run until runtime is idle } - if (cm.end_hold_requested) { - if (cm.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing + if (cm->end_hold_requested) { + if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing cm_end_hold(); } } @@ -1716,7 +1721,7 @@ stat_t cm_feedhold_sequencing_callback() */ bool cm_has_hold() { - return (cm.hold_state != FEEDHOLD_OFF); + return (cm->hold_state != FEEDHOLD_OFF); } void cm_start_hold() @@ -1725,22 +1730,22 @@ void cm_start_hold() cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected cm_set_motion_state(MOTION_HOLD); - cm.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } void cm_end_hold() { - if (cm.hold_state == FEEDHOLD_HOLD) { - cm.end_hold_requested = false; + if (cm->hold_state == FEEDHOLD_HOLD) { + cm->end_hold_requested = false; mp_exit_hold_state(); // State machine cases: - if (cm.machine_state == MACHINE_ALARM) { + if (cm->machine_state == MACHINE_ALARM) { cm_spindle_off_immediate(); cm_coolant_off_immediate(); - } else if (cm.motion_state == MOTION_STOP) { // && (! MACHINE_ALARM) + } else if (cm->motion_state == MOTION_STOP) { // && (! MACHINE_ALARM) cm_spindle_off_immediate(); cm_coolant_off_immediate(); cm_cycle_end(); @@ -1762,10 +1767,10 @@ void cm_queue_flush() for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions cm_set_position(axis, mp_get_runtime_absolute_position(axis)); } - if(cm.hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one + if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one cm_end_hold(); } - cm.queue_flush_state = FLUSH_OFF; + cm->queue_flush_state = FLUSH_OFF; qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } } @@ -1826,25 +1831,25 @@ static void _exec_program_finalize(float *value, bool *flag) cm_set_motion_state(MOTION_STOP); // Allow update in the alarm state, to accommodate queue flush (RAS) - if ((cm.cycle_state == CYCLE_MACHINING || cm.cycle_state == CYCLE_OFF) && -// (cm.machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) - (cm.machine_state != MACHINE_SHUTDOWN)) { - cm.machine_state = (cmMachineState)value[0]; // don't update macs/cycs if we're in the middle of a canned cycle, - cm.cycle_state = CYCLE_OFF; // or if we're in machine alarm/shutdown mode + if ((cm->cycle_state == CYCLE_MACHINING || cm->cycle_state == CYCLE_OFF) && +// (cm->machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) + (cm->machine_state != MACHINE_SHUTDOWN)) { + cm->machine_state = (cmMachineState)value[0]; // don't update macs/cycs if we're in the middle of a canned cycle, + cm->cycle_state = CYCLE_OFF; // or if we're in machine alarm/shutdown mode } // reset the rest of the states - cm.cycle_state = CYCLE_OFF; - cm.hold_state = FEEDHOLD_OFF; + cm->cycle_state = CYCLE_OFF; + cm->hold_state = FEEDHOLD_OFF; mp_zero_segment_velocity(); // for reporting purposes // perform the following resets if it's a program END if (((uint8_t)value[0]) == MACHINE_PROGRAM_END) { cm_suspend_origin_offsets(); // G92.2 - as per NIST // cm_reset_origin_offsets(); // G92.1 - alternative to above - cm_set_coord_system(cm.default_coord_system); // reset to default coordinate system - cm_select_plane(cm.default_select_plane); // reset to default arc plane - cm_set_distance_mode(cm.default_distance_mode); + cm_set_coord_system(cm->default_coord_system); // reset to default coordinate system + cm_select_plane(cm->default_select_plane); // reset to default arc plane + cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_MODE); // always the default cm_spindle_off_immediate(); // M5 cm_coolant_off_immediate(); // M9 @@ -1858,16 +1863,16 @@ static void _exec_program_finalize(float *value, bool *flag) void cm_cycle_start() { - if (cm.cycle_state == CYCLE_OFF) { // don't (re)start homing, probe or other canned cycles - cm.machine_state = MACHINE_CYCLE; - cm.cycle_state = CYCLE_MACHINING; + if (cm->cycle_state == CYCLE_OFF) { // don't (re)start homing, probe or other canned cycles + cm->machine_state = MACHINE_CYCLE; + cm->cycle_state = CYCLE_MACHINING; qr_init_queue_report(); // clear queue reporting buffer counts } } void cm_cycle_end() { - if(cm.cycle_state == CYCLE_MACHINING) { + if(cm->cycle_state == CYCLE_MACHINING) { float value[] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 }; bool flags[] = { 1,0,0,0,0,0 }; _exec_program_finalize(value, flags); @@ -1876,7 +1881,7 @@ void cm_cycle_end() void cm_canned_cycle_end() { - cm.cycle_state = CYCLE_OFF; + cm->cycle_state = CYCLE_OFF; float value[] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 }; bool flags[] = { 1,0,0,0,0,0 }; _exec_program_finalize(value, flags); @@ -2252,6 +2257,9 @@ stat_t cm_get_am(nvObj_t *nv) return(_get_msg_helper(nv, msg_am, nv->value)); } +#pragma GCC push_options +#pragma GCC optimize ("O0") + stat_t cm_set_am(nvObj_t *nv) // axis mode { if (_get_axis_type(nv->index) == 0) { // linear @@ -2259,10 +2267,22 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode } else { if (nv->value > AXIS_MODE_MAX_ROTARY) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } + cmAxisMode *am = (cmAxisMode *)cfgArray[nv->index].target; + void *p = (cfgArray[nv->index].target); + cmAxisMode a = *((cmAxisMode *)cfgArray[nv->index].target); +// *((uint8_t *)cfgArray[nv->index].target) = nv->value; +// cmAxisMode a = (cmAxisMode)nv->value; +// *am = (cmAxisMode)nv->value; + *am = a; + nv->valuetype = TYPE_INT; + return(STAT_OK); + set_ui8(nv); return(STAT_OK); } +#pragma GCC reset_options + stat_t cm_set_hi(nvObj_t *nv) { if ((nv->value < 0) || (nv->value > D_IN_CHANNELS)) { @@ -2293,7 +2313,7 @@ stat_t cm_set_hi(nvObj_t *nv) */ float cm_get_axis_jerk(const uint8_t axis) { - return (cm.a[axis].jerk_max); + return (cm->a[axis].jerk_max); } // Precompute sqrt(3)/10 for the max_junction_accel. @@ -2303,16 +2323,16 @@ static const float _junction_accel_multiplier = sqrt(3.0)/10.0; // Important note: Actual jerk is stored jerk * JERK_MULTIPLIER, and // Time Quanta is junction_integration_time / 1000. void _cm_recalc_max_junction_accel(const uint8_t axis) { - float T = cm.junction_integration_time / 1000.0; + float T = cm->junction_integration_time / 1000.0; float T2 = T*T; - cm.a[axis].max_junction_accel = _junction_accel_multiplier * T2 * (cm.a[axis].jerk_max * JERK_MULTIPLIER); + cm->a[axis].max_junction_accel = _junction_accel_multiplier * T2 * (cm->a[axis].jerk_max * JERK_MULTIPLIER); } void cm_set_axis_jerk(const uint8_t axis, const float jerk) { - cm.a[axis].jerk_max = jerk; - //cm.a[axis].recip_jerk = 1/(jerk * JERK_MULTIPLIER); + cm->a[axis].jerk_max = jerk; + //cm->a[axis].recip_jerk = 1/(jerk * JERK_MULTIPLIER); // Must recalculate the max_junction_accel now that the jerk has changed. _cm_recalc_max_junction_accel(axis); @@ -2326,7 +2346,7 @@ stat_t cm_set_vm(nvObj_t *nv) } else { set_flu(nv); } - cm.a[axis].recip_velocity_max = 1/nv->value; + cm->a[axis].recip_velocity_max = 1/nv->value; return(STAT_OK); } @@ -2338,7 +2358,7 @@ stat_t cm_set_fr(nvObj_t *nv) } else { set_flu(nv); } - cm.a[axis].recip_feedrate_max = 1/nv->value; + cm->a[axis].recip_feedrate_max = 1/nv->value; return(STAT_OK); } @@ -2468,7 +2488,7 @@ stat_t cm_dam(nvObj_t *nv) float cm_get_jogging_dest(void) { - return cm.jogging_dest; + return cm->jogging_dest; } stat_t cm_run_jogx(nvObj_t *nv) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index ee699091..c851a2c7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -37,12 +37,12 @@ /* Defines, Macros, and Assorted Parameters */ -#define MODEL (GCodeState_t *)&cm.gm // absolute pointer from canonical machine gm model +#define MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model #define PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to #define RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct -#define ACTIVE_MODEL cm.am // active model pointer is maintained by state management +#define ACTIVE_MODEL cm->am // active model pointer is maintained by state management -#define _to_millimeters(a) ((cm.gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) +#define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) #define JOGGING_START_VELOCITY ((float)10.0) #define DISABLE_SOFT_LIMIT (999999) @@ -53,9 +53,9 @@ * MACHINE STATE MODEL * * The following main variables track canonical machine state and state transitions. - * - cm.machine_state - overall state of machine and program execution - * - cm.cycle_state - what cycle the machine is executing (or none) - * - cm.motion_state - state of movement + * - cm->machine_state - overall state of machine and program execution + * - cm->cycle_state - what cycle the machine is executing (or none) + * - cm->motion_state - state of movement */ // *** Note: check config printout strings align with all the state variables @@ -128,15 +128,15 @@ typedef enum { // queue flush state machine FLUSH_REQUESTED, // flush has been requested but not started yet } cmQueueFlushState; -typedef enum { // applies to cm.homing_state +typedef enum { // applies to cm->homing_state HOMING_NOT_HOMED = 0, // machine is not homed (0=false) HOMING_HOMED = 1, // machine is homed (1=true) HOMING_WAITING // machine waiting to be homed } cmHomingState; -typedef enum { // applies to cm.probe_state +typedef enum { // applies to cm->probe_state PROBE_FAILED = 0, // probe reached endpoint without triggering - PROBE_SUCCEEDED = 1, // probe was triggered, cm.probe_results has position + PROBE_SUCCEEDED = 1, // probe was triggered, cm->probe_results has position PROBE_WAITING // probe is waiting to be started } cmProbeState; @@ -308,7 +308,7 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) * some state elements are necessarily restored from gm. * * - gf is used by the gcode parser interpreter to hold flags for any data - * that has changed in gn during the parse. cm.gf.target[] values are also used + * that has changed in gn during the parse. cm->gf.target[] values are also used * by the canonical machine during set_target(). * * - cfg (config struct in config.h) is also used heavily and contains some @@ -580,9 +580,12 @@ typedef struct cmSingleton { // struct to manage cm globals and c magic_t magic_end; } cmMachine_t; -/**** Externs - See canonical_machine.c for allocation ****/ +/**** Externs - See canonical_machine.cpp for allocation ****/ -extern cmMachine_t cm; // canonical machine controller singleton +//extern cmMachine_t cm; // canonical machine controller singleton +extern cmMachine_t *cm; // pointer to active canonical machine +extern cmMachine_t cm0; // canonical machine primary machine +extern cmMachine_t cm1; // canonical machine secondary machine /***************************************************************************** * FUNCTION PROTOTYPES diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index ed913244..267dbfc6 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -113,8 +113,8 @@ const cfgItem_t cfgArray[] = { // dynamic model attributes for reporting purposes (up front for speed) { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_nul,(float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_int,(float *)&cm.gm.linenum,0 }, // Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_int,(float *)&cm.gm.linenum,0 }, // Active line number - model or runtime line number + { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_int,(float *)&cm->gm.linenum,0 }, // Model line number + { "", "line",_fi, 0, cm_print_line, cm_get_line, set_int,(float *)&cm->gm.linenum,0 }, // Active line number - model or runtime line number { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_nul,(float *)&cs.null, 0 }, // current velocity { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_nul,(float *)&cs.null, 0 }, // feed rate { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_nul,(float *)&cs.null, 0 }, // raw machine state @@ -130,7 +130,7 @@ const cfgItem_t cfgArray[] = { { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_nul,(float *)&cs.null, 0 }, // arc distance mode { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_nul,(float *)&cs.null, 0 }, // feed rate mode { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_nul,(float *)&cs.null, 0 }, // active tool - { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_nul,(float *)&cm.gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_nul,(float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs @@ -157,28 +157,28 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // B work offset { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // C work offset - { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_01,(float *)&cm.homing_state, 0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_X], false }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_Y], false }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_Z], false }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_A], false }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_B], false }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_C], false }, // C homed + { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_01,(float *)&cm->homing_state, 0 }, // homing state, invoke homing cycle + { "hom","homx",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_X], false }, // X homed - Homing status group + { "hom","homy",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_Y], false }, // Y homed + { "hom","homz",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_Z], false }, // Z homed + { "hom","homa",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_A], false }, // A homed + { "hom","homb",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_B], false }, // B homed + { "hom","homc",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_C], false }, // C homed - { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_nul,(float *)&cm.probe_state[0], 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[0][AXIS_X], 0 }, - { "prb","prby",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[0][AXIS_Y], 0 }, - { "prb","prbz",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[0][AXIS_Z], 0 }, - { "prb","prba",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[0][AXIS_A], 0 }, - { "prb","prbb",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[0][AXIS_B], 0 }, - { "prb","prbc",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[0][AXIS_C], 0 }, + { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_nul,(float *)&cm->probe_state[0], 0 }, // probing state + { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_X], 0 }, + { "prb","prby",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_Y], 0 }, + { "prb","prbz",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_Z], 0 }, + { "prb","prba",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_A], 0 }, + { "prb","prbb",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_B], 0 }, + { "prb","prbc",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_C], 0 }, - { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm.jogging_dest, 0}, - { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm.jogging_dest, 0}, - { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jogz, (float *)&cm.jogging_dest, 0}, - { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_joga, (float *)&cm.jogging_dest, 0}, -// { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jogb, (float *)&cm.jogging_dest, 0}, -// { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jogc, (float *)&cm.jogging_dest, 0}, + { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm->jogging_dest, 0}, + { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm->jogging_dest, 0}, + { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jogz, (float *)&cm->jogging_dest, 0}, + { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_joga, (float *)&cm->jogging_dest, 0}, +// { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jogb, (float *)&cm->jogging_dest, 0}, +// { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jogc, (float *)&cm->jogging_dest, 0}, { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0}, // motor power readouts { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0}, @@ -267,92 +267,92 @@ const cfgItem_t cfgArray[] = { // { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, #endif // Axis parameters - { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm.a[AXIS_X].axis_mode, X_AXIS_MODE }, - { "x","xvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm.a[AXIS_X].velocity_max, X_VELOCITY_MAX }, - { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm.a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, - { "x","xtn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm.a[AXIS_X].travel_min, X_TRAVEL_MIN }, - { "x","xtm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm.a[AXIS_X].travel_max, X_TRAVEL_MAX }, - { "x","xjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm.a[AXIS_X].jerk_max, X_JERK_MAX }, - { "x","xjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm.a[AXIS_X].jerk_high, X_JERK_HIGH_SPEED }, - { "x","xhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm.a[AXIS_X].homing_input, X_HOMING_INPUT }, - { "x","xhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm.a[AXIS_X].homing_dir, X_HOMING_DIRECTION }, - { "x","xsv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm.a[AXIS_X].search_velocity,X_SEARCH_VELOCITY }, - { "x","xlv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm.a[AXIS_X].latch_velocity, X_LATCH_VELOCITY }, - { "x","xlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm.a[AXIS_X].latch_backoff, X_LATCH_BACKOFF }, - { "x","xzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm.a[AXIS_X].zero_backoff, X_ZERO_BACKOFF }, + { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_X].axis_mode, X_AXIS_MODE }, + { "x","xvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_X].velocity_max, X_VELOCITY_MAX }, + { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, + { "x","xtn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_min, X_TRAVEL_MIN }, + { "x","xtm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_max, X_TRAVEL_MAX }, + { "x","xjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_X].jerk_max, X_JERK_MAX }, + { "x","xjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_X].jerk_high, X_JERK_HIGH_SPEED }, + { "x","xhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_X].homing_input, X_HOMING_INPUT }, + { "x","xhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_X].homing_dir, X_HOMING_DIRECTION }, + { "x","xsv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm->a[AXIS_X].search_velocity,X_SEARCH_VELOCITY }, + { "x","xlv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm->a[AXIS_X].latch_velocity, X_LATCH_VELOCITY }, + { "x","xlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_X].latch_backoff, X_LATCH_BACKOFF }, + { "x","xzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_X].zero_backoff, X_ZERO_BACKOFF }, - { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm.a[AXIS_Y].axis_mode, Y_AXIS_MODE }, - { "y","yvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm.a[AXIS_Y].velocity_max, Y_VELOCITY_MAX }, - { "y","yfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm.a[AXIS_Y].feedrate_max, Y_FEEDRATE_MAX }, - { "y","ytn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm.a[AXIS_Y].travel_min, Y_TRAVEL_MIN }, - { "y","ytm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm.a[AXIS_Y].travel_max, Y_TRAVEL_MAX }, - { "y","yjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm.a[AXIS_Y].jerk_max, Y_JERK_MAX }, - { "y","yjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm.a[AXIS_Y].jerk_high, Y_JERK_HIGH_SPEED }, - { "y","yhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm.a[AXIS_Y].homing_input, Y_HOMING_INPUT }, - { "y","yhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm.a[AXIS_Y].homing_dir, Y_HOMING_DIRECTION }, - { "y","ysv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm.a[AXIS_Y].search_velocity,Y_SEARCH_VELOCITY }, - { "y","ylv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm.a[AXIS_Y].latch_velocity, Y_LATCH_VELOCITY }, - { "y","ylb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm.a[AXIS_Y].latch_backoff, Y_LATCH_BACKOFF }, - { "y","yzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm.a[AXIS_Y].zero_backoff, Y_ZERO_BACKOFF }, + { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_Y].axis_mode, Y_AXIS_MODE }, + { "y","yvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Y].velocity_max, Y_VELOCITY_MAX }, + { "y","yfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_Y].feedrate_max, Y_FEEDRATE_MAX }, + { "y","ytn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_Y].travel_min, Y_TRAVEL_MIN }, + { "y","ytm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_Y].travel_max, Y_TRAVEL_MAX }, + { "y","yjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_Y].jerk_max, Y_JERK_MAX }, + { "y","yjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_Y].jerk_high, Y_JERK_HIGH_SPEED }, + { "y","yhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_Y].homing_input, Y_HOMING_INPUT }, + { "y","yhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_Y].homing_dir, Y_HOMING_DIRECTION }, + { "y","ysv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm->a[AXIS_Y].search_velocity,Y_SEARCH_VELOCITY }, + { "y","ylv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm->a[AXIS_Y].latch_velocity, Y_LATCH_VELOCITY }, + { "y","ylb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_Y].latch_backoff, Y_LATCH_BACKOFF }, + { "y","yzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_Y].zero_backoff, Y_ZERO_BACKOFF }, - { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm.a[AXIS_Z].axis_mode, Z_AXIS_MODE }, - { "z","zvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm.a[AXIS_Z].velocity_max, Z_VELOCITY_MAX }, - { "z","zfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm.a[AXIS_Z].feedrate_max, Z_FEEDRATE_MAX }, - { "z","ztn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm.a[AXIS_Z].travel_min, Z_TRAVEL_MIN }, - { "z","ztm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm.a[AXIS_Z].travel_max, Z_TRAVEL_MAX }, - { "z","zjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm.a[AXIS_Z].jerk_max, Z_JERK_MAX }, - { "z","zjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm.a[AXIS_Z].jerk_high, Z_JERK_HIGH_SPEED }, - { "z","zhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm.a[AXIS_Z].homing_input, Z_HOMING_INPUT }, - { "z","zhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm.a[AXIS_Z].homing_dir, Z_HOMING_DIRECTION }, - { "z","zsv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm.a[AXIS_Z].search_velocity,Z_SEARCH_VELOCITY }, - { "z","zlv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm.a[AXIS_Z].latch_velocity, Z_LATCH_VELOCITY }, - { "z","zlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm.a[AXIS_Z].latch_backoff, Z_LATCH_BACKOFF }, - { "z","zzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm.a[AXIS_Z].zero_backoff, Z_ZERO_BACKOFF }, + { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_Z].axis_mode, Z_AXIS_MODE }, + { "z","zvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Z].velocity_max, Z_VELOCITY_MAX }, + { "z","zfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_Z].feedrate_max, Z_FEEDRATE_MAX }, + { "z","ztn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_Z].travel_min, Z_TRAVEL_MIN }, + { "z","ztm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_Z].travel_max, Z_TRAVEL_MAX }, + { "z","zjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_Z].jerk_max, Z_JERK_MAX }, + { "z","zjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_Z].jerk_high, Z_JERK_HIGH_SPEED }, + { "z","zhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_Z].homing_input, Z_HOMING_INPUT }, + { "z","zhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_Z].homing_dir, Z_HOMING_DIRECTION }, + { "z","zsv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm->a[AXIS_Z].search_velocity,Z_SEARCH_VELOCITY }, + { "z","zlv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm->a[AXIS_Z].latch_velocity, Z_LATCH_VELOCITY }, + { "z","zlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_Z].latch_backoff, Z_LATCH_BACKOFF }, + { "z","zzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_Z].zero_backoff, Z_ZERO_BACKOFF }, - { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm.a[AXIS_A].axis_mode, A_AXIS_MODE }, - { "a","avm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm.a[AXIS_A].velocity_max, A_VELOCITY_MAX }, - { "a","afr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm.a[AXIS_A].feedrate_max, A_FEEDRATE_MAX }, - { "a","atn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm.a[AXIS_A].travel_min, A_TRAVEL_MIN }, - { "a","atm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm.a[AXIS_A].travel_max, A_TRAVEL_MAX }, - { "a","ajm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm.a[AXIS_A].jerk_max, A_JERK_MAX }, - { "a","ajh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm.a[AXIS_A].jerk_high, A_JERK_HIGH_SPEED }, - { "a","ara",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm.a[AXIS_A].radius, A_RADIUS}, - { "a","ahi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm.a[AXIS_A].homing_input, A_HOMING_INPUT }, - { "a","ahd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm.a[AXIS_A].homing_dir, A_HOMING_DIRECTION }, - { "a","asv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm.a[AXIS_A].search_velocity,A_SEARCH_VELOCITY }, - { "a","alv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm.a[AXIS_A].latch_velocity, A_LATCH_VELOCITY }, - { "a","alb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm.a[AXIS_A].latch_backoff, A_LATCH_BACKOFF }, - { "a","azb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm.a[AXIS_A].zero_backoff, A_ZERO_BACKOFF }, + { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_A].axis_mode, A_AXIS_MODE }, + { "a","avm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_A].velocity_max, A_VELOCITY_MAX }, + { "a","afr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_A].feedrate_max, A_FEEDRATE_MAX }, + { "a","atn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_A].travel_min, A_TRAVEL_MIN }, + { "a","atm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm->a[AXIS_A].travel_max, A_TRAVEL_MAX }, + { "a","ajm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_A].jerk_max, A_JERK_MAX }, + { "a","ajh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_A].jerk_high, A_JERK_HIGH_SPEED }, + { "a","ara",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm->a[AXIS_A].radius, A_RADIUS}, + { "a","ahi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_A].homing_input, A_HOMING_INPUT }, + { "a","ahd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_A].homing_dir, A_HOMING_DIRECTION }, + { "a","asv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm->a[AXIS_A].search_velocity,A_SEARCH_VELOCITY }, + { "a","alv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm->a[AXIS_A].latch_velocity, A_LATCH_VELOCITY }, + { "a","alb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_A].latch_backoff, A_LATCH_BACKOFF }, + { "a","azb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_A].zero_backoff, A_ZERO_BACKOFF }, - { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm.a[AXIS_B].axis_mode, B_AXIS_MODE }, - { "b","bvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm.a[AXIS_B].velocity_max, B_VELOCITY_MAX }, - { "b","bfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm.a[AXIS_B].feedrate_max, B_FEEDRATE_MAX }, - { "b","btn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm.a[AXIS_B].travel_min, B_TRAVEL_MIN }, - { "b","btm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm.a[AXIS_B].travel_max, B_TRAVEL_MAX }, - { "b","bjm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm.a[AXIS_B].jerk_max, B_JERK_MAX }, - { "b","bjh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm.a[AXIS_B].jerk_high, B_JERK_HIGH_SPEED }, - { "b","bra",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm.a[AXIS_B].radius, B_RADIUS }, - { "b","bhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm.a[AXIS_B].homing_input, B_HOMING_INPUT }, - { "b","bhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm.a[AXIS_B].homing_dir, B_HOMING_DIRECTION }, - { "b","bsv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm.a[AXIS_B].search_velocity,B_SEARCH_VELOCITY }, - { "b","blv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm.a[AXIS_B].latch_velocity, B_LATCH_VELOCITY }, - { "b","blb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm.a[AXIS_B].latch_backoff, B_LATCH_BACKOFF }, - { "b","bzb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm.a[AXIS_B].zero_backoff, B_ZERO_BACKOFF }, + { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_B].axis_mode, B_AXIS_MODE }, + { "b","bvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_B].velocity_max, B_VELOCITY_MAX }, + { "b","bfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_B].feedrate_max, B_FEEDRATE_MAX }, + { "b","btn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_B].travel_min, B_TRAVEL_MIN }, + { "b","btm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm->a[AXIS_B].travel_max, B_TRAVEL_MAX }, + { "b","bjm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_B].jerk_max, B_JERK_MAX }, + { "b","bjh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_B].jerk_high, B_JERK_HIGH_SPEED }, + { "b","bra",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm->a[AXIS_B].radius, B_RADIUS }, + { "b","bhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_B].homing_input, B_HOMING_INPUT }, + { "b","bhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_B].homing_dir, B_HOMING_DIRECTION }, + { "b","bsv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm->a[AXIS_B].search_velocity,B_SEARCH_VELOCITY }, + { "b","blv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm->a[AXIS_B].latch_velocity, B_LATCH_VELOCITY }, + { "b","blb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_B].latch_backoff, B_LATCH_BACKOFF }, + { "b","bzb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_B].zero_backoff, B_ZERO_BACKOFF }, - { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm.a[AXIS_C].axis_mode, C_AXIS_MODE }, - { "c","cvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm.a[AXIS_C].velocity_max, C_VELOCITY_MAX }, - { "c","cfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm.a[AXIS_C].feedrate_max, C_FEEDRATE_MAX }, - { "c","ctn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm.a[AXIS_C].travel_min, C_TRAVEL_MIN }, - { "c","ctm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm.a[AXIS_C].travel_max, C_TRAVEL_MAX }, - { "c","cjm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm.a[AXIS_C].jerk_max, C_JERK_MAX }, - { "c","cjh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm.a[AXIS_C].jerk_high, C_JERK_HIGH_SPEED }, - { "c","cra",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm.a[AXIS_C].radius, C_RADIUS }, - { "c","chi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm.a[AXIS_C].homing_input, C_HOMING_INPUT }, - { "c","chd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm.a[AXIS_C].homing_dir, C_HOMING_DIRECTION }, - { "c","csv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm.a[AXIS_C].search_velocity,C_SEARCH_VELOCITY }, - { "c","clv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm.a[AXIS_C].latch_velocity, C_LATCH_VELOCITY }, - { "c","clb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm.a[AXIS_C].latch_backoff, C_LATCH_BACKOFF }, - { "c","czb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm.a[AXIS_C].zero_backoff, C_ZERO_BACKOFF }, + { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_C].axis_mode, C_AXIS_MODE }, + { "c","cvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_C].velocity_max, C_VELOCITY_MAX }, + { "c","cfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_C].feedrate_max, C_FEEDRATE_MAX }, + { "c","ctn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_C].travel_min, C_TRAVEL_MIN }, + { "c","ctm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm->a[AXIS_C].travel_max, C_TRAVEL_MAX }, + { "c","cjm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_C].jerk_max, C_JERK_MAX }, + { "c","cjh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_C].jerk_high, C_JERK_HIGH_SPEED }, + { "c","cra",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm->a[AXIS_C].radius, C_RADIUS }, + { "c","chi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_C].homing_input, C_HOMING_INPUT }, + { "c","chd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_C].homing_dir, C_HOMING_DIRECTION }, + { "c","csv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm->a[AXIS_C].search_velocity,C_SEARCH_VELOCITY }, + { "c","clv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm->a[AXIS_C].latch_velocity, C_LATCH_VELOCITY }, + { "c","clb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_C].latch_backoff, C_LATCH_BACKOFF }, + { "c","czb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_C].zero_backoff, C_ZERO_BACKOFF }, // Digital input configs { "di1","di1mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, @@ -532,69 +532,69 @@ const cfgItem_t cfgArray[] = { { "he3","he3fh",_f0, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, // Coordinate system offsets (G54-G59 and G92) - { "g54","g54x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G54][AXIS_X], G54_X_OFFSET }, - { "g54","g54y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G54][AXIS_Y], G54_Y_OFFSET }, - { "g54","g54z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G54][AXIS_Z], G54_Z_OFFSET }, - { "g54","g54a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G54][AXIS_A], G54_A_OFFSET }, - { "g54","g54b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G54][AXIS_B], G54_B_OFFSET }, - { "g54","g54c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G54][AXIS_C], G54_C_OFFSET }, + { "g54","g54x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G54][AXIS_X], G54_X_OFFSET }, + { "g54","g54y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G54][AXIS_Y], G54_Y_OFFSET }, + { "g54","g54z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G54][AXIS_Z], G54_Z_OFFSET }, + { "g54","g54a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G54][AXIS_A], G54_A_OFFSET }, + { "g54","g54b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G54][AXIS_B], G54_B_OFFSET }, + { "g54","g54c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G54][AXIS_C], G54_C_OFFSET }, - { "g55","g55x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G55][AXIS_X], G55_X_OFFSET }, - { "g55","g55y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G55][AXIS_Y], G55_Y_OFFSET }, - { "g55","g55z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G55][AXIS_Z], G55_Z_OFFSET }, - { "g55","g55a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G55][AXIS_A], G55_A_OFFSET }, - { "g55","g55b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G55][AXIS_B], G55_B_OFFSET }, - { "g55","g55c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G55][AXIS_C], G55_C_OFFSET }, + { "g55","g55x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G55][AXIS_X], G55_X_OFFSET }, + { "g55","g55y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G55][AXIS_Y], G55_Y_OFFSET }, + { "g55","g55z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G55][AXIS_Z], G55_Z_OFFSET }, + { "g55","g55a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G55][AXIS_A], G55_A_OFFSET }, + { "g55","g55b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G55][AXIS_B], G55_B_OFFSET }, + { "g55","g55c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G55][AXIS_C], G55_C_OFFSET }, - { "g56","g56x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G56][AXIS_X], G56_X_OFFSET }, - { "g56","g56y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G56][AXIS_Y], G56_Y_OFFSET }, - { "g56","g56z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G56][AXIS_Z], G56_Z_OFFSET }, - { "g56","g56a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G56][AXIS_A], G56_A_OFFSET }, - { "g56","g56b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G56][AXIS_B], G56_B_OFFSET }, - { "g56","g56c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G56][AXIS_C], G56_C_OFFSET }, + { "g56","g56x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G56][AXIS_X], G56_X_OFFSET }, + { "g56","g56y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G56][AXIS_Y], G56_Y_OFFSET }, + { "g56","g56z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G56][AXIS_Z], G56_Z_OFFSET }, + { "g56","g56a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G56][AXIS_A], G56_A_OFFSET }, + { "g56","g56b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G56][AXIS_B], G56_B_OFFSET }, + { "g56","g56c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G56][AXIS_C], G56_C_OFFSET }, - { "g57","g57x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G57][AXIS_X], G57_X_OFFSET }, - { "g57","g57y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G57][AXIS_Y], G57_Y_OFFSET }, - { "g57","g57z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G57][AXIS_Z], G57_Z_OFFSET }, - { "g57","g57a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G57][AXIS_A], G57_A_OFFSET }, - { "g57","g57b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G57][AXIS_B], G57_B_OFFSET }, - { "g57","g57c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G57][AXIS_C], G57_C_OFFSET }, + { "g57","g57x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G57][AXIS_X], G57_X_OFFSET }, + { "g57","g57y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G57][AXIS_Y], G57_Y_OFFSET }, + { "g57","g57z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G57][AXIS_Z], G57_Z_OFFSET }, + { "g57","g57a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G57][AXIS_A], G57_A_OFFSET }, + { "g57","g57b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G57][AXIS_B], G57_B_OFFSET }, + { "g57","g57c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G57][AXIS_C], G57_C_OFFSET }, - { "g58","g58x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G58][AXIS_X], G58_X_OFFSET }, - { "g58","g58y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G58][AXIS_Y], G58_Y_OFFSET }, - { "g58","g58z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G58][AXIS_Z], G58_Z_OFFSET }, - { "g58","g58a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G58][AXIS_A], G58_A_OFFSET }, - { "g58","g58b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G58][AXIS_B], G58_B_OFFSET }, - { "g58","g58c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G58][AXIS_C], G58_C_OFFSET }, + { "g58","g58x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G58][AXIS_X], G58_X_OFFSET }, + { "g58","g58y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G58][AXIS_Y], G58_Y_OFFSET }, + { "g58","g58z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G58][AXIS_Z], G58_Z_OFFSET }, + { "g58","g58a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G58][AXIS_A], G58_A_OFFSET }, + { "g58","g58b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G58][AXIS_B], G58_B_OFFSET }, + { "g58","g58c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G58][AXIS_C], G58_C_OFFSET }, - { "g59","g59x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G59][AXIS_X], G59_X_OFFSET }, - { "g59","g59y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G59][AXIS_Y], G59_Y_OFFSET }, - { "g59","g59z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G59][AXIS_Z], G59_Z_OFFSET }, - { "g59","g59a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G59][AXIS_A], G59_A_OFFSET }, - { "g59","g59b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G59][AXIS_B], G59_B_OFFSET }, - { "g59","g59c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.offset[G59][AXIS_C], G59_C_OFFSET }, + { "g59","g59x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G59][AXIS_X], G59_X_OFFSET }, + { "g59","g59y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G59][AXIS_Y], G59_Y_OFFSET }, + { "g59","g59z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G59][AXIS_Z], G59_Z_OFFSET }, + { "g59","g59a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G59][AXIS_A], G59_A_OFFSET }, + { "g59","g59b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G59][AXIS_B], G59_B_OFFSET }, + { "g59","g59c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G59][AXIS_C], G59_C_OFFSET }, - { "g92","g92x",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_X], 0 },// G92 handled differently - { "g92","g92y",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_Y], 0 }, - { "g92","g92z",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_Z], 0 }, - { "g92","g92a",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_A], 0 }, - { "g92","g92b",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_B], 0 }, - { "g92","g92c",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_C], 0 }, + { "g92","g92x",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_X], 0 },// G92 handled differently + { "g92","g92y",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_Y], 0 }, + { "g92","g92z",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_Z], 0 }, + { "g92","g92a",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_A], 0 }, + { "g92","g92b",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_B], 0 }, + { "g92","g92c",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_C], 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_X], 0 },// g28 handled differently - { "g28","g28y",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_Y], 0 }, - { "g28","g28z",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_Z], 0 }, - { "g28","g28a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_A], 0 }, - { "g28","g28b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_B], 0 }, - { "g28","g28c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_C], 0 }, + { "g28","g28x",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_X], 0 },// g28 handled differently + { "g28","g28y",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_Y], 0 }, + { "g28","g28z",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_Z], 0 }, + { "g28","g28a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_A], 0 }, + { "g28","g28b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_B], 0 }, + { "g28","g28c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_C], 0 }, - { "g30","g30x",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_X], 0 },// g30 handled differently - { "g30","g30y",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_Y], 0 }, - { "g30","g30z",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_Z], 0 }, - { "g30","g30a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_A], 0 }, - { "g30","g30b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_B], 0 }, - { "g30","g30c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_C], 0 }, + { "g30","g30x",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_X], 0 },// g30 handled differently + { "g30","g30y",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_Y], 0 }, + { "g30","g30z",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_Z], 0 }, + { "g30","g30a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_A], 0 }, + { "g30","g30b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_B], 0 }, + { "g30","g30c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_C], 0 }, // this is a 128bit UUID for identifying a previously committed job state { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, @@ -603,16 +603,16 @@ const cfgItem_t cfgArray[] = { { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, get_flt, cm_set_jt,(float *)&cm.junction_integration_time,JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, get_flt, set_flu, (float *)&cm.chordal_tolerance, CHORDAL_TOLERANCE }, - { "sys","sl", _fipn, 0, cm_print_sl, get_ui8, set_01, (float *)&cm.soft_limit_enable, SOFT_LIMIT_ENABLE }, - { "sys","lim", _fipn,0, cm_print_lim, get_ui8, set_01, (float *)&cm.limit_enable, HARD_LIMIT_ENABLE }, - { "sys","saf", _fipn,0, cm_print_saf, get_ui8, set_01, (float *)&cm.safety_interlock_enable, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm.gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable - { "sys","mfoe",_fipn,0, cm_print_mfoe,get_ui8, set_01, (float *)&cm.gmx.mfo_enable, FEED_OVERRIDE_ENABLE}, - { "sys","mfo", _fipn,3, cm_print_mfo, get_flt,cm_set_mfo,(float *)&cm.gmx.mfo_factor, FEED_OVERRIDE_FACTOR}, - { "sys","mtoe",_fipn,0, cm_print_mtoe,get_ui8, set_01, (float *)&cm.gmx.mto_enable, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","mto", _fipn,3, cm_print_mto, get_flt,cm_set_mto,(float *)&cm.gmx.mto_factor, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","jt", _fipn, 2, cm_print_jt, get_flt, cm_set_jt,(float *)&cm->junction_integration_time,JUNCTION_INTEGRATION_TIME }, + { "sys","ct", _fipnc,4, cm_print_ct, get_flt, set_flu, (float *)&cm->chordal_tolerance, CHORDAL_TOLERANCE }, + { "sys","sl", _fipn, 0, cm_print_sl, get_ui8, set_01, (float *)&cm->soft_limit_enable, SOFT_LIMIT_ENABLE }, + { "sys","lim", _fipn,0, cm_print_lim, get_ui8, set_01, (float *)&cm->limit_enable, HARD_LIMIT_ENABLE }, + { "sys","saf", _fipn,0, cm_print_saf, get_ui8, set_01, (float *)&cm->safety_interlock_enable, SAFETY_INTERLOCK_ENABLE }, + { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable + { "sys","mfoe",_fipn,0, cm_print_mfoe,get_ui8, set_01, (float *)&cm->gmx.mfo_enable, FEED_OVERRIDE_ENABLE}, + { "sys","mfo", _fipn,3, cm_print_mfo, get_flt,cm_set_mfo,(float *)&cm->gmx.mfo_factor, FEED_OVERRIDE_FACTOR}, + { "sys","mtoe",_fipn,0, cm_print_mtoe,get_ui8, set_01, (float *)&cm->gmx.mto_enable, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","mto", _fipn,3, cm_print_mto, get_flt,cm_set_mto,(float *)&cm->gmx.mto_factor, TRAVERSE_OVERRIDE_FACTOR}, { "sys","mt", _fipn,2, st_print_mt, get_flt, st_set_mt,(float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, { "", "me", _f0, 0, st_print_me, get_nul, st_set_me,(float *)&cs.null, 0 }, // GET or SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md,(float *)&cs.null, 0 }, // GET or SET to disable motors @@ -647,11 +647,11 @@ const cfgItem_t cfgArray[] = { // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco - { "sys","gpl", _fipn, 0, cm_print_gpl, get_ui8, set_012, (float *)&cm.default_select_plane, GCODE_DEFAULT_PLANE }, - { "sys","gun", _fipn, 0, cm_print_gun, get_ui8, set_01, (float *)&cm.default_units_mode, GCODE_DEFAULT_UNITS }, - { "sys","gco", _fipn, 0, cm_print_gco, get_ui8, set_ui8, (float *)&cm.default_coord_system, GCODE_DEFAULT_COORD_SYSTEM }, - { "sys","gpa", _fipn, 0, cm_print_gpa, get_ui8, set_012, (float *)&cm.default_path_control, GCODE_DEFAULT_PATH_CONTROL }, - { "sys","gdi", _fipn, 0, cm_print_gdi, get_ui8, set_01, (float *)&cm.default_distance_mode, GCODE_DEFAULT_DISTANCE_MODE }, + { "sys","gpl", _fipn, 0, cm_print_gpl, get_ui8, set_012, (float *)&cm->default_select_plane, GCODE_DEFAULT_PLANE }, + { "sys","gun", _fipn, 0, cm_print_gun, get_ui8, set_01, (float *)&cm->default_units_mode, GCODE_DEFAULT_UNITS }, + { "sys","gco", _fipn, 0, cm_print_gco, get_ui8, set_ui8, (float *)&cm->default_coord_system, GCODE_DEFAULT_COORD_SYSTEM }, + { "sys","gpa", _fipn, 0, cm_print_gpa, get_ui8, set_012, (float *)&cm->default_path_control, GCODE_DEFAULT_PATH_CONTROL }, + { "sys","gdi", _fipn, 0, cm_print_gdi, get_ui8, set_01, (float *)&cm->default_distance_mode, GCODE_DEFAULT_DISTANCE_MODE }, { "", "gc", _f0, 0, tx_print_nul, gc_get_gc,gc_run_gc,(float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports diff --git a/g2core/controller.cpp b/g2core/controller.cpp index aa4df6e4..8955a3ca 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -371,10 +371,10 @@ static stat_t _sync_to_planner() */ static stat_t _shutdown_handler(void) { - if (cm.shutdown_requested != 0) { // request may contain the (non-zero) input number + if (cm->shutdown_requested != 0) { // request may contain the (non-zero) input number char msg[10]; - sprintf(msg, "input %d", (int)cm.shutdown_requested); - cm.shutdown_requested = false; // clear limit request used here ^ + sprintf(msg, "input %d", (int)cm->shutdown_requested); + cm->shutdown_requested = false; // clear limit request used here ^ cm_shutdown(STAT_SHUTDOWN, msg); } return(STAT_OK); @@ -389,10 +389,10 @@ static stat_t _limit_switch_handler(void) // safe_pin = 1; - if ((cm.limit_enable == true) && (cm.limit_requested != 0)) { + if ((cm->limit_enable == true) && (cm->limit_requested != 0)) { char msg[10]; - sprintf(msg, "input %d", (int)cm.limit_requested); - cm.limit_requested = false; // clear limit request used here ^ + sprintf(msg, "input %d", (int)cm->limit_requested); + cm->limit_requested = false; // clear limit request used here ^ cm_alarm(STAT_LIMIT_SWITCH_HIT, msg); } return (STAT_OK); @@ -400,11 +400,11 @@ static stat_t _limit_switch_handler(void) static stat_t _interlock_handler(void) { - if (cm.safety_interlock_enable) { + if (cm->safety_interlock_enable) { // interlock broken - if (cm.safety_interlock_disengaged != 0) { - cm.safety_interlock_disengaged = 0; - cm.safety_interlock_state = SAFETY_INTERLOCK_DISENGAGED; + if (cm->safety_interlock_disengaged != 0) { + cm->safety_interlock_disengaged = 0; + cm->safety_interlock_state = SAFETY_INTERLOCK_DISENGAGED; cm_request_feedhold(); // may have already requested STOP as INPUT_ACTION // feedhold was initiated by input action in gpio // pause spindle @@ -412,9 +412,9 @@ static stat_t _interlock_handler(void) } // interlock restored - if ((cm.safety_interlock_reengaged != 0) && (mp_runtime_is_idle())) { - cm.safety_interlock_reengaged = 0; - cm.safety_interlock_state = SAFETY_INTERLOCK_ENGAGED; // interlock restored + if ((cm->safety_interlock_reengaged != 0) && (mp_runtime_is_idle())) { + cm->safety_interlock_reengaged = 0; + cm->safety_interlock_state = SAFETY_INTERLOCK_ENGAGED; // interlock restored // restart spindle with dwell cm_request_end_hold(); // use cm_request_end_hold() instead of just ending // restart coolant diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp old mode 100755 new mode 100644 index a66f3a20..1a37b393 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -172,9 +172,9 @@ stat_t cm_homing_cycle_start(void) { hm.axis = -1; // set to retrieve initial axis hm.func = _homing_axis_start; // bind initial processing function - cm.machine_state = MACHINE_CYCLE; - cm.cycle_state = CYCLE_HOMING; - cm.homing_state = HOMING_NOT_HOMED; + cm->machine_state = MACHINE_CYCLE; + cm->cycle_state = CYCLE_HOMING; + cm->homing_state = HOMING_NOT_HOMED; return (STAT_OK); } @@ -185,7 +185,7 @@ stat_t cm_homing_cycle_start_no_set(void) { } stat_t cm_homing_cycle_callback(void) { - if (cm.cycle_state != CYCLE_HOMING) { // exit if not in a homing cycle + if (cm->cycle_state != CYCLE_HOMING) { // exit if not in a homing cycle return (STAT_NOOP); } if (hm.waiting_for_motion_end) { // sync to planner move ends (using callback) @@ -210,57 +210,57 @@ static stat_t _homing_axis_start(int8_t axis) { // get the first or next axis if ((axis = _get_next_axis(axis)) < 0) { // axes are done or error if (axis == -1) { // -1 is done - cm.homing_state = HOMING_HOMED; + cm->homing_state = HOMING_HOMED; return (_set_homing_func(_homing_finalize_exit)); } else if (axis == -2) { // -2 is error return (_homing_error_exit(-2, STAT_HOMING_ERROR_BAD_OR_NO_AXIS)); } } // clear the homed flag for axis so we'll be able to move w/o triggering soft limits - cm.homed[axis] = false; + cm->homed[axis] = false; // trap axis mis-configurations - if (fp_ZERO(cm.a[axis].homing_input)) { + if (fp_ZERO(cm->a[axis].homing_input)) { return (_homing_error_exit(axis, STAT_HOMING_ERROR_HOMING_INPUT_MISCONFIGURED)); } - if (fp_ZERO(cm.a[axis].search_velocity)) { + if (fp_ZERO(cm->a[axis].search_velocity)) { return (_homing_error_exit(axis, STAT_HOMING_ERROR_ZERO_SEARCH_VELOCITY)); } - if (fp_ZERO(cm.a[axis].latch_velocity)) { + if (fp_ZERO(cm->a[axis].latch_velocity)) { return (_homing_error_exit(axis, STAT_HOMING_ERROR_ZERO_LATCH_VELOCITY)); } // calculate and test travel distance - float travel_distance = fabs(cm.a[axis].travel_max - cm.a[axis].travel_min) + cm.a[axis].latch_backoff; + float travel_distance = fabs(cm->a[axis].travel_max - cm->a[axis].travel_min) + cm->a[axis].latch_backoff; if (fp_ZERO(travel_distance)) { return (_homing_error_exit(axis, STAT_HOMING_ERROR_TRAVEL_MIN_MAX_IDENTICAL)); } // Nothing to do about direction now that direction is explicit // However, here's a good place to stash the homing_switch: - hm.homing_input = cm.a[axis].homing_input; + hm.homing_input = cm->a[axis].homing_input; gpio_set_homing_mode(hm.homing_input, true); hm.axis = axis; // persist the axis - hm.search_velocity = fabs(cm.a[axis].search_velocity); // search velocity is always positive - hm.latch_velocity = fabs(cm.a[axis].latch_velocity); // latch velocity is always positive + hm.search_velocity = fabs(cm->a[axis].search_velocity); // search velocity is always positive + hm.latch_velocity = fabs(cm->a[axis].latch_velocity); // latch velocity is always positive - bool homing_to_max = cm.a[axis].homing_dir; + bool homing_to_max = cm->a[axis].homing_dir; // setup parameters for positive or negative travel (homing to the max or min switch) if (homing_to_max) { hm.search_travel = travel_distance; // search travels in positive direction - hm.latch_backoff = fabs(cm.a[axis].latch_backoff); // latch travels in positive direction - hm.zero_backoff = -max(0.0f, cm.a[axis].zero_backoff); // zero backoff is negative direction (or zero) + hm.latch_backoff = fabs(cm->a[axis].latch_backoff); // latch travels in positive direction + hm.zero_backoff = -max(0.0f, cm->a[axis].zero_backoff); // zero backoff is negative direction (or zero) // will set the maximum position // (plus any negative backoff) - hm.setpoint = cm.a[axis].travel_max + (max(0.0f, -cm.a[axis].zero_backoff)); + hm.setpoint = cm->a[axis].travel_max + (max(0.0f, -cm->a[axis].zero_backoff)); } else { hm.search_travel = -travel_distance; // search travels in negative direction - hm.latch_backoff = -fabs(cm.a[axis].latch_backoff); // latch travels in negative direction - hm.zero_backoff = max(0.0f, cm.a[axis].zero_backoff); // zero backoff is positive direction (or zero) + hm.latch_backoff = -fabs(cm->a[axis].latch_backoff); // latch travels in negative direction + hm.zero_backoff = max(0.0f, cm->a[axis].zero_backoff); // zero backoff is positive direction (or zero) // will set the minimum position // (minus any negative backoff) - hm.setpoint = cm.a[axis].travel_min + (max(0.0f, -cm.a[axis].zero_backoff)); + hm.setpoint = cm->a[axis].travel_min + (max(0.0f, -cm->a[axis].zero_backoff)); } // if homing is disabled for the axis then skip to the next axis @@ -276,7 +276,7 @@ static stat_t _homing_axis_clear_init(int8_t axis) // first clear move // determine if the input switch for this axis is shared w/other axes for (uint8_t check_axis = AXIS_X; check_axis < AXES; check_axis++) { - if (axis != check_axis && cm.a[check_axis].homing_input == hm.homing_input) { + if (axis != check_axis && cm->a[check_axis].homing_input == hm.homing_input) { return (_homing_error_exit( axis, STAT_HOMING_ERROR_MUST_CLEAR_SWITCHES_BEFORE_HOMING)); // axis cannot be homed } @@ -288,7 +288,7 @@ static stat_t _homing_axis_clear_init(int8_t axis) // first clear move static stat_t _homing_axis_search(int8_t axis) // drive to switch { - cm_set_axis_jerk(axis, cm.a[axis].jerk_high); // use the high-speed jerk for search onward + cm_set_axis_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for search onward _homing_axis_move(axis, hm.search_travel, hm.search_velocity); return (_set_homing_func(_homing_axis_clear)); } @@ -315,7 +315,7 @@ static stat_t _homing_axis_set_position(int8_t axis) // set axis zero / max and { if (hm.set_coordinates) { cm_set_position(axis, hm.setpoint); - cm.homed[axis] = true; + cm->homed[axis] = true; } else { // handle G28.4 cycle - set position to the point of switch closure float contact_position[AXES]; @@ -407,38 +407,38 @@ static stat_t _homing_finalize_exit(int8_t axis) // third part of return to hom static int8_t _get_next_axis(int8_t axis) { #if (HOMING_AXES <= 4) if (axis == -1) { // inelegant brute force solution - if (cm.gf.target[AXIS_Z]) { + if (cm->gf.target[AXIS_Z]) { return (AXIS_Z); } - if (cm.gf.target[AXIS_X]) { + if (cm->gf.target[AXIS_X]) { return (AXIS_X); } - if (cm.gf.target[AXIS_Y]) { + if (cm->gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } return (-2); // error } else if (axis == AXIS_Z) { - if (cm.gf.target[AXIS_X]) { + if (cm->gf.target[AXIS_X]) { return (AXIS_X); } - if (cm.gf.target[AXIS_Y]) { + if (cm->gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_X) { - if (cm.gf.target[AXIS_Y]) { + if (cm->gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_Y) { - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } } @@ -446,73 +446,73 @@ static int8_t _get_next_axis(int8_t axis) { #else if (axis == -1) { - if (cm.gf.target[AXIS_Z]) { + if (cm->gf.target[AXIS_Z]) { return (AXIS_Z); } - if (cm.gf.target[AXIS_X]) { + if (cm->gf.target[AXIS_X]) { return (AXIS_X); } - if (cm.gf.target[AXIS_Y]) { + if (cm->gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } - if (cm.gf.target[AXIS_B]) { + if (cm->gf.target[AXIS_B]) { return (AXIS_B); } - if (cm.gf.target[AXIS_C]) { + if (cm->gf.target[AXIS_C]) { return (AXIS_C); } return (-2); // error } else if (axis == AXIS_Z) { - if (cm.gf.target[AXIS_X]) { + if (cm->gf.target[AXIS_X]) { return (AXIS_X); } - if (cm.gf.target[AXIS_Y]) { + if (cm->gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } - if (cm.gf.target[AXIS_B]) { + if (cm->gf.target[AXIS_B]) { return (AXIS_B); } - if (cm.gf.target[AXIS_C]) { + if (cm->gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_X) { - if (cm.gf.target[AXIS_Y]) { + if (cm->gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } - if (cm.gf.target[AXIS_B]) { + if (cm->gf.target[AXIS_B]) { return (AXIS_B); } - if (cm.gf.target[AXIS_C]) { + if (cm->gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_Y) { - if (cm.gf.target[AXIS_A]) { + if (cm->gf.target[AXIS_A]) { return (AXIS_A); } - if (cm.gf.target[AXIS_B]) { + if (cm->gf.target[AXIS_B]) { return (AXIS_B); } - if (cm.gf.target[AXIS_C]) { + if (cm->gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_A) { - if (cm.gf.target[AXIS_B]) { + if (cm->gf.target[AXIS_B]) { return (AXIS_B); } - if (cm.gf.target[AXIS_C]) { + if (cm->gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_B) { - if (cm.gf.target[AXIS_C]) { + if (cm->gf.target[AXIS_C]) { return (AXIS_C); } } diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index 43d8ddd2..e161831e 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -84,12 +84,12 @@ static stat_t _jogging_finalize_exit(int8_t axis); stat_t cm_jogging_cycle_start(uint8_t axis) { // save relevant non-axis parameters from Gcode model - jog.saved_units_mode = cm_get_units_mode(ACTIVE_MODEL); // cm.gm.units_mode; - jog.saved_coord_system = cm_get_coord_system(ACTIVE_MODEL); // cm.gm.coord_system; - jog.saved_distance_mode = cm_get_distance_mode(ACTIVE_MODEL); // cm.gm.distance_mode; + jog.saved_units_mode = cm_get_units_mode(ACTIVE_MODEL); // cm->gm.units_mode; + jog.saved_coord_system = cm_get_coord_system(ACTIVE_MODEL); // cm->gm.coord_system; + jog.saved_distance_mode = cm_get_distance_mode(ACTIVE_MODEL); // cm->gm.distance_mode; jog.saved_feed_rate_mode = cm_get_feed_rate_mode(ACTIVE_MODEL); - jog.saved_feed_rate = (ACTIVE_MODEL)->feed_rate; // cm.gm.feed_rate; - jog.saved_jerk = cm.a[axis].jerk_max; + jog.saved_feed_rate = (ACTIVE_MODEL)->feed_rate; // cm->gm.feed_rate; + jog.saved_jerk = cm->a[axis].jerk_max; // set working values cm_set_units_mode(MILLIMETERS); @@ -98,7 +98,7 @@ stat_t cm_jogging_cycle_start(uint8_t axis) { cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); jog.velocity_start = JOGGING_START_VELOCITY; // see canonical_machine.h for #define - jog.velocity_max = cm.a[axis].velocity_max; + jog.velocity_max = cm->a[axis].velocity_max; jog.start_pos = cm_get_absolute_position(RUNTIME, axis); jog.dest_pos = cm_get_jogging_dest(); @@ -107,8 +107,8 @@ stat_t cm_jogging_cycle_start(uint8_t axis) { jog.axis = axis; jog.func = _jogging_axis_start; // bind initial processing function - cm.machine_state = MACHINE_CYCLE; - cm.cycle_state = CYCLE_JOG; + cm->machine_state = MACHINE_CYCLE; + cm->cycle_state = CYCLE_JOG; return (STAT_OK); } @@ -123,7 +123,7 @@ stat_t cm_jogging_cycle_start(uint8_t axis) { */ stat_t cm_jogging_cycle_callback(void) { - if (cm.cycle_state != CYCLE_JOG) { + if (cm->cycle_state != CYCLE_JOG) { return (STAT_NOOP); // exit if not in a jogging cycle } if (jog.func == _jogging_finalize_exit && cm_get_runtime_busy() == true) { diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp old mode 100755 new mode 100644 index c6ac4dba..52d18c41 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -130,8 +130,8 @@ static stat_t _set_pb_func(uint8_t (*func)()) { * in-progress) occupies one of those positions, wich is the one reported by the * "prb" JSON. * - * Internally we store the active/most recent probe in cm.probe_results[0] and - * cm.probe_state[0]. Before we start a new probe, if cm.probe_state[0] == + * Internally we store the active/most recent probe in cm->probe_results[0] and + * cm->probe_state[0]. Before we start a new probe, if cm->probe_state[0] == * PROBE_SUCCEEDED, then we roll 0 to 1, and 1 to 2, up to PROBES_STORED-1. * The oldest probe is "lost." * @@ -139,7 +139,7 @@ static stat_t _set_pb_func(uint8_t (*func)()) { uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, bool moving_toward_switch) { // trap zero feed rate condition - if (fp_ZERO(cm.gm.feed_rate)) { + if (fp_ZERO(cm->gm.feed_rate)) { return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); } @@ -156,19 +156,19 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, b copy_vector(pb.flags, flags); // set axes involved on the move // if the previous probe succeeded, roll probes to the next position - if (cm.probe_state[0] == PROBE_SUCCEEDED) { + if (cm->probe_state[0] == PROBE_SUCCEEDED) { for (uint8_t n = PROBES_STORED - 1; n > 0; n--) { - cm.probe_state[n] = cm.probe_state[n - 1]; - for (uint8_t axis = 0; axis < AXES; axis++) { cm.probe_results[n][axis] = cm.probe_results[n - 1][axis]; } + cm->probe_state[n] = cm->probe_state[n - 1]; + for (uint8_t axis = 0; axis < AXES; axis++) { cm->probe_results[n][axis] = cm->probe_results[n - 1][axis]; } } } // clear the old probe position - clear_vector(cm.probe_results[0]); + clear_vector(cm->probe_results[0]); // NOTE: relying on probe_result will not detect a probe to 0,0,0. - cm.probe_state[0] = PROBE_WAITING; // wait until planner queue empties before completing initialization + cm->probe_state[0] = PROBE_WAITING; // wait until planner queue empties before completing initialization pb.waiting_for_motion_end = true; // queue a function to let us know when we can start probing @@ -195,7 +195,7 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, b */ uint8_t cm_probing_cycle_callback(void) { - if ((cm.cycle_state != CYCLE_PROBE) && (cm.probe_state[0] != PROBE_WAITING)) { // exit if not in a homing cycle + if ((cm->cycle_state != CYCLE_PROBE) && (cm->probe_state[0] != PROBE_WAITING)) { // exit if not in a homing cycle return (STAT_NOOP); } if (pb.waiting_for_motion_end) { // sync to planner move ends (using callback) @@ -219,9 +219,9 @@ static uint8_t _probing_init() { // so optimistic... ;) // NOTE: it is *not* an error condition for the probe not to trigger. // it is an error for the limit or homing switches to fire, or for some other configuration error. - cm.probe_state[0] = PROBE_FAILED; - cm.machine_state = MACHINE_CYCLE; - cm.cycle_state = CYCLE_PROBE; + cm->probe_state[0] = PROBE_FAILED; + cm->machine_state = MACHINE_CYCLE; + cm->cycle_state = CYCLE_PROBE; // save relevant non-axis parameters from Gcode model pb.saved_coord_system = cm_get_coord_system(ACTIVE_MODEL); @@ -234,7 +234,7 @@ static uint8_t _probing_init() { // initialize the axes - save the jerk settings & switch to the jerk_homing settings for (uint8_t axis = 0; axis < AXES; axis++) { pb.saved_jerk[axis] = cm_get_axis_jerk(axis); // save the max jerk value - cm_set_axis_jerk(axis, cm.a[axis].jerk_high); // use the high-speed jerk for probe + cm_set_axis_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for probe start_position[axis] = cm_get_absolute_position(ACTIVE_MODEL, axis); } @@ -254,10 +254,10 @@ static uint8_t _probing_init() { // initialize the probe switch // TODO -- for now we hard code it to z homing switch - if (fp_ZERO(cm.a[AXIS_Z].homing_input)) { + if (fp_ZERO(cm->a[AXIS_Z].homing_input)) { return (_probing_error_exit(-2)); } - pb.probe_input = cm.a[AXIS_Z].homing_input; + pb.probe_input = cm->a[AXIS_Z].homing_input; gpio_set_probing_mode(pb.probe_input, true); // turn off spindle and start the move @@ -281,7 +281,7 @@ static stat_t _probing_start() { return (_set_pb_func(_probing_backoff)); } - cm.probe_state[0] = PROBE_FAILED; // we failed + cm->probe_state[0] = PROBE_FAILED; // we failed return (_set_pb_func(_probing_finish)); } @@ -299,7 +299,7 @@ static stat_t _probing_backoff() { // INPUT_INACTIVE is the right end condition for G38.4 and G38.5 // Note that we're testing for SUCCESS here if (probe == (pb.moving_toward_switch ? INPUT_ACTIVE : INPUT_INACTIVE)) { - cm.probe_state[0] = PROBE_SUCCEEDED; + cm->probe_state[0] = PROBE_SUCCEEDED; // capture contact position in step space and convert from steps to mm. // snapshot was taken by switch interrupt at the time of closure @@ -308,18 +308,18 @@ static stat_t _probing_backoff() { _probe_axis_move(contact_position, true); // NB: feed rate is the same as the probe move } else { - cm.probe_state[0] = PROBE_FAILED; + cm->probe_state[0] = PROBE_FAILED; } return (_set_pb_func(_probing_finish)); } static stat_t _probe_axis_move(const float target[], bool exact_position) { - auto stored_units_mode = cm.gm.units_mode; - auto stored_distance_mode = cm.gm.distance_mode; + auto stored_units_mode = cm->gm.units_mode; + auto stored_distance_mode = cm->gm.distance_mode; if (exact_position) { cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); // Position was stored in absolute coords - cm.gm.units_mode = MILLIMETERS; - cm.gm.distance_mode = ABSOLUTE_MODE; + cm->gm.units_mode = MILLIMETERS; + cm->gm.distance_mode = ABSOLUTE_MODE; } for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions @@ -332,8 +332,8 @@ static stat_t _probe_axis_move(const float target[], bool exact_position) { cm_straight_feed(target, pb.flags); if (exact_position) { - cm.gm.units_mode = stored_units_mode; - cm.gm.distance_mode = stored_distance_mode; + cm->gm.units_mode = stored_units_mode; + cm->gm.distance_mode = stored_distance_mode; } // the last two arguments are ignored anyway @@ -350,30 +350,30 @@ static void _probe_axis_move_callback(float* vect, bool* flag) { pb.waiting_for_ static stat_t _probing_finish() { for (uint8_t axis = 0; axis < AXES; axis++) { - cm.probe_results[0][axis] = cm_get_absolute_position(ACTIVE_MODEL, axis); + cm->probe_results[0][axis] = cm_get_absolute_position(ACTIVE_MODEL, axis); } // If probe was successful the 'e' word == 1, otherwise e == 0 to signal an error char buf[32]; char* bufp = buf; - bufp += sprintf(bufp, "{\"prb\":{\"e\":%i, \"", (int)cm.probe_state[0]); + bufp += sprintf(bufp, "{\"prb\":{\"e\":%i, \"", (int)cm->probe_state[0]); if (pb.flags[AXIS_X]) { - sprintf(bufp, "x\":%0.3f}}\n", cm.probe_results[0][AXIS_X]); + sprintf(bufp, "x\":%0.3f}}\n", cm->probe_results[0][AXIS_X]); } if (pb.flags[AXIS_Y]) { - sprintf(bufp, "y\":%0.3f}}\n", cm.probe_results[0][AXIS_Y]); + sprintf(bufp, "y\":%0.3f}}\n", cm->probe_results[0][AXIS_Y]); } if (pb.flags[AXIS_Z]) { - sprintf(bufp, "z\":%0.3f}}\n", cm.probe_results[0][AXIS_Z]); + sprintf(bufp, "z\":%0.3f}}\n", cm->probe_results[0][AXIS_Z]); } if (pb.flags[AXIS_A]) { - sprintf(bufp, "a\":%0.3f}}\n", cm.probe_results[0][AXIS_A]); + sprintf(bufp, "a\":%0.3f}}\n", cm->probe_results[0][AXIS_A]); } if (pb.flags[AXIS_B]) { - sprintf(bufp, "b\":%0.3f}}\n", cm.probe_results[0][AXIS_B]); + sprintf(bufp, "b\":%0.3f}}\n", cm->probe_results[0][AXIS_B]); } if (pb.flags[AXIS_C]) { - sprintf(bufp, "c\":%0.3f}}\n", cm.probe_results[0][AXIS_C]); + sprintf(bufp, "c\":%0.3f}}\n", cm->probe_results[0][AXIS_C]); } xio_writeline(buf); @@ -391,7 +391,7 @@ static void _probe_restore_settings() { gpio_set_probing_mode(pb.probe_input, false); // restore axis jerk - for (uint8_t axis = 0; axis < AXES; axis++) { cm.a[axis].jerk_max = pb.saved_jerk[axis]; } + for (uint8_t axis = 0; axis < AXES; axis++) { cm->a[axis].jerk_max = pb.saved_jerk[axis]; } // restore coordinate system and distance mode cm_set_coord_system(pb.saved_coord_system); @@ -407,7 +407,7 @@ static void _probe_restore_settings() { static stat_t _probing_finalize_exit() { _probe_restore_settings(); - if (cm.probe_state[0] == PROBE_SUCCEEDED) { + if (cm->probe_state[0] == PROBE_SUCCEEDED) { return (STAT_OK); } diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index cd591cda..d302b4e7 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -35,9 +35,9 @@ static stat_t _validate_gcode_block(char *active_comment); static stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs static stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block -#define SET_MODAL(m,parm,val) ({cm.gn.parm=val; cm.gf.parm=true; cm.gf.modals[m]=true; break;}) -#define SET_NON_MODAL(parm,val) ({cm.gn.parm=val; cm.gf.parm=true; break;}) -#define EXEC_FUNC(f,v) if(cm.gf.v) { status=f(cm.gn.v);} +#define SET_MODAL(m,parm,val) ({cm->gn.parm=val; cm->gf.parm=true; cm->gf.modals[m]=true; break;}) +#define SET_NON_MODAL(parm,val) ({cm->gn.parm=val; cm->gf.parm=true; break;}) +#define EXEC_FUNC(f,v) if(cm->gf.v) { status=f(cm->gn.v);} /* * gcode_parser() - parse a block (line) of gcode @@ -387,12 +387,12 @@ static stat_t _validate_gcode_block(char *active_comment) // uses axis words appears on the line, the activity of the group 1 G-code is suspended // for that line. The axis word-using G-codes from group 0 are G10, G28, G30, and G92" -// if ((cm.gn.modals[MODAL_GROUP_G0] == true) && (cm.gn.modals[MODAL_GROUP_G1] == true)) { +// if ((cm->gn.modals[MODAL_GROUP_G0] == true) && (cm->gn.modals[MODAL_GROUP_G1] == true)) { // return (STAT_MODAL_GROUP_VIOLATION); // } // look for commands that require an axis word to be present -// if ((cm.gn.modals[MODAL_GROUP_G0] == true) || (cm.gn.modals[MODAL_GROUP_G1] == true)) { +// if ((cm->gn.modals[MODAL_GROUP_G0] == true) || (cm->gn.modals[MODAL_GROUP_G1] == true)) { // if (_axis_changed() == false) // return (STAT_GCODE_AXIS_IS_MISSING); // } @@ -415,16 +415,16 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) stat_t status = STAT_OK; // set initial state for new move - memset(&cm.gn, 0, sizeof(GCodeInput_t)); // clear all next-state values - memset(&cm.gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags - cm.gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block + memset(&cm->gn, 0, sizeof(GCodeInput_t)); // clear all next-state values + memset(&cm->gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags + cm->gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block // Causes a later exception if // (1) INVERSE_TIME_MODE is active and a feed rate is not provided or // (2) INVERSE_TIME_MODE is changed to UNITS_PER_MINUTE and a new feed rate is missing - if (cm.gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate req'd when in INV_TIME_MODE - cm.gn.feed_rate = 0; - cm.gf.feed_rate = true; + if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate req'd when in INV_TIME_MODE + cm->gn.feed_rate = 0; + cm->gf.feed_rate = true; } // extract commands and parameters @@ -620,7 +620,7 @@ static stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; - cm_set_model_linenum(cm.gn.linenum); + cm_set_model_linenum(cm->gn.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, feed_rate); // F EXEC_FUNC(cm_set_spindle_speed, spindle_speed); // S @@ -642,8 +642,8 @@ static stat_t _execute_gcode_block(char *active_comment) // EXEC_FUNC(cm_mfo_enable, feed_rate_override_factor); // EXEC_FUNC(cm_sso_enable, sso_enable); - if (cm.gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell - ritorno(cm_dwell(cm.gn.parameter)); // return if error, otherwise complete the block + if (cm->gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell + ritorno(cm_dwell(cm->gn.parameter)); // return if error, otherwise complete the block } EXEC_FUNC(cm_select_plane, select_plane); // G17, G18, G19 EXEC_FUNC(cm_set_units_mode, units_mode); // G20, G21 @@ -651,29 +651,29 @@ static stat_t _execute_gcode_block(char *active_comment) //--> cutter length compensation goes here EXEC_FUNC(cm_set_coord_system, coord_system); // G54, G55, G56, G57, G58, G59 // EXEC_FUNC(cm_set_path_control, path_control); // G61, G61.1, G64 - if(cm.gf.path_control) { status = cm_set_path_control(MODEL, cm.gn.path_control); } + if(cm->gf.path_control) { status = cm_set_path_control(MODEL, cm->gn.path_control); } EXEC_FUNC(cm_set_distance_mode, distance_mode); // G90, G91 EXEC_FUNC(cm_set_arc_distance_mode, arc_distance_mode); // G90.1, G91.1 //--> set retract mode goes here - switch (cm.gn.next_action) { + switch (cm->gn.next_action) { case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(cm.gn.target, cm.gf.target); break;} // G28 + case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(cm->gn.target, cm->gf.target); break;} // G28 case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(cm.gn.target, cm.gf.target); break;} // G30 + case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(cm->gn.target, cm->gf.target); break;} // G30 case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(cm.gn.target, cm.gf.target); break;}// G28.3 + case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(cm->gn.target, cm->gf.target); break;}// G28.3 case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(); break;} // G28.4 - case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(cm.gn.target, cm.gf.target, true, true); break;} // G38.2 - case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(cm.gn.target, cm.gf.target, false, true); break;} // G38.3 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(cm.gn.target, cm.gf.target, true, false); break;} // G38.4 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(cm.gn.target, cm.gf.target, false, false); break;} // G38.5 + case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(cm->gn.target, cm->gf.target, true, true); break;} // G38.2 + case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(cm->gn.target, cm->gf.target, false, true); break;} // G38.3 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(cm->gn.target, cm->gf.target, true, false); break;} // G38.4 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(cm->gn.target, cm->gf.target, false, false); break;} // G38.5 - case NEXT_ACTION_SET_COORD_DATA: { status = cm_set_coord_offsets(cm.gn.parameter, cm.gn.L_word, cm.gn.target, cm.gf.target); break;} - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(cm.gn.target, cm.gf.target); break;}// G92 + case NEXT_ACTION_SET_COORD_DATA: { status = cm_set_coord_offsets(cm->gn.parameter, cm->gn.L_word, cm->gn.target, cm->gf.target); break;} + case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(cm->gn.target, cm->gf.target); break;}// G92 case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 @@ -683,18 +683,18 @@ static stat_t _execute_gcode_block(char *active_comment) // case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 case NEXT_ACTION_DEFAULT: { - cm_set_absolute_override(MODEL, cm.gn.absolute_override); // apply absolute override - switch (cm.gn.motion_mode) { - case MOTION_MODE_CANCEL_MOTION_MODE: { cm.gm.motion_mode = cm.gn.motion_mode; break;} // G80 - case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(cm.gn.target, cm.gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(cm.gn.target, cm.gf.target); break;} // G1 + cm_set_absolute_override(MODEL, cm->gn.absolute_override); // apply absolute override + switch (cm->gn.motion_mode) { + case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = cm->gn.motion_mode; break;} // G80 + case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(cm->gn.target, cm->gf.target); break;} // G0 + case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(cm->gn.target, cm->gf.target); break;} // G1 case MOTION_MODE_CW_ARC: // G2 - case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(cm.gn.target, cm.gf.target, // G3 - cm.gn.arc_offset, cm.gf.arc_offset, - cm.gn.arc_radius, cm.gf.arc_radius, - cm.gn.parameter, cm.gf.parameter, - cm.gf.modals[MODAL_GROUP_G1], - cm.gn.motion_mode); + case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(cm->gn.target, cm->gf.target, // G3 + cm->gn.arc_offset, cm->gf.arc_offset, + cm->gn.arc_radius, cm->gf.arc_radius, + cm->gn.parameter, cm->gf.parameter, + cm->gf.modals[MODAL_GROUP_G1], + cm->gn.motion_mode); break; } default: break; @@ -704,8 +704,8 @@ static stat_t _execute_gcode_block(char *active_comment) } // do the program stops and ends : M0, M1, M2, M30, M60 - if (cm.gf.program_flow == true) { - if (cm.gn.program_flow == PROGRAM_STOP) { + if (cm->gf.program_flow == true) { + if (cm->gn.program_flow == PROGRAM_STOP) { cm_program_stop(); } else { cm_program_end(); diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp old mode 100755 new mode 100644 index 4ec98fb8..18992875 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -194,20 +194,20 @@ struct ioDigitalInputExt { // these functions trigger on the leading edge if (in->edge == INPUT_EDGE_LEADING) { if (in->function == INPUT_FUNCTION_LIMIT) { - cm.limit_requested = ext_pin_number; + cm->limit_requested = ext_pin_number; } else if (in->function == INPUT_FUNCTION_SHUTDOWN) { - cm.shutdown_requested = ext_pin_number; + cm->shutdown_requested = ext_pin_number; } else if (in->function == INPUT_FUNCTION_INTERLOCK) { - cm.safety_interlock_disengaged = ext_pin_number; + cm->safety_interlock_disengaged = ext_pin_number; } } // trigger interlock release on trailing edge if (in->edge == INPUT_EDGE_TRAILING) { if (in->function == INPUT_FUNCTION_INTERLOCK) { - cm.safety_interlock_reengaged = ext_pin_number; + cm->safety_interlock_reengaged = ext_pin_number; } } diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp old mode 100755 new mode 100644 index 9aa2abdd..e2c0b5e2 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -529,7 +529,7 @@ void json_print_response(uint8_t status) } if (js.json_verbosity == JV_EXCEPTIONS) { // cutout for JV_EXCEPTIONS mode if (status == STAT_OK) { - if (cm.machine_state != MACHINE_INITIALIZING) { // always do full echo during startup + if (cm->machine_state != MACHINE_INITIALIZING) { // always do full echo during startup return; } } @@ -541,7 +541,7 @@ void json_print_response(uint8_t status) nv_reset_nv_list(); nv_add_string((const char *)"err", escape_string(cs.bufp, cs.saved_buf)); - } else if ((cm.machine_state != MACHINE_INITIALIZING) || (status == STAT_INITIALIZING)) { // always do full echo during startup + } else if ((cm->machine_state != MACHINE_INITIALIZING) || (status == STAT_INITIALIZING)) { // always do full echo during startup uint8_t nv_type; do { if ((nv_type = nv_get_type(nv)) == NV_TYPE_NULL) break; diff --git a/g2core/kinematics.cpp b/g2core/kinematics.cpp old mode 100755 new mode 100644 index db55679a..9e200f61 --- a/g2core/kinematics.cpp +++ b/g2core/kinematics.cpp @@ -57,7 +57,7 @@ void kn_inverse_kinematics(const float travel[], float steps[]) { // Most of the conversion math has already been done in during config in steps_per_unit() // which takes axis travel, step angle and microsteps into account. for (uint8_t axis=0; axisa[axis].axis_mode == AXIS_INHIBITED) { joint[axis] = 0;} if (st_cfg.mot[MOTOR_1].motor_map == axis) { steps[MOTOR_1] = joint[axis] * st_cfg.mot[MOTOR_1].steps_per_unit; } @@ -85,7 +85,7 @@ void kn_inverse_kinematics(const float travel[], float steps[]) { #else for (uint8_t axis = 0; axis < AXES; axis++) { - if (cm.a[axis].axis_mode == AXIS_INHIBITED) { + if (cm->a[axis].axis_mode == AXIS_INHIBITED) { joint[axis] = 0; continue; } @@ -141,7 +141,7 @@ void kn_forward_kinematics(const float steps[], float travel[]) { // Scan through each axis, and then through each motor for (uint8_t axis = 0; axis < AXES; axis++) { - if (cm.a[axis].axis_mode == AXIS_INHIBITED) { + if (cm->a[axis].axis_mode == AXIS_INHIBITED) { travel[axis] = 0.0; continue; } diff --git a/g2core/main.cpp b/g2core/main.cpp old mode 100755 new mode 100644 index 8ec0c53e..048f39b0 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -101,7 +101,8 @@ void application_init_services(void) void application_init_machine(void) { - cm.machine_state = MACHINE_INITIALIZING; + cm = &cm0; + cm->machine_state = MACHINE_INITIALIZING; stepper_init(); // stepper subsystem encoder_init(); // virtual encoders diff --git a/g2core/persistence.cpp b/g2core/persistence.cpp old mode 100755 new mode 100644 index b58d25ca..8644d6da --- a/g2core/persistence.cpp +++ b/g2core/persistence.cpp @@ -71,7 +71,7 @@ stat_t read_persistent_value(nvObj_t *nv) stat_t write_persistent_value(nvObj_t *nv) { - if (cm.cycle_state != CYCLE_OFF) { // can't write when machine is moving + if (cm->cycle_state != CYCLE_OFF) { // can't write when machine is moving return(rpt_exception(STAT_FILE_NOT_OPEN, "write_persistent_value() can't write when machine is in cycle")); } return (STAT_OK); diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index d9dc6bc8..9c715e56 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -135,21 +135,21 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // - rotary axes are present. Ignored // trap missing feed rate - if (fp_ZERO(cm.gm.feed_rate)) { + if (fp_ZERO(cm->gm.feed_rate)) { return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); } // Set the arc plane for the current G17/G18/G19 setting and test arc specification // Plane axis 0 and 1 are the arc plane, the linear axis is normal to the arc plane. - if (cm.gm.select_plane == CANON_PLANE_XY) { // G17 - the vast majority of arcs are in the G17 (XY) plane + if (cm->gm.select_plane == CANON_PLANE_XY) { // G17 - the vast majority of arcs are in the G17 (XY) plane arc.plane_axis_0 = AXIS_X; arc.plane_axis_1 = AXIS_Y; arc.linear_axis = AXIS_Z; - } else if (cm.gm.select_plane == CANON_PLANE_XZ) { // G18 + } else if (cm->gm.select_plane == CANON_PLANE_XZ) { // G18 arc.plane_axis_0 = AXIS_X; arc.plane_axis_1 = AXIS_Z; arc.linear_axis = AXIS_Y; - } else if (cm.gm.select_plane == CANON_PLANE_YZ) { // G19 + } else if (cm->gm.select_plane == CANON_PLANE_YZ) { // G19 arc.plane_axis_0 = AXIS_Y; arc.plane_axis_1 = AXIS_Z; arc.linear_axis = AXIS_X; @@ -175,7 +175,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en } } else { // test that center format absolute distance mode arcs have both offsets specified - if (cm.gm.arc_distance_mode == ABSOLUTE_MODE) { + if (cm->gm.arc_distance_mode == ABSOLUTE_MODE) { if (!(offset_f[arc.plane_axis_0] && offset_f[arc.plane_axis_1])) { // if one or both offsets are missing return (STAT_ARC_OFFSETS_MISSING_FOR_SELECTED_PLANE); } @@ -204,18 +204,18 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // in radius mode it's an error for start == end if (radius_f) { - if ((fp_EQ(cm.gmx.position[AXIS_X], cm.gm.target[AXIS_X])) && - (fp_EQ(cm.gmx.position[AXIS_Y], cm.gm.target[AXIS_Y])) && - (fp_EQ(cm.gmx.position[AXIS_Z], cm.gm.target[AXIS_Z]))) { + if ((fp_EQ(cm->gmx.position[AXIS_X], cm->gm.target[AXIS_X])) && + (fp_EQ(cm->gmx.position[AXIS_Y], cm->gm.target[AXIS_Y])) && + (fp_EQ(cm->gmx.position[AXIS_Z], cm->gm.target[AXIS_Z]))) { return (STAT_ARC_ENDPOINT_IS_STARTING_POINT); } } // *** now get down to the rest of the work setting up the arc for execution *** - cm.gm.motion_mode = motion_mode; - cm_set_work_offsets(&cm.gm); // capture the fully resolved offsets to gm - memcpy(&arc.gm, &cm.gm, sizeof(GCodeState_t)); // copy GCode context to arc singleton - some will be overwritten to run segments - copy_vector(arc.position, cm.gmx.position); // set initial arc position from gcode model + cm->gm.motion_mode = motion_mode; + cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to gm + memcpy(&arc.gm, &cm->gm, sizeof(GCodeState_t)); // copy GCode context to arc singleton - some will be overwritten to run segments + copy_vector(arc.position, cm->gmx.position); // set initial arc position from gcode model // setup offsets arc.offset[OFS_I] = _to_millimeters(offset[OFS_I]); // copy offsets with conversion to canonical form (mm) @@ -240,8 +240,8 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // test arc soft limits stat_t status = _test_arc_soft_limits(); if (status != STAT_OK) { - cm.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - copy_vector(cm.gm.target, arc.position); // reset model position + cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + copy_vector(cm->gm.target, arc.position); // reset model position return (cm_alarm(status, "arc soft_limits")); // throw an alarm } @@ -333,7 +333,7 @@ static stat_t _compute_arc(const bool radius_f) // Note: removed segment_length test as segment_time accounts for this (build 083.37) float arc_time; float segments_for_minimum_time = _estimate_arc_time(arc_time) * (MICROSECONDS_PER_MINUTE / MIN_ARC_SEGMENT_USEC); - float segments_for_chordal_accuracy = arc.length / sqrt(4*cm.chordal_tolerance * (2 * arc.radius - cm.chordal_tolerance)); + float segments_for_chordal_accuracy = arc.length / sqrt(4*cm->chordal_tolerance * (2 * arc.radius - cm->chordal_tolerance)); arc.segments = floor(min(segments_for_chordal_accuracy, segments_for_minimum_time)); arc.segments = max(arc.segments, (float)1.0); //...but is at least 1 segment @@ -482,14 +482,14 @@ static float _estimate_arc_time (float arc_time) if (arc.gm.feed_rate_mode == INVERSE_TIME_MODE) { arc_time = arc.gm.feed_rate; // inverse feed rate has been normalized to minutes } else { - arc_time = arc.length / cm.gm.feed_rate; + arc_time = arc.length / cm->gm.feed_rate; } // Downgrade the time if there is a rate-limiting axis - arc_time = max(arc_time, (float)fabs(arc.planar_travel/cm.a[arc.plane_axis_0].feedrate_max)); - arc_time = max(arc_time, (float)fabs(arc.planar_travel/cm.a[arc.plane_axis_1].feedrate_max)); + arc_time = max(arc_time, (float)fabs(arc.planar_travel/cm->a[arc.plane_axis_0].feedrate_max)); + arc_time = max(arc_time, (float)fabs(arc.planar_travel/cm->a[arc.plane_axis_1].feedrate_max)); if (fabs(arc.linear_travel) > 0) { - arc_time = max(arc_time, (float)fabs(arc.linear_travel/cm.a[arc.linear_axis].feedrate_max)); + arc_time = max(arc_time, (float)fabs(arc.linear_travel/cm->a[arc.linear_axis].feedrate_max)); } return (arc_time); } @@ -555,11 +555,11 @@ static stat_t _test_arc_soft_limit_plane_axis(float center, uint8_t plane_axis) if (arc.angular_travel < M_PI) { // case (1) return (STAT_OK); } - if ((center - arc.radius) < cm.a[plane_axis].travel_min) { // case (2) + if ((center - arc.radius) < cm->a[plane_axis].travel_min) { // case (2) return (STAT_SOFT_LIMIT_EXCEEDED); } } - if ((center + arc.radius) > cm.a[plane_axis].travel_max) { // cases (3) and (4) + if ((center + arc.radius) > cm->a[plane_axis].travel_max) { // cases (3) and (4) return (STAT_SOFT_LIMIT_EXCEEDED); } return(STAT_OK); @@ -568,7 +568,7 @@ static stat_t _test_arc_soft_limit_plane_axis(float center, uint8_t plane_axis) static stat_t _test_arc_soft_limits() { /* - if (cm.soft_limit_enable == true) { + if (cm->soft_limit_enable == true) { // Test if target falls outside boundaries. This is a 3 dimensional test // so it also checks the linear axis of the arc (helix axis) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 8727e4e4..04e49d90 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -253,7 +253,7 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { - if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm.motion_state == MOTION_RUN)) { + if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) { __asm__("BKPT"); // mp_exec_move() buffer is not prepped // IMPORTANT: We can't rpt_exception from here! st_prep_null(); @@ -266,7 +266,7 @@ stat_t mp_exec_move() } if (bf->buffer_state == MP_BUFFER_PREPPED) { - if (cm.motion_state == MOTION_RUN) { + if (cm->motion_state == MOTION_RUN) { __asm__("BKPT"); // we are running but don't have a block planned } // We need to have it planned. We don't want to do this here, as it @@ -292,7 +292,7 @@ stat_t mp_exec_move() } // Manage motion state transitions - if ((cm.motion_state != MOTION_RUN) && (cm.motion_state != MOTION_HOLD)) { + if ((cm->motion_state != MOTION_RUN) && (cm->motion_state != MOTION_HOLD)) { cm_set_motion_state(MOTION_RUN); } } @@ -519,20 +519,20 @@ stat_t mp_exec_aline(mpBuf_t *bf) // (8) - We are removing the hold state and there is queued motion (handled outside this routine) // (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) - if (cm.motion_state == MOTION_HOLD) { + if (cm->motion_state == MOTION_HOLD) { // Case (7) - all motion has ceased - if (cm.hold_state == FEEDHOLD_HOLD) { + if (cm->hold_state == FEEDHOLD_HOLD) { return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } // Case (6) - wait for the steppers to stop - if (cm.hold_state == FEEDHOLD_PENDING) { + if (cm->hold_state == FEEDHOLD_PENDING) { if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out - if ((cm.cycle_state == CYCLE_HOMING) || (cm.cycle_state == CYCLE_PROBE)) { + if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { // when homing, we don't need to stay in HOLD - cm.hold_state = FEEDHOLD_OFF; + cm->hold_state = FEEDHOLD_OFF; } else { - cm.hold_state = FEEDHOLD_HOLD; + cm->hold_state = FEEDHOLD_HOLD; } mp_zero_segment_velocity(); // for reporting purposes sr_request_status_report(SR_REQUEST_IMMEDIATE); // was SR_REQUEST_TIMED @@ -543,16 +543,16 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (5) - decelerated to zero // Update the run buffer then force a replan of the whole planner queue - if (cm.hold_state == FEEDHOLD_DECEL_END) { + if (cm->hold_state == FEEDHOLD_DECEL_END) { mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr.target, mr.position);// reset length //bf->entry_vmax = 0; // set bp+0 as hold point - cm.hold_state = FEEDHOLD_PENDING; + cm->hold_state = FEEDHOLD_PENDING; // No point bothering with the rest of this move if homing or probing - if ((cm.cycle_state == CYCLE_HOMING) || (cm.cycle_state == CYCLE_PROBE)) { + if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { mp_free_run_buffer(); } @@ -564,15 +564,15 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Cases (1a, 1b), Case (2), Case (4) // Build a tail-only move from here. Decelerate as fast as possible in the space we have. - if ((cm.hold_state == FEEDHOLD_SYNC) || - ((cm.hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr.block_state == BLOCK_INITIAL_ACTION))) { + if ((cm->hold_state == FEEDHOLD_SYNC) || + ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr.block_state == BLOCK_INITIAL_ACTION))) { // Case (3a) - already decelerating, continue the deceleration. if (mr.section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are if (fp_ZERO(mr.r->exit_velocity)) { - cm.hold_state = FEEDHOLD_DECEL_TO_ZERO; + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; } else { - cm.hold_state = FEEDHOLD_DECEL_CONTINUE; + cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } // Case (3b) - currently accelerating - is simply skipped and waited for @@ -590,17 +590,17 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr.r->tail_length = mp_get_target_length(0, mr.r->cruise_velocity, bf); // braking length if (fp_ZERO(available_length - mr.r->tail_length)) { // (1c) the deceleration time is almost exactly the remaining of the current move - cm.hold_state = FEEDHOLD_DECEL_TO_ZERO; + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr.r->tail_length = available_length; mr.r->exit_velocity = 0; } else if (available_length < mr.r->tail_length) { // (1b) the deceleration has to span multiple moves - cm.hold_state = FEEDHOLD_DECEL_CONTINUE; + cm->hold_state = FEEDHOLD_DECEL_CONTINUE; mr.r->tail_length = available_length; mr.r->exit_velocity = mp_get_decel_velocity(mr.r->cruise_velocity, mr.r->tail_length, bf); } else { // (1a)the deceleration will fit into the current move - cm.hold_state = FEEDHOLD_DECEL_TO_ZERO; + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr.r->exit_velocity = 0; } mr.r->tail_time = mr.r->tail_length*2 / (mr.r->exit_velocity + mr.r->cruise_velocity); @@ -627,8 +627,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Feedhold Case (5): Look for the end of the deceleration to go into HOLD state - if ((cm.hold_state == FEEDHOLD_DECEL_TO_ZERO) && (status == STAT_OK)) { - cm.hold_state = FEEDHOLD_DECEL_END; + if ((cm->hold_state == FEEDHOLD_DECEL_TO_ZERO) && (status == STAT_OK)) { + cm->hold_state = FEEDHOLD_DECEL_END; bf->block_state = BLOCK_INITIAL_ACTION; // reset bf so it can restart the rest of the move } @@ -652,7 +652,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (bf->block_state == BLOCK_ACTIVE) { if (mp_free_run_buffer()) { // returns true of the buffer is empty - if (cm.hold_state == FEEDHOLD_OFF) { + if (cm->hold_state == FEEDHOLD_OFF) { cm_cycle_end(); // free buffer & end cycle if planner is empty } } else { @@ -677,7 +677,7 @@ stat_t mp_plan_feedhold_move() /* * mp_exit_hold_state() - end a feedhold * - * Feedhold is executed as cm.hold_state transitions executed inside _exec_aline() + * Feedhold is executed as cm->hold_state transitions executed inside _exec_aline() * Invoke a feedhold by calling cm_request_hold() or cm_start_hold() directly * Return from feedhold by calling cm_request_end_hold() or cm_end_hold directly. * See canonical_macine.c for a more detailed explanation of feedhold operation. @@ -685,7 +685,7 @@ stat_t mp_plan_feedhold_move() void mp_exit_hold_state() { - cm.hold_state = FEEDHOLD_OFF; + cm->hold_state = FEEDHOLD_OFF; if (mp_has_runnable_buffer(ACTIVE_Q)) { cm_set_motion_state(MOTION_RUN); sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -1029,7 +1029,7 @@ static stat_t _exec_aline_segment() // Otherwise if not at a section waypoint compute target from segment time and velocity // Don't do waypoint correction if you are going into a hold. - if ((--mr.segment_count == 0) && (cm.motion_state != MOTION_HOLD)) { + if ((--mr.segment_count == 0) && (cm->motion_state != MOTION_HOLD)) { copy_vector(mr.gm.target, mr.waypoint[mr.section]); } else { float segment_length = mr.segment_velocity * mr.segment_time; diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 1132345b..d76fd7a3 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -87,14 +87,14 @@ float mp_get_runtime_work_position(uint8_t axis) { // target_rotated[2] = a z_1 + b z_2 + c z_3 + z_offset if (axis == AXIS_X) { - return mr.position[0] * cm.rotation_matrix[0][0] + mr.position[1] * cm.rotation_matrix[1][0] + - mr.position[2] * cm.rotation_matrix[2][0] - mr.gm.work_offset[0]; + return mr.position[0] * cm->rotation_matrix[0][0] + mr.position[1] * cm->rotation_matrix[1][0] + + mr.position[2] * cm->rotation_matrix[2][0] - mr.gm.work_offset[0]; } else if (axis == AXIS_Y) { - return mr.position[0] * cm.rotation_matrix[0][1] + mr.position[1] * cm.rotation_matrix[1][1] + - mr.position[2] * cm.rotation_matrix[2][1] - mr.gm.work_offset[1]; + return mr.position[0] * cm->rotation_matrix[0][1] + mr.position[1] * cm->rotation_matrix[1][1] + + mr.position[2] * cm->rotation_matrix[2][1] - mr.gm.work_offset[1]; } else if (axis == AXIS_Z) { - return mr.position[0] * cm.rotation_matrix[0][2] + mr.position[1] * cm.rotation_matrix[1][2] + - mr.position[2] * cm.rotation_matrix[2][2] - cm.rotation_z_offset - mr.gm.work_offset[2]; + return mr.position[0] * cm->rotation_matrix[0][2] + mr.position[1] * cm->rotation_matrix[1][2] + + mr.position[2] * cm->rotation_matrix[2][2] - cm->rotation_z_offset - mr.gm.work_offset[2]; } else { // ABC, UVW, we don't rotate them return (mr.position[axis] - mr.gm.work_offset[axis]); @@ -110,7 +110,7 @@ float mp_get_runtime_work_position(uint8_t axis) { */ bool mp_get_runtime_busy() { - if (cm.cycle_state == CYCLE_OFF) { + if (cm->cycle_state == CYCLE_OFF) { return (false); } if ((st_runtime_isbusy() == true) || @@ -165,20 +165,20 @@ stat_t mp_aline(GCodeState_t* gm_in) // a being target[0], // b being target[1], // c being target[2], - // x_1 being cm.rotation_matrix[1][0] + // x_1 being cm->rotation_matrix[1][0] - target_rotated[0] = gm_in->target[0] * cm.rotation_matrix[0][0] + - gm_in->target[1] * cm.rotation_matrix[0][1] + - gm_in->target[2] * cm.rotation_matrix[0][2]; + target_rotated[0] = gm_in->target[0] * cm->rotation_matrix[0][0] + + gm_in->target[1] * cm->rotation_matrix[0][1] + + gm_in->target[2] * cm->rotation_matrix[0][2]; - target_rotated[1] = gm_in->target[0] * cm.rotation_matrix[1][0] + - gm_in->target[1] * cm.rotation_matrix[1][1] + - gm_in->target[2] * cm.rotation_matrix[1][2]; + target_rotated[1] = gm_in->target[0] * cm->rotation_matrix[1][0] + + gm_in->target[1] * cm->rotation_matrix[1][1] + + gm_in->target[2] * cm->rotation_matrix[1][2]; - target_rotated[2] = gm_in->target[0] * cm.rotation_matrix[2][0] + - gm_in->target[1] * cm.rotation_matrix[2][1] + - gm_in->target[2] * cm.rotation_matrix[2][2] + - cm.rotation_z_offset; + target_rotated[2] = gm_in->target[0] * cm->rotation_matrix[2][0] + + gm_in->target[1] * cm->rotation_matrix[2][1] + + gm_in->target[2] * cm->rotation_matrix[2][2] + + cm->rotation_z_offset; // copy rotation axes ABC target_rotated[3] = gm_in->target[3]; @@ -256,7 +256,7 @@ void mp_plan_block_list() } // OK to replan running buffer during feedhold, but no other times (not supposed to happen) - if ((cm.hold_state == FEEDHOLD_OFF) && (bf->buffer_state == MP_BUFFER_RUNNING)) { + if ((cm->hold_state == FEEDHOLD_OFF) && (bf->buffer_state == MP_BUFFER_RUNNING)) { mp.p = mp.p->nx; return; } @@ -267,7 +267,7 @@ void mp_plan_block_list() mp.p = bf; //+++++ DIAGNOSTIC - this is not needed but is set here for debugging purposes } if (mp.planner_state > PLANNER_STARTUP) { - if (planned_something && (cm.hold_state != FEEDHOLD_HOLD)) { + if (planned_something && (cm->hold_state != FEEDHOLD_HOLD)) { st_request_forward_plan(); // start motion if runtime is not already busy } } @@ -452,7 +452,7 @@ static void _calculate_override(mpBuf_t* bf) // execute ramp to adjust cruise v // TODO: Account for rapid overrides as well as feed overrides // pull in override factor from previous block or seed initial value from the system setting - bf->override_factor = fp_ZERO(bf->pv->override_factor) ? cm.gmx.mfo_factor : bf->pv->override_factor; + bf->override_factor = fp_ZERO(bf->pv->override_factor) ? cm->gmx.mfo_factor : bf->pv->override_factor; bf->cruise_vmax = bf->override_factor * bf->cruise_vset; // generate ramp term is a ramp is active @@ -518,13 +518,13 @@ static void _calculate_jerk(mpBuf_t* bf) switch (bf->gm.motion_mode) { case MOTION_MODE_STRAIGHT_TRAVERSE: //case MOTION_MODE_STRAIGHT_PROBE: // <-- not sure on this one - axis_jerk = cm.a[axis].jerk_high; + axis_jerk = cm->a[axis].jerk_high; break; default: - axis_jerk = cm.a[axis].jerk_max; + axis_jerk = cm->a[axis].jerk_max; } #else - axis_jerk = cm.a[axis].jerk_max; + axis_jerk = cm->a[axis].jerk_max; #endif jerk = axis_jerk / fabs(bf->unit[axis]); @@ -630,9 +630,9 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (bf->axis_flags[axis]) { if (bf->gm.motion_mode == MOTION_MODE_STRAIGHT_TRAVERSE) { - tmp_time = fabs(axis_length[axis]) / cm.a[axis].velocity_max; + tmp_time = fabs(axis_length[axis]) / cm->a[axis].velocity_max; } else { // gm.motion_mode == MOTION_MODE_STRAIGHT_FEED - tmp_time = fabs(axis_length[axis]) / cm.a[axis].feedrate_max; + tmp_time = fabs(axis_length[axis]) / cm->a[axis].feedrate_max; } max_time = max(max_time, tmp_time); @@ -716,9 +716,9 @@ static void _calculate_junction_vmax(mpBuf_t* bf) if (delta > EPSILON) { // formula (4): (See Note 1, above) - // velocity = min(velocity, (cm.a[axis].max_junction_accel / delta)); - if ((cm.a[axis].max_junction_accel / delta) < velocity) { - velocity = (cm.a[axis].max_junction_accel / delta); + // velocity = min(velocity, (cm->a[axis].max_junction_accel / delta)); + if ((cm->a[axis].max_junction_accel / delta) < velocity) { + velocity = (cm->a[axis].max_junction_accel / delta); // bf->jerk_axis = axis; } } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index eef111ac..e6f8c8e6 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -466,7 +466,7 @@ bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) bool mp_is_phat_city_time() { - if(cm.hold_state == FEEDHOLD_HOLD) { + if(cm->hold_state == FEEDHOLD_HOLD) { return true; } return ((mp.plannable_time <= 0.0) || (PHAT_CITY_TIME < mp.plannable_time)); @@ -510,8 +510,8 @@ stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state if ((mp_get_planner_buffers(ACTIVE_Q) == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state - (cm.motion_state == MOTION_STOP) && - (cm.hold_state == FEEDHOLD_OFF)) { + (cm->motion_state == MOTION_STOP) && + (cm->hold_state == FEEDHOLD_OFF)) { mp.planner_state = PLANNER_IDLE; return (STAT_OK); } @@ -580,7 +580,7 @@ void mp_replan_queue(mpBuf_t *bf) void mp_start_feed_override(const float ramp_time, const float override_factor) { - cm.mfo_state = MFO_REQUESTED; + cm->mfo_state = MFO_REQUESTED; if (mp.planner_state == PLANNER_IDLE) { mp.mfo_factor = override_factor; // that was easy @@ -817,11 +817,11 @@ void mp_commit_write_buffer(const blockType block_type) q->w->block_state = BLOCK_INITIAL_ACTION; if (block_type == BLOCK_TYPE_ALINE) { - if (cm.motion_state == MOTION_STOP) { + if (cm->motion_state == MOTION_STOP) { cm_set_motion_state(MOTION_PLANNING); } } else { - if ((mp.planner_state > PLANNER_STARTUP) && (cm.hold_state == FEEDHOLD_OFF)) { + if ((mp.planner_state > PLANNER_STARTUP) && (cm->hold_state == FEEDHOLD_OFF)) { // NB: BEWARE! the requested exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents st_request_forward_plan(); // request an exec if the runtime is not busy diff --git a/g2core/planner.h b/g2core/planner.h index 2192bbe5..dbac1cb1 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -449,7 +449,7 @@ typedef struct mpMotionPlannerSingleton { // common variables for planning (mov bool ramp_active; // true when a ramp is occurring bool entry_changed; // mark if exit_velocity changed to invalidate next block's hint - // feed overrides and ramp variables (these extend the variables in cm.gmx) + // feed overrides and ramp variables (these extend the variables in cm->gmx) float mfo_factor; // runtime override factor float ramp_target; float ramp_dvdt; diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp old mode 100755 new mode 100644 index df86f333..00dd7c17 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -228,7 +228,7 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) /* stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 { - if (fp_TRUE(cm.gf.parameter) && fp_ZERO(cm.gn.parameter)) { + if (fp_TRUE(cm->gf.parameter) && fp_ZERO(cm->gn.parameter)) { spindle.override_enable = false; } else { spindle.override_enable = true; @@ -239,7 +239,7 @@ stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 stat_t cm_spindle_override_factor(uint8_t flag) // M50.1 { spindle.override_enable = flag; - spindle.override_factor = cm.gn.parameter; + spindle.override_factor = cm->gn.parameter; // change spindle speed return (STAT_OK); } diff --git a/g2core/temperature.cpp b/g2core/temperature.cpp old mode 100755 new mode 100644 index a3666df7..f5209677 --- a/g2core/temperature.cpp +++ b/g2core/temperature.cpp @@ -523,7 +523,7 @@ const float kTempDiffSRTrigger = 0.25; stat_t temperature_callback() { - if (cm.machine_state == MACHINE_ALARM) { + if (cm->machine_state == MACHINE_ALARM) { // Force the heaters off (redundant with the safety circuit) fet_pin1 = 0.0; fet_pin2 = 0.0; From 2f0ee56ecbffad52f47ad239005ff48c209fa481 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 07:51:57 -0500 Subject: [PATCH 013/283] Messing with axis types a bit --- g2core/canonical_machine.cpp | 23 ++++++++++++----------- g2core/canonical_machine.h | 10 ++++++++-- g2core/config_app.cpp | 3 ++- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 434102d1..f99bb641 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -128,7 +128,7 @@ static void _exec_absolute_origin(float *value, bool *flag); static void _exec_program_finalize(float *value, bool *flag); static int8_t _get_axis(const index_t index); -static int8_t _get_axis_type(const index_t index); +static cmAxisType _get_axis_type(const index_t index); /*********************************************************************************** **** CODE ************************************************************************* @@ -2107,12 +2107,12 @@ static int8_t _get_axis(const index_t index) return (ptr - axes); } -static int8_t _get_axis_type(const index_t index) +static cmAxisType _get_axis_type(const index_t index) { int8_t axis = _get_axis(index); - if (axis >= AXIS_A) return (1); - if (axis == -1) return (-1); - return (0); + if (axis >= AXIS_A) return (AXIS_TYPE_ROTARY); + if (axis == -1) return (AXIS_TYPE_UNDEFINED); + return (AXIS_TYPE_LINEAR); } /**** Functions called directly from cfgArray table - mostly wrappers **** @@ -2262,10 +2262,12 @@ stat_t cm_get_am(nvObj_t *nv) stat_t cm_set_am(nvObj_t *nv) // axis mode { - if (_get_axis_type(nv->index) == 0) { // linear - if (nv->value > AXIS_MODE_MAX_LINEAR) { return (STAT_INPUT_VALUE_RANGE_ERROR);} + + nv->valuetype = TYPE_INT; + if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { + if (nv->value > AXIS_MODE_LINEAR_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } else { - if (nv->value > AXIS_MODE_MAX_ROTARY) { return (STAT_INPUT_VALUE_RANGE_ERROR);} + if (nv->value > AXIS_MODE_ROTARY_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } cmAxisMode *am = (cmAxisMode *)cfgArray[nv->index].target; void *p = (cfgArray[nv->index].target); @@ -2274,11 +2276,10 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode // cmAxisMode a = (cmAxisMode)nv->value; // *am = (cmAxisMode)nv->value; *am = a; - nv->valuetype = TYPE_INT; return(STAT_OK); - set_ui8(nv); - return(STAT_OK); +// set_ui8(nv); +// return(STAT_OK); } #pragma GCC reset_options diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index c851a2c7..13b51ff9 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -276,14 +276,20 @@ typedef enum { // used for spindle and arc dir DIRECTION_CCW } cmDirection; +typedef enum { // axis types + AXIS_TYPE_UNDEFINED=-1, // invalid type + AXIS_TYPE_LINEAR, // linear axis + AXIS_TYPE_ROTARY // rotary axis +} cmAxisType; + typedef enum { // axis modes (ordered: see _cm_get_feed_time()) AXIS_DISABLED = 0, // kill axis AXIS_STANDARD, // axis in coordinated motion w/standard behaviors AXIS_INHIBITED, // axis is computed but not activated AXIS_RADIUS // rotary axis calibrated to circumference } cmAxisMode; -#define AXIS_MODE_MAX_LINEAR AXIS_INHIBITED -#define AXIS_MODE_MAX_ROTARY AXIS_RADIUS +#define AXIS_MODE_LINEAR_MAX AXIS_INHIBITED +#define AXIS_MODE_ROTARY_MAX AXIS_RADIUS /***************************************************************************** * GCODE MODEL - The following GCodeModel/GCodeInput structs are used: diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 267dbfc6..2eaa9636 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -267,7 +267,8 @@ const cfgItem_t cfgArray[] = { // { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, #endif // Axis parameters - { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_X].axis_mode, X_AXIS_MODE }, + { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, +// { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_X].axis_mode, X_AXIS_MODE }, { "x","xvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_X].velocity_max, X_VELOCITY_MAX }, { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, { "x","xtn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_min, X_TRAVEL_MIN }, From 03f725ae4afa5d8faaefb4376d0921b2e9123482 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 08:48:59 -0500 Subject: [PATCH 014/283] Changed axis mode get/set functions to work with multiple machine models; Simplified some of the Gcode status code defines (internal only); Added system state model Graffle to Resources/Documentation --- Resources/Documentation/SystemStates.graffle | Bin 0 -> 5805 bytes g2core/canonical_machine.cpp | 31 +++++++------------ g2core/canonical_machine.h | 2 +- g2core/config_app.cpp | 11 +++---- g2core/cycle_probing.cpp | 4 +-- g2core/error.h | 24 +++++++------- 6 files changed, 31 insertions(+), 41 deletions(-) create mode 100644 Resources/Documentation/SystemStates.graffle diff --git a/Resources/Documentation/SystemStates.graffle b/Resources/Documentation/SystemStates.graffle new file mode 100644 index 0000000000000000000000000000000000000000..4bdcd9b1007cfd0362160efc89cc6fd9aabb6cce GIT binary patch literal 5805 zcmV;e7EqUNjmAt;*OosLq4!_NNx!EhLO z`}@yMpE<{`U!9yfDv$mB=Wic64=87y3&H9{o^Y*Pd-oT5W zf+zdauhS%|Y`^CwD$9>q&a*^r9J~6f0}|dvOtX ztoz38shm!dDE6N0PsDR6A(LI2d+=m`nt4` zdN!Azwkpaua3*$=+yvfSa$4i;p~^D)Jb#*doIQUQyVvt-%`5iyUA{W1J!cIu{WkxS zwcyD6BZ{sXjEEyQ{Nj$@#s0vbkA-PdrY)K8$TUS1jIY9jz#oK_{9!f!RQhD-_EZ)# z`Pg%Vr%*iEPrpn>)h~KvK64YVTonW$>p;*!(1G+ZppPMT{t47irFJ@#C@!Zz^n<{8 z?S+vams33RN5jCqIqA7UrC8|rq4Tq&Kg!8o_6mnAh+S6WbVS)aaC zQ<|nPzLUzfK7Fa7a0%)b6^2yDmdiqm$|?^5oxC(y2y5EZLN|5uVP$9(oxI$93r1D7 ztr`#EmW5SE0Dy*fg|+EdZ0gR6J>6+FtU9X>;?C`~XimqBoTY-T7s__#v3343_EDE^QfUQbgF3@M>OF1|$xIh#=Yo^rKIx1YCB)%Py5wK}?H$h*V? zO>G*7Ui{we`{QB}Y4vIGHT2_8em}XaN}{}E-UgP;Vaa}%>RWs|AAo0ZaskiWaO9`| z^o9e7C_3v!y~x#%2q4)nqw%@=opA8r+u4OO=E-?*b^*>VM%Vsmbav6ZbmNhi0OzF_ zeDO48_}6zO+0z3{iT>*>_WFp@vq9{6q5g6nj6L4_{oqRE&z{aY@duZQ7hbqMMJmCA2fEhhs@{k= zXT1yHydQ_oBl?fBhU%u8lAmL@UtuQ5$V_tIno>Iq)F4-ORsp5bcLaa}JWNG8{ZZJ1 z&=y$U@6S(mMDS#5f+vW9;Jx<41@M>8D4!E9=9CE^Meg;Z5JabGGO~{tSauj2*#t!?=_1L6T_qMqN?b{UabYT8YI#RS&u_Yu|i82 z`gqnS2Cz253q%X><)xP&Zw*0%ki{xo16tSsTJPfIG8#mo8yvc^UQ)YK*wM=+pRTEy z4La}^r`Z!;;dD_AfS>Cj9 z10j9w4cy*MLHfcCMw20#v%Dp1SGT%418~<5YF`4Fs;*PiR-HB_$SRZ8>JGVyBNV|a zw*ZLiz~L6e5JIgqM0O>Rj4B-#46DCsVuA;IhIf}3zVJhTbm{fmPI=)1m9!kP1-@{3D-H?&)*Mplh+-+ZO35XZ5<#f9$q209 z6@ckR8o{E=kY$pVNp6x!64HuElGaSpqG%%&1=~VV2(>aOkP@N`s`#>Lyo5^u(!!sG zzjp9+9{shX0~fUIfS6wLWpc71_`|NMIc60xnRLsF~j=k2eH^- zvB6?P{V9YEda5C!Xv6M2)fV`n<)rkX7klK(!o;Q>b?f~~|3=uewezZ&(v+A$vHh9L zv}{s)9nM4oN^D`r!p>$KWCiI0rEowBN&uovvvk;H7)yc)hLA!=(j6*2RH@yeDgqT; z*OD)hEth-=!%PB*5u_Y&0PLYpyF+z%7krOydVzQL;3RSH#Xc1#%J3oyWOk%l{g-W9 zDUGA5b&ycXC(>;zq_4)r78Z-J2-XIRqAe_Pp!!S-1&fkHF0qA0yAyVoPs4j&|Lnob zDCpmzt+0AvRDIP&kVr}aRXkB}K3Ub3LbV?g2qS^m%%kaE@8?swE)=7nt@{xplyVL* zVhnK3rA0A|Vs{wDe(6Ph?|uLngk6aN5Li+uqyjO`>_it+tn^G^^#@Mn^p+!ZzX5D* z{*#2arD0hUV+j-mV~R&x0J8vghXL#j+H>Auu#=OhYNpc7-z)?4y}N>TrC^L8fFy>P zWtub98N(2wShZQJ|EJ2nY!QR8M*>CR$9qyOUOMKbG9M>~f+H`$0g}d`Vv{ zjsWXYAvsZy$N&fFA!sb_kBdnSc&#lu3~syP2DzFE3&;qAs=<|svEXI>LE2o))C6(P zzNrbM8$S-uzMnlXu9?|;yw~RjOSk6+OIYe?O2pRB=Rgj-ptSmlpDpc1-$>UU1*ydxv4!BK+)DtB;jgtEHqeXu+XsZ^xh`#abPr1w1S`SaA4Tg9G2% zR0Qv8DuUz^a8OmV;9$XFbN9O-K(a8Pa1!YZ>bne}*n*eM)Cpimu7{#MBAL8*-nfI% zTdL_DHS*LP006`w!LP%#F55|O7FAVwsF zfDynrrmEv=G61PGF8$O>uUguQuUnSX)2B)sGRo`I7i)@8n!fl_sJ{NymfCYb)53IU z+j3b9;im7()8wW0!=!0b>mVYfEE#Cr(aI$0$68YvNnXfi53kK#yY=;bfT|vY5EDeD`rn?vv+mkI*y+0++}kH)dXqTRlU|`-6+$SG zP>g$edjkBiZ%??zoENPL0#WNLVwj*9NoBPp=MYMJV8tTf9YjEuA)r!JFR@2mcI944 z*5WI_5D4KG;~{rR;fT0ikR{s>k4()4=e91nm`D^3=-90a8zHXsCxtv1)TDo=eqgiTU{0>e{#Zv9z@x-oUL+ zCSZHc3~$ddLCP-R08=6{lUSxsgj6WYux&>L1wOP?5d}!KUJI(;WpR7hVzbO(4VVYe zhEVT5hrdDD!FP~(M+ms*5W7rX0z}g_bt~=~uAs?3_`1zO;19wE%U$>W!jYw`&If@T zUpc)f?5DPF^!V&S$2oNS>Q7f!ZrInqzV@&D#ED`@z4t&h%?5Aq{qcy-*6tS}9PR4l z##pL;Fp%U%7|H7u)e(* ze4FhRwA$im89HmXEV9iMP>^QQE|l7Z(k0_sv|jjJbmJ*WL&`I#qe|OD7Yl)5r9&4~ zG9(DsYmibBEJ=0>K_bc|6aJbMw9T0Xm8T#Gb0Lw$m;!*j zPW>r$Qw>^Fz}Nt-TD#R*f|UyEtoW|2efe+Gx7HQky5d_`{PnovAG@L7a~?swJ8%4{ z*@wa&wOnTPv9RYRCt-iJT*6QEh>YrSW6E#diW%$wV3_l^0D}L-93rh_@vWDLp zerx!x;kSn08vffG{#VL|#6i^itSmp=wB@fc+P}oncxW*3Q4qMpk=HMp%$)zef<_7q zkMIetd@6IuL&!u<0VU&iIJNuWGA)!#DsPwj$&ddMNlwo z2<5m6r^ZdH3R@|5(;65{Th6jNYgwJQtb@6%%w1MyFD?1Y>I`Oe4%3#!tj=SKOvcP* zOzK(UGbNE4PE(dL@tVfW#>j1I*o~3jG%u+DGv(imJjd7`6|PgycFd)e8Ba~Cn^}*U z_tY^TBljr-ZUucS2Bh*1WeLlJ<~-=vXfRMsp;!?3M^(}5d62oUYKi$Rs0T$0ogXas zSj;_`?wiNZc*%fhE?rw^;gdOZp)!{jl`I(ho~NEd8+bS`z!BJSn?`0J6?11IqP`fhjspDmCIYE zAV#ZylZ*dUsiZ$T8J`a{)R?Z8y3I{~h*%H&CLZ{ZuQAGDN?)sC*BVENBj&h+bTd&7 zk+C#{nugvJgqflo^2U+>Oaa>Dq9X*=cyyf>0qItXa;U@6wTMP%3P!gy7F~T)D^Ww} zKh~=nwkNBeughhtP7nM%<3xp$OL7<#u;6g7pHzvugC;^+&K?#3NUVt6XUn zCJfxJRY$jqi@r;0r$VjRNuZ7Is>$B6W;g z!OcfiXT_%Otk}~lF6^`&#GTt|k)?T-=2@Dz9-8;wbNe^WBe-LlhpDA`Eoh#wYdm(1 z$FA{M<8O_>HU6vIj_N1A8~A^v_j7<9-H-aChCmdiK-{IXvUOo=8?gYyw-uNf0v)bb z*%H9Jf?_&lYM5;~O!Fj0t^^AMJ674GjoAD{MQqMq;?NC(O@?lskCVx@%YHwvzO$a1 zJv|w^Jyn-kv00fUU*?3W|2K+_31)FGi}(6vqx3Sm9_dtbadXV(OgeOjqtmE?{QP~> z_Za(qZ}d9qefDMvjiWgy{m~!!=kw;SDJC6W$L?SrXVe_#GXuOUC3vJJjfodG5dV+o z4Ns#&r_YCBHU!-pFP@h?Lx7Tv(l5R&#&0J1*1a-Z+npBUz^eFhY=l;0xb2U=cfC}! zZkVbXMB}7>pdN(2G6`N~P?X{r>!&?G?nQ6>@R>hKN`o4T(wI(VPdvps+ydTD^$wKe zgS48@!-0Z^N?rOBDPu+5rveJxl`Zsxe5cIv!d8zniImO#3@tVKOyV&=_q|mx%qcD|LW2JHC8fXqx z2Yntjkkz_buQ6{=4x>a7sq7f!d?4gl#3a9qAaawUK2N?ASk&D){$wS*jAH*U&6!la z{jfCRss;6;zJ_N*L5By)U;UTA2ETuT!293B;Ez`?qXY8W;cu@_o?jkZzWV?uJpc4- z&>I}7-}~=Az&|d}Uw#Y@)bpd~^z;<{`sW{?-hzWypPnC_{HbJKd=0LTepy`o*WN|4 zO7mzqS(N{=J5-}SPumUISJ&jGtdQy5JuZtp&`^pV2k*Tv%20TQ!FeA#;=P{oZL%j$ zqv0m9FJfrg5${4zD{+lI*9+J0!r*4PcE69V4+4J>HlPtov_#1&)^0+@6#kz2Nfn5W z-0+J#DiDAy#g&4~v>N*Gc1D{HdWrv~32RCdYa{H2J+Ecj5263(*qhHE7rgz4k@q}I z{CH8be{4$NKKY@VG}VLZ(KwD(OQbDX<-edxf1iIHx}j3G|I3;<7p;D7|0XK}ah{sx zd`L0VAyp>VjmvD~ft9Ymm{IM*Og(qzeER(TIGCHpih$~)b9dR};7R`3!TL9|R>CT8-zHz?rOtSLHB=+#!7Hie{Q&k=xhS^ftb+U1WZx+)XF%Iro9 reRP9yrH5*#^#-N+$(X-+;b{(06*!rH4g;k>Paph0#f_tLen|lU)mn5F literal 0 HcmV?d00001 diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f99bb641..bcfd2db3 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1323,7 +1323,7 @@ stat_t cm_set_feed_rate(const float feed_rate) { if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) { if (fp_ZERO(feed_rate)) { - return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); + return (STAT_FEEDRATE_NOT_SPECIFIED); } cm->gm.feed_rate = 1/feed_rate; // normalize to minutes (NB: active for this gcode block only) } else { @@ -1382,7 +1382,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) { // trap zero feed rate condition if (fp_ZERO(cm->gm.feed_rate)) { - return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); + return (STAT_FEEDRATE_NOT_SPECIFIED); } cm->gm.motion_mode = MOTION_MODE_STRAIGHT_FEED; @@ -2251,35 +2251,26 @@ stat_t cm_get_ofs(nvObj_t *nv) * cm_set_hi() - set homing input */ -stat_t cm_get_am(nvObj_t *nv) -{ - get_ui8(nv); - return(_get_msg_helper(nv, msg_am, nv->value)); -} - #pragma GCC push_options #pragma GCC optimize ("O0") +stat_t cm_get_am(nvObj_t *nv) +{ + int8_t axis = _get_axis(nv->index); + nv->value = (float)cm->a[axis].axis_mode; + return(_get_msg_helper(nv, msg_am, nv->value)); +} + stat_t cm_set_am(nvObj_t *nv) // axis mode { - nv->valuetype = TYPE_INT; if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { if (nv->value > AXIS_MODE_LINEAR_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } else { if (nv->value > AXIS_MODE_ROTARY_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } - cmAxisMode *am = (cmAxisMode *)cfgArray[nv->index].target; - void *p = (cfgArray[nv->index].target); - cmAxisMode a = *((cmAxisMode *)cfgArray[nv->index].target); -// *((uint8_t *)cfgArray[nv->index].target) = nv->value; -// cmAxisMode a = (cmAxisMode)nv->value; -// *am = (cmAxisMode)nv->value; - *am = a; - return(STAT_OK); - -// set_ui8(nv); -// return(STAT_OK); + cm->a[_get_axis(nv->index)].axis_mode = (cmAxisMode)nv->value; + return(STAT_OK); } #pragma GCC reset_options diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 13b51ff9..b8d4ca0b 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -515,7 +515,7 @@ typedef struct cmAxis { float zero_backoff; // backoff from switches for machine zero } cfgAxis_t; -typedef struct cmSingleton { // struct to manage cm globals and cycles +typedef struct cmMachine { // struct to manage canonical machine globals and state magic_t magic_start; // magic number to test memory integrity /**** Config variables (PUBLIC) ****/ diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 2eaa9636..531aedee 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -268,7 +268,6 @@ const cfgItem_t cfgArray[] = { #endif // Axis parameters { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, -// { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_X].axis_mode, X_AXIS_MODE }, { "x","xvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_X].velocity_max, X_VELOCITY_MAX }, { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, { "x","xtn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_min, X_TRAVEL_MIN }, @@ -282,7 +281,7 @@ const cfgItem_t cfgArray[] = { { "x","xlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_X].latch_backoff, X_LATCH_BACKOFF }, { "x","xzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_X].zero_backoff, X_ZERO_BACKOFF }, - { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_Y].axis_mode, Y_AXIS_MODE }, + { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, { "y","yvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Y].velocity_max, Y_VELOCITY_MAX }, { "y","yfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_Y].feedrate_max, Y_FEEDRATE_MAX }, { "y","ytn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_Y].travel_min, Y_TRAVEL_MIN }, @@ -296,7 +295,7 @@ const cfgItem_t cfgArray[] = { { "y","ylb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_Y].latch_backoff, Y_LATCH_BACKOFF }, { "y","yzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_Y].zero_backoff, Y_ZERO_BACKOFF }, - { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_Z].axis_mode, Z_AXIS_MODE }, + { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, { "z","zvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Z].velocity_max, Z_VELOCITY_MAX }, { "z","zfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_Z].feedrate_max, Z_FEEDRATE_MAX }, { "z","ztn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_Z].travel_min, Z_TRAVEL_MIN }, @@ -310,7 +309,7 @@ const cfgItem_t cfgArray[] = { { "z","zlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_Z].latch_backoff, Z_LATCH_BACKOFF }, { "z","zzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_Z].zero_backoff, Z_ZERO_BACKOFF }, - { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_A].axis_mode, A_AXIS_MODE }, + { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, { "a","avm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_A].velocity_max, A_VELOCITY_MAX }, { "a","afr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_A].feedrate_max, A_FEEDRATE_MAX }, { "a","atn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_A].travel_min, A_TRAVEL_MIN }, @@ -325,7 +324,7 @@ const cfgItem_t cfgArray[] = { { "a","alb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_A].latch_backoff, A_LATCH_BACKOFF }, { "a","azb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_A].zero_backoff, A_ZERO_BACKOFF }, - { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_B].axis_mode, B_AXIS_MODE }, + { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, { "b","bvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_B].velocity_max, B_VELOCITY_MAX }, { "b","bfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_B].feedrate_max, B_FEEDRATE_MAX }, { "b","btn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_B].travel_min, B_TRAVEL_MIN }, @@ -340,7 +339,7 @@ const cfgItem_t cfgArray[] = { { "b","blb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_B].latch_backoff, B_LATCH_BACKOFF }, { "b","bzb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_B].zero_backoff, B_ZERO_BACKOFF }, - { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cm->a[AXIS_C].axis_mode, C_AXIS_MODE }, + { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, { "c","cvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_C].velocity_max, C_VELOCITY_MAX }, { "c","cfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_C].feedrate_max, C_FEEDRATE_MAX }, { "c","ctn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_C].travel_min, C_TRAVEL_MIN }, diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 52d18c41..861ff145 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -140,12 +140,12 @@ static stat_t _set_pb_func(uint8_t (*func)()) { uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, bool moving_toward_switch) { // trap zero feed rate condition if (fp_ZERO(cm->gm.feed_rate)) { - return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); + return (STAT_FEEDRATE_NOT_SPECIFIED); } // error if no axes specified if (!flags[AXIS_X] && !flags[AXIS_Y] && !flags[AXIS_Z]) { - return (STAT_GCODE_AXIS_IS_MISSING); + return (STAT_AXIS_IS_MISSING); } pb.failure_is_fatal = failure_is_fatal; diff --git a/g2core/error.h b/g2core/error.h index 15ff8e65..8d4ca4ec 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -226,19 +226,19 @@ char *get_status_message(stat_t status); #define STAT_GCODE_COMMAND_UNSUPPORTED 131 // G command is not supported #define STAT_MCODE_COMMAND_UNSUPPORTED 132 // M command is not supported #define STAT_GCODE_MODAL_GROUP_VIOLATION 133 // gcode modal group error -#define STAT_GCODE_AXIS_IS_MISSING 134 // command requires at least one axis present -#define STAT_GCODE_AXIS_CANNOT_BE_PRESENT 135 // error if G80 has axis words -#define STAT_GCODE_AXIS_IS_INVALID 136 // an axis is specified that is illegal for the command -#define STAT_GCODE_AXIS_IS_NOT_CONFIGURED 137 // WARNING: attempt to program an axis that is disabled -#define STAT_GCODE_AXIS_NUMBER_IS_MISSING 138 // axis word is missing its value -#define STAT_GCODE_AXIS_NUMBER_IS_INVALID 139 // axis word value is illegal +#define STAT_AXIS_IS_MISSING 134 // command requires at least one axis present +#define STAT_AXIS_CANNOT_BE_PRESENT 135 // error if G80 has axis words +#define STAT_AXIS_IS_INVALID 136 // an axis is specified that is illegal for the command +#define STAT_AXIS_IS_NOT_CONFIGURED 137 // WARNING: attempt to program an axis that is disabled +#define STAT_AXIS_NUMBER_IS_MISSING 138 // axis word is missing its value +#define STAT_AXIS_NUMBER_IS_INVALID 139 // axis word value is illegal -#define STAT_GCODE_ACTIVE_PLANE_IS_MISSING 140 // active plane is not programmed -#define STAT_GCODE_ACTIVE_PLANE_IS_INVALID 141 // active plane selected is not valid for this command -#define STAT_GCODE_FEEDRATE_NOT_SPECIFIED 142 // move has no feedrate -#define STAT_GCODE_INVERSE_TIME_MODE_CANNOT_BE_USED 143 // G38.2 and some canned cycles cannot accept inverse time mode -#define STAT_GCODE_ROTARY_AXIS_CANNOT_BE_USED 144 // G38.2 and some other commands cannot have rotary axes -#define STAT_GCODE_G53_WITHOUT_G0_OR_G1 145 // G0 or G1 must be active for G53 +#define STAT_ACTIVE_PLANE_IS_MISSING 140 // active plane is not programmed +#define STAT_ACTIVE_PLANE_IS_INVALID 141 // active plane selected is not valid for this command +#define STAT_FEEDRATE_NOT_SPECIFIED 142 // move has no feedrate +#define STAT_INVERSE_TIME_MODE_CANNOT_BE_USED 143 // G38.2 and some canned cycles cannot accept inverse time mode +#define STAT_ROTARY_AXIS_CANNOT_BE_USED 144 // G38.2 and some other commands cannot have rotary axes +#define STAT_GCODE_G53_WITHOUT_G0_OR_G1 145 // G0 or G1 must be active for G53 #define STAT_REQUESTED_VELOCITY_EXCEEDS_LIMITS 146 #define STAT_CUTTER_COMPENSATION_CANNOT_BE_ENABLED 147 #define STAT_PROGRAMMED_POINT_SAME_AS_CURRENT_POINT 148 From 5a21ad794c0e2af695159a9fb2829d073e87920b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 09:18:17 -0500 Subject: [PATCH 015/283] stubbed in getter and setter for axes --- g2core/canonical_machine.cpp | 189 +++++++++++++++++++++++++++++------ g2core/canonical_machine.h | 34 +++++-- g2core/config_app.cpp | 2 +- 3 files changed, 185 insertions(+), 40 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index bcfd2db3..8c38f7c6 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2245,15 +2245,16 @@ stat_t cm_get_ofs(nvObj_t *nv) /* * AXIS GET AND SET FUNCTIONS - * + */ +/* Axis Basic Settings * cm_get_am() - get axis mode w/enumeration string * cm_set_am() - set axis mode w/exception handling for axis type - * cm_set_hi() - set homing input + * cm_get_tn() - get axis travel min + * cm_set_tn() - set axis travel min + * cm_get_tm() - get axis travel max + * cm_set_tm() - set axis travel max */ -#pragma GCC push_options -#pragma GCC optimize ("O0") - stat_t cm_get_am(nvObj_t *nv) { int8_t axis = _get_axis(nv->index); @@ -2273,35 +2274,29 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode return(STAT_OK); } -#pragma GCC reset_options - -stat_t cm_set_hi(nvObj_t *nv) +stat_t cm_get_tn(nvObj_t *nv) { - if ((nv->value < 0) || (nv->value > D_IN_CHANNELS)) { - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - set_ui8(nv); return (STAT_OK); } -/**** Velocity and Jerk functions +stat_t cm_set_tn(nvObj_t *nv) +{ + return (STAT_OK); +} + +stat_t cm_get_tm(nvObj_t *nv) +{ + return (STAT_OK); +} + +stat_t cm_set_tm(nvObj_t *nv) +{ + return (STAT_OK); +} + +/**** Axis Jerk Primitives * cm_get_axis_jerk() - returns jerk for an axis * cm_set_axis_jerk() - sets the jerk for an axis, including recirpcal and cached values - * - * cm_set_vm() - set velocity max value - called from dispatch table - * cm_set_fr() - set feedrate max value - called from dispatch table - * cm_set_jm() - set jerk max value - called from dispatch table - * cm_set_jh() - set jerk homing value - called from dispatch table - * - * Jerk values can be rather large, often in the billions. This makes for some pretty big - * numbers for people to deal with. Jerk values are stored in the system in truncated format; - * values are divided by 1,000,000 then reconstituted before use. - * - * The set_xjm() nad set_xjh() functions will accept either truncated or untruncated jerk - * numbers as input. If the number is > 1,000,000 it is divided by 1,000,000 before storing. - * Numbers are accepted in either millimeter or inch mode and converted to millimeter mode. - * - * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form */ float cm_get_axis_jerk(const uint8_t axis) { @@ -2317,17 +2312,40 @@ static const float _junction_accel_multiplier = sqrt(3.0)/10.0; void _cm_recalc_max_junction_accel(const uint8_t axis) { float T = cm->junction_integration_time / 1000.0; float T2 = T*T; - cm->a[axis].max_junction_accel = _junction_accel_multiplier * T2 * (cm->a[axis].jerk_max * JERK_MULTIPLIER); } void cm_set_axis_jerk(const uint8_t axis, const float jerk) { cm->a[axis].jerk_max = jerk; - //cm->a[axis].recip_jerk = 1/(jerk * JERK_MULTIPLIER); + _cm_recalc_max_junction_accel(axis); // Must recalculate the max_junction_accel now that the jerk has changed. - // Must recalculate the max_junction_accel now that the jerk has changed. - _cm_recalc_max_junction_accel(axis); +} + +/**** Axis Velocity and Jerk Settings + * cm_get_vm() - get velocity max value - called from dispatch table + * cm_set_vm() - set velocity max value - called from dispatch table + * cm_get_fr() - get feedrate max value - called from dispatch table + * cm_set_fr() - set feedrate max value - called from dispatch table + * cm_get_jm() - get jerk max value - called from dispatch table + * cm_set_jm() - set jerk max value - called from dispatch table + * cm_get_jh() - get jerk homing value - called from dispatch table + * cm_set_jh() - set jerk homing value - called from dispatch table + * + * Jerk values can be rather large, often in the billions. This makes for some pretty big + * numbers for people to deal with. Jerk values are stored in the system in truncated format; + * values are divided by 1,000,000 then reconstituted before use. + * + * The set_xjm() nad set_xjh() functions will accept either truncated or untruncated jerk + * numbers as input. If the number is > 1,000,000 it is divided by 1,000,000 before storing. + * Numbers are accepted in either millimeter or inch mode and converted to millimeter mode. + * + * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form + */ + +stat_t cm_get_vm(nvObj_t *nv) +{ + return(STAT_OK); } stat_t cm_set_vm(nvObj_t *nv) @@ -2342,6 +2360,11 @@ stat_t cm_set_vm(nvObj_t *nv) return(STAT_OK); } +stat_t cm_get_fr(nvObj_t *nv) +{ + return(STAT_OK); +} + stat_t cm_set_fr(nvObj_t *nv) { uint8_t axis = _get_axis(nv->index); @@ -2354,6 +2377,11 @@ stat_t cm_set_fr(nvObj_t *nv) return(STAT_OK); } +stat_t cm_get_jm(nvObj_t *nv) +{ + return(STAT_OK); +} + stat_t cm_set_jm(nvObj_t *nv) { // if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER; @@ -2362,6 +2390,11 @@ stat_t cm_set_jm(nvObj_t *nv) return(STAT_OK); } +stat_t cm_get_jh(nvObj_t *nv) +{ + return(STAT_OK); +} + stat_t cm_set_jh(nvObj_t *nv) { // if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER; @@ -2369,6 +2402,97 @@ stat_t cm_set_jh(nvObj_t *nv) return(STAT_OK); } +/**** Axis Homing Settings + * cm_get_hi() - get homing input + * cm_set_hi() - set homing input + * cm_get_hd() - get homing direction + * cm_set_hd() - set homing direction + * cm_get_sv() - get homing search velocity + * cm_set_sv() - set homing search velocity + * cm_get_lv() - get homing latch velocity + * cm_set_lv() - set homing latch velocity + * cm_get_lb() - get homing latch backoff + * cm_set_lb() - set homing latch backoff + * cm_get_zb() - get homing zero backoff + * cm_set_zb() - set homing zero backoff + */ + +stat_t cm_get_hi(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_set_hi(nvObj_t *nv) +{ + if ((nv->value < 0) || (nv->value > D_IN_CHANNELS)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + set_ui8(nv); + return (STAT_OK); +} + +stat_t cm_get_hd(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_set_hd(nvObj_t *nv) +{ + return (STAT_OK); +} + +stat_t cm_get_sv(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_set_sv(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_get_lv(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_set_lv(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_get_lb(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_set_lb(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_get_zb(nvObj_t *nv) +{ + return(STAT_OK); +} + +stat_t cm_set_zb(nvObj_t *nv) +{ + return(STAT_OK); +} + + +/*** Canonical Machine Global Settings ***/ +/* + * cm_get_jt() - get junction integration time + * cm_set_jt() - get junction integration time + */ + +stat_t cm_get_jt(nvObj_t *nv) +{ + return(STAT_OK); +} + stat_t cm_set_jt(nvObj_t *nv) { // // Prescale it. @@ -2390,7 +2514,6 @@ stat_t cm_set_jt(nvObj_t *nv) for (uint8_t axis=0; axisa[AXIS_X].velocity_max, X_VELOCITY_MAX }, + { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cm->a[AXIS_X].velocity_max, X_VELOCITY_MAX }, { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, { "x","xtn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_min, X_TRAVEL_MIN }, { "x","xtm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_max, X_TRAVEL_MAX }, From 94e62349c53bf8a6904bfc3ddacd1310ada60cd0 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 10:54:49 -0500 Subject: [PATCH 016/283] Changing the way floats are unit converted. Part of the way there. --- g2core/canonical_machine.cpp | 60 +++++++++++++++++++++++++++--------- g2core/canonical_machine.h | 1 + g2core/config.h | 3 +- g2core/config_app.cpp | 27 ++++++++++------ g2core/json_parser.cpp | 2 +- g2core/text_parser.cpp | 2 +- 6 files changed, 68 insertions(+), 27 deletions(-) mode change 100755 => 100644 g2core/config.h mode change 100755 => 100644 g2core/text_parser.cpp diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8c38f7c6..0079c2bc 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -128,7 +128,7 @@ static void _exec_absolute_origin(float *value, bool *flag); static void _exec_program_finalize(float *value, bool *flag); static int8_t _get_axis(const index_t index); -static cmAxisType _get_axis_type(const index_t index); +//static cmAxisType _get_axis_type(const index_t index); /*********************************************************************************** **** CODE ************************************************************************* @@ -2080,18 +2080,11 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; /***** AXIS HELPERS ***************************************************************** - * cm_get_axis_char() - return ASCII char for axis given the axis number - * _get_axis() - return axis number or -1 if NA - * _get_axis_type() - return 0 -f axis is linear, 1 if rotary, -1 if NA + * _get_axis() - return axis number or -1 if not an axis + * cm_get_axis_char() - return ASCII char for axis given the axis number + * cm_get_axis_type() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) */ -char cm_get_axis_char(const int8_t axis) -{ - char axis_char[] = "XYZABC"; - if ((axis < 0) || (axis > AXES)) return (' '); - return (axis_char[axis]); -} - static int8_t _get_axis(const index_t index) { char *ptr; @@ -2107,7 +2100,14 @@ static int8_t _get_axis(const index_t index) return (ptr - axes); } -static cmAxisType _get_axis_type(const index_t index) +char cm_get_axis_char(const int8_t axis) +{ + char axis_char[] = "XYZABC"; + if ((axis < 0) || (axis > AXES)) return (' '); + return (axis_char[axis]); +} + +cmAxisType cm_get_axis_type(const index_t index) { int8_t axis = _get_axis(index); if (axis >= AXIS_A) return (AXIS_TYPE_ROTARY); @@ -2246,6 +2246,36 @@ stat_t cm_get_ofs(nvObj_t *nv) /* * AXIS GET AND SET FUNCTIONS */ + +/* + * _decorate_settable_float() - convert incoming float value by units and axis type & complete NV struct + * _decorate_gettable_float() - convert outcoming float value by units and axis type & complete NV struct + */ +/* +float _preprocess_float(nvObj_t *nv) +{ + if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode + if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... + nv->value *= MM_PER_INCH; // convert to canonical millimeter units + } + } + nv->precision = GET_TABLE_WORD(precision); + nv->valuetype = TYPE_FLOAT; + return(nv->value); +} + +float _decorate_gettable_float(nvObj_t *nv) +{ + if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode + if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... + nv->value *= MM_PER_INCH; // convert to canonical millimeter units + } + } + nv->precision = GET_TABLE_WORD(precision); + nv->valuetype = TYPE_FLOAT; + return(nv->value); +} +*/ /* Axis Basic Settings * cm_get_am() - get axis mode w/enumeration string * cm_set_am() - set axis mode w/exception handling for axis type @@ -2265,7 +2295,7 @@ stat_t cm_get_am(nvObj_t *nv) stat_t cm_set_am(nvObj_t *nv) // axis mode { nv->valuetype = TYPE_INT; - if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { if (nv->value > AXIS_MODE_LINEAR_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } else { if (nv->value > AXIS_MODE_ROTARY_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} @@ -2780,7 +2810,7 @@ static void _print_axis_ui8(nvObj_t *nv, const char *format) static void _print_axis_flt(nvObj_t *nv, const char *format) { char *units; - if (_get_axis_type(nv->index) == 0) { // linear + if (cm_get_axis_type(nv->index) == 0) { // linear units = (char *)GET_UNITS(MODEL); } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); @@ -2792,7 +2822,7 @@ static void _print_axis_flt(nvObj_t *nv, const char *format) static void _print_axis_coord_flt(nvObj_t *nv, const char *format) { char *units; - if (_get_axis_type(nv->index) == 0) { // linear + if (cm_get_axis_type(nv->index) == 0) { // linear units = (char *)GET_UNITS(MODEL); } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 88cb0b2a..61cee9e5 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -771,6 +771,7 @@ float cm_get_jogging_dest(void); /*--- cfgArray interface functions ---*/ char cm_get_axis_char(const int8_t axis); +char cm_get_axis_type(const int8_t axis); stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number diff --git a/g2core/config.h b/g2core/config.h old mode 100755 new mode 100644 index 49fc5c24..d7ebd517 --- a/g2core/config.h +++ b/g2core/config.h @@ -353,7 +353,8 @@ void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); // application specific helpers and functions (config_app.c) stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion -void preprocess_float(nvObj_t *nv); // pre-process float values for units and illegal values +void preprocess_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values +void preprocess_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units // diagnostics void nv_dump_nv(nvObj_t *nv); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 326634d2..faacc491 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -995,20 +995,27 @@ stat_t set_flu(nvObj_t *nv) } /* - * preprocess_float() - pre-process floating point number for units display + * preprocess_incoming_float() - pre-process an incoming floating point number for canonical units + * preprocess_outgoing_float() - pre-process an outgoing floating point number for units display */ -void preprocess_float(nvObj_t *nv) -/* +void preprocess_incoming_float(nvObj_t *nv) { - if (isnan((double)nv->value) || isinf((double)nv->value)) return; // illegal float values - if (GET_TABLE_BYTE(flags) & F_CONVERT) { // unit conversion required? - if (cm_get_units_mode(MODEL) == INCHES) { - nv->value *= INCHES_PER_MM; + uint8_t f; + f = GET_TABLE_BYTE(flags); +// if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? + if (f & F_CONVERT) { // unit conversion required? + if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... + nv->value *= MM_PER_INCH; // convert to canonical millimeter units + } } - } + } + nv->precision = GET_TABLE_WORD(precision); + nv->valuetype = TYPE_FLOAT; } -*/ + +void preprocess_outgoing_float(nvObj_t *nv) { uint8_t f; if (isnan((double)nv->value) || isinf((double)nv->value)) return; // illegal float values @@ -1022,6 +1029,8 @@ void preprocess_float(nvObj_t *nv) } } } + nv->precision = GET_TABLE_WORD(precision); + nv->valuetype = TYPE_FLOAT; } /* diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index e2c0b5e2..d37838d5 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -421,7 +421,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) need_a_comma = false; break; } - case (TYPE_FLOAT): { preprocess_float(nv); + case (TYPE_FLOAT): { preprocess_outgoing_float(nv); str += floattoa(str, nv->value, nv->precision); break; } diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp old mode 100755 new mode 100644 index 505858aa..8262d48f --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -196,7 +196,7 @@ void text_print_multiline_formatted(nvObj_t *nv) { for (uint8_t i=0; ivaluetype != TYPE_PARENT) { - preprocess_float(nv); + preprocess_outgoing_float(nv); nv_print(nv); } if ((nv = nv->nx) == NULL) return; From d46998c1fd6856a2560f73545f85f675dc31ab36 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 13:23:00 -0500 Subject: [PATCH 017/283] intermediate checkpoint --- g2core/canonical_machine.cpp | 44 ++++++++++-------------------------- g2core/canonical_machine.h | 2 +- g2core/config_app.cpp | 8 +++---- g2core/g2core.cppproj | 4 ++-- 4 files changed, 19 insertions(+), 39 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0079c2bc..7187fbdd 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2243,39 +2243,10 @@ stat_t cm_get_ofs(nvObj_t *nv) return (STAT_OK); } -/* - * AXIS GET AND SET FUNCTIONS - */ +/************************************ + **** AXIS GET AND SET FUNCTIONS **** + ************************************/ -/* - * _decorate_settable_float() - convert incoming float value by units and axis type & complete NV struct - * _decorate_gettable_float() - convert outcoming float value by units and axis type & complete NV struct - */ -/* -float _preprocess_float(nvObj_t *nv) -{ - if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode - if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... - nv->value *= MM_PER_INCH; // convert to canonical millimeter units - } - } - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return(nv->value); -} - -float _decorate_gettable_float(nvObj_t *nv) -{ - if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode - if (_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... - nv->value *= MM_PER_INCH; // convert to canonical millimeter units - } - } - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return(nv->value); -} -*/ /* Axis Basic Settings * cm_get_am() - get axis mode w/enumeration string * cm_set_am() - set axis mode w/exception handling for axis type @@ -2306,21 +2277,30 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode stat_t cm_get_tn(nvObj_t *nv) { + nv->value = cm->a[_get_axis(nv->index)].travel_min; + nv->valuetype = TYPE_FLOAT; return (STAT_OK); } + stat_t cm_set_tn(nvObj_t *nv) { + preprocess_incoming_float(nv); + cm->a[_get_axis(nv->index)].travel_min = nv->value; return (STAT_OK); } stat_t cm_get_tm(nvObj_t *nv) { + nv->value = cm->a[_get_axis(nv->index)].travel_max; + nv->valuetype = TYPE_FLOAT; return (STAT_OK); } stat_t cm_set_tm(nvObj_t *nv) { + preprocess_incoming_float(nv); + cm->a[_get_axis(nv->index)].travel_max = nv->value; return (STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 61cee9e5..f6814aa6 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -771,7 +771,7 @@ float cm_get_jogging_dest(void); /*--- cfgArray interface functions ---*/ char cm_get_axis_char(const int8_t axis); -char cm_get_axis_type(const int8_t axis); +cmAxisType cm_get_axis_type(const index_t index); stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index faacc491..487a21f1 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -270,8 +270,8 @@ const cfgItem_t cfgArray[] = { { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cm->a[AXIS_X].velocity_max, X_VELOCITY_MAX }, { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, - { "x","xtn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_min, X_TRAVEL_MIN }, - { "x","xtm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_X].travel_max, X_TRAVEL_MAX }, + { "x","xtn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, + { "x","xtm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, { "x","xjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_X].jerk_max, X_JERK_MAX }, { "x","xjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_X].jerk_high, X_JERK_HIGH_SPEED }, { "x","xhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_X].homing_input, X_HOMING_INPUT }, @@ -1011,8 +1011,8 @@ void preprocess_incoming_float(nvObj_t *nv) } } } - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; +// nv->precision = GET_TABLE_WORD(precision); +// nv->valuetype = TYPE_FLOAT; } void preprocess_outgoing_float(nvObj_t *nv) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 4669f074..e96a497c 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800043527 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800043527 0x284E0A60 2000000 From c82acb9fa7ba86e0942628e3c9c7a58d6116112b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 13:49:57 -0500 Subject: [PATCH 018/283] Changed gcode_parser.h to code.h in anticipation of moving Gcode state into it. --- g2core/config_app.cpp | 2 +- g2core/controller.cpp | 2 +- g2core/g2core.cppproj | 2 +- g2core/{gcode_parser.h => gcode.h} | 8 ++++---- g2core/gcode_parser.cpp | 2 +- g2core/plan_arc.cpp | 4 ++-- g2core/plan_arc.h | 0 g2core/settings/settings_makeblock.h | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) rename g2core/{gcode_parser.h => gcode.h} (87%) mode change 100755 => 100644 mode change 100755 => 100644 g2core/plan_arc.h diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 487a21f1..04e47a0b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -30,7 +30,7 @@ #include "config.h" // #2 #include "controller.h" #include "canonical_machine.h" -#include "gcode_parser.h" +#include "gcode.h" #include "json_parser.h" #include "text_parser.h" #include "settings.h" diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 8955a3ca..b41f37ff 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -31,7 +31,7 @@ #include "controller.h" #include "json_parser.h" #include "text_parser.h" -#include "gcode_parser.h" +#include "gcode.h" #include "canonical_machine.h" #include "plan_arc.h" #include "planner.h" diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index e96a497c..028566ff 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -1782,7 +1782,7 @@ compile - + compile diff --git a/g2core/gcode_parser.h b/g2core/gcode.h old mode 100755 new mode 100644 similarity index 87% rename from g2core/gcode_parser.h rename to g2core/gcode.h index 25570c0c..3b543fe9 --- a/g2core/gcode_parser.h +++ b/g2core/gcode.h @@ -1,5 +1,5 @@ /* - * gcode_parser.h - rs274/ngc Gcode parser + * gcode.h - rs274/ngc Gcode model and parser support * This file is part of the g2core project * * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. @@ -17,8 +17,8 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef GCODE_PARSER_H_ONCE -#define GCODE_PARSER_H_ONCE +#ifndef GCODE_H_ONCE +#define GCODE_H_ONCE /* * Global Scope Functions @@ -27,4 +27,4 @@ stat_t gcode_parser(char* block); stat_t gc_get_gc(nvObj_t* nv); stat_t gc_run_gc(nvObj_t* nv); -#endif // End of include guard: GCODE_PARSER_H_ONCE +#endif // End of include guard: GCODE_H_ONCE diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index d302b4e7..0878ecb8 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -20,7 +20,7 @@ #include "g2core.h" // #1 #include "config.h" // #2 #include "controller.h" -#include "gcode_parser.h" +#include "gcode.h" #include "canonical_machine.h" #include "spindle.h" #include "coolant.h" diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 9c715e56..e6639897 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -136,7 +136,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // trap missing feed rate if (fp_ZERO(cm->gm.feed_rate)) { - return (STAT_GCODE_FEEDRATE_NOT_SPECIFIED); + return (STAT_FEEDRATE_NOT_SPECIFIED); } // Set the arc plane for the current G17/G18/G19 setting and test arc specification @@ -154,7 +154,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en arc.plane_axis_1 = AXIS_Z; arc.linear_axis = AXIS_X; } else { - return(cm_panic(STAT_GCODE_ACTIVE_PLANE_IS_MISSING, "cm_arc_feed() impossible value")); // plane axis has impossible value + return(cm_panic(STAT_ACTIVE_PLANE_IS_MISSING, "cm_arc_feed() impossible value")); // plane axis has impossible value } // test if no endpoints are specified in the selected plane diff --git a/g2core/plan_arc.h b/g2core/plan_arc.h old mode 100755 new mode 100644 diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 02ac216b..23be9690 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -52,7 +52,7 @@ // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE From 33af41892065b7b55a7bb94238731c6c61b73362 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 14:13:39 -0500 Subject: [PATCH 019/283] moved Gcode defines and structures into code.h --- g2core/canonical_machine.cpp | 21 +- g2core/canonical_machine.h | 349 +--------------------------------- g2core/cycle_homing.cpp | 62 +++--- g2core/gcode.h | 359 +++++++++++++++++++++++++++++++++++ g2core/gcode_parser.cpp | 76 ++++---- g2core/spindle.cpp | 4 +- 6 files changed, 443 insertions(+), 428 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 7187fbdd..03655842 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -86,8 +86,9 @@ * and have no buffer. */ -#include "g2core.h" // #1 -#include "config.h" // #2 +#include "g2core.h" // #1 +#include "config.h" // #2 +#include "gcode.h" // #3 #include "canonical_machine.h" #include "hardware.h" #include "controller.h" @@ -705,8 +706,8 @@ void canonical_machine_init() // memset(&cm, 0, sizeof(cm)); // do not reset canonicalMachineSingleton once it's been initialized memset(cm, 0, sizeof(cm0)); // do not reset canonicalMachineSingleton once it's been initialized memset(&cm->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status - memset(&cm->gn, 0, sizeof(GCodeInput_t)); - memset(&cm->gf, 0, sizeof(GCodeFlags_t)); + memset(&gc.gn, 0, sizeof(GCodeInput_t)); + memset(&gc.gf, 0, sizeof(GCodeFlags_t)); canonical_machine_init_assertions(); // establish assertions ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer @@ -1055,7 +1056,7 @@ stat_t cm_set_coord_offsets(const uint8_t coord_system, if ((coord_system < G54) || (coord_system > COORD_SYSTEM_MAX)) { // you can't set G53 return (STAT_P_WORD_IS_INVALID); } - if (!cm->gf.L_word) { + if (!gc.gf.L_word) { return (STAT_L_WORD_IS_MISSING); } if ((L_word != 2) && (L_word != 20)) { @@ -1558,17 +1559,17 @@ stat_t cm_mfo_enable(uint8_t enable) // M50 { bool new_enable = true; bool new_override = false; - if (cm->gf.parameter) { // if parameter is present in Gcode block - if (fp_ZERO(cm->gn.parameter)) { + if (gc.gf.parameter) { // if parameter is present in Gcode block + if (fp_ZERO(gc.gn.parameter)) { new_enable = false; // P0 disables override } else { - if (cm->gn.parameter < FEED_OVERRIDE_MIN) { + if (gc.gn.parameter < FEED_OVERRIDE_MIN) { return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (cm->gn.parameter > FEED_OVERRIDE_MAX) { + if (gc.gn.parameter > FEED_OVERRIDE_MAX) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - cm->gmx.mfo_factor = cm->gn.parameter; // it validates - store it. + cm->gmx.mfo_factor = gc.gn.parameter; // it validates - store it. new_override = true; } } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index f6814aa6..bec9c5f9 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -34,6 +34,7 @@ #include "config.h" #include "hardware.h" // Note: hardware.h is specific to the hardware target selected +#include "gcode.h" /* Defines, Macros, and Assorted Parameters */ @@ -48,7 +49,6 @@ #define DISABLE_SOFT_LIMIT (999999) #define PROBES_STORED 3 // we store three probes for coordinate rotation computation - /***************************************************************************** * MACHINE STATE MODEL * @@ -145,350 +145,6 @@ typedef enum { SAFETY_INTERLOCK_DISENGAGED } cmSafetyState; -/* The difference between NextAction and MotionMode is that NextAction is - * used by the current block, and may carry non-modal commands, whereas - * MotionMode persists across blocks (as G modal group 1) - */ - -typedef enum { // these are in order to optimized CASE statement - NEXT_ACTION_DEFAULT = 0, // Must be zero (invokes motion modes) - NEXT_ACTION_SEARCH_HOME, // G28.2 homing cycle - NEXT_ACTION_SET_ABSOLUTE_ORIGIN, // G28.3 origin set - NEXT_ACTION_HOMING_NO_SET, // G28.4 homing cycle with no coordinate setting - NEXT_ACTION_SET_G28_POSITION, // G28.1 set position in abs coordinates - NEXT_ACTION_GOTO_G28_POSITION, // G28 go to machine position - NEXT_ACTION_SET_G30_POSITION, // G30.1 - NEXT_ACTION_GOTO_G30_POSITION, // G30 - NEXT_ACTION_SET_COORD_DATA, // G10 - NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92 - NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1 - NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2 - NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3 - NEXT_ACTION_DWELL, // G4 - NEXT_ACTION_STRAIGHT_PROBE_ERR, // G38.2 - NEXT_ACTION_STRAIGHT_PROBE, // G38.3 - NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR,// G38.4 - NEXT_ACTION_STRAIGHT_PROBE_AWAY, // G38.5 - NEXT_ACTION_JSON_COMMAND_SYNC, // M100 - NEXT_ACTION_JSON_COMMAND_IMMEDIATE, // M101 - NEXT_ACTION_JSON_WAIT // M102 -} cmNextAction; - -typedef enum { // G Modal Group 1 - MOTION_MODE_STRAIGHT_TRAVERSE=0, // G0 - straight traverse - MOTION_MODE_STRAIGHT_FEED, // G1 - straight feed - MOTION_MODE_CW_ARC, // G2 - clockwise arc feed - MOTION_MODE_CCW_ARC, // G3 - counter-clockwise arc feed - MOTION_MODE_CANCEL_MOTION_MODE, // G80 - MOTION_MODE_STRAIGHT_PROBE, // G38.2 - MOTION_MODE_CANNED_CYCLE_81, // G81 - drilling - MOTION_MODE_CANNED_CYCLE_82, // G82 - drilling with dwell - MOTION_MODE_CANNED_CYCLE_83, // G83 - peck drilling - MOTION_MODE_CANNED_CYCLE_84, // G84 - right hand tapping - MOTION_MODE_CANNED_CYCLE_85, // G85 - boring, no dwell, feed out - MOTION_MODE_CANNED_CYCLE_86, // G86 - boring, spindle stop, rapid out - MOTION_MODE_CANNED_CYCLE_87, // G87 - back boring - MOTION_MODE_CANNED_CYCLE_88, // G88 - boring, spindle stop, manual out - MOTION_MODE_CANNED_CYCLE_89 // G89 - boring, dwell, feed out -} cmMotionMode; - -typedef enum { // Used for detecting gcode errors. See NIST section 3.4 - MODAL_GROUP_G0 = 0, // {G10,G28,G28.1,G92} non-modal axis commands (note 1) - MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion - MODAL_GROUP_G2, // {G17,G18,G19} plane selection - MODAL_GROUP_G3, // {G90,G91} distance mode - MODAL_GROUP_G5, // {G93,G94} feed rate mode - MODAL_GROUP_G6, // {G20,G21} units - MODAL_GROUP_G7, // {G40,G41,G42} cutter radius compensation - MODAL_GROUP_G8, // {G43,G49} tool length offset - MODAL_GROUP_G9, // {G98,G99} return mode in canned cycles - MODAL_GROUP_G12, // {G54,G55,G56,G57,G58,G59} coordinate system selection - MODAL_GROUP_G13, // {G61,G61.1,G64} path control mode - MODAL_GROUP_M4, // {M0,M1,M2,M30,M60} stopping - MODAL_GROUP_M6, // {M6} tool change - MODAL_GROUP_M7, // {M3,M4,M5} spindle turning - MODAL_GROUP_M8, // {M7,M8,M9} coolant (M7 & M8 may be active together) - MODAL_GROUP_M9 // {M48,M49} speed/feed override switches -} cmModalGroup; -#define MODAL_GROUP_COUNT (MODAL_GROUP_M9+1) -// Note 1: Our G0 omits G4,G30,G53,G92.1,G92.2,G92.3 as these have no axis components to error check - -typedef enum { // canonical plane - translates to: - // axis_0 axis_1 axis_2 - CANON_PLANE_XY = 0, // G17 X Y Z - CANON_PLANE_XZ, // G18 X Z Y - CANON_PLANE_YZ // G19 Y Z X -} cmCanonicalPlane; - -typedef enum { - INCHES = 0, // G20 - MILLIMETERS, // G21 - DEGREES // ABC axes (this value used for displays only) -} cmUnitsMode; - -typedef enum { - ABSOLUTE_COORDS = 0, // machine coordinate system - G54, // G54 coordinate system - G55, // G55 coordinate system - G56, // G56 coordinate system - G57, // G57 coordinate system - G58, // G58 coordinate system - G59 // G59 coordinate system -} cmCoordSystem; -#define COORD_SYSTEM_MAX G59 // set this manually to the last one - -typedef enum { - ABSOLUTE_OVERRIDE_OFF = 0,// G53 enabled - ABSOLUTE_OVERRIDE_ON -} cmAbsoluteOverride; - -typedef enum { // G Modal Group 13 - PATH_EXACT_PATH = 0, // G61 - hits corners but does not stop if it does not need to. - PATH_EXACT_STOP, // G61.1 - stops at all corners - PATH_CONTINUOUS // G64 and typically the default mode -} cmPathControl; - -typedef enum { - ABSOLUTE_MODE = 0, // G90 / G90.1 - INCREMENTAL_MODE // G91 / G91.1 -} cmDistanceMode; - -typedef enum { - INVERSE_TIME_MODE = 0, // G93 - UNITS_PER_MINUTE_MODE, // G94 - UNITS_PER_REVOLUTION_MODE// G95 (unimplemented) -} cmFeedRateMode; - -typedef enum { - ORIGIN_OFFSET_SET=0, // G92 - set origin offsets - ORIGIN_OFFSET_CANCEL, // G92.1 - zero out origin offsets - ORIGIN_OFFSET_SUSPEND, // G92.2 - do not apply offsets, but preserve the values - ORIGIN_OFFSET_RESUME // G92.3 - resume application of the suspended offsets -} cmOriginOffset; - -typedef enum { - PROGRAM_STOP = 0, - PROGRAM_END -} cmProgramFlow; - -typedef enum { // used for spindle and arc dir - DIRECTION_CW = 0, - DIRECTION_CCW -} cmDirection; - -typedef enum { // axis types - AXIS_TYPE_UNDEFINED=-1, // invalid type - AXIS_TYPE_LINEAR, // linear axis - AXIS_TYPE_ROTARY // rotary axis -} cmAxisType; - -typedef enum { // axis modes (ordered: see _cm_get_feed_time()) - AXIS_DISABLED = 0, // kill axis - AXIS_STANDARD, // axis in coordinated motion w/standard behaviors - AXIS_INHIBITED, // axis is computed but not activated - AXIS_RADIUS // rotary axis calibrated to circumference -} cmAxisMode; -#define AXIS_MODE_LINEAR_MAX AXIS_INHIBITED -#define AXIS_MODE_ROTARY_MAX AXIS_RADIUS - -/***************************************************************************** - * GCODE MODEL - The following GCodeModel/GCodeInput structs are used: - * - * - gm is the core Gcode model state. It keeps the internal gcode state model in - * normalized, canonical form. All values are unit converted (to mm) and in the - * machine coordinate system (absolute coordinate system). Gm is owned by the - * canonical machine layer and should be accessed only through cm_ routines. - * - * The gm core struct is copied and passed as context to the runtime where it is - * used for planning, move execution, feedholds, and reporting. - * - * - gmx is the extended gcode model variables that are only used by the canonical - * machine and do not need to be passed further down. It keeps "global" gcode - * state that does not change when you go down through the planner to the runtime. - * Other Gcode model state is kept in the singletons for various sub-systems, such - * as arcs, spindle, coolant, and others (i.e. not ALL gcode global state is in gmx) - * - * - gn is used by the gcode interpreter and is re-initialized for each - * gcode block.It accepts data in the new gcode block in the formats - * present in the block (pre-normalized forms). During initialization - * some state elements are necessarily restored from gm. - * - * - gf is used by the gcode parser interpreter to hold flags for any data - * that has changed in gn during the parse. cm->gf.target[] values are also used - * by the canonical machine during set_target(). - * - * - cfg (config struct in config.h) is also used heavily and contains some - * values that might be considered to be Gcode model values. The distinction - * is that all values in the config are persisted and restored, whereas the - * gm structs are transient. So cfg has the G54 - G59 offsets, but gm has the - * G92 offsets. cfg has the power-on / reset gcode default values, but gm has - * the operating state for the values (which may have changed). - */ -typedef struct GCodeState { // Gcode model state - used by model, planning and runtime - uint32_t linenum; // Gcode block line number - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, - // G82, G83 G84, G85, G86, G87, G88, G89 - - float target[AXES]; // XYZABC where the move should go - float target_comp[AXES]; // summation compensation (Kahan) overflow value - float work_offset[AXES]; // offset from the work coordinate system (for reporting only) - - float feed_rate; // F - normalized to millimeters/minute or in inverse time mode - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... - - cmFeedRateMode feed_rate_mode; // See cmFeedRateMode for settings - cmCanonicalPlane select_plane; // G17,G18,G19 - values to set plane to - cmUnitsMode units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - cmPathControl path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - cmDistanceMode distance_mode; // G90=use absolute coords, G91=incremental movement - cmDistanceMode arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - cmAbsoluteOverride absolute_override;// G53 TRUE = move using machine coordinates - this block only - cmCoordSystem coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t tool; // G // M6 tool change - moves "tool_select" to "tool" - uint8_t tool_select; // G // T value - T sets this value - - void reset() { - linenum = 0; - motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; - - for (uint8_t i = 0; i< AXES; i++) { - target[i] = 0.0; - work_offset[i] = 0.0; - } - - feed_rate = 0.0; - parameter = 0.0; - - feed_rate_mode = INVERSE_TIME_MODE; - select_plane = CANON_PLANE_XY; - units_mode = INCHES; - path_control = PATH_EXACT_PATH; - distance_mode = ABSOLUTE_MODE; - arc_distance_mode = ABSOLUTE_MODE; - absolute_override = ABSOLUTE_OVERRIDE_OFF; - coord_system = ABSOLUTE_COORDS; - tool = 0; - tool_select = 0; - - }; -} GCodeState_t; - -typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used by model and arcs - uint16_t magic_start; // magic number to test memory integrity - uint8_t next_action; // handles G modal group 1 moves & non-modals - uint8_t program_flow; // used only by the gcode_parser - - float position[AXES]; // XYZABC model position (Note: not used in gn or gf) - float origin_offset[AXES]; // XYZABC G92 offsets (Note: not used in gn or gf) - float g28_position[AXES]; // XYZABC stored machine position for G28 - float g30_position[AXES]; // XYZABC stored machine position for G30 - - bool m48_enable; // master feedrate / spindle speed override enable - bool mfo_enable; // feedrate override enable - float mfo_factor; // 1.0000 x F feed rate. Go up or down from there - bool mto_enable; // traverse override enable - float mto_factor; // valid from 0.05 to 1.00 - - bool origin_offset_enable; // G92 offsets enabled/disabled. 0=disabled, 1=enabled - bool block_delete_switch; // set true to enable block deletes (true is default) - -// unimplemented gcode parameters -// float cutter_radius; // D - cutter radius compensation (0 is off) -// float cutter_length; // H - cutter length compensation (0 is off) - - uint16_t magic_end; - -} GCodeStateX_t; - -typedef struct GCodeInput { // Gcode model inputs - meaning depends on context - - uint8_t next_action; // handles G modal group 1 moves & non-modals - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 - // G83, G84, G85, G86, G87, G88, G89 - - uint8_t program_flow; // used only by the gcode_parser - uint32_t linenum; // N word - float target[AXES]; // XYZABC where the move should go - - uint8_t L_word; // L word - used by G10s - - float feed_rate; // F - normalized to millimeters/minute - uint8_t feed_rate_mode; // See cmFeedRateMode for settings - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... - float arc_radius; // R - radius value in arc radius mode - float arc_offset[3]; // IJK - used by arc commands - - bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_enable; // M50 feedrate override enable - bool mto_enable; // Mxx traverse override enable - bool sso_enable; // M51 spindle speed override enable - - uint8_t select_plane; // G17,G18,G19 - values to set plane to - uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - uint8_t coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement - uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode - uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) - uint8_t tool; // Tool after T and M6 (tool_select and tool_change) - uint8_t tool_select; // T value - T sets this value - uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" - uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) - uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) - - uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - float spindle_speed; // in RPM - float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there - uint8_t spindle_override_enable; // TRUE = override enabled - -// unimplemented gcode parameters -// float cutter_radius; // D - cutter radius compensation (0 is off) -// float cutter_length; // H - cutter length compensation (0 is off) - -} GCodeInput_t; - -typedef struct GCodeFlags { // Gcode model input flags - bool next_action; - bool motion_mode; - bool modals[MODAL_GROUP_COUNT]; - bool program_flow; - bool linenum; - bool target[AXES]; - - bool L_word; - bool feed_rate; - bool feed_rate_mode; - - bool m48_enable; - bool mfo_enable; - bool mto_enable; - bool sso_enable; - - bool select_plane; - bool units_mode; - bool coord_system; - bool path_control; - bool distance_mode; - bool arc_distance_mode; - bool origin_offset_mode; - bool absolute_override; - bool tool; - bool tool_select; - bool tool_change; - bool mist_coolant; - bool flood_coolant; - - bool spindle_control; - bool spindle_speed; - bool spindle_override_factor; - bool spindle_override_enable; - - bool parameter; - bool arc_radius; - bool arc_offset[3]; -} GCodeFlags_t; - /***************************************************************************** * CANONICAL MACHINE STRUCTURES */ @@ -580,15 +236,12 @@ typedef struct cmMachine { // struct to manage canonical machin GCodeState_t *am; // active Gcode model is maintained by state management GCodeState_t gm; // core gcode model state GCodeStateX_t gmx; // extended gcode model state - GCodeInput_t gn; // gcode input values - transient - GCodeFlags_t gf; // gcode input flags - transient magic_t magic_end; } cmMachine_t; /**** Externs - See canonical_machine.cpp for allocation ****/ -//extern cmMachine_t cm; // canonical machine controller singleton extern cmMachine_t *cm; // pointer to active canonical machine extern cmMachine_t cm0; // canonical machine primary machine extern cmMachine_t cm1; // canonical machine secondary machine diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index 1a37b393..81bc042b 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -407,38 +407,38 @@ static stat_t _homing_finalize_exit(int8_t axis) // third part of return to hom static int8_t _get_next_axis(int8_t axis) { #if (HOMING_AXES <= 4) if (axis == -1) { // inelegant brute force solution - if (cm->gf.target[AXIS_Z]) { + if (gc.gf.target[AXIS_Z]) { return (AXIS_Z); } - if (cm->gf.target[AXIS_X]) { + if (gc.gf.target[AXIS_X]) { return (AXIS_X); } - if (cm->gf.target[AXIS_Y]) { + if (gc.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } return (-2); // error } else if (axis == AXIS_Z) { - if (cm->gf.target[AXIS_X]) { + if (gc.gf.target[AXIS_X]) { return (AXIS_X); } - if (cm->gf.target[AXIS_Y]) { + if (gc.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_X) { - if (cm->gf.target[AXIS_Y]) { + if (gc.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_Y) { - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } } @@ -446,73 +446,73 @@ static int8_t _get_next_axis(int8_t axis) { #else if (axis == -1) { - if (cm->gf.target[AXIS_Z]) { + if (gc.gf.target[AXIS_Z]) { return (AXIS_Z); } - if (cm->gf.target[AXIS_X]) { + if (gc.gf.target[AXIS_X]) { return (AXIS_X); } - if (cm->gf.target[AXIS_Y]) { + if (gc.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } - if (cm->gf.target[AXIS_B]) { + if (gc.gf.target[AXIS_B]) { return (AXIS_B); } - if (cm->gf.target[AXIS_C]) { + if (gc.gf.target[AXIS_C]) { return (AXIS_C); } return (-2); // error } else if (axis == AXIS_Z) { - if (cm->gf.target[AXIS_X]) { + if (gc.gf.target[AXIS_X]) { return (AXIS_X); } - if (cm->gf.target[AXIS_Y]) { + if (gc.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } - if (cm->gf.target[AXIS_B]) { + if (gc.gf.target[AXIS_B]) { return (AXIS_B); } - if (cm->gf.target[AXIS_C]) { + if (gc.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_X) { - if (cm->gf.target[AXIS_Y]) { + if (gc.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } - if (cm->gf.target[AXIS_B]) { + if (gc.gf.target[AXIS_B]) { return (AXIS_B); } - if (cm->gf.target[AXIS_C]) { + if (gc.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_Y) { - if (cm->gf.target[AXIS_A]) { + if (gc.gf.target[AXIS_A]) { return (AXIS_A); } - if (cm->gf.target[AXIS_B]) { + if (gc.gf.target[AXIS_B]) { return (AXIS_B); } - if (cm->gf.target[AXIS_C]) { + if (gc.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_A) { - if (cm->gf.target[AXIS_B]) { + if (gc.gf.target[AXIS_B]) { return (AXIS_B); } - if (cm->gf.target[AXIS_C]) { + if (gc.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_B) { - if (cm->gf.target[AXIS_C]) { + if (gc.gf.target[AXIS_C]) { return (AXIS_C); } } diff --git a/g2core/gcode.h b/g2core/gcode.h index 3b543fe9..f4e02426 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -20,6 +20,365 @@ #ifndef GCODE_H_ONCE #define GCODE_H_ONCE +#include "hardware.h" + +/* Gcode-specific definitions */ + +/* The difference between NextAction and MotionMode is that NextAction is + * used by the current block, and may carry non-modal commands, whereas + * MotionMode persists across blocks (as G modal group 1) + */ + +typedef enum { // these are in order to optimized CASE statement + NEXT_ACTION_DEFAULT = 0, // Must be zero (invokes motion modes) + NEXT_ACTION_SEARCH_HOME, // G28.2 homing cycle + NEXT_ACTION_SET_ABSOLUTE_ORIGIN, // G28.3 origin set + NEXT_ACTION_HOMING_NO_SET, // G28.4 homing cycle with no coordinate setting + NEXT_ACTION_SET_G28_POSITION, // G28.1 set position in abs coordinates + NEXT_ACTION_GOTO_G28_POSITION, // G28 go to machine position + NEXT_ACTION_SET_G30_POSITION, // G30.1 + NEXT_ACTION_GOTO_G30_POSITION, // G30 + NEXT_ACTION_SET_COORD_DATA, // G10 + NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92 + NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1 + NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2 + NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3 + NEXT_ACTION_DWELL, // G4 + NEXT_ACTION_STRAIGHT_PROBE_ERR, // G38.2 + NEXT_ACTION_STRAIGHT_PROBE, // G38.3 + NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR,// G38.4 + NEXT_ACTION_STRAIGHT_PROBE_AWAY, // G38.5 + NEXT_ACTION_JSON_COMMAND_SYNC, // M100 + NEXT_ACTION_JSON_COMMAND_IMMEDIATE, // M101 + NEXT_ACTION_JSON_WAIT // M102 +} cmNextAction; + +typedef enum { // G Modal Group 1 + MOTION_MODE_STRAIGHT_TRAVERSE=0, // G0 - straight traverse + MOTION_MODE_STRAIGHT_FEED, // G1 - straight feed + MOTION_MODE_CW_ARC, // G2 - clockwise arc feed + MOTION_MODE_CCW_ARC, // G3 - counter-clockwise arc feed + MOTION_MODE_CANCEL_MOTION_MODE, // G80 + MOTION_MODE_STRAIGHT_PROBE, // G38.2 + MOTION_MODE_CANNED_CYCLE_81, // G81 - drilling + MOTION_MODE_CANNED_CYCLE_82, // G82 - drilling with dwell + MOTION_MODE_CANNED_CYCLE_83, // G83 - peck drilling + MOTION_MODE_CANNED_CYCLE_84, // G84 - right hand tapping + MOTION_MODE_CANNED_CYCLE_85, // G85 - boring, no dwell, feed out + MOTION_MODE_CANNED_CYCLE_86, // G86 - boring, spindle stop, rapid out + MOTION_MODE_CANNED_CYCLE_87, // G87 - back boring + MOTION_MODE_CANNED_CYCLE_88, // G88 - boring, spindle stop, manual out + MOTION_MODE_CANNED_CYCLE_89 // G89 - boring, dwell, feed out +} cmMotionMode; + +typedef enum { // Used for detecting gcode errors. See NIST section 3.4 + MODAL_GROUP_G0 = 0, // {G10,G28,G28.1,G92} non-modal axis commands (note 1) + MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion + MODAL_GROUP_G2, // {G17,G18,G19} plane selection + MODAL_GROUP_G3, // {G90,G91} distance mode + MODAL_GROUP_G5, // {G93,G94} feed rate mode + MODAL_GROUP_G6, // {G20,G21} units + MODAL_GROUP_G7, // {G40,G41,G42} cutter radius compensation + MODAL_GROUP_G8, // {G43,G49} tool length offset + MODAL_GROUP_G9, // {G98,G99} return mode in canned cycles + MODAL_GROUP_G12, // {G54,G55,G56,G57,G58,G59} coordinate system selection + MODAL_GROUP_G13, // {G61,G61.1,G64} path control mode + MODAL_GROUP_M4, // {M0,M1,M2,M30,M60} stopping + MODAL_GROUP_M6, // {M6} tool change + MODAL_GROUP_M7, // {M3,M4,M5} spindle turning + MODAL_GROUP_M8, // {M7,M8,M9} coolant (M7 & M8 may be active together) + MODAL_GROUP_M9 // {M48,M49} speed/feed override switches +} cmModalGroup; +#define MODAL_GROUP_COUNT (MODAL_GROUP_M9+1) +// Note 1: Our G0 omits G4,G30,G53,G92.1,G92.2,G92.3 as these have no axis components to error check + +typedef enum { // canonical plane - translates to: + // axis_0 axis_1 axis_2 + CANON_PLANE_XY = 0, // G17 X Y Z + CANON_PLANE_XZ, // G18 X Z Y + CANON_PLANE_YZ // G19 Y Z X +} cmCanonicalPlane; + +typedef enum { + INCHES = 0, // G20 + MILLIMETERS, // G21 + DEGREES // ABC axes (this value used for displays only) +} cmUnitsMode; + +typedef enum { + ABSOLUTE_COORDS = 0, // machine coordinate system + G54, // G54 coordinate system + G55, // G55 coordinate system + G56, // G56 coordinate system + G57, // G57 coordinate system + G58, // G58 coordinate system + G59 // G59 coordinate system +} cmCoordSystem; +#define COORD_SYSTEM_MAX G59 // set this manually to the last one + +typedef enum { + ABSOLUTE_OVERRIDE_OFF = 0,// G53 enabled + ABSOLUTE_OVERRIDE_ON +} cmAbsoluteOverride; + +typedef enum { // G Modal Group 13 + PATH_EXACT_PATH = 0, // G61 - hits corners but does not stop if it does not need to. + PATH_EXACT_STOP, // G61.1 - stops at all corners + PATH_CONTINUOUS // G64 and typically the default mode +} cmPathControl; + +typedef enum { + ABSOLUTE_MODE = 0, // G90 / G90.1 + INCREMENTAL_MODE // G91 / G91.1 +} cmDistanceMode; + +typedef enum { + INVERSE_TIME_MODE = 0, // G93 + UNITS_PER_MINUTE_MODE, // G94 + UNITS_PER_REVOLUTION_MODE// G95 (unimplemented) +} cmFeedRateMode; + +typedef enum { + ORIGIN_OFFSET_SET=0, // G92 - set origin offsets + ORIGIN_OFFSET_CANCEL, // G92.1 - zero out origin offsets + ORIGIN_OFFSET_SUSPEND, // G92.2 - do not apply offsets, but preserve the values + ORIGIN_OFFSET_RESUME // G92.3 - resume application of the suspended offsets +} cmOriginOffset; + +typedef enum { + PROGRAM_STOP = 0, + PROGRAM_END +} cmProgramFlow; + +typedef enum { // used for spindle and arc dir + DIRECTION_CW = 0, + DIRECTION_CCW +} cmDirection; + +typedef enum { // axis types + AXIS_TYPE_UNDEFINED=-1, // invalid type + AXIS_TYPE_LINEAR, // linear axis + AXIS_TYPE_ROTARY // rotary axis +} cmAxisType; + +typedef enum { // axis modes (ordered: see _cm_get_feed_time()) + AXIS_DISABLED = 0, // kill axis + AXIS_STANDARD, // axis in coordinated motion w/standard behaviors + AXIS_INHIBITED, // axis is computed but not activated + AXIS_RADIUS // rotary axis calibrated to circumference +} cmAxisMode; +#define AXIS_MODE_LINEAR_MAX AXIS_INHIBITED +#define AXIS_MODE_ROTARY_MAX AXIS_RADIUS + +/* Gcode state structures */ + +/***************************************************************************** + * GCODE MODEL - The following GCodeModel/GCodeInput structs are used: + * + * - gm is the core Gcode model state. It keeps the internal gcode state model in + * normalized, canonical form. All values are unit converted (to mm) and in the + * machine coordinate system (absolute coordinate system). Gm is owned by the + * canonical machine layer and should be accessed only through cm_ routines. + * + * The gm core struct is copied and passed as context to the runtime where it is + * used for planning, move execution, feedholds, and reporting. + * + * - gmx is the extended gcode model variables that are only used by the canonical + * machine and do not need to be passed further down. It keeps "global" gcode + * state that does not change when you go down through the planner to the runtime. + * Other Gcode model state is kept in the singletons for various sub-systems, such + * as arcs, spindle, coolant, and others (i.e. not ALL gcode global state is in gmx) + * + * - gn is used by the gcode interpreter and is re-initialized for each + * gcode block.It accepts data in the new gcode block in the formats + * present in the block (pre-normalized forms). During initialization + * some state elements are necessarily restored from gm. + * + * - gf is used by the gcode parser interpreter to hold flags for any data + * that has changed in gn during the parse. gc.gf.target[] values are also used + * by the canonical machine during set_target(). + * + * - cfg (config struct in config.h) is also used heavily and contains some + * values that might be considered to be Gcode model values. The distinction + * is that all values in the config are persisted and restored, whereas the + * gm structs are transient. So cfg has the G54 - G59 offsets, but gm has the + * G92 offsets. cfg has the power-on / reset gcode default values, but gm has + * the operating state for the values (which may have changed). + */ +typedef struct GCodeState { // Gcode model state - used by model, planning and runtime + uint32_t linenum; // Gcode block line number + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, + // G82, G83 G84, G85, G86, G87, G88, G89 + + float target[AXES]; // XYZABC where the move should go + float target_comp[AXES]; // summation compensation (Kahan) overflow value + float work_offset[AXES]; // offset from the work coordinate system (for reporting only) + + float feed_rate; // F - normalized to millimeters/minute or in inverse time mode + float parameter; // P - parameter used for dwell time in seconds, G10 coord select... + + cmFeedRateMode feed_rate_mode; // See cmFeedRateMode for settings + cmCanonicalPlane select_plane; // G17,G18,G19 - values to set plane to + cmUnitsMode units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) + cmPathControl path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS + cmDistanceMode distance_mode; // G90=use absolute coords, G91=incremental movement + cmDistanceMode arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets + cmAbsoluteOverride absolute_override;// G53 TRUE = move using machine coordinates - this block only + cmCoordSystem coord_system; // G54-G59 - select coordinate system 1-9 + uint8_t tool; // G // M6 tool change - moves "tool_select" to "tool" + uint8_t tool_select; // G // T value - T sets this value + + void reset() { + linenum = 0; + motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; + + for (uint8_t i = 0; i< AXES; i++) { + target[i] = 0.0; + work_offset[i] = 0.0; + } + + feed_rate = 0.0; + parameter = 0.0; + + feed_rate_mode = INVERSE_TIME_MODE; + select_plane = CANON_PLANE_XY; + units_mode = INCHES; + path_control = PATH_EXACT_PATH; + distance_mode = ABSOLUTE_MODE; + arc_distance_mode = ABSOLUTE_MODE; + absolute_override = ABSOLUTE_OVERRIDE_OFF; + coord_system = ABSOLUTE_COORDS; + tool = 0; + tool_select = 0; + + }; +} GCodeState_t; + +typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used by model and arcs + uint16_t magic_start; // magic number to test memory integrity + uint8_t next_action; // handles G modal group 1 moves & non-modals + uint8_t program_flow; // used only by the gcode_parser + + float position[AXES]; // XYZABC model position (Note: not used in gn or gf) + float origin_offset[AXES]; // XYZABC G92 offsets (Note: not used in gn or gf) + float g28_position[AXES]; // XYZABC stored machine position for G28 + float g30_position[AXES]; // XYZABC stored machine position for G30 + + bool m48_enable; // master feedrate / spindle speed override enable + bool mfo_enable; // feedrate override enable + float mfo_factor; // 1.0000 x F feed rate. Go up or down from there + bool mto_enable; // traverse override enable + float mto_factor; // valid from 0.05 to 1.00 + + bool origin_offset_enable; // G92 offsets enabled/disabled. 0=disabled, 1=enabled + bool block_delete_switch; // set true to enable block deletes (true is default) + +// unimplemented gcode parameters +// float cutter_radius; // D - cutter radius compensation (0 is off) +// float cutter_length; // H - cutter length compensation (0 is off) + + uint16_t magic_end; + +} GCodeStateX_t; + + +typedef struct GCodeInput { // Gcode model inputs - meaning depends on context + + uint8_t next_action; // handles G modal group 1 moves & non-modals + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 + // G83, G84, G85, G86, G87, G88, G89 + + uint8_t program_flow; // used only by the gcode_parser + uint32_t linenum; // N word + float target[AXES]; // XYZABC where the move should go + + uint8_t L_word; // L word - used by G10s + + float feed_rate; // F - normalized to millimeters/minute + uint8_t feed_rate_mode; // See cmFeedRateMode for settings + float parameter; // P - parameter used for dwell time in seconds, G10 coord select... + float arc_radius; // R - radius value in arc radius mode + float arc_offset[3]; // IJK - used by arc commands + + bool m48_enable; // M48/M49 input (enables for feed and spindle) + bool mfo_enable; // M50 feedrate override enable + bool mto_enable; // Mxx traverse override enable + bool sso_enable; // M51 spindle speed override enable + + uint8_t select_plane; // G17,G18,G19 - values to set plane to + uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) + uint8_t coord_system; // G54-G59 - select coordinate system 1-9 + uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS + uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement + uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets + uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode + uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) + uint8_t tool; // Tool after T and M6 (tool_select and tool_change) + uint8_t tool_select; // T value - T sets this value + uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" + uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) + uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) + + uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) + float spindle_speed; // in RPM + float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there + uint8_t spindle_override_enable; // TRUE = override enabled + + // unimplemented gcode parameters + // float cutter_radius; // D - cutter radius compensation (0 is off) + // float cutter_length; // H - cutter length compensation (0 is off) + +} GCodeInput_t; + +typedef struct GCodeFlags { // Gcode model input flags + bool next_action; + bool motion_mode; + bool modals[MODAL_GROUP_COUNT]; + bool program_flow; + bool linenum; + bool target[AXES]; + + bool L_word; + bool feed_rate; + bool feed_rate_mode; + + bool m48_enable; + bool mfo_enable; + bool mto_enable; + bool sso_enable; + + bool select_plane; + bool units_mode; + bool coord_system; + bool path_control; + bool distance_mode; + bool arc_distance_mode; + bool origin_offset_mode; + bool absolute_override; + bool tool; + bool tool_select; + bool tool_change; + bool mist_coolant; + bool flood_coolant; + + bool spindle_control; + bool spindle_speed; + bool spindle_override_factor; + bool spindle_override_enable; + + bool parameter; + bool arc_radius; + bool arc_offset[3]; +} GCodeFlags_t; + +typedef struct GCodeSingleton { + GCodeInput_t gn; // gcode input values - transient + GCodeFlags_t gf; // gcode input flags - transient +} GCodeSingleton_t; + +extern GCodeSingleton_t gc; // gcode structs + + /* * Global Scope Functions */ diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 0878ecb8..3de2045a 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -27,6 +27,8 @@ #include "util.h" #include "xio.h" // for char definitions +GCodeSingleton_t gc; // gcode structs + // local helper functions and macros static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value); @@ -35,9 +37,9 @@ static stat_t _validate_gcode_block(char *active_comment); static stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs static stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block -#define SET_MODAL(m,parm,val) ({cm->gn.parm=val; cm->gf.parm=true; cm->gf.modals[m]=true; break;}) -#define SET_NON_MODAL(parm,val) ({cm->gn.parm=val; cm->gf.parm=true; break;}) -#define EXEC_FUNC(f,v) if(cm->gf.v) { status=f(cm->gn.v);} +#define SET_MODAL(m,parm,val) ({gc.gn.parm=val; gc.gf.parm=true; gc.gf.modals[m]=true; break;}) +#define SET_NON_MODAL(parm,val) ({gc.gn.parm=val; gc.gf.parm=true; break;}) +#define EXEC_FUNC(f,v) if(gc.gf.v) { status=f(gc.gn.v);} /* * gcode_parser() - parse a block (line) of gcode @@ -387,12 +389,12 @@ static stat_t _validate_gcode_block(char *active_comment) // uses axis words appears on the line, the activity of the group 1 G-code is suspended // for that line. The axis word-using G-codes from group 0 are G10, G28, G30, and G92" -// if ((cm->gn.modals[MODAL_GROUP_G0] == true) && (cm->gn.modals[MODAL_GROUP_G1] == true)) { +// if ((gc.gn.modals[MODAL_GROUP_G0] == true) && (gc.gn.modals[MODAL_GROUP_G1] == true)) { // return (STAT_MODAL_GROUP_VIOLATION); // } // look for commands that require an axis word to be present -// if ((cm->gn.modals[MODAL_GROUP_G0] == true) || (cm->gn.modals[MODAL_GROUP_G1] == true)) { +// if ((gc.gn.modals[MODAL_GROUP_G0] == true) || (gc.gn.modals[MODAL_GROUP_G1] == true)) { // if (_axis_changed() == false) // return (STAT_GCODE_AXIS_IS_MISSING); // } @@ -415,16 +417,16 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) stat_t status = STAT_OK; // set initial state for new move - memset(&cm->gn, 0, sizeof(GCodeInput_t)); // clear all next-state values - memset(&cm->gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags - cm->gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block + memset(&gc.gn, 0, sizeof(GCodeInput_t)); // clear all next-state values + memset(&gc.gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags + gc.gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block // Causes a later exception if // (1) INVERSE_TIME_MODE is active and a feed rate is not provided or // (2) INVERSE_TIME_MODE is changed to UNITS_PER_MINUTE and a new feed rate is missing if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate req'd when in INV_TIME_MODE - cm->gn.feed_rate = 0; - cm->gf.feed_rate = true; + gc.gn.feed_rate = 0; + gc.gf.feed_rate = true; } // extract commands and parameters @@ -620,7 +622,7 @@ static stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; - cm_set_model_linenum(cm->gn.linenum); + cm_set_model_linenum(gc.gn.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, feed_rate); // F EXEC_FUNC(cm_set_spindle_speed, spindle_speed); // S @@ -642,8 +644,8 @@ static stat_t _execute_gcode_block(char *active_comment) // EXEC_FUNC(cm_mfo_enable, feed_rate_override_factor); // EXEC_FUNC(cm_sso_enable, sso_enable); - if (cm->gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell - ritorno(cm_dwell(cm->gn.parameter)); // return if error, otherwise complete the block + if (gc.gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell + ritorno(cm_dwell(gc.gn.parameter)); // return if error, otherwise complete the block } EXEC_FUNC(cm_select_plane, select_plane); // G17, G18, G19 EXEC_FUNC(cm_set_units_mode, units_mode); // G20, G21 @@ -651,29 +653,29 @@ static stat_t _execute_gcode_block(char *active_comment) //--> cutter length compensation goes here EXEC_FUNC(cm_set_coord_system, coord_system); // G54, G55, G56, G57, G58, G59 // EXEC_FUNC(cm_set_path_control, path_control); // G61, G61.1, G64 - if(cm->gf.path_control) { status = cm_set_path_control(MODEL, cm->gn.path_control); } + if(gc.gf.path_control) { status = cm_set_path_control(MODEL, gc.gn.path_control); } EXEC_FUNC(cm_set_distance_mode, distance_mode); // G90, G91 EXEC_FUNC(cm_set_arc_distance_mode, arc_distance_mode); // G90.1, G91.1 //--> set retract mode goes here - switch (cm->gn.next_action) { + switch (gc.gn.next_action) { case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(cm->gn.target, cm->gf.target); break;} // G28 + case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gc.gn.target, gc.gf.target); break;} // G28 case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(cm->gn.target, cm->gf.target); break;} // G30 + case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gc.gn.target, gc.gf.target); break;} // G30 case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(cm->gn.target, cm->gf.target); break;}// G28.3 + case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gc.gn.target, gc.gf.target); break;}// G28.3 case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(); break;} // G28.4 - case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(cm->gn.target, cm->gf.target, true, true); break;} // G38.2 - case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(cm->gn.target, cm->gf.target, false, true); break;} // G38.3 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(cm->gn.target, cm->gf.target, true, false); break;} // G38.4 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(cm->gn.target, cm->gf.target, false, false); break;} // G38.5 + case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gc.gn.target, gc.gf.target, true, true); break;} // G38.2 + case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gc.gn.target, gc.gf.target, false, true); break;} // G38.3 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gc.gn.target, gc.gf.target, true, false); break;} // G38.4 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gc.gn.target, gc.gf.target, false, false); break;} // G38.5 - case NEXT_ACTION_SET_COORD_DATA: { status = cm_set_coord_offsets(cm->gn.parameter, cm->gn.L_word, cm->gn.target, cm->gf.target); break;} - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(cm->gn.target, cm->gf.target); break;}// G92 + case NEXT_ACTION_SET_COORD_DATA: { status = cm_set_coord_offsets(gc.gn.parameter, gc.gn.L_word, gc.gn.target, gc.gf.target); break;} + case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gc.gn.target, gc.gf.target); break;}// G92 case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 @@ -683,18 +685,18 @@ static stat_t _execute_gcode_block(char *active_comment) // case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 case NEXT_ACTION_DEFAULT: { - cm_set_absolute_override(MODEL, cm->gn.absolute_override); // apply absolute override - switch (cm->gn.motion_mode) { - case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = cm->gn.motion_mode; break;} // G80 - case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(cm->gn.target, cm->gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(cm->gn.target, cm->gf.target); break;} // G1 + cm_set_absolute_override(MODEL, gc.gn.absolute_override); // apply absolute override + switch (gc.gn.motion_mode) { + case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gc.gn.motion_mode; break;} // G80 + case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gc.gn.target, gc.gf.target); break;} // G0 + case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gc.gn.target, gc.gf.target); break;} // G1 case MOTION_MODE_CW_ARC: // G2 - case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(cm->gn.target, cm->gf.target, // G3 - cm->gn.arc_offset, cm->gf.arc_offset, - cm->gn.arc_radius, cm->gf.arc_radius, - cm->gn.parameter, cm->gf.parameter, - cm->gf.modals[MODAL_GROUP_G1], - cm->gn.motion_mode); + case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gc.gn.target, gc.gf.target, // G3 + gc.gn.arc_offset, gc.gf.arc_offset, + gc.gn.arc_radius, gc.gf.arc_radius, + gc.gn.parameter, gc.gf.parameter, + gc.gf.modals[MODAL_GROUP_G1], + gc.gn.motion_mode); break; } default: break; @@ -704,8 +706,8 @@ static stat_t _execute_gcode_block(char *active_comment) } // do the program stops and ends : M0, M1, M2, M30, M60 - if (cm->gf.program_flow == true) { - if (cm->gn.program_flow == PROGRAM_STOP) { + if (gc.gf.program_flow == true) { + if (gc.gn.program_flow == PROGRAM_STOP) { cm_program_stop(); } else { cm_program_end(); diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 00dd7c17..076f728f 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -228,7 +228,7 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) /* stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 { - if (fp_TRUE(cm->gf.parameter) && fp_ZERO(cm->gn.parameter)) { + if (fp_TRUE(gc.gf.parameter) && fp_ZERO(gc.gn.parameter)) { spindle.override_enable = false; } else { spindle.override_enable = true; @@ -239,7 +239,7 @@ stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 stat_t cm_spindle_override_factor(uint8_t flag) // M50.1 { spindle.override_enable = flag; - spindle.override_factor = cm->gn.parameter; + spindle.override_factor = gc.gn.parameter; // change spindle speed return (STAT_OK); } From 5e91aa91fa62170b53e0a3a4f26cef14fb72b8b5 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 16:05:17 -0500 Subject: [PATCH 020/283] Moved Gcode defaults from canonical machine to Gcode.h; Installed generic sets and gets for floating point values --- g2core/canonical_machine.cpp | 63 ++++++++++++++---------------------- g2core/canonical_machine.h | 10 +++--- g2core/config.h | 6 ++-- g2core/config_app.cpp | 39 +++++++++++++++------- g2core/gcode.h | 9 ++++++ 5 files changed, 71 insertions(+), 56 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 03655842..519213b8 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -128,8 +128,7 @@ static void _exec_select_tool(float *value, bool *flag); static void _exec_absolute_origin(float *value, bool *flag); static void _exec_program_finalize(float *value, bool *flag); -static int8_t _get_axis(const index_t index); -//static cmAxisType _get_axis_type(const index_t index); +static int8_t _axis(const index_t index); /*********************************************************************************** **** CODE ************************************************************************* @@ -726,11 +725,11 @@ void canonical_machine_reset_rotation() { void canonical_machine_reset() { // set gcode defaults - cm_set_units_mode(cm->default_units_mode); - cm_set_coord_system(cm->default_coord_system); // NB: queues a block to the planner with the coordinates - cm_select_plane(cm->default_select_plane); - cm_set_path_control(MODEL, cm->default_path_control); - cm_set_distance_mode(cm->default_distance_mode); + cm_set_units_mode(gc.default_units_mode); + cm_set_coord_system(gc.default_coord_system); // NB: queues a block to the planner with the coordinates + cm_select_plane(gc.default_select_plane); + cm_set_path_control(MODEL, gc.default_path_control); + cm_set_distance_mode(gc.default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_MODE); // always the default cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default cm_reset_overrides(); // set overrides to initial conditions @@ -1848,9 +1847,9 @@ static void _exec_program_finalize(float *value, bool *flag) if (((uint8_t)value[0]) == MACHINE_PROGRAM_END) { cm_suspend_origin_offsets(); // G92.2 - as per NIST // cm_reset_origin_offsets(); // G92.1 - alternative to above - cm_set_coord_system(cm->default_coord_system); // reset to default coordinate system - cm_select_plane(cm->default_select_plane); // reset to default arc plane - cm_set_distance_mode(cm->default_distance_mode); + cm_set_coord_system(gc.default_coord_system); // reset to default coordinate system + cm_select_plane(gc.default_select_plane); // reset to default arc plane + cm_set_distance_mode(gc.default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_MODE); // always the default cm_spindle_off_immediate(); // M5 cm_coolant_off_immediate(); // M9 @@ -2086,7 +2085,7 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; * cm_get_axis_type() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) */ -static int8_t _get_axis(const index_t index) +static int8_t _axis(const index_t index) { char *ptr; char tmp[TOKEN_LEN+1]; @@ -2110,7 +2109,7 @@ char cm_get_axis_char(const int8_t axis) cmAxisType cm_get_axis_type(const index_t index) { - int8_t axis = _get_axis(index); + int8_t axis = _axis(index); if (axis >= AXIS_A) return (AXIS_TYPE_ROTARY); if (axis == -1) return (AXIS_TYPE_UNDEFINED); return (AXIS_TYPE_LINEAR); @@ -2222,7 +2221,7 @@ stat_t cm_get_feed(nvObj_t *nv) stat_t cm_get_pos(nvObj_t *nv) { - nv->value = cm_get_work_position(ACTIVE_MODEL, _get_axis(nv->index)); + nv->value = cm_get_work_position(ACTIVE_MODEL, _axis(nv->index)); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return (STAT_OK); @@ -2230,7 +2229,7 @@ stat_t cm_get_pos(nvObj_t *nv) stat_t cm_get_mpo(nvObj_t *nv) { - nv->value = cm_get_absolute_position(ACTIVE_MODEL, _get_axis(nv->index)); + nv->value = cm_get_absolute_position(ACTIVE_MODEL, _axis(nv->index)); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return (STAT_OK); @@ -2238,7 +2237,7 @@ stat_t cm_get_mpo(nvObj_t *nv) stat_t cm_get_ofs(nvObj_t *nv) { - nv->value = cm_get_work_offset(ACTIVE_MODEL, _get_axis(nv->index)); + nv->value = cm_get_work_offset(ACTIVE_MODEL, _axis(nv->index)); nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return (STAT_OK); @@ -2259,7 +2258,7 @@ stat_t cm_get_ofs(nvObj_t *nv) stat_t cm_get_am(nvObj_t *nv) { - int8_t axis = _get_axis(nv->index); + int8_t axis = _axis(nv->index); nv->value = (float)cm->a[axis].axis_mode; return(_get_msg_helper(nv, msg_am, nv->value)); } @@ -2272,28 +2271,16 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode } else { if (nv->value > AXIS_MODE_ROTARY_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} } - cm->a[_get_axis(nv->index)].axis_mode = (cmAxisMode)nv->value; + cm->a[_axis(nv->index)].axis_mode = (cmAxisMode)nv->value; return(STAT_OK); } -stat_t cm_get_tn(nvObj_t *nv) -{ - nv->value = cm->a[_get_axis(nv->index)].travel_min; - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); -} - - -stat_t cm_set_tn(nvObj_t *nv) -{ - preprocess_incoming_float(nv); - cm->a[_get_axis(nv->index)].travel_min = nv->value; - return (STAT_OK); -} +stat_t cm_get_tn(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].travel_min)); } +stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_min));} stat_t cm_get_tm(nvObj_t *nv) { - nv->value = cm->a[_get_axis(nv->index)].travel_max; + nv->value = cm->a[_axis(nv->index)].travel_max; nv->valuetype = TYPE_FLOAT; return (STAT_OK); } @@ -2301,7 +2288,7 @@ stat_t cm_get_tm(nvObj_t *nv) stat_t cm_set_tm(nvObj_t *nv) { preprocess_incoming_float(nv); - cm->a[_get_axis(nv->index)].travel_max = nv->value; + cm->a[_axis(nv->index)].travel_max = nv->value; return (STAT_OK); } @@ -2361,7 +2348,7 @@ stat_t cm_get_vm(nvObj_t *nv) stat_t cm_set_vm(nvObj_t *nv) { - uint8_t axis = _get_axis(nv->index); + uint8_t axis = _axis(nv->index); if ((axis == AXIS_A) || (axis == AXIS_B) || (axis == AXIS_C)) { set_flt(nv); } else { @@ -2378,7 +2365,7 @@ stat_t cm_get_fr(nvObj_t *nv) stat_t cm_set_fr(nvObj_t *nv) { - uint8_t axis = _get_axis(nv->index); + uint8_t axis = _axis(nv->index); if ((axis == AXIS_A) || (axis == AXIS_B) || (axis == AXIS_C)) { set_flt(nv); } else { @@ -2397,7 +2384,7 @@ stat_t cm_set_jm(nvObj_t *nv) { // if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER; set_flu(nv); - cm_set_axis_jerk(_get_axis(nv->index), nv->value); + cm_set_axis_jerk(_axis(nv->index), nv->value); return(STAT_OK); } @@ -2815,7 +2802,7 @@ static void _print_axis_coord_flt(nvObj_t *nv, const char *format) static void _print_pos(nvObj_t *nv, const char *format, uint8_t units) { char axes[] = {"XYZABC"}; - uint8_t axis = _get_axis(nv->index); + uint8_t axis = _axis(nv->index); if (axis >= AXIS_A) { units = DEGREES;} sprintf(cs.out_buf, format, axes[axis], nv->value, GET_TEXT_ITEM(msg_units, units)); xio_writeline(cs.out_buf); @@ -2824,7 +2811,7 @@ static void _print_pos(nvObj_t *nv, const char *format, uint8_t units) static void _print_hom(nvObj_t *nv, const char *format) { char axes[] = {"XYZABC"}; - uint8_t axis = _get_axis(nv->index); + uint8_t axis = _axis(nv->index); sprintf(cs.out_buf, format, axes[axis], nv->value); xio_writeline(cs.out_buf); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index bec9c5f9..9a11d3d1 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -184,11 +184,11 @@ typedef struct cmMachine { // struct to manage canonical machin bool safety_interlock_enable; // true to enable safety interlock system // gcode power-on default settings - defaults are not the same as the gm state - cmCoordSystem default_coord_system; // G10 active coordinate system default - cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default - cmUnitsMode default_units_mode; // G20,G21 reset default - cmPathControl default_path_control; // G61,G61.1,G64 reset default - cmDistanceMode default_distance_mode; // G90,G91 reset default +// cmCoordSystem default_coord_system; // G10 active coordinate system default +// cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default +// cmUnitsMode default_units_mode; // G20,G21 reset default +// cmPathControl default_path_control; // G61,G61.1,G64 reset default +// cmDistanceMode default_distance_mode; // G90,G91 reset default // coordinate systems and offsets float offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 diff --git a/g2core/config.h b/g2core/config.h index d7ebd517..188554cc 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -353,8 +353,10 @@ void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); // application specific helpers and functions (config_app.c) stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion -void preprocess_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values -void preprocess_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units +stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving a floating point value +stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value +void preprocess_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values +void preprocess_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units // diagnostics void nv_dump_nv(nvObj_t *nv); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 04e47a0b..80198072 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -200,7 +200,7 @@ const cfgItem_t cfgArray[] = { { "1","1sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_1].step_angle, M1_STEP_ANGLE }, { "1","1tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_1].travel_rev, M1_TRAVEL_PER_REV }, { "1","1mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_1].microsteps, M1_MICROSTEPS }, - { "1","1su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, + { "1","1su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, { "1","1pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_1].power_level, M1_POWER_LEVEL }, @@ -211,7 +211,7 @@ const cfgItem_t cfgArray[] = { { "2","2sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_2].step_angle, M2_STEP_ANGLE }, { "2","2tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_2].travel_rev, M2_TRAVEL_PER_REV }, { "2","2mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_2].microsteps, M2_MICROSTEPS }, - { "2","2su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, + { "2","2su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, { "2","2pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_2].power_level, M2_POWER_LEVEL}, @@ -223,7 +223,7 @@ const cfgItem_t cfgArray[] = { { "3","3sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_3].step_angle, M3_STEP_ANGLE }, { "3","3tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_3].travel_rev, M3_TRAVEL_PER_REV }, { "3","3mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_3].microsteps, M3_MICROSTEPS }, - { "3","3su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, + { "3","3su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, { "3","3pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_3].power_level, M3_POWER_LEVEL }, @@ -235,7 +235,7 @@ const cfgItem_t cfgArray[] = { { "4","4sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_4].step_angle, M4_STEP_ANGLE }, { "4","4tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_4].travel_rev, M4_TRAVEL_PER_REV }, { "4","4mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_4].microsteps, M4_MICROSTEPS }, - { "4","4su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, + { "4","4su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, { "4","4pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_4].power_level, M4_POWER_LEVEL }, @@ -247,7 +247,7 @@ const cfgItem_t cfgArray[] = { { "5","5sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_5].step_angle, M5_STEP_ANGLE }, { "5","5tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_5].travel_rev, M5_TRAVEL_PER_REV }, { "5","5mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_5].microsteps, M5_MICROSTEPS }, - { "5","5su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, + { "5","5su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, { "5","5pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_5].power_level, M5_POWER_LEVEL }, @@ -259,7 +259,7 @@ const cfgItem_t cfgArray[] = { { "6","6sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_6].step_angle, M6_STEP_ANGLE }, { "6","6tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_6].travel_rev, M6_TRAVEL_PER_REV }, { "6","6mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_6].microsteps, M6_MICROSTEPS }, - { "6","6su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, + { "6","6su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, { "6","6pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_6].power_level, M6_POWER_LEVEL }, @@ -647,11 +647,11 @@ const cfgItem_t cfgArray[] = { // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco - { "sys","gpl", _fipn, 0, cm_print_gpl, get_ui8, set_012, (float *)&cm->default_select_plane, GCODE_DEFAULT_PLANE }, - { "sys","gun", _fipn, 0, cm_print_gun, get_ui8, set_01, (float *)&cm->default_units_mode, GCODE_DEFAULT_UNITS }, - { "sys","gco", _fipn, 0, cm_print_gco, get_ui8, set_ui8, (float *)&cm->default_coord_system, GCODE_DEFAULT_COORD_SYSTEM }, - { "sys","gpa", _fipn, 0, cm_print_gpa, get_ui8, set_012, (float *)&cm->default_path_control, GCODE_DEFAULT_PATH_CONTROL }, - { "sys","gdi", _fipn, 0, cm_print_gdi, get_ui8, set_01, (float *)&cm->default_distance_mode, GCODE_DEFAULT_DISTANCE_MODE }, + { "sys","gpl", _fipn, 0, cm_print_gpl, get_ui8, set_012, (float *)&gc.default_select_plane, GCODE_DEFAULT_PLANE }, + { "sys","gun", _fipn, 0, cm_print_gun, get_ui8, set_01, (float *)&gc.default_units_mode, GCODE_DEFAULT_UNITS }, + { "sys","gco", _fipn, 0, cm_print_gco, get_ui8, set_ui8, (float *)&gc.default_coord_system, GCODE_DEFAULT_COORD_SYSTEM }, + { "sys","gpa", _fipn, 0, cm_print_gpa, get_ui8, set_012, (float *)&gc.default_path_control, GCODE_DEFAULT_PATH_CONTROL }, + { "sys","gdi", _fipn, 0, cm_print_gdi, get_ui8, set_01, (float *)&gc.default_distance_mode, GCODE_DEFAULT_DISTANCE_MODE }, { "", "gc", _f0, 0, tx_print_nul, gc_get_gc,gc_run_gc,(float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports @@ -994,6 +994,23 @@ stat_t set_flu(nvObj_t *nv) return(STAT_OK); } +/* + * get_float() - boilerplate for retrieving a floating point value + * set_float() - boilerplate for setting a floating point value + */ + +stat_t get_float(nvObj_t *nv, const float value) { + nv->value = value; + nv->valuetype = TYPE_FLOAT; + return STAT_OK; +} + +stat_t set_float(nvObj_t *nv, float &value) { + preprocess_incoming_float(nv); + value = nv->value; + return (STAT_OK); +} + /* * preprocess_incoming_float() - pre-process an incoming floating point number for canonical units * preprocess_outgoing_float() - pre-process an outgoing floating point number for units display diff --git a/g2core/gcode.h b/g2core/gcode.h index f4e02426..c87441ac 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -372,8 +372,17 @@ typedef struct GCodeFlags { // Gcode model input flags } GCodeFlags_t; typedef struct GCodeSingleton { + + // gcode power-on default settings - defaults are not the same as the gm state + cmCoordSystem default_coord_system; // G10 active coordinate system default + cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default + cmUnitsMode default_units_mode; // G20,G21 reset default + cmPathControl default_path_control; // G61,G61.1,G64 reset default + cmDistanceMode default_distance_mode; // G90,G91 reset default + GCodeInput_t gn; // gcode input values - transient GCodeFlags_t gf; // gcode input flags - transient + } GCodeSingleton_t; extern GCodeSingleton_t gc; // gcode structs From f88b7b679c31e5e79f4f985ae6b3cb97c56ba5ff Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 18:02:08 -0500 Subject: [PATCH 021/283] Finished gets and sets for axis parameters. Still need to install in config_app table. --- g2core/canonical_machine.cpp | 171 ++++++++--------------------------- g2core/canonical_machine.h | 7 -- g2core/config.h | 5 +- g2core/config_app.cpp | 74 +++++++++------ 4 files changed, 88 insertions(+), 169 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 519213b8..743a86fb 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2276,21 +2276,9 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode } stat_t cm_get_tn(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].travel_min)); } -stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_min));} - -stat_t cm_get_tm(nvObj_t *nv) -{ - nv->value = cm->a[_axis(nv->index)].travel_max; - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); -} - -stat_t cm_set_tm(nvObj_t *nv) -{ - preprocess_incoming_float(nv); - cm->a[_axis(nv->index)].travel_max = nv->value; - return (STAT_OK); -} +stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_min)); } +stat_t cm_get_tm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].travel_max)); } +stat_t cm_set_tm(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_max)); } /**** Axis Jerk Primitives * cm_get_axis_jerk() - returns jerk for an axis @@ -2341,64 +2329,32 @@ void cm_set_axis_jerk(const uint8_t axis, const float jerk) * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form */ -stat_t cm_get_vm(nvObj_t *nv) -{ - return(STAT_OK); -} +stat_t cm_get_vm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].velocity_max)); } +stat_t cm_set_vm(nvObj_t *nv) { + uint8_t axis = _axis(nv->index); + set_float(nv, cm->a[axis].velocity_max); + cm->a[axis].recip_velocity_max = 1/nv->value; + return(STAT_OK); + } -stat_t cm_set_vm(nvObj_t *nv) -{ - uint8_t axis = _axis(nv->index); - if ((axis == AXIS_A) || (axis == AXIS_B) || (axis == AXIS_C)) { - set_flt(nv); - } else { - set_flu(nv); - } - cm->a[axis].recip_velocity_max = 1/nv->value; - return(STAT_OK); -} +stat_t cm_get_fr(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].feedrate_max)); } +stat_t cm_set_fr(nvObj_t *nv) { + uint8_t axis = _axis(nv->index); + set_float(nv, cm->a[axis].feedrate_max); + cm->a[axis].recip_feedrate_max = 1/nv->value; + return(STAT_OK); + } -stat_t cm_get_fr(nvObj_t *nv) -{ - return(STAT_OK); -} +stat_t cm_get_jm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_max)); } +stat_t cm_set_jm(nvObj_t *nv) { + uint8_t axis = _axis(nv->index); + set_float(nv, cm->a[axis].jerk_max); + cm_set_axis_jerk(axis, nv->value); + return(STAT_OK); + } -stat_t cm_set_fr(nvObj_t *nv) -{ - uint8_t axis = _axis(nv->index); - if ((axis == AXIS_A) || (axis == AXIS_B) || (axis == AXIS_C)) { - set_flt(nv); - } else { - set_flu(nv); - } - cm->a[axis].recip_feedrate_max = 1/nv->value; - return(STAT_OK); -} - -stat_t cm_get_jm(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_jm(nvObj_t *nv) -{ -// if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER; - set_flu(nv); - cm_set_axis_jerk(_axis(nv->index), nv->value); - return(STAT_OK); -} - -stat_t cm_get_jh(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_jh(nvObj_t *nv) -{ -// if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER; - set_flu(nv); - return(STAT_OK); -} +stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_high)); } +stat_t cm_set_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_high)); } /**** Axis Homing Settings * cm_get_hi() - get homing input @@ -2415,69 +2371,18 @@ stat_t cm_set_jh(nvObj_t *nv) * cm_set_zb() - set homing zero backoff */ -stat_t cm_get_hi(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_hi(nvObj_t *nv) -{ - if ((nv->value < 0) || (nv->value > D_IN_CHANNELS)) { - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - set_ui8(nv); - return (STAT_OK); -} - -stat_t cm_get_hd(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_hd(nvObj_t *nv) -{ - return (STAT_OK); -} - -stat_t cm_get_sv(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_sv(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_get_lv(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_lv(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_get_lb(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_lb(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_get_zb(nvObj_t *nv) -{ - return(STAT_OK); -} - -stat_t cm_set_zb(nvObj_t *nv) -{ - return(STAT_OK); -} +stat_t cm_get_hi(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv->index)].homing_input)); } +stat_t cm_set_hi(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv->index)].homing_input, 0, D_IN_CHANNELS)); } +stat_t cm_get_hd(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv->index)].homing_dir)); } +stat_t cm_set_hd(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv->index)].homing_dir, 0, 1)); } +stat_t cm_get_sv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].search_velocity)); } +stat_t cm_set_sv(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].search_velocity)); } +stat_t cm_get_lv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].latch_velocity)); } +stat_t cm_set_lv(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].latch_velocity)); } +stat_t cm_get_lb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].latch_backoff)); } +stat_t cm_set_lb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].latch_backoff)); } +stat_t cm_get_zb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].zero_backoff)); } +stat_t cm_set_zb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].zero_backoff)); } /*** Canonical Machine Global Settings ***/ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 9a11d3d1..1908f8f5 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -183,13 +183,6 @@ typedef struct cmMachine { // struct to manage canonical machin bool limit_enable; // true to enable limit switches (disabled is same as override) bool safety_interlock_enable; // true to enable safety interlock system - // gcode power-on default settings - defaults are not the same as the gm state -// cmCoordSystem default_coord_system; // G10 active coordinate system default -// cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default -// cmUnitsMode default_units_mode; // G20,G21 reset default -// cmPathControl default_path_control; // G61,G61.1,G64 reset default -// cmDistanceMode default_distance_mode; // G90,G91 reset default - // coordinate systems and offsets float offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 diff --git a/g2core/config.h b/g2core/config.h index 188554cc..7d95bce1 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -352,9 +352,12 @@ nvObj_t *nv_add_conditional_message(const char *string); void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); // application specific helpers and functions (config_app.c) -stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion +stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion + stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving a floating point value stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value +stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving an integer value +stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); void preprocess_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values void preprocess_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 80198072..97a45cc2 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -267,33 +267,33 @@ const cfgItem_t cfgArray[] = { // { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, #endif // Axis parameters - { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, - { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cm->a[AXIS_X].velocity_max, X_VELOCITY_MAX }, - { "x","xfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_X].feedrate_max, X_FEEDRATE_MAX }, - { "x","xtn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, - { "x","xtm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, - { "x","xjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_X].jerk_max, X_JERK_MAX }, - { "x","xjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_X].jerk_high, X_JERK_HIGH_SPEED }, - { "x","xhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_X].homing_input, X_HOMING_INPUT }, - { "x","xhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_X].homing_dir, X_HOMING_DIRECTION }, - { "x","xsv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm->a[AXIS_X].search_velocity,X_SEARCH_VELOCITY }, - { "x","xlv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm->a[AXIS_X].latch_velocity, X_LATCH_VELOCITY }, - { "x","xlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_X].latch_backoff, X_LATCH_BACKOFF }, - { "x","xzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_X].zero_backoff, X_ZERO_BACKOFF }, + { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, + { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, X_VELOCITY_MAX }, + { "x","xfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, X_FEEDRATE_MAX }, + { "x","xtn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, + { "x","xtm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, + { "x","xjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, X_JERK_MAX }, + { "x","xjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, X_JERK_HIGH_SPEED }, + { "x","xhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, X_HOMING_INPUT }, + { "x","xhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, X_HOMING_DIRECTION }, + { "x","xsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, X_SEARCH_VELOCITY }, + { "x","xlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, X_LATCH_VELOCITY }, + { "x","xlb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, X_LATCH_BACKOFF }, + { "x","xzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, X_ZERO_BACKOFF }, { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, - { "y","yvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Y].velocity_max, Y_VELOCITY_MAX }, - { "y","yfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_Y].feedrate_max, Y_FEEDRATE_MAX }, - { "y","ytn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_Y].travel_min, Y_TRAVEL_MIN }, - { "y","ytm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_Y].travel_max, Y_TRAVEL_MAX }, - { "y","yjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_Y].jerk_max, Y_JERK_MAX }, - { "y","yjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_Y].jerk_high, Y_JERK_HIGH_SPEED }, - { "y","yhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_Y].homing_input, Y_HOMING_INPUT }, - { "y","yhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_Y].homing_dir, Y_HOMING_DIRECTION }, - { "y","ysv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm->a[AXIS_Y].search_velocity,Y_SEARCH_VELOCITY }, - { "y","ylv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm->a[AXIS_Y].latch_velocity, Y_LATCH_VELOCITY }, - { "y","ylb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_Y].latch_backoff, Y_LATCH_BACKOFF }, - { "y","yzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_Y].zero_backoff, Y_ZERO_BACKOFF }, + { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cm->a[AXIS_Y].velocity_max, Y_VELOCITY_MAX }, + { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cm->a[AXIS_Y].feedrate_max, Y_FEEDRATE_MAX }, + { "y","ytn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cm->a[AXIS_Y].travel_min, Y_TRAVEL_MIN }, + { "y","ytm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cm->a[AXIS_Y].travel_max, Y_TRAVEL_MAX }, + { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cm->a[AXIS_Y].jerk_max, Y_JERK_MAX }, + { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cm->a[AXIS_Y].jerk_high, Y_JERK_HIGH_SPEED }, + { "y","yhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cm->a[AXIS_Y].homing_input, Y_HOMING_INPUT }, + { "y","yhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cm->a[AXIS_Y].homing_dir, Y_HOMING_DIRECTION }, + { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cm->a[AXIS_Y].search_velocity,Y_SEARCH_VELOCITY }, + { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cm->a[AXIS_Y].latch_velocity, Y_LATCH_VELOCITY }, + { "y","ylb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cm->a[AXIS_Y].latch_backoff, Y_LATCH_BACKOFF }, + { "y","yzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cm->a[AXIS_Y].zero_backoff, Y_ZERO_BACKOFF }, { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, { "z","zvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Z].velocity_max, Z_VELOCITY_MAX }, @@ -1011,6 +1011,26 @@ stat_t set_float(nvObj_t *nv, float &value) { return (STAT_OK); } +/* + * get_int() - boilerplate for retrieving an integer value + * set_int() - boilerplate for setting an integer value + */ + +stat_t get_int(nvObj_t *nv, const uint8_t value) { + nv->value = value; + nv->valuetype = TYPE_INT; + return STAT_OK; +} + +stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { + + if ((nv->value < low) || (nv->value > high)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + value = nv->value; + return (STAT_OK); +} + /* * preprocess_incoming_float() - pre-process an incoming floating point number for canonical units * preprocess_outgoing_float() - pre-process an outgoing floating point number for units display @@ -1027,9 +1047,7 @@ void preprocess_incoming_float(nvObj_t *nv) nv->value *= MM_PER_INCH; // convert to canonical millimeter units } } - } -// nv->precision = GET_TABLE_WORD(precision); -// nv->valuetype = TYPE_FLOAT; + } } void preprocess_outgoing_float(nvObj_t *nv) From 6f9c0ff5760bf2a72a801889d0e6306cf9b2078d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 18:36:12 -0500 Subject: [PATCH 022/283] Installed new axis getters and setter in config_app table --- g2core/canonical_machine.cpp | 2 + g2core/canonical_machine.h | 2 + g2core/config_app.cpp | 136 +++++++++++++++++------------------ 3 files changed, 72 insertions(+), 68 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 743a86fb..2c0e572b 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2279,6 +2279,8 @@ stat_t cm_get_tn(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].tr stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_min)); } stat_t cm_get_tm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].travel_max)); } stat_t cm_set_tm(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_max)); } +stat_t cm_get_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].radius)); } +stat_t cm_set_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].radius)); } /**** Axis Jerk Primitives * cm_get_axis_jerk() - returns jerk for an axis diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 1908f8f5..fa92896a 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -460,6 +460,8 @@ stat_t cm_get_tn(nvObj_t *nv); // get travel minimum stat_t cm_set_tn(nvObj_t *nv); // set travel minimum stat_t cm_get_tm(nvObj_t *nv); // get travel maximum stat_t cm_set_tm(nvObj_t *nv); // set travel maximum +stat_t cm_get_ra(nvObj_t *nv); // get radius +stat_t cm_set_ra(nvObj_t *nv); // set radius float cm_get_axis_jerk(const uint8_t axis); void cm_set_axis_jerk(const uint8_t axis, const float jerk); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 97a45cc2..207645da 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -281,78 +281,78 @@ const cfgItem_t cfgArray[] = { { "x","xlb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, X_LATCH_BACKOFF }, { "x","xzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, X_ZERO_BACKOFF }, - { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, - { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cm->a[AXIS_Y].velocity_max, Y_VELOCITY_MAX }, - { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cm->a[AXIS_Y].feedrate_max, Y_FEEDRATE_MAX }, - { "y","ytn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cm->a[AXIS_Y].travel_min, Y_TRAVEL_MIN }, - { "y","ytm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cm->a[AXIS_Y].travel_max, Y_TRAVEL_MAX }, - { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cm->a[AXIS_Y].jerk_max, Y_JERK_MAX }, - { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cm->a[AXIS_Y].jerk_high, Y_JERK_HIGH_SPEED }, - { "y","yhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cm->a[AXIS_Y].homing_input, Y_HOMING_INPUT }, - { "y","yhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cm->a[AXIS_Y].homing_dir, Y_HOMING_DIRECTION }, - { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cm->a[AXIS_Y].search_velocity,Y_SEARCH_VELOCITY }, - { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cm->a[AXIS_Y].latch_velocity, Y_LATCH_VELOCITY }, - { "y","ylb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cm->a[AXIS_Y].latch_backoff, Y_LATCH_BACKOFF }, - { "y","yzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cm->a[AXIS_Y].zero_backoff, Y_ZERO_BACKOFF }, + { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, + { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Y_VELOCITY_MAX }, + { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Y_FEEDRATE_MAX }, + { "y","ytn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Y_TRAVEL_MIN }, + { "y","ytm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Y_TRAVEL_MAX }, + { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Y_JERK_MAX }, + { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, Y_JERK_HIGH_SPEED }, + { "y","yhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Y_HOMING_INPUT }, + { "y","yhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Y_HOMING_DIRECTION }, + { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Y_SEARCH_VELOCITY }, + { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Y_LATCH_VELOCITY }, + { "y","ylb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Y_LATCH_BACKOFF }, + { "y","yzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, Y_ZERO_BACKOFF }, - { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, - { "z","zvm",_fipc, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_Z].velocity_max, Z_VELOCITY_MAX }, - { "z","zfr",_fipc, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_Z].feedrate_max, Z_FEEDRATE_MAX }, - { "z","ztn",_fipc, 3, cm_print_tn, get_flt, set_flu, (float *)&cm->a[AXIS_Z].travel_min, Z_TRAVEL_MIN }, - { "z","ztm",_fipc, 3, cm_print_tm, get_flt, set_flu, (float *)&cm->a[AXIS_Z].travel_max, Z_TRAVEL_MAX }, - { "z","zjm",_fipc, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_Z].jerk_max, Z_JERK_MAX }, - { "z","zjh",_fipc, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_Z].jerk_high, Z_JERK_HIGH_SPEED }, - { "z","zhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_Z].homing_input, Z_HOMING_INPUT }, - { "z","zhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_Z].homing_dir, Z_HOMING_DIRECTION }, - { "z","zsv",_fipc, 0, cm_print_sv, get_flt, set_flu, (float *)&cm->a[AXIS_Z].search_velocity,Z_SEARCH_VELOCITY }, - { "z","zlv",_fipc, 2, cm_print_lv, get_flt, set_flu, (float *)&cm->a[AXIS_Z].latch_velocity, Z_LATCH_VELOCITY }, - { "z","zlb",_fipc, 3, cm_print_lb, get_flt, set_flu, (float *)&cm->a[AXIS_Z].latch_backoff, Z_LATCH_BACKOFF }, - { "z","zzb",_fipc, 3, cm_print_zb, get_flt, set_flu, (float *)&cm->a[AXIS_Z].zero_backoff, Z_ZERO_BACKOFF }, + { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, + { "z","zvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Z_VELOCITY_MAX }, + { "z","zfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Z_FEEDRATE_MAX }, + { "z","ztn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Z_TRAVEL_MIN }, + { "z","ztm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Z_TRAVEL_MAX }, + { "z","zjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Z_JERK_MAX }, + { "z","zjh",_fipc, 0, cm_print_jh, cm_get_jm, cm_set_jh, (float *)&cs.null, Z_JERK_HIGH_SPEED }, + { "z","zhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Z_HOMING_INPUT }, + { "z","zhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Z_HOMING_DIRECTION }, + { "z","zsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Z_SEARCH_VELOCITY }, + { "z","zlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Z_LATCH_VELOCITY }, + { "z","zlb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Z_LATCH_BACKOFF }, + { "z","zzb",_fipc, 3, cm_print_zb, cm_get_lb, cm_set_zb, (float *)&cs.null, Z_ZERO_BACKOFF }, - { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, - { "a","avm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_A].velocity_max, A_VELOCITY_MAX }, - { "a","afr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_A].feedrate_max, A_FEEDRATE_MAX }, - { "a","atn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_A].travel_min, A_TRAVEL_MIN }, - { "a","atm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm->a[AXIS_A].travel_max, A_TRAVEL_MAX }, - { "a","ajm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_A].jerk_max, A_JERK_MAX }, - { "a","ajh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_A].jerk_high, A_JERK_HIGH_SPEED }, - { "a","ara",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm->a[AXIS_A].radius, A_RADIUS}, - { "a","ahi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_A].homing_input, A_HOMING_INPUT }, - { "a","ahd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_A].homing_dir, A_HOMING_DIRECTION }, - { "a","asv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm->a[AXIS_A].search_velocity,A_SEARCH_VELOCITY }, - { "a","alv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm->a[AXIS_A].latch_velocity, A_LATCH_VELOCITY }, - { "a","alb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_A].latch_backoff, A_LATCH_BACKOFF }, - { "a","azb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_A].zero_backoff, A_ZERO_BACKOFF }, + { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, + { "a","avm",_fip, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, A_VELOCITY_MAX }, + { "a","afr",_fip, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, A_FEEDRATE_MAX }, + { "a","atn",_fip, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, + { "a","atm",_fip, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, A_TRAVEL_MAX }, + { "a","ajm",_fip, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, A_JERK_MAX }, + { "a","ajh",_fip, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, A_JERK_HIGH_SPEED }, + { "a","ara",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, A_RADIUS}, + { "a","ahi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, A_HOMING_INPUT }, + { "a","ahd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, A_HOMING_DIRECTION }, + { "a","asv",_fip, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, A_SEARCH_VELOCITY }, + { "a","alv",_fip, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, A_LATCH_VELOCITY }, + { "a","alb",_fip, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, + { "a","azb",_fip, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, - { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, - { "b","bvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_B].velocity_max, B_VELOCITY_MAX }, - { "b","bfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_B].feedrate_max, B_FEEDRATE_MAX }, - { "b","btn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_B].travel_min, B_TRAVEL_MIN }, - { "b","btm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm->a[AXIS_B].travel_max, B_TRAVEL_MAX }, - { "b","bjm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_B].jerk_max, B_JERK_MAX }, - { "b","bjh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_B].jerk_high, B_JERK_HIGH_SPEED }, - { "b","bra",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm->a[AXIS_B].radius, B_RADIUS }, - { "b","bhi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_B].homing_input, B_HOMING_INPUT }, - { "b","bhd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_B].homing_dir, B_HOMING_DIRECTION }, - { "b","bsv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm->a[AXIS_B].search_velocity,B_SEARCH_VELOCITY }, - { "b","blv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm->a[AXIS_B].latch_velocity, B_LATCH_VELOCITY }, - { "b","blb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_B].latch_backoff, B_LATCH_BACKOFF }, - { "b","bzb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_B].zero_backoff, B_ZERO_BACKOFF }, + { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, + { "b","bvm",_fip, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, B_VELOCITY_MAX }, + { "b","bfr",_fip, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, B_FEEDRATE_MAX }, + { "b","btn",_fip, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, + { "b","btm",_fip, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, B_TRAVEL_MAX }, + { "b","bjm",_fip, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, B_JERK_MAX }, + { "b","bjh",_fip, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, B_JERK_HIGH_SPEED }, + { "b","bra",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, B_RADIUS }, + { "b","bhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, B_HOMING_INPUT }, + { "b","bhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, B_HOMING_DIRECTION }, + { "b","bsv",_fip, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, B_SEARCH_VELOCITY }, + { "b","blv",_fip, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, B_LATCH_VELOCITY }, + { "b","blb",_fip, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, + { "b","bzb",_fip, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, - { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, - { "c","cvm",_fip, 0, cm_print_vm, get_flt, cm_set_vm, (float *)&cm->a[AXIS_C].velocity_max, C_VELOCITY_MAX }, - { "c","cfr",_fip, 0, cm_print_fr, get_flt, cm_set_fr, (float *)&cm->a[AXIS_C].feedrate_max, C_FEEDRATE_MAX }, - { "c","ctn",_fip, 3, cm_print_tn, get_flt, set_flt, (float *)&cm->a[AXIS_C].travel_min, C_TRAVEL_MIN }, - { "c","ctm",_fip, 3, cm_print_tm, get_flt, set_flt, (float *)&cm->a[AXIS_C].travel_max, C_TRAVEL_MAX }, - { "c","cjm",_fip, 0, cm_print_jm, get_flt, cm_set_jm, (float *)&cm->a[AXIS_C].jerk_max, C_JERK_MAX }, - { "c","cjh",_fip, 0, cm_print_jh, get_flt, cm_set_jh, (float *)&cm->a[AXIS_C].jerk_high, C_JERK_HIGH_SPEED }, - { "c","cra",_fipc, 3, cm_print_ra, get_flt, set_flt, (float *)&cm->a[AXIS_C].radius, C_RADIUS }, - { "c","chi",_fip, 0, cm_print_hi, get_ui8, cm_set_hi, (float *)&cm->a[AXIS_C].homing_input, C_HOMING_INPUT }, - { "c","chd",_fip, 0, cm_print_hd, get_ui8, set_01, (float *)&cm->a[AXIS_C].homing_dir, C_HOMING_DIRECTION }, - { "c","csv",_fip, 0, cm_print_sv, get_flt, set_flt, (float *)&cm->a[AXIS_C].search_velocity,C_SEARCH_VELOCITY }, - { "c","clv",_fip, 2, cm_print_lv, get_flt, set_flt, (float *)&cm->a[AXIS_C].latch_velocity, C_LATCH_VELOCITY }, - { "c","clb",_fip, 3, cm_print_lb, get_flt, set_flt, (float *)&cm->a[AXIS_C].latch_backoff, C_LATCH_BACKOFF }, - { "c","czb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm->a[AXIS_C].zero_backoff, C_ZERO_BACKOFF }, + { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, + { "c","cvm",_fip, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, C_VELOCITY_MAX }, + { "c","cfr",_fip, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, C_FEEDRATE_MAX }, + { "c","ctn",_fip, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, + { "c","ctm",_fip, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, C_TRAVEL_MAX }, + { "c","cjm",_fip, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, C_JERK_MAX }, + { "c","cjh",_fip, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, C_JERK_HIGH_SPEED }, + { "c","cra",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, C_RADIUS }, + { "c","chi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, C_HOMING_INPUT }, + { "c","chd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, C_HOMING_DIRECTION }, + { "c","csv",_fip, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, C_SEARCH_VELOCITY }, + { "c","clv",_fip, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, C_LATCH_VELOCITY }, + { "c","clb",_fip, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, + { "c","czb",_fip, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, // Digital input configs { "di1","di1mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, From 03adc6484d5cb47d6557c69d7cbcf80d5cfd480a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 19:59:17 -0500 Subject: [PATCH 023/283] fify --- g2core/canonical_machine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 2c0e572b..0e72edc1 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2356,7 +2356,7 @@ stat_t cm_set_jm(nvObj_t *nv) { } stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_high)); } -stat_t cm_set_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_high)); } +stat_t cm_set_jh(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].jerk_high)); } /**** Axis Homing Settings * cm_get_hi() - get homing input From b9a7a3f53e5e55e23d0d12726f6f5e2a569d0ba6 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 9 Dec 2016 21:02:01 -0500 Subject: [PATCH 024/283] Changed homing state readers --- g2core/canonical_machine.cpp | 17 ++++++++++++ g2core/canonical_machine.h | 33 +++++++++++----------- g2core/config_app.cpp | 54 ++++++++++++++++++------------------ 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0e72edc1..e3c87745 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -159,6 +159,7 @@ void cm_set_motion_state(const cmMotionState motion_state) * cm_get_cycle_state() * cm_get_hold_state() * cm_get_homing_state() + * cm_get_homing_state() */ cmMachineState cm_get_machine_state() { return cm->machine_state;} cmCycleState cm_get_cycle_state() { return cm->cycle_state;} @@ -2243,6 +2244,21 @@ stat_t cm_get_ofs(nvObj_t *nv) return (STAT_OK); } +stat_t cm_get_hom(nvObj_t *nv) +{ + nv->value = (float)cm->homed[_axis(nv->index)]; + nv->valuetype = TYPE_INT; + return (STAT_OK); +} +/* +stat_t cm_get_prb(nvObj_t *nv) +{ + nv->value = (float)cm->homed[_axis(nv->index)]; + nv->valuetype = TYPE_INT; + return (STAT_OK); +} +*/ + /************************************ **** AXIS GET AND SET FUNCTIONS **** ************************************/ @@ -2311,6 +2327,7 @@ void cm_set_axis_jerk(const uint8_t axis, const float jerk) } /**** Axis Velocity and Jerk Settings + * * cm_get_vm() - get velocity max value - called from dispatch table * cm_set_vm() - set velocity max value - called from dispatch table * cm_get_fr() - get feedrate max value - called from dispatch table diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index fa92896a..179ceaba 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -423,26 +423,27 @@ stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number stat_t cm_get_stat(nvObj_t *nv); // get combined machine state as value and string stat_t cm_get_macs(nvObj_t *nv); // get raw machine state as value and string -stat_t cm_get_cycs(nvObj_t *nv); // get raw cycle state (etc etc)... -stat_t cm_get_mots(nvObj_t *nv); // get raw motion state... -stat_t cm_get_hold(nvObj_t *nv); // get raw hold state... -stat_t cm_get_home(nvObj_t *nv); // get raw homing state... -stat_t cm_get_unit(nvObj_t *nv); // get unit mode... -stat_t cm_get_coor(nvObj_t *nv); // get coordinate system in effect... -stat_t cm_get_momo(nvObj_t *nv); // get motion mode... -stat_t cm_get_plan(nvObj_t *nv); // get active plane... -stat_t cm_get_path(nvObj_t *nv); // get patch control mode... -stat_t cm_get_dist(nvObj_t *nv); // get distance mode... -stat_t cm_get_admo(nvObj_t *nv); // get arc offset mode... -stat_t cm_get_frmo(nvObj_t *nv); // get feedrate mode... +stat_t cm_get_cycs(nvObj_t *nv); // get raw cycle state +stat_t cm_get_mots(nvObj_t *nv); // get raw motion state +stat_t cm_get_hold(nvObj_t *nv); // get raw hold state +stat_t cm_get_home(nvObj_t *nv); // get raw homing state +stat_t cm_get_hom(nvObj_t *nv); // get axis homing state +stat_t cm_get_unit(nvObj_t *nv); // get unit mode +stat_t cm_get_coor(nvObj_t *nv); // get coordinate system in effect +stat_t cm_get_momo(nvObj_t *nv); // get motion mode +stat_t cm_get_plan(nvObj_t *nv); // get active plane +stat_t cm_get_path(nvObj_t *nv); // get patch control mode +stat_t cm_get_dist(nvObj_t *nv); // get distance mode +stat_t cm_get_admo(nvObj_t *nv); // get arc offset mode +stat_t cm_get_frmo(nvObj_t *nv); // get feedrate mode stat_t cm_get_toolv(nvObj_t *nv); // get tool (value) stat_t cm_get_pwr(nvObj_t *nv); // get motor power enable state -stat_t cm_get_vel(nvObj_t *nv); // get runtime velocity... +stat_t cm_get_vel(nvObj_t *nv); // get runtime velocity stat_t cm_get_feed(nvObj_t *nv); // get feed rate, converted to units -stat_t cm_get_pos(nvObj_t *nv); // get runtime work position... -stat_t cm_get_mpo(nvObj_t *nv); // get runtime machine position... -stat_t cm_get_ofs(nvObj_t *nv); // get runtime work offset... +stat_t cm_get_pos(nvObj_t *nv); // get runtime work position +stat_t cm_get_mpo(nvObj_t *nv); // get runtime machine position +stat_t cm_get_ofs(nvObj_t *nv); // get runtime work offset stat_t cm_run_qf(nvObj_t *nv); // run queue flush stat_t cm_run_home(nvObj_t *nv); // start homing cycle diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 207645da..5d35688b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -113,8 +113,8 @@ const cfgItem_t cfgArray[] = { // dynamic model attributes for reporting purposes (up front for speed) { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_nul,(float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_int,(float *)&cm->gm.linenum,0 }, // Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_int,(float *)&cm->gm.linenum,0 }, // Active line number - model or runtime line number + { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_nul,(float *)&cs.null, 0 }, // Model line number + { "", "line",_fi, 0, cm_print_line, cm_get_line, set_nul,(float *)&cs.null, 0 }, // Active line number - model or runtime line number { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_nul,(float *)&cs.null, 0 }, // current velocity { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_nul,(float *)&cs.null, 0 }, // feed rate { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_nul,(float *)&cs.null, 0 }, // raw machine state @@ -136,34 +136,34 @@ const cfgItem_t cfgArray[] = { { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif - { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0 }, // C machine position + { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // X machine position + { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // Y machine position + { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // Z machine position + { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // A machine position + { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // B machine position + { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // C machine position - { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_nul,(float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_nul,(float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_nul,(float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_nul,(float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_nul,(float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_nul,(float *)&cs.null, 0 }, // C work position + { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // X work position + { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // Y work position + { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // Z work position + { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // A work position + { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // B work position + { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // C work position - { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // X work offset - { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // Y work offset - { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // Z work offset - { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // A work offset - { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // B work offset - { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0 }, // C work offset + { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // X work offset + { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // Y work offset + { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // Z work offset + { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // A work offset + { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // B work offset + { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // C work offset - { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_01,(float *)&cm->homing_state, 0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_X], false }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_Y], false }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_Z], false }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_A], false }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_B], false }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm->homed[AXIS_C], false }, // C homed + { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_nul, (float *)&cs.null, 0 }, // homing state, invoke homing cycle + { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // X homed - Homing status group + { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // Y homed + { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // Z homed + { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // A homed + { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // B homed + { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // C homed { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_nul,(float *)&cm->probe_state[0], 0 }, // probing state { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_X], 0 }, From 80147a336a07bd3937064e9802d66109c05a94ad Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 10 Dec 2016 08:47:37 -0500 Subject: [PATCH 025/283] Added ability to manually home and unhome a machine; added get_float_range() function; resolved conflict in get_int functions; built and tested homing setter and getters; rearranged values in the cm structure; removed some deprecated items --- g2core/canonical_machine.cpp | 22 +++---- g2core/canonical_machine.h | 53 ++++++++------- g2core/config.cpp | 6 +- g2core/config.h | 11 ++-- g2core/config_app.cpp | 121 ++++++++++++++++++++--------------- g2core/g2core.cppproj | 4 +- g2core/report.cpp | 2 +- 7 files changed, 121 insertions(+), 98 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index e3c87745..7b91c52d 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -344,8 +344,8 @@ void cm_set_work_offsets(GCodeState_t *gcode_state) * cm_get_absolute_position() - get position of axis in absolute coordinates * * This function accepts as input: - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model + * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct * * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) * NOTE: Machine position is always returned in mm mode. No units conversion is performed @@ -2163,6 +2163,7 @@ stat_t cm_get_cycs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_cycs, cm_get_cy stat_t cm_get_mots(nvObj_t *nv) { return(_get_msg_helper(nv, msg_mots, cm_get_motion_state()));} stat_t cm_get_hold(nvObj_t *nv) { return(_get_msg_helper(nv, msg_hold, cm_get_hold_state()));} stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state()));} +stat_t cm_set_home(nvObj_t *nv) { return( set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } stat_t cm_get_unit(nvObj_t *nv) { return(_get_msg_helper(nv, msg_unit, cm_get_units_mode(ACTIVE_MODEL)));} stat_t cm_get_coor(nvObj_t *nv) { return(_get_msg_helper(nv, msg_coor, cm_get_coord_system(ACTIVE_MODEL)));} @@ -2244,20 +2245,15 @@ stat_t cm_get_ofs(nvObj_t *nv) return (STAT_OK); } -stat_t cm_get_hom(nvObj_t *nv) -{ - nv->value = (float)cm->homed[_axis(nv->index)]; - nv->valuetype = TYPE_INT; - return (STAT_OK); -} -/* +stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv->index)])); } + stat_t cm_get_prb(nvObj_t *nv) { - nv->value = (float)cm->homed[_axis(nv->index)]; - nv->valuetype = TYPE_INT; - return (STAT_OK); + return (get_float(nv, *cm->probe_results[_axis(nv->index)])); +// nv->value = (float)cm->probe_results[_axis(nv->index)]; +// nv->valuetype = TYPE_FLOAT; +// return (STAT_OK); } -*/ /************************************ **** AXIS GET AND SET FUNCTIONS **** diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 179ceaba..5e69af5f 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -150,19 +150,23 @@ typedef enum { */ typedef struct cmAxis { + + // axis settings cmAxisMode axis_mode; // see cmAxisMode above float velocity_max; // max velocity in mm/min or deg/min - float recip_velocity_max; float feedrate_max; // max velocity in mm/min or deg/min - float recip_feedrate_max; - float travel_max; // max work envelope for soft limits float travel_min; // min work envelope for soft limits + float travel_max; // max work envelope for soft limits float jerk_max; // max jerk (Jm) in mm/min^3 divided by 1 million float jerk_high; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million - float max_junction_accel; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million - float junction_dev; // aka cornering delta -- DEPRICATED! float radius; // radius in mm for rotary axis modes + // derived + float recip_velocity_max; + float recip_feedrate_max; + float max_junction_accel; // high speed deceleration jerk (Jh) in mm/min^3 divided by 1 million + + // homing settings uint8_t homing_input; // set 1-N for homing input. 0 will disable homing uint8_t homing_dir; // 0=search to negative, 1=search to positive float search_velocity; // homing search velocity @@ -176,22 +180,22 @@ typedef struct cmMachine { // struct to manage canonical machin /**** Config variables (PUBLIC) ****/ - // system group settings + // System group settings float junction_integration_time; // how aggressively will the machine corner? 1.6 or so is about the upper limit float chordal_tolerance; // arc chordal accuracy setting in mm bool soft_limit_enable; // true to enable soft limit testing on Gcode inputs bool limit_enable; // true to enable limit switches (disabled is same as override) bool safety_interlock_enable; // true to enable safety interlock system - // coordinate systems and offsets + // Coordinate systems and offsets float offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 - // settings for axes X,Y,Z,A B,C + // Axis settings cfgAxis_t a[AXES]; /**** Runtime variables (PRIVATE) ****/ - // global state variables and requestors + // Global state variables and requestors cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleState cycle_state; // cycs @@ -205,19 +209,6 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot - cmHomingState homing_state; // home: homing cycle sub-state machine - uint8_t homed[AXES]; // individual axis homing flags - - cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple) - float probe_results[PROBES_STORED][AXES]; // probing results - - float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore rotary axes. - float rotation_z_offset; // we seperately handle a z-offset, so that the new plane - // maintains a consistent distance from the old one. - // We only need z, since we are rotating to the z axis. - - float jogging_dest; // jogging direction as a relative move from current position - bool g28_flag; // true = complete a G28 move bool g30_flag; // true = complete a G30 move bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them @@ -225,6 +216,19 @@ typedef struct cmMachine { // struct to manage canonical machin uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) + cmHomingState homing_state; // home: homing cycle sub-state machine + uint8_t homed[AXES]; // individual axis homing flags + + cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple) + float probe_results[PROBES_STORED][AXES]; // probing results + + float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore rotary axes. + float rotation_z_offset; // separately handle a z-offset, so that the new plane + // maintains a consistent distance from the old one. + // We only need z, since we are rotating to the z axis. + + float jogging_dest; // jogging destination as a relative move from current position + /**** Model states ****/ GCodeState_t *am; // active Gcode model is maintained by state management GCodeState_t gm; // core gcode model state @@ -412,7 +416,7 @@ stat_t cm_probing_cycle_callback(void); // G38.x main lo // Jogging cycle stat_t cm_jogging_cycle_callback(void); // jogging cycle main loop stat_t cm_jogging_cycle_start(uint8_t axis); // {"jogx":-100.3} -float cm_get_jogging_dest(void); +float cm_get_jogging_dest(void); // get jogging destination /*--- cfgArray interface functions ---*/ @@ -426,7 +430,8 @@ stat_t cm_get_macs(nvObj_t *nv); // get raw machine state as value and st stat_t cm_get_cycs(nvObj_t *nv); // get raw cycle state stat_t cm_get_mots(nvObj_t *nv); // get raw motion state stat_t cm_get_hold(nvObj_t *nv); // get raw hold state -stat_t cm_get_home(nvObj_t *nv); // get raw homing state +stat_t cm_get_home(nvObj_t *nv); // get machine homing state +stat_t cm_set_home(nvObj_t *nv); // set machine homing state stat_t cm_get_hom(nvObj_t *nv); // get axis homing state stat_t cm_get_unit(nvObj_t *nv); // get unit mode stat_t cm_get_coor(nvObj_t *nv); // get coordinate system in effect diff --git a/g2core/config.cpp b/g2core/config.cpp index 5b0b048c..0b468b9d 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -191,7 +191,7 @@ stat_t config_test_assertions() * get_nul() - get nothing (returns STAT_NOOP) * get_ui8() - get value as 8 bit uint8_t (use uint8 for booleans) * get_int8() - get value as 8 bit int8_t - * get_int() - get value as 32 bit integer + * get_int32() - get value as 32 bit integer * get_data() - get value as 32 bit integer blind cast * get_flt() - get value as float */ @@ -215,7 +215,7 @@ stat_t get_int8(nvObj_t *nv) return (STAT_OK); } -stat_t get_int(nvObj_t *nv) +stat_t get_int32(nvObj_t *nv) { nv->value = *((uint32_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_INT; @@ -293,7 +293,7 @@ stat_t set_0123(nvObj_t *nv) return (set_ui8(nv)); } -stat_t set_int(nvObj_t *nv) +stat_t set_int32(nvObj_t *nv) { *((uint32_t *)GET_TABLE_WORD(target)) = (uint32_t)nv->value; nv->valuetype = TYPE_INT; diff --git a/g2core/config.h b/g2core/config.h index 7d95bce1..74cf43e1 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -323,7 +323,7 @@ stat_t set_int8(nvObj_t *nv); // set signed 8 bit integer stat_t set_01(nvObj_t *nv); // set a 0 or 1 value with validation stat_t set_012(nvObj_t *nv); // set a 0, 1 or 2 value with validation stat_t set_0123(nvObj_t *nv); // set a 0, 1, 2 or 3 value with validation -stat_t set_int(nvObj_t *nv); // set uint32_t integer value +stat_t set_int32(nvObj_t *nv); // set uint32_t integer value stat_t set_data(nvObj_t *nv); // set uint32_t integer value blind cast stat_t set_flt(nvObj_t *nv); // set floating point value @@ -331,7 +331,7 @@ stat_t get_nul(nvObj_t *nv); // get null value type stat_t get_bool(nvObj_t *nv); // get boolean value stat_t get_ui8(nvObj_t *nv); // get uint8_t value stat_t get_int8(nvObj_t *nv); // get signed 8 bit integer -stat_t get_int(nvObj_t *nv); // get uint32_t integer value +stat_t get_int32(nvObj_t *nv); // get uint32_t integer value stat_t get_data(nvObj_t *nv); // get uint32_t integer value blind cast stat_t get_flt(nvObj_t *nv); // get floating point value @@ -354,10 +354,13 @@ void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); // application specific helpers and functions (config_app.c) stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion -stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving a floating point value -stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value +stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving raw floating point value +stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion +stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); + stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving an integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); + void preprocess_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values void preprocess_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 5d35688b..1c1e73d8 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -157,13 +157,13 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // B work offset { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // C work offset - { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_nul, (float *)&cs.null, 0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, false }, // C homed + { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home, (float *)&cs.null,0 },// homing state, invoke homing cycle + { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // X homed - Homing status group + { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Y homed + { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Z homed + { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // A homed + { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // B homed + { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // C homed { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_nul,(float *)&cm->probe_state[0], 0 }, // probing state { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_X], 0 }, @@ -643,7 +643,7 @@ const cfgItem_t cfgArray[] = { { "sys","jv", _fipn, 0, js_print_jv, get_ui8, json_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY }, { "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_0123, (float *)&qr.queue_report_verbosity, QUEUE_REPORT_VERBOSITY }, { "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity,STATUS_REPORT_VERBOSITY }, - { "sys","si", _fipn, 0, sr_print_si, get_int, sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, + { "sys","si", _fipn, 0, sr_print_si, get_int32, sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco @@ -774,46 +774,46 @@ const cfgItem_t cfgArray[] = { // Persistence for status report - must be in sequence // *** Count must agree with NV_STATUS_REPORT_LEN in report.h *** - { "","se00",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[0],0 }, - { "","se01",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[1],0 }, - { "","se02",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[2],0 }, - { "","se03",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[3],0 }, - { "","se04",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[4],0 }, - { "","se05",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[5],0 }, - { "","se06",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[6],0 }, - { "","se07",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[7],0 }, - { "","se08",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[8],0 }, - { "","se09",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[9],0 }, - { "","se10",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[10],0 }, - { "","se11",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[11],0 }, - { "","se12",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[12],0 }, - { "","se13",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[13],0 }, - { "","se14",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[14],0 }, - { "","se15",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[15],0 }, - { "","se16",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[16],0 }, - { "","se17",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[17],0 }, - { "","se18",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[18],0 }, - { "","se19",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[19],0 }, - { "","se20",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[20],0 }, - { "","se21",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[21],0 }, - { "","se22",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[22],0 }, - { "","se23",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[23],0 }, - { "","se24",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[24],0 }, - { "","se25",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[25],0 }, - { "","se26",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[26],0 }, - { "","se27",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[27],0 }, - { "","se28",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[28],0 }, - { "","se29",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[29],0 }, - { "","se30",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[30],0 }, - { "","se31",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[31],0 }, - { "","se32",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[32],0 }, - { "","se33",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[33],0 }, - { "","se34",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[34],0 }, - { "","se35",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[35],0 }, - { "","se36",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[36],0 }, - { "","se37",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[37],0 }, - { "","se38",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[38],0 }, - { "","se39",_fp, 0, tx_print_nul, get_int, set_int,(float *)&sr.status_report_list[39],0 }, + { "","se00",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[0],0 }, + { "","se01",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[1],0 }, + { "","se02",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[2],0 }, + { "","se03",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[3],0 }, + { "","se04",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[4],0 }, + { "","se05",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[5],0 }, + { "","se06",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[6],0 }, + { "","se07",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[7],0 }, + { "","se08",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[8],0 }, + { "","se09",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[9],0 }, + { "","se10",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[10],0 }, + { "","se11",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[11],0 }, + { "","se12",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[12],0 }, + { "","se13",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[13],0 }, + { "","se14",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[14],0 }, + { "","se15",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[15],0 }, + { "","se16",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[16],0 }, + { "","se17",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[17],0 }, + { "","se18",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[18],0 }, + { "","se19",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[19],0 }, + { "","se20",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[20],0 }, + { "","se21",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[21],0 }, + { "","se22",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[22],0 }, + { "","se23",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[23],0 }, + { "","se24",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[24],0 }, + { "","se25",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[25],0 }, + { "","se26",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[26],0 }, + { "","se27",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[27],0 }, + { "","se28",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[28],0 }, + { "","se29",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[29],0 }, + { "","se30",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[30],0 }, + { "","se31",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[31],0 }, + { "","se32",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[32],0 }, + { "","se33",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[33],0 }, + { "","se34",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[34],0 }, + { "","se35",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[35],0 }, + { "","se36",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[36],0 }, + { "","se37",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[37],0 }, + { "","se38",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[38],0 }, + { "","se39",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[39],0 }, // Count is 40, since se00 counts as one. // Group lookups - must follow the single-valued entries for proper sub-string matching @@ -995,13 +995,23 @@ stat_t set_flu(nvObj_t *nv) } /* - * get_float() - boilerplate for retrieving a floating point value - * set_float() - boilerplate for setting a floating point value + * get_float() - boilerplate for retrieving raw floating point value + * set_float() - boilerplate for setting a floating point value with unit conversion + * set_float_range() - set a floating point value with inclusive range check + * + * get_float() returns a raw float value in internal canonical units (e.g. mm, degrees) + * without units conversion. If conversion is required call preprocess_outgoing_float() + * afterwards. The text mode and JSON display routines do this, so you generally don't + * have to worry about this. + * + * set_float() is designed to capture incoming float values, so it performs unit conversion. + * set_float_range() perfoems an inclusive range test on the CONVERTED value */ stat_t get_float(nvObj_t *nv, const float value) { nv->value = value; nv->valuetype = TYPE_FLOAT; + nv->precision = GET_TABLE_WORD(precision); return STAT_OK; } @@ -1011,9 +1021,18 @@ stat_t set_float(nvObj_t *nv, float &value) { return (STAT_OK); } +stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { + preprocess_incoming_float(nv); + if ((nv->value < low) || (nv->value > high)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + value = nv->value; + return (STAT_OK); +} + /* * get_int() - boilerplate for retrieving an integer value - * set_int() - boilerplate for setting an integer value + * set_int() - boilerplate for setting an integer value with range checking */ stat_t get_int(nvObj_t *nv, const uint8_t value) { diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 028566ff..504c10bd 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800043527 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800043527 + J41800036434 0x284E0A60 2000000 diff --git a/g2core/report.cpp b/g2core/report.cpp index 7b42cb59..ea5757a4 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -432,7 +432,7 @@ stat_t sr_set_si(nvObj_t *nv) if (nv->value < STATUS_REPORT_MIN_MS) { nv->value = STATUS_REPORT_MIN_MS; } - set_int(nv); + set_int32(nv); return(STAT_OK); } From 57706276834c24ae50797166a6ee0466b5fbcd02 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 10 Dec 2016 16:37:53 -0500 Subject: [PATCH 026/283] Fixed up probe deter and getters --- g2core/canonical_machine.cpp | 25 +++++----- g2core/canonical_machine.h | 27 ++++++----- g2core/config_app.cpp | 16 +++--- g2core/cycle_probing.cpp | 94 ++++++++++++++++-------------------- 4 files changed, 77 insertions(+), 85 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 7b91c52d..3e2a5663 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -159,13 +159,14 @@ void cm_set_motion_state(const cmMotionState motion_state) * cm_get_cycle_state() * cm_get_hold_state() * cm_get_homing_state() - * cm_get_homing_state() + * cm_get_probe_state() */ cmMachineState cm_get_machine_state() { return cm->machine_state;} cmCycleState cm_get_cycle_state() { return cm->cycle_state;} cmMotionState cm_get_motion_state() { return cm->motion_state;} cmFeedholdState cm_get_hold_state() { return cm->hold_state;} cmHomingState cm_get_homing_state() { return cm->homing_state;} +cmProbeState cm_get_probe_state() { return cm->probe_state[0];} /* * cm_get_combined_state() - combines raw states into something a user might want to see @@ -1976,7 +1977,6 @@ static const char *const msg_stat[] = { msg_stat0, msg_stat1, msg_stat2, msg_sta msg_stat4, msg_stat5, msg_stat6, msg_stat7, msg_stat8, msg_stat9, msg_stat10, msg_stat11, msg_stat12, msg_stat13 }; - static const char msg_macs0[] = "Initializing"; static const char msg_macs1[] = "Ready"; static const char msg_macs2[] = "Alarm"; @@ -1989,7 +1989,6 @@ static const char msg_macs8[] = "PANIC"; static const char *const msg_macs[] = { msg_macs0, msg_macs1, msg_macs2, msg_macs3, msg_macs4, msg_macs5, msg_macs6, msg_macs7, msg_macs8 }; - static const char msg_cycs0[] = "Off"; static const char msg_cycs1[] = "Machining"; static const char msg_cycs2[] = "Homing"; @@ -2019,6 +2018,11 @@ static const char msg_home1[] = "Homed"; static const char msg_home2[] = "Homing"; static const char *const msg_home[] = { msg_home0, msg_home1, msg_home2 }; +static const char msg_probe0[] = "Probe Failed"; +static const char msg_probe1[] = "Probe Succeeded"; +static const char msg_probe2[] = "Probe Waiting"; +static const char *const msg_probe[] = { msg_probe0, msg_probe1, msg_probe2 }; + static const char msg_g53[] = "G53 - machine coordinate system"; static const char msg_g54[] = "G54 - coordinate system 1"; static const char msg_g55[] = "G55 - coordinate system 2"; @@ -2162,8 +2166,6 @@ stat_t cm_get_macs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_macs, cm_get_ma stat_t cm_get_cycs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_cycs, cm_get_cycle_state()));} stat_t cm_get_mots(nvObj_t *nv) { return(_get_msg_helper(nv, msg_mots, cm_get_motion_state()));} stat_t cm_get_hold(nvObj_t *nv) { return(_get_msg_helper(nv, msg_hold, cm_get_hold_state()));} -stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state()));} -stat_t cm_set_home(nvObj_t *nv) { return( set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } stat_t cm_get_unit(nvObj_t *nv) { return(_get_msg_helper(nv, msg_unit, cm_get_units_mode(ACTIVE_MODEL)));} stat_t cm_get_coor(nvObj_t *nv) { return(_get_msg_helper(nv, msg_coor, cm_get_coord_system(ACTIVE_MODEL)));} @@ -2245,15 +2247,12 @@ stat_t cm_get_ofs(nvObj_t *nv) return (STAT_OK); } -stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv->index)])); } +stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state()));} +stat_t cm_set_home(nvObj_t *nv) { return (set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } +stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv->index)])); } -stat_t cm_get_prb(nvObj_t *nv) -{ - return (get_float(nv, *cm->probe_results[_axis(nv->index)])); -// nv->value = (float)cm->probe_results[_axis(nv->index)]; -// nv->valuetype = TYPE_FLOAT; -// return (STAT_OK); -} +stat_t cm_get_prob(nvObj_t *nv) { return(_get_msg_helper(nv, msg_probe, cm_get_probe_state()));} +stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_axis(nv->index)])); } /************************************ **** AXIS GET AND SET FUNCTIONS **** diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 5e69af5f..9e9a6673 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -117,17 +117,6 @@ typedef enum { // feedhold state machine FEEDHOLD_HOLD // holding } cmFeedholdState; -typedef enum { // feed override state machine - MFO_OFF = 0, - MFO_REQUESTED, - MFO_SYNC -} cmOverrideState; - -typedef enum { // queue flush state machine - FLUSH_OFF = 0, // no queue flush in effect - FLUSH_REQUESTED, // flush has been requested but not started yet -} cmQueueFlushState; - typedef enum { // applies to cm->homing_state HOMING_NOT_HOMED = 0, // machine is not homed (0=false) HOMING_HOMED = 1, // machine is homed (1=true) @@ -145,6 +134,17 @@ typedef enum { SAFETY_INTERLOCK_DISENGAGED } cmSafetyState; +typedef enum { // feed override state machine + MFO_OFF = 0, + MFO_REQUESTED, + MFO_SYNC +} cmOverrideState; + +typedef enum { // queue flush state machine + FLUSH_OFF = 0, // no queue flush in effect + FLUSH_REQUESTED, // flush has been requested but not started yet +} cmQueueFlushState; + /***************************************************************************** * CANONICAL MACHINE STRUCTURES */ @@ -257,6 +257,7 @@ cmCycleState cm_get_cycle_state(void); cmMotionState cm_get_motion_state(void); cmFeedholdState cm_get_hold_state(void); cmHomingState cm_get_homing_state(void); +cmProbeState cm_get_probe_state(void); uint8_t cm_get_jogging_state(void); void cm_set_motion_state(const cmMotionState motion_state); @@ -432,7 +433,9 @@ stat_t cm_get_mots(nvObj_t *nv); // get raw motion state stat_t cm_get_hold(nvObj_t *nv); // get raw hold state stat_t cm_get_home(nvObj_t *nv); // get machine homing state stat_t cm_set_home(nvObj_t *nv); // set machine homing state -stat_t cm_get_hom(nvObj_t *nv); // get axis homing state +stat_t cm_get_hom(nvObj_t *nv); // get homing state for axis +stat_t cm_get_prob(nvObj_t *nv); // get probe state +stat_t cm_get_prb (nvObj_t *nv); // get probe result for axis stat_t cm_get_unit(nvObj_t *nv); // get unit mode stat_t cm_get_coor(nvObj_t *nv); // get coordinate system in effect stat_t cm_get_momo(nvObj_t *nv); // get motion mode diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 1c1e73d8..b905be86 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -157,7 +157,7 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // B work offset { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // C work offset - { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home, (float *)&cs.null,0 },// homing state, invoke homing cycle + { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 },// homing state, invoke homing cycle { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // X homed - Homing status group { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Y homed { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Z homed @@ -165,13 +165,13 @@ const cfgItem_t cfgArray[] = { { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // B homed { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // C homed - { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_nul,(float *)&cm->probe_state[0], 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_X], 0 }, - { "prb","prby",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_Y], 0 }, - { "prb","prbz",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_Z], 0 }, - { "prb","prba",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_A], 0 }, - { "prb","prbb",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_B], 0 }, - { "prb","prbc",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm->probe_results[0][AXIS_C], 0 }, + { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_nul,(float *)&cs.null, 0 }, // probing state + { "prb","prbx",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // X probe results + { "prb","prby",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // Y probe results + { "prb","prbz",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // Z probe results + { "prb","prba",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // A probe results + { "prb","prbb",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // B probe results + { "prb","prbc",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // C probe results { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm->jogging_dest, 0}, { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm->jogging_dest, 0}, diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 861ff145..32eaca8d 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -44,23 +44,22 @@ #define MINIMUM_PROBE_TRAVEL 0.254 struct pbProbingSingleton { // persistent probing runtime variables - bool waiting_for_motion_end; // flag to use to now when the motion has ended - bool failure_is_fatal; // flag for G38.2 and G38.4, where failure is NOT an option - bool moving_toward_switch; // flag for G38.4 and G38.5, where we move off of the switch - - stat_t (*func)(); // binding for callback function state machine // controls for probing cycle + stat_t (*func)(); // binding for callback function state machine uint8_t probe_input; // which input should we check? + float target[AXES]; // probe destination + bool flags[AXES]; // state saved from gcode model uint8_t saved_distance_mode; // G90,G91 global setting uint8_t saved_coord_system; // G54 - G59 setting float saved_jerk[AXES]; // saved and restored for each axis - // probe destination - float target[AXES]; - bool flags[AXES]; + // internals + bool waiting_for_motion_end; // flag to use to now when the motion has ended + bool failure_is_fatal; // flag for G38.2 and G38.4, where failure is NOT an option + bool moving_toward_switch; // flag for G38.4 and G38.5, where we move off of the switch }; static struct pbProbingSingleton pb; @@ -92,68 +91,62 @@ static stat_t _set_pb_func(uint8_t (*func)()) { * cm_probing_cycle_start() - G38.x probing cycle using limit switches * cm_probing_cycle_callback() - main loop callback for running the probing cycle * - * All cm_probe_cycle_start does is prevent any new commands from queueing to the + * All cm_probe_cycle_start does is prevent any new commands from queuing to the * planner so that the planner can move to a stop and report MACHINE_PROGRAM_STOP. * OK, it also queues the function that's called once motion has stopped. * - * Note: When coding a cycle (like this one) you get to perform one queued - * move per entry into the continuation, then you must exit. We put two buffer - * items into the queue: We queue a move, then we queue a "command" that simply - * sets a flag in the probing object (pb.waiting_for_motion_end) to tell us that - * the move has finished. The runtime has a special exception for probing and - * homing where if a move is interrupted it clears it out of the queue. - * - * --- Some further details --- + * Note: When coding a cycle (like this one) you get to perform one queued move per + * entry into the continuation, then you must exit. We put two buffer items into the + * queue: We queue a move, then we queue a "command" that simply sets a flag in the + * probing object (pb.waiting_for_motion_end) to tell us that the move has finished. + * The runtime has a special exception for probing and homing where if a move is + * interrupted it clears it out of the queue. + */ +/* --- Some further details --- * Starting from the definition of G38.x from the LinuxCNC docs: * http://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G38-probe * - * Once we are past the starting conditions for the probe to succeed as listed - * in the LinuxCNC documentation, we will then execute the move. After the move - * we interpret "success" as the probe value changing in the correct direction, - * and "failure" as it not changing. IOW, the move can finish and the switch not - * change, which we consider to be a failure. + * Once we are past the starting conditions for the probe to succeed as listed in + * the LinuxCNC documentation, we will then execute the move. After the move we + * interpret "success" as the probe value changing in the correct direction, and + * "failure" as it not changing. IOW, the move can finish and the switch not change, + * which we consider to be a failure. * - * Taking polarity of the switch into account to give a value of Active or - * Inactive, for G38.2 and G38.3, success requires going from Inactive to Active, - * and for G38.4 and G38.5 success requires an edge from Inactive to Active. + * Taking polarity of the switch into account to give a value of Active or Inactive, + * for G38.2 and G38.3, success requires going from Inactive to Active, and for + * G38.4 and G38.5 success requires an edge from Inactive to Active. * - * For G38.2 and G38.4 we also put the machine into an ALARM state if the probing - * "fails". + * For G38.2 and G38.4 we also put the machine into an ALARM state if the probing "fails". + */ +/* When the probe switch fires the input interrupt takes a snapshot of the internal + * encoders, then requests a "high speed" feedhold. It then runs forward kinematics on + * the encoder snapshot to get the reported position. It also executes a move from the + * final position (after the feedhold) back to the point we report. * - * When the switch fires, the input interrupt takes a snapshot of the internal - * encoders, then requests a "high speed" feedhold. We then run forward kinematics - * on the encoder snapshot to get the reported position. We also execute a move - * from the final position (after the feedhold) back to the point we report. + * Additionally, probing record the last PROBES_STORED (at least 3) probe points that + * succeeded. The current or most recent probe (be it success, failure, or in-progress) + * occupies one of those positions, which is the one reported by the {prb:n} JSON. * - * Additionally, we record the last PROBES_STORED (at least 3) probe points that - * succeded. The current or most recent probe (be it sucess, failure, or - * in-progress) occupies one of those positions, wich is the one reported by the - * "prb" JSON. - * - * Internally we store the active/most recent probe in cm->probe_results[0] and - * cm->probe_state[0]. Before we start a new probe, if cm->probe_state[0] == - * PROBE_SUCCEEDED, then we roll 0 to 1, and 1 to 2, up to PROBES_STORED-1. + * Internally the active/most recent probe is stored in cm->probe_results[0] and + * cm->probe_state[0]. Before a new probe is started, if cm->probe_state[0] == + * PROBE_SUCCEEDED, then 0 rolls to 1, and 1 to 2, up to PROBES_STORED-1. * The oldest probe is "lost." - * */ uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, bool moving_toward_switch) { - // trap zero feed rate condition - if (fp_ZERO(cm->gm.feed_rate)) { + + if (fp_ZERO(cm->gm.feed_rate)) { // trap zero feed rate condition return (STAT_FEEDRATE_NOT_SPECIFIED); } - - // error if no axes specified - if (!flags[AXIS_X] && !flags[AXIS_Y] && !flags[AXIS_Z]) { + if (!flags[AXIS_X] && !flags[AXIS_Y] && !flags[AXIS_Z]) { // error if no axes specified return (STAT_AXIS_IS_MISSING); } pb.failure_is_fatal = failure_is_fatal; pb.moving_toward_switch = moving_toward_switch; - // set probe move endpoint - copy_vector(pb.target, target); // set probe move endpoint - copy_vector(pb.flags, flags); // set axes involved on the move + copy_vector(pb.target, target); // set probe move endpoint + copy_vector(pb.flags, flags); // set axes involved on the move // if the previous probe succeeded, roll probes to the next position if (cm->probe_state[0] == PROBE_SUCCEEDED) { @@ -162,12 +155,9 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, b for (uint8_t axis = 0; axis < AXES; axis++) { cm->probe_results[n][axis] = cm->probe_results[n - 1][axis]; } } } - - // clear the old probe position - clear_vector(cm->probe_results[0]); + clear_vector(cm->probe_results[0]); // clear the old probe position // NOTE: relying on probe_result will not detect a probe to 0,0,0. - cm->probe_state[0] = PROBE_WAITING; // wait until planner queue empties before completing initialization pb.waiting_for_motion_end = true; From 077b8a0bea919fcc0f600c4420de0cbc5f7be2db Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 10 Dec 2016 17:06:12 -0500 Subject: [PATCH 027/283] Wrapped jogging functions and reduced to a single run function --- g2core/canonical_machine.cpp | 64 ++++++++++++++---------------------- g2core/canonical_machine.h | 8 ++--- g2core/config_app.cpp | 26 +++++++-------- 3 files changed, 40 insertions(+), 58 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 3e2a5663..6b2520e8 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2464,7 +2464,7 @@ stat_t cm_set_mto(nvObj_t *nv) } /* - * Commands + * Run Commands * * cm_run_qf() - flush planner queue * cm_run_home() - run homing sequence @@ -2485,8 +2485,30 @@ stat_t cm_run_home(nvObj_t *nv) } /* - * Debugging Commands + * Jogging Commands * + * cm_get_jogging_dest() + * cm_run_jog() + */ + +float cm_get_jogging_dest(void) +{ + return cm->jogging_dest; +} + +stat_t cm_run_jog(nvObj_t *nv) +{ + set_float(nv, cm->jogging_dest); + cm_jogging_cycle_start(_axis(nv->index)); + return (STAT_OK); +} + + +/*********************************************************************************** + * Debugging Commands + ***********************************************************************************/ + +/* * cm_dam() - dump active model */ @@ -2513,44 +2535,6 @@ stat_t cm_dam(nvObj_t *nv) return (STAT_OK); } - -/*********************************************************************************** - * AXIS JOGGING - ***********************************************************************************/ - -float cm_get_jogging_dest(void) -{ - return cm->jogging_dest; -} - -stat_t cm_run_jogx(nvObj_t *nv) -{ - set_flt(nv); - cm_jogging_cycle_start(AXIS_X); - return (STAT_OK); -} - -stat_t cm_run_jogy(nvObj_t *nv) -{ - set_flt(nv); - cm_jogging_cycle_start(AXIS_Y); - return (STAT_OK); -} - -stat_t cm_run_jogz(nvObj_t *nv) -{ - set_flt(nv); - cm_jogging_cycle_start(AXIS_Z); - return (STAT_OK); -} - -stat_t cm_run_joga(nvObj_t *nv) -{ - set_flt(nv); - cm_jogging_cycle_start(AXIS_A); - return (STAT_OK); -} - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 9e9a6673..75d4d3b9 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -431,11 +431,14 @@ stat_t cm_get_macs(nvObj_t *nv); // get raw machine state as value and st stat_t cm_get_cycs(nvObj_t *nv); // get raw cycle state stat_t cm_get_mots(nvObj_t *nv); // get raw motion state stat_t cm_get_hold(nvObj_t *nv); // get raw hold state + stat_t cm_get_home(nvObj_t *nv); // get machine homing state stat_t cm_set_home(nvObj_t *nv); // set machine homing state stat_t cm_get_hom(nvObj_t *nv); // get homing state for axis stat_t cm_get_prob(nvObj_t *nv); // get probe state stat_t cm_get_prb (nvObj_t *nv); // get probe result for axis +stat_t cm_run_jog(nvObj_t *nv); // start jogging cycle + stat_t cm_get_unit(nvObj_t *nv); // get unit mode stat_t cm_get_coor(nvObj_t *nv); // get coordinate system in effect stat_t cm_get_momo(nvObj_t *nv); // get motion mode @@ -458,11 +461,6 @@ stat_t cm_run_home(nvObj_t *nv); // start homing cycle stat_t cm_dam(nvObj_t *nv); // dump active model (debugging command) -stat_t cm_run_jogx(nvObj_t *nv); // start jogging cycle for x -stat_t cm_run_jogy(nvObj_t *nv); // start jogging cycle for y -stat_t cm_run_jogz(nvObj_t *nv); // start jogging cycle for z -stat_t cm_run_joga(nvObj_t *nv); // start jogging cycle for a - stat_t cm_get_am(nvObj_t *nv); // get axis mode stat_t cm_set_am(nvObj_t *nv); // set axis mode stat_t cm_get_tn(nvObj_t *nv); // get travel minimum diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index b905be86..cb8907f9 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -165,20 +165,20 @@ const cfgItem_t cfgArray[] = { { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // B homed { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // C homed - { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_nul,(float *)&cs.null, 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // X probe results - { "prb","prby",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // Y probe results - { "prb","prbz",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // Z probe results - { "prb","prba",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // A probe results - { "prb","prbb",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // B probe results - { "prb","prbc",_f0, 3, tx_print_nul, cm_get_prb, set_nul,(float *)&cs.null, 0 }, // C probe results + { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_nul, (float *)&cs.null, 0 }, // probing state + { "prb","prbx",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // X probe results + { "prb","prby",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // Y probe results + { "prb","prbz",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // Z probe results + { "prb","prba",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // A probe results + { "prb","prbb",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // B probe results + { "prb","prbc",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // C probe results - { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm->jogging_dest, 0}, - { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm->jogging_dest, 0}, - { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jogz, (float *)&cm->jogging_dest, 0}, - { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_joga, (float *)&cm->jogging_dest, 0}, -// { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jogb, (float *)&cm->jogging_dest, 0}, -// { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jogc, (float *)&cm->jogging_dest, 0}, + { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in X axis + { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Y axis + { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Z axis + { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in A axis + { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in B axis + { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in C axis { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0}, // motor power readouts { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0}, From 25c17bc4f715f416d8b9362d49b471e1f5d02212 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 10 Dec 2016 18:19:09 -0500 Subject: [PATCH 028/283] Wrapped g54-g59 coordinate system setters and getters --- g2core/canonical_machine.cpp | 59 ++++++++++++----------------- g2core/canonical_machine.h | 2 + g2core/config_app.cpp | 72 ++++++++++++++++++------------------ 3 files changed, 62 insertions(+), 71 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 6b2520e8..0beb2dc5 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2085,7 +2085,8 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; /***** AXIS HELPERS ***************************************************************** - * _get_axis() - return axis number or -1 if not an axis + * _axis() - return axis number or -1 if not an axis + * _coord() - return coordinate system number or -1 if error * cm_get_axis_char() - return ASCII char for axis given the axis number * cm_get_axis_type() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) */ @@ -2105,6 +2106,17 @@ static int8_t _axis(const index_t index) return (ptr - axes); } +int8_t _coord(char *token) // extract coordinate system from 3rd character +{ + char *ptr; + char coord_list[] = {"456789"}; + + if ((ptr = strchr(coord_list, token[2])) == NULL) { // test the 3rd character against the string + return (-1); + } + return (ptr - coord_list); +} + char cm_get_axis_char(const int8_t axis) { char axis_char[] = "XYZABC"; @@ -2212,40 +2224,10 @@ stat_t cm_get_vel(nvObj_t *nv) return (STAT_OK); } -stat_t cm_get_feed(nvObj_t *nv) -{ - nv->value = cm_get_feed_rate(ACTIVE_MODEL); - if (cm_get_units_mode(ACTIVE_MODEL) == INCHES) { - nv->value *= INCHES_PER_MM; - } - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); -} - -stat_t cm_get_pos(nvObj_t *nv) -{ - nv->value = cm_get_work_position(ACTIVE_MODEL, _axis(nv->index)); - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); -} - -stat_t cm_get_mpo(nvObj_t *nv) -{ - nv->value = cm_get_absolute_position(ACTIVE_MODEL, _axis(nv->index)); - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); -} - -stat_t cm_get_ofs(nvObj_t *nv) -{ - nv->value = cm_get_work_offset(ACTIVE_MODEL, _axis(nv->index)); - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); -} +stat_t cm_get_feed(nvObj_t *nv) { return (get_float(nv, cm_get_feed_rate(ACTIVE_MODEL))); } +stat_t cm_get_pos(nvObj_t *nv) { return (get_float(nv, cm_get_work_position(ACTIVE_MODEL, _axis(nv->index)))); } +stat_t cm_get_mpo(nvObj_t *nv) { return (get_float(nv, cm_get_absolute_position(ACTIVE_MODEL, _axis(nv->index)))); } +stat_t cm_get_ofs(nvObj_t *nv) { return (get_float(nv, cm_get_work_offset(ACTIVE_MODEL, _axis(nv->index)))); } stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state()));} stat_t cm_set_home(nvObj_t *nv) { return (set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } @@ -2254,6 +2236,13 @@ stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv->index) stat_t cm_get_prob(nvObj_t *nv) { return(_get_msg_helper(nv, msg_probe, cm_get_probe_state()));} stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_axis(nv->index)])); } +stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->offset[_coord(nv->token)][_axis(nv->index)]));} +stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->offset[_coord(nv->token)][_axis(nv->index)]));} + +stat_t cm_get_g92(nvObj_t *nv){ return (get_float(nv, cm->gmx.origin_offset[_axis(nv->index)]));} +stat_t cm_set_g92(nvObj_t *nv){ return (get_float(nv, cm->gmx.origin_offset[_axis(nv->index)]));} + + /************************************ **** AXIS GET AND SET FUNCTIONS **** ************************************/ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 75d4d3b9..9bacee2f 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -455,6 +455,8 @@ stat_t cm_get_feed(nvObj_t *nv); // get feed rate, converted to units stat_t cm_get_pos(nvObj_t *nv); // get runtime work position stat_t cm_get_mpo(nvObj_t *nv); // get runtime machine position stat_t cm_get_ofs(nvObj_t *nv); // get runtime work offset +stat_t cm_get_coord(nvObj_t *nv); // get coordinate offset +stat_t cm_set_coord(nvObj_t *nv); // set coordinate offset stat_t cm_run_qf(nvObj_t *nv); // run queue flush stat_t cm_run_home(nvObj_t *nv); // start homing cycle diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index cb8907f9..229afa4f 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -532,47 +532,47 @@ const cfgItem_t cfgArray[] = { { "he3","he3fh",_f0, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, // Coordinate system offsets (G54-G59 and G92) - { "g54","g54x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G54][AXIS_X], G54_X_OFFSET }, - { "g54","g54y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G54][AXIS_Y], G54_Y_OFFSET }, - { "g54","g54z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G54][AXIS_Z], G54_Z_OFFSET }, - { "g54","g54a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G54][AXIS_A], G54_A_OFFSET }, - { "g54","g54b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G54][AXIS_B], G54_B_OFFSET }, - { "g54","g54c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G54][AXIS_C], G54_C_OFFSET }, + { "g54","g54x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_X_OFFSET }, + { "g54","g54y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Y_OFFSET }, + { "g54","g54z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Z_OFFSET }, + { "g54","g54a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_A_OFFSET }, + { "g54","g54b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_B_OFFSET }, + { "g54","g54c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_C_OFFSET }, - { "g55","g55x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G55][AXIS_X], G55_X_OFFSET }, - { "g55","g55y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G55][AXIS_Y], G55_Y_OFFSET }, - { "g55","g55z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G55][AXIS_Z], G55_Z_OFFSET }, - { "g55","g55a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G55][AXIS_A], G55_A_OFFSET }, - { "g55","g55b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G55][AXIS_B], G55_B_OFFSET }, - { "g55","g55c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G55][AXIS_C], G55_C_OFFSET }, + { "g55","g55x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_X_OFFSET }, + { "g55","g55y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Y_OFFSET }, + { "g55","g55z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Z_OFFSET }, + { "g55","g55a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_A_OFFSET }, + { "g55","g55b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_B_OFFSET }, + { "g55","g55c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_C_OFFSET }, - { "g56","g56x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G56][AXIS_X], G56_X_OFFSET }, - { "g56","g56y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G56][AXIS_Y], G56_Y_OFFSET }, - { "g56","g56z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G56][AXIS_Z], G56_Z_OFFSET }, - { "g56","g56a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G56][AXIS_A], G56_A_OFFSET }, - { "g56","g56b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G56][AXIS_B], G56_B_OFFSET }, - { "g56","g56c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G56][AXIS_C], G56_C_OFFSET }, + { "g56","g56x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_X_OFFSET }, + { "g56","g56y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Y_OFFSET }, + { "g56","g56z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Z_OFFSET }, + { "g56","g56a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_A_OFFSET }, + { "g56","g56b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_B_OFFSET }, + { "g56","g56c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_C_OFFSET }, - { "g57","g57x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G57][AXIS_X], G57_X_OFFSET }, - { "g57","g57y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G57][AXIS_Y], G57_Y_OFFSET }, - { "g57","g57z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G57][AXIS_Z], G57_Z_OFFSET }, - { "g57","g57a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G57][AXIS_A], G57_A_OFFSET }, - { "g57","g57b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G57][AXIS_B], G57_B_OFFSET }, - { "g57","g57c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G57][AXIS_C], G57_C_OFFSET }, + { "g57","g57x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_X_OFFSET }, + { "g57","g57y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Y_OFFSET }, + { "g57","g57z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Z_OFFSET }, + { "g57","g57a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_A_OFFSET }, + { "g57","g57b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_B_OFFSET }, + { "g57","g57c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_C_OFFSET }, - { "g58","g58x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G58][AXIS_X], G58_X_OFFSET }, - { "g58","g58y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G58][AXIS_Y], G58_Y_OFFSET }, - { "g58","g58z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G58][AXIS_Z], G58_Z_OFFSET }, - { "g58","g58a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G58][AXIS_A], G58_A_OFFSET }, - { "g58","g58b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G58][AXIS_B], G58_B_OFFSET }, - { "g58","g58c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G58][AXIS_C], G58_C_OFFSET }, + { "g58","g58x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_X_OFFSET }, + { "g58","g58y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Y_OFFSET }, + { "g58","g58z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Z_OFFSET }, + { "g58","g58a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_A_OFFSET }, + { "g58","g58b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_B_OFFSET }, + { "g58","g58c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_C_OFFSET }, - { "g59","g59x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G59][AXIS_X], G59_X_OFFSET }, - { "g59","g59y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G59][AXIS_Y], G59_Y_OFFSET }, - { "g59","g59z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->offset[G59][AXIS_Z], G59_Z_OFFSET }, - { "g59","g59a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G59][AXIS_A], G59_A_OFFSET }, - { "g59","g59b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G59][AXIS_B], G59_B_OFFSET }, - { "g59","g59c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm->offset[G59][AXIS_C], G59_C_OFFSET }, + { "g59","g59x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_X_OFFSET }, + { "g59","g59y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Y_OFFSET }, + { "g59","g59z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Z_OFFSET }, + { "g59","g59a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_A_OFFSET }, + { "g59","g59b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, + { "g59","g59c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, { "g92","g92x",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_X], 0 },// G92 handled differently { "g92","g92y",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_Y], 0 }, From 21770500bbef6496fbbabe0d7ad2b7774cd7d820 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 10 Dec 2016 19:05:23 -0500 Subject: [PATCH 029/283] Checkpoint. Untested --- g2core/canonical_machine.cpp | 11 ++++++++--- g2core/canonical_machine.h | 4 ++++ g2core/config_app.cpp | 36 ++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0beb2dc5..3fb7c6a6 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2188,6 +2188,10 @@ stat_t cm_get_dist(nvObj_t *nv) { return(_get_msg_helper(nv, msg_dist, cm_get_di stat_t cm_get_admo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_admo, cm_get_arc_distance_mode(ACTIVE_MODEL)));} stat_t cm_get_frmo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_frmo, cm_get_feed_rate_mode(ACTIVE_MODEL)));} +stat_t cm_get_toolv(nvObj_t *nv) { return(get_int(nv, cm_get_tool(ACTIVE_MODEL))); } +stat_t cm_get_mline(nvObj_t *nv) { return(get_int(nv, cm_get_linenum(MODEL))); } +stat_t cm_get_line(nvObj_t *nv) { return(get_int(nv, cm_get_linenum(ACTIVE_MODEL))); } +/* stat_t cm_get_toolv(nvObj_t *nv) { nv->value = (float)cm_get_tool(ACTIVE_MODEL); @@ -2208,7 +2212,7 @@ stat_t cm_get_line(nvObj_t *nv) nv->valuetype = TYPE_INT; return (STAT_OK); } - +*/ stat_t cm_get_vel(nvObj_t *nv) { if (cm_get_motion_state() == MOTION_STOP) { @@ -2239,8 +2243,9 @@ stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_ax stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->offset[_coord(nv->token)][_axis(nv->index)]));} stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->offset[_coord(nv->token)][_axis(nv->index)]));} -stat_t cm_get_g92(nvObj_t *nv){ return (get_float(nv, cm->gmx.origin_offset[_axis(nv->index)]));} -stat_t cm_set_g92(nvObj_t *nv){ return (get_float(nv, cm->gmx.origin_offset[_axis(nv->index)]));} +stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv->index)]));} +stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv->index)]));} +stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv->index)]));} /************************************ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 9bacee2f..4f22fa02 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -458,6 +458,10 @@ stat_t cm_get_ofs(nvObj_t *nv); // get runtime work offset stat_t cm_get_coord(nvObj_t *nv); // get coordinate offset stat_t cm_set_coord(nvObj_t *nv); // set coordinate offset +stat_t cm_get_g92(nvObj_t *nv); // get g92 offset +stat_t cm_get_g28(nvObj_t *nv); // get g28 offset +stat_t cm_get_g30(nvObj_t *nv); // get g30 offset + stat_t cm_run_qf(nvObj_t *nv); // run queue flush stat_t cm_run_home(nvObj_t *nv); // start homing cycle diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 229afa4f..294d663e 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -574,27 +574,27 @@ const cfgItem_t cfgArray[] = { { "g59","g59b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, { "g59","g59c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, - { "g92","g92x",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_X], 0 },// G92 handled differently - { "g92","g92y",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_Y], 0 }, - { "g92","g92z",_fic, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_Z], 0 }, - { "g92","g92a",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_A], 0 }, - { "g92","g92b",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_B], 0 }, - { "g92","g92c",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm->gmx.origin_offset[AXIS_C], 0 }, + { "g92","g92x",_fic, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 },// G92 handled differently + { "g92","g92y",_fic, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, + { "g92","g92z",_fic, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, + { "g92","g92a",_fi, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, + { "g92","g92b",_fi, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, + { "g92","g92c",_fi, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_X], 0 },// g28 handled differently - { "g28","g28y",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_Y], 0 }, - { "g28","g28z",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_Z], 0 }, - { "g28","g28a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_A], 0 }, - { "g28","g28b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_B], 0 }, - { "g28","g28c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g28_position[AXIS_C], 0 }, + { "g28","g28x",_fic, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 },// g28 handled differently + { "g28","g28y",_fic, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, + { "g28","g28z",_fic, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, + { "g28","g28a",_fi, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, + { "g28","g28b",_fi, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, + { "g28","g28c",_fi, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, - { "g30","g30x",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_X], 0 },// g30 handled differently - { "g30","g30y",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_Y], 0 }, - { "g30","g30z",_fic, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_Z], 0 }, - { "g30","g30a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_A], 0 }, - { "g30","g30b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_B], 0 }, - { "g30","g30c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm->gmx.g30_position[AXIS_C], 0 }, + { "g30","g30x",_fic, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 },// g30 handled differently + { "g30","g30y",_fic, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, + { "g30","g30z",_fic, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, + { "g30","g30a",_fi, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, + { "g30","g30b",_fi, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, + { "g30","g30c",_fi, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, // this is a 128bit UUID for identifying a previously committed job state { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, From c5224b34a1d909239ff13364dc24f0a376c5e755 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 11 Dec 2016 08:03:52 -0500 Subject: [PATCH 030/283] Refactored JT command --- g2core/canonical_machine.cpp | 26 +++++++------------------- g2core/canonical_machine.h | 1 + g2core/config_app.cpp | 2 +- g2core/util.h | 1 + 4 files changed, 10 insertions(+), 20 deletions(-) mode change 100755 => 100644 g2core/util.h diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 3fb7c6a6..a0bc3f8c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2399,33 +2399,21 @@ stat_t cm_set_zb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].ze * cm_set_jt() - get junction integration time */ -stat_t cm_get_jt(nvObj_t *nv) -{ - return(STAT_OK); -} +stat_t cm_get_jt(nvObj_t *nv) { + return(get_float(nv, cm->junction_integration_time)); } stat_t cm_set_jt(nvObj_t *nv) { -// // Prescale it. -// if (nv->value > 10) nv->value /= 100; - - stat_t status = STAT_OK; - - if (nv->value < JUNCTION_INTEGRATION_MIN) { - nv->value = JUNCTION_INTEGRATION_MIN; - status = STAT_INPUT_LESS_THAN_MIN_VALUE; - } - if (nv->value > JUNCTION_INTEGRATION_MAX) { - nv->value = JUNCTION_INTEGRATION_MAX; - status = STAT_INPUT_EXCEEDS_MAX_VALUE; - } - set_flt(nv); + // Get JT or return range error + ritorno(set_float_range(nv, cm->junction_integration_time, + JUNCTION_INTEGRATION_MIN, + JUNCTION_INTEGRATION_MAX)); // Must recalculate the max_junction_accel now that the time quanta has changed. for (uint8_t axis=0; axisjunction_integration_time,JUNCTION_INTEGRATION_TIME }, + { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cm->junction_integration_time,JUNCTION_INTEGRATION_TIME }, { "sys","ct", _fipnc,4, cm_print_ct, get_flt, set_flu, (float *)&cm->chordal_tolerance, CHORDAL_TOLERANCE }, { "sys","sl", _fipn, 0, cm_print_sl, get_ui8, set_01, (float *)&cm->soft_limit_enable, SOFT_LIMIT_ENABLE }, { "sys","lim", _fipn,0, cm_print_lim, get_ui8, set_01, (float *)&cm->limit_enable, HARD_LIMIT_ENABLE }, diff --git a/g2core/util.h b/g2core/util.h old mode 100755 new mode 100644 index d419aaa2..2da35a6a --- a/g2core/util.h +++ b/g2core/util.h @@ -53,6 +53,7 @@ using Motate::SysTickTimer; #pragma GCC push_options #pragma GCC optimize ("O0") +//#pragma GCC reset_options inline void _debug_trap(const char *reason) { // We might be able to put a print here, but it MIGHT interrupt other output // and might be deep in an ISR, so we had better just _NOP() and hope for the best. From 07896b8886fb94994740bede68359b2dde080255 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 11 Dec 2016 08:25:57 -0500 Subject: [PATCH 031/283] Refactored CT command; renamed a few things --- g2core/canonical_machine.cpp | 12 ++++-- g2core/canonical_machine.h | 3 ++ g2core/config.h | 7 ++- g2core/config_app.cpp | 83 ++++++++++++++++++------------------ g2core/json_parser.cpp | 2 +- g2core/text_parser.cpp | 2 +- 6 files changed, 58 insertions(+), 51 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a0bc3f8c..01d59ec0 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2396,11 +2396,12 @@ stat_t cm_set_zb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].ze /*** Canonical Machine Global Settings ***/ /* * cm_get_jt() - get junction integration time - * cm_set_jt() - get junction integration time + * cm_set_jt() - set junction integration time + * cm_get_ct() - get chordal tolerance + * cm_set_ct() - set chordal tolerance */ -stat_t cm_get_jt(nvObj_t *nv) { - return(get_float(nv, cm->junction_integration_time)); } +stat_t cm_get_jt(nvObj_t *nv) { return(get_float(nv, cm->junction_integration_time)); } stat_t cm_set_jt(nvObj_t *nv) { @@ -2416,6 +2417,11 @@ stat_t cm_set_jt(nvObj_t *nv) return(STAT_OK); } +stat_t cm_get_ct(nvObj_t *nv) { return(get_float(nv, cm->chordal_tolerance)); } +stat_t cm_set_ct(nvObj_t *nv) { return(set_float_range(nv, cm->chordal_tolerance, + CHORDAL_TOLERANCE_MIN, + 10000000)); } + /* * cm_set_mfo() - set manual feedrate override factor * cm_set_mto() - set manual traverse override factor diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 70e60882..48d4e059 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -47,6 +47,7 @@ #define JOGGING_START_VELOCITY ((float)10.0) #define DISABLE_SOFT_LIMIT (999999) +#define CHORDAL_TOLERANCE_MIN (0.001) #define PROBES_STORED 3 // we store three probes for coordinate rotation computation /***************************************************************************** @@ -503,6 +504,8 @@ stat_t cm_set_zb(nvObj_t *nv); // set homing zero backoff stat_t cm_get_jt(nvObj_t *nv); // get junction integration time constant stat_t cm_set_jt(nvObj_t *nv); // set junction integration time constant +stat_t cm_get_ct(nvObj_t *nv); // get chordal tolerance +stat_t cm_set_ct(nvObj_t *nv); // set chordal tolerance stat_t cm_set_mfo(nvObj_t *nv); // set manual feedrate override factor stat_t cm_set_mto(nvObj_t *nv); // set manual traverse override factor diff --git a/g2core/config.h b/g2core/config.h index 74cf43e1..3be9d07b 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -354,16 +354,15 @@ void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); // application specific helpers and functions (config_app.c) stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion +void process_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values +void process_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving raw floating point value stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); -stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving an integer value +stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving an integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); -void preprocess_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values -void preprocess_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units - // diagnostics void nv_dump_nv(nvObj_t *nv); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 8e42a051..c102aad2 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -603,8 +603,8 @@ const cfgItem_t cfgArray[] = { { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cm->junction_integration_time,JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, get_flt, set_flu, (float *)&cm->chordal_tolerance, CHORDAL_TOLERANCE }, + { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, + { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, { "sys","sl", _fipn, 0, cm_print_sl, get_ui8, set_01, (float *)&cm->soft_limit_enable, SOFT_LIMIT_ENABLE }, { "sys","lim", _fipn,0, cm_print_lim, get_ui8, set_01, (float *)&cm->limit_enable, HARD_LIMIT_ENABLE }, { "sys","saf", _fipn,0, cm_print_saf, get_ui8, set_01, (float *)&cm->safety_interlock_enable, SAFETY_INTERLOCK_ENABLE }, @@ -995,9 +995,11 @@ stat_t set_flu(nvObj_t *nv) } /* - * get_float() - boilerplate for retrieving raw floating point value - * set_float() - boilerplate for setting a floating point value with unit conversion - * set_float_range() - set a floating point value with inclusive range check + * process_incoming_float() - pre-process an incoming floating point number for canonical units + * process_outgoing_float() - pre-process an outgoing floating point number for units display + * get_float() - boilerplate for retrieving raw floating point value + * set_float() - boilerplate for setting a floating point value with unit conversion + * set_float_range() - set a floating point value with inclusive range check * * get_float() returns a raw float value in internal canonical units (e.g. mm, degrees) * without units conversion. If conversion is required call preprocess_outgoing_float() @@ -1008,6 +1010,37 @@ stat_t set_flu(nvObj_t *nv) * set_float_range() perfoems an inclusive range test on the CONVERTED value */ +void process_incoming_float(nvObj_t *nv) +{ + uint8_t f; + f = GET_TABLE_BYTE(flags); +// if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? + if (f & F_CONVERT) { // unit conversion required? + if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... + nv->value *= MM_PER_INCH; // convert to canonical millimeter units + } + } + } +} + +void process_outgoing_float(nvObj_t *nv) +{ + uint8_t f; + if (isnan((double)nv->value) || isinf((double)nv->value)) return; // illegal float values + f = GET_TABLE_BYTE(flags); + if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? + if (cm_get_units_mode(MODEL) == INCHES) { + if(f & F_ICONVERT) { + nv->value *= MM_PER_INCH; + } else { + nv->value *= INCHES_PER_MM; + } + } + } + nv->precision = GET_TABLE_WORD(precision); + nv->valuetype = TYPE_FLOAT; +} stat_t get_float(nvObj_t *nv, const float value) { nv->value = value; nv->valuetype = TYPE_FLOAT; @@ -1016,14 +1049,15 @@ stat_t get_float(nvObj_t *nv, const float value) { } stat_t set_float(nvObj_t *nv, float &value) { - preprocess_incoming_float(nv); + process_incoming_float(nv); value = nv->value; return (STAT_OK); } stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { - preprocess_incoming_float(nv); + process_incoming_float(nv); // conditional unit conversion if ((nv->value < low) || (nv->value > high)) { + nv->valuetype = TYPE_NULL; return (STAT_INPUT_VALUE_RANGE_ERROR); } value = nv->value; @@ -1050,42 +1084,7 @@ stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { return (STAT_OK); } -/* - * preprocess_incoming_float() - pre-process an incoming floating point number for canonical units - * preprocess_outgoing_float() - pre-process an outgoing floating point number for units display - */ -void preprocess_incoming_float(nvObj_t *nv) -{ - uint8_t f; - f = GET_TABLE_BYTE(flags); -// if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? - if (f & F_CONVERT) { // unit conversion required? - if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... - nv->value *= MM_PER_INCH; // convert to canonical millimeter units - } - } - } -} - -void preprocess_outgoing_float(nvObj_t *nv) -{ - uint8_t f; - if (isnan((double)nv->value) || isinf((double)nv->value)) return; // illegal float values - f = GET_TABLE_BYTE(flags); - if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? - if (cm_get_units_mode(MODEL) == INCHES) { - if(f & F_ICONVERT) { - nv->value *= MM_PER_INCH; - } else { - nv->value *= INCHES_PER_MM; - } - } - } - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; -} /* * nv_group_is_prefixed() - hack diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index d37838d5..c2605b89 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -421,7 +421,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) need_a_comma = false; break; } - case (TYPE_FLOAT): { preprocess_outgoing_float(nv); + case (TYPE_FLOAT): { process_outgoing_float(nv); str += floattoa(str, nv->value, nv->precision); break; } diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index 8262d48f..c731553d 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -196,7 +196,7 @@ void text_print_multiline_formatted(nvObj_t *nv) { for (uint8_t i=0; ivaluetype != TYPE_PARENT) { - preprocess_outgoing_float(nv); + process_outgoing_float(nv); nv_print(nv); } if ((nv = nv->nx) == NULL) return; From baff4fa7e6687a01eeb7157fd381bc1996517ea3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 11 Dec 2016 14:40:38 -0500 Subject: [PATCH 032/283] Refactored some more system settings; testing axis settings - some tweaks; fixed length of system ID string to accommodate longer strings from Motate. --- g2core/board/Archim/hardware.h | 4 +- g2core/board/ArduinoDue/hardware.h | 4 +- g2core/board/G2v9/hardware.h | 4 +- g2core/board/gquadratic/hardware.h | 4 +- g2core/board/gquintic/hardware.h | 4 +- g2core/board/printrboardg2/hardware.h | 4 +- g2core/board/sbv300/hardware.h | 4 +- g2core/canonical_machine.cpp | 159 ++++++++++++-------------- g2core/canonical_machine.h | 35 ++++-- g2core/config.cpp | 7 +- g2core/config_app.cpp | 42 +++---- g2core/cycle_jogging.cpp | 2 + g2core/plan_arc.h | 2 + 13 files changed, 143 insertions(+), 132 deletions(-) mode change 100755 => 100644 g2core/board/gquintic/hardware.h mode change 100755 => 100644 g2core/board/printrboardg2/hardware.h mode change 100755 => 100644 g2core/board/sbv300/hardware.h diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 6da17870..9e88aee5 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -83,8 +83,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h index e01e70d4..e6022d85 100644 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -85,8 +85,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index b8f19f4a..7668b21d 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -86,8 +86,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index a28bf858..dc87fbee 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -86,8 +86,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h old mode 100755 new mode 100644 index e7fb56ba..5bd64ad3 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -84,8 +84,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/board/printrboardg2/hardware.h b/g2core/board/printrboardg2/hardware.h old mode 100755 new mode 100644 index 244a2681..44f970e9 --- a/g2core/board/printrboardg2/hardware.h +++ b/g2core/board/printrboardg2/hardware.h @@ -83,8 +83,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h old mode 100755 new mode 100644 index 5ded07eb..0c1ce429 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -83,8 +83,8 @@ using Motate::OutputPin; *************************/ #define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 12 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 16 // total length including dashes and NUL +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 01d59ec0..7d292cb5 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -546,11 +546,9 @@ stat_t cm_set_tram(nvObj_t *nv) return (STAT_COMMAND_NOT_ACCEPTED); } - } else { return (STAT_INPUT_VALUE_RANGE_ERROR); } - return (STAT_OK); } @@ -569,15 +567,12 @@ stat_t cm_get_tram(nvObj_t *nv) fp_NE(1.0, cm->rotation_matrix[1][1]) || fp_NE(1.0, cm->rotation_matrix[2][2])) { - nv->value = false; } - nv->valuetype = TYPE_BOOL; return (STAT_OK); } - /* * cm_set_model_target() - set target vector in GM model * @@ -2270,12 +2265,17 @@ stat_t cm_get_am(nvObj_t *nv) stat_t cm_set_am(nvObj_t *nv) // axis mode { - nv->valuetype = TYPE_INT; + nv->valuetype = TYPE_NULL; if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { - if (nv->value > AXIS_MODE_LINEAR_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} + if (nv->value > AXIS_MODE_LINEAR_MAX) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } } else { - if (nv->value > AXIS_MODE_ROTARY_MAX) { return (STAT_INPUT_VALUE_RANGE_ERROR);} + if (nv->value > AXIS_MODE_ROTARY_MAX) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } } + nv->valuetype = TYPE_INT; cm->a[_axis(nv->index)].axis_mode = (cmAxisMode)nv->value; return(STAT_OK); } @@ -2330,39 +2330,40 @@ void cm_set_axis_jerk(const uint8_t axis, const float jerk) * numbers for people to deal with. Jerk values are stored in the system in truncated format; * values are divided by 1,000,000 then reconstituted before use. * - * The set_xjm() nad set_xjh() functions will accept either truncated or untruncated jerk - * numbers as input. If the number is > 1,000,000 it is divided by 1,000,000 before storing. - * Numbers are accepted in either millimeter or inch mode and converted to millimeter mode. - * - * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form + * The axis_jerk() functions expect the jerk in divided-by 1,000,000 form. + * The set_xjm() and set_xjh() functions accept values divided by 1,000,000. + * This is corrected to mm/min^3 by the internals of the code. */ stat_t cm_get_vm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].velocity_max)); } -stat_t cm_set_vm(nvObj_t *nv) { - uint8_t axis = _axis(nv->index); - set_float(nv, cm->a[axis].velocity_max); - cm->a[axis].recip_velocity_max = 1/nv->value; - return(STAT_OK); - } +stat_t cm_set_vm(nvObj_t *nv) +{ + uint8_t axis = _axis(nv->index); + set_float(nv, cm->a[axis].velocity_max); + cm->a[axis].recip_velocity_max = 1/nv->value; + return(STAT_OK); +} stat_t cm_get_fr(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].feedrate_max)); } -stat_t cm_set_fr(nvObj_t *nv) { - uint8_t axis = _axis(nv->index); - set_float(nv, cm->a[axis].feedrate_max); - cm->a[axis].recip_feedrate_max = 1/nv->value; - return(STAT_OK); - } +stat_t cm_set_fr(nvObj_t *nv) +{ + uint8_t axis = _axis(nv->index); + set_float(nv, cm->a[axis].feedrate_max); + cm->a[axis].recip_feedrate_max = 1/nv->value; + return(STAT_OK); +} stat_t cm_get_jm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_max)); } -stat_t cm_set_jm(nvObj_t *nv) { - uint8_t axis = _axis(nv->index); - set_float(nv, cm->a[axis].jerk_max); - cm_set_axis_jerk(axis, nv->value); - return(STAT_OK); - } +stat_t cm_set_jm(nvObj_t *nv) +{ + uint8_t axis = _axis(nv->index); + ritorno(set_float_range(nv, cm->a[axis].jerk_max, JERK_INPUT_MIN, JERK_INPUT_MAX)); + cm_set_axis_jerk(axis, nv->value); + return(STAT_OK); +} stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_high)); } -stat_t cm_set_jh(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].jerk_high)); } +stat_t cm_set_jh(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->index)].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); } /**** Axis Homing Settings * cm_get_hi() - get homing input @@ -2395,61 +2396,51 @@ stat_t cm_set_zb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].ze /*** Canonical Machine Global Settings ***/ /* - * cm_get_jt() - get junction integration time - * cm_set_jt() - set junction integration time - * cm_get_ct() - get chordal tolerance - * cm_set_ct() - set chordal tolerance + * cm_get_jt() - get junction integration time + * cm_set_jt() - set junction integration time + * cm_get_ct() - get chordal tolerance + * cm_set_ct() - set chordal tolerance + * cm_get_sl() - get soft limit enable + * cm_set_sl() - set soft limit enable + * cm_get_lim() - get hard limit enable + * cm_set_lim() - set hard limit enable + * cm_get_saf() - get safety interlock enable + * cm_set_saf() - set safety interlock enable + * cm_set_mfo() - set manual feedrate override factor + * cm_set_mto() - set manual traverse override factor */ stat_t cm_get_jt(nvObj_t *nv) { return(get_float(nv, cm->junction_integration_time)); } - stat_t cm_set_jt(nvObj_t *nv) { - // Get JT or return range error - ritorno(set_float_range(nv, cm->junction_integration_time, - JUNCTION_INTEGRATION_MIN, - JUNCTION_INTEGRATION_MAX)); - - // Must recalculate the max_junction_accel now that the time quanta has changed. - for (uint8_t axis=0; axisjunction_integration_time, JUNCTION_INTEGRATION_MIN, JUNCTION_INTEGRATION_MAX)); + for (uint8_t axis=0; axischordal_tolerance)); } -stat_t cm_set_ct(nvObj_t *nv) { return(set_float_range(nv, cm->chordal_tolerance, - CHORDAL_TOLERANCE_MIN, - 10000000)); } +stat_t cm_set_ct(nvObj_t *nv) { return(set_float_range(nv, cm->chordal_tolerance, CHORDAL_TOLERANCE_MIN, 10000000)); } -/* - * cm_set_mfo() - set manual feedrate override factor - * cm_set_mto() - set manual traverse override factor - */ +stat_t cm_get_sl(nvObj_t *nv) { return(get_int(nv, cm->soft_limit_enable)); } +stat_t cm_set_sl(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->soft_limit_enable, 0, 1)); } -stat_t cm_set_mfo(nvObj_t *nv) -{ - if (nv->value < FEED_OVERRIDE_MIN) { - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value > FEED_OVERRIDE_MAX) { - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - set_flt(nv); - return(STAT_OK); -} +stat_t cm_get_lim(nvObj_t *nv) { return(get_int(nv, cm->limit_enable)); } +stat_t cm_set_lim(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->limit_enable, 0, 1)); } -stat_t cm_set_mto(nvObj_t *nv) -{ - if (nv->value < TRAVERSE_OVERRIDE_MIN) { - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value > TRAVERSE_OVERRIDE_MAX) { - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - set_flt(nv); - return(STAT_OK); -} +stat_t cm_get_saf(nvObj_t *nv) { return(get_int(nv, cm->safety_interlock_enable)); } +stat_t cm_set_saf(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->safety_interlock_enable, 0, 1)); } + +stat_t cm_get_froe(nvObj_t *nv) { return(get_int(nv, cm->gmx.mfo_enable)); } +stat_t cm_set_froe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.mfo_enable, 0, 1)); } +stat_t cm_get_fro(nvObj_t *nv) { return(get_float(nv, cm->gmx.mfo_factor)); } +stat_t cm_set_fro(nvObj_t *nv) { return(set_float_range(nv, cm->gmx.mfo_factor, FEED_OVERRIDE_MIN, FEED_OVERRIDE_MAX)); } + +stat_t cm_get_troe(nvObj_t *nv) { return(get_int(nv, cm->gmx.mto_enable)); } +stat_t cm_set_troe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.mto_enable, 0, 1)); } +stat_t cm_get_tro(nvObj_t *nv) { return(get_float(nv, cm->gmx.mto_factor)); } +stat_t cm_set_tro(nvObj_t *nv) { return(set_float_range(nv, cm->gmx.mto_factor, TRAVERSE_OVERRIDE_MIN, TRAVERSE_OVERRIDE_MAX)); } /* * Run Commands @@ -2598,18 +2589,18 @@ void cm_print_sl(nvObj_t *nv) { text_print(nv, fmt_sl);} // TYPE_INT void cm_print_lim(nvObj_t *nv){ text_print(nv, fmt_lim);} // TYPE_INT void cm_print_saf(nvObj_t *nv){ text_print(nv, fmt_saf);} // TYPE_INT -static const char fmt_m48e[] = "[m48e] overrides enabled%11d [0=disable,1=enable]\n"; -static const char fmt_mfoe[] = "[mfoe] manual feed override enab%3d [0=disable,1=enable]\n"; -static const char fmt_mfo[] = "[mfo] manual feedrate override%8.3f [0.05 < mfo < 2.00]\n"; -static const char fmt_mtoe[] = "[mtoe] manual traverse over enab%3d [0=disable,1=enable]\n"; -static const char fmt_mto[] = "[mto] manual traverse override%8.3f [0.05 < mto < 1.00]\n"; -static const char fmt_tram[] = "[tram] is coordinate space rotated to be tram %s\n"; +//static const char fmt_m48e[] = "[m48e] overrides enabled%11d [0=disable,1=enable]\n"; +static const char fmt_froe[] = "[froe] feed override enable%8d [0=disable,1=enable]\n"; +static const char fmt_fro[] = "[fro] feedrate override%15.3f [0.05 < mfo < 2.00]\n"; +static const char fmt_troe[] = "[troe] traverse over enable%8d [0=disable,1=enable]\n"; +static const char fmt_tro[] = "[tro] traverse override%15.3f [0.05 < mto < 1.00]\n"; +static const char fmt_tram[] = "[tram] is coordinate space rotated to be tram %s\n"; -void cm_print_m48e(nvObj_t *nv) { text_print(nv, fmt_m48e);} // TYPE_INT -void cm_print_mfoe(nvObj_t *nv) { text_print(nv, fmt_mfoe);} // TYPE INT -void cm_print_mfo(nvObj_t *nv) { text_print(nv, fmt_mfo);} // TYPE FLOAT -void cm_print_mtoe(nvObj_t *nv) { text_print(nv, fmt_mtoe);} // TYPE INT -void cm_print_mto(nvObj_t *nv) { text_print(nv, fmt_mto);} // TYPE FLOAT +//void cm_print_m48e(nvObj_t *nv) { text_print(nv, fmt_m48e);} // TYPE_INT +void cm_print_froe(nvObj_t *nv) { text_print(nv, fmt_froe);} // TYPE INT +void cm_print_fro(nvObj_t *nv) { text_print(nv, fmt_fro);} // TYPE FLOAT +void cm_print_troe(nvObj_t *nv) { text_print(nv, fmt_troe);} // TYPE INT +void cm_print_tro(nvObj_t *nv) { text_print(nv, fmt_tro);} // TYPE FLOAT void cm_print_tram(nvObj_t *nv) { text_print(nv, fmt_tram);}; // TYPE BOOL /* diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 48d4e059..26f8c06c 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -38,16 +38,16 @@ /* Defines, Macros, and Assorted Parameters */ -#define MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model +#define MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model #define PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to #define RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct -#define ACTIVE_MODEL cm->am // active model pointer is maintained by state management +#define ACTIVE_MODEL cm->am // active model pointer is maintained by state management #define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) -#define JOGGING_START_VELOCITY ((float)10.0) #define DISABLE_SOFT_LIMIT (999999) -#define CHORDAL_TOLERANCE_MIN (0.001) +#define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3 +#define JERK_INPUT_MAX (100000) // maximum allowable jerk setting in millions mm/min^3 #define PROBES_STORED 3 // we store three probes for coordinate rotation computation /***************************************************************************** @@ -506,9 +506,22 @@ stat_t cm_get_jt(nvObj_t *nv); // get junction integration time constan stat_t cm_set_jt(nvObj_t *nv); // set junction integration time constant stat_t cm_get_ct(nvObj_t *nv); // get chordal tolerance stat_t cm_set_ct(nvObj_t *nv); // set chordal tolerance +stat_t cm_get_sl(nvObj_t *nv); // get soft limit enable +stat_t cm_set_sl(nvObj_t *nv); // set soft limit enable +stat_t cm_get_lim(nvObj_t *nv); // get hard limit enable +stat_t cm_set_lim(nvObj_t *nv); // set hard limit enable +stat_t cm_get_saf(nvObj_t *nv); // get safety interlock enable +stat_t cm_set_saf(nvObj_t *nv); // set safety interlock enable -stat_t cm_set_mfo(nvObj_t *nv); // set manual feedrate override factor -stat_t cm_set_mto(nvObj_t *nv); // set manual traverse override factor +stat_t cm_get_froe(nvObj_t *nv); // get feedrate override enable +stat_t cm_set_froe(nvObj_t *nv); // set feedrate override enable +stat_t cm_get_fro(nvObj_t *nv); // get feedrate override factor +stat_t cm_set_fro(nvObj_t *nv); // set feedrate override factor + +stat_t cm_get_troe(nvObj_t *nv); // get traverse override enable +stat_t cm_set_troe(nvObj_t *nv); // set traverse override enable +stat_t cm_get_tro(nvObj_t *nv); // get traverse override factor +stat_t cm_set_tro(nvObj_t *nv); // set traverse override factor stat_t cm_set_tram(nvObj_t *nv); // attempt setting the rotation matrix stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non-identity @@ -555,11 +568,11 @@ stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non- void cm_print_lim(nvObj_t *nv); void cm_print_saf(nvObj_t *nv); - void cm_print_m48e(nvObj_t *nv); - void cm_print_mfoe(nvObj_t *nv); - void cm_print_mfo(nvObj_t *nv); - void cm_print_mtoe(nvObj_t *nv); - void cm_print_mto(nvObj_t *nv); +// void cm_print_m48e(nvObj_t *nv); + void cm_print_froe(nvObj_t *nv); + void cm_print_fro(nvObj_t *nv); + void cm_print_troe(nvObj_t *nv); + void cm_print_tro(nvObj_t *nv); void cm_print_tram(nvObj_t *nv); // print if the axis has been rotated diff --git a/g2core/config.cpp b/g2core/config.cpp index 0b468b9d..e6e73585 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -249,9 +249,12 @@ stat_t get_flt(nvObj_t *nv) * set_data() - set value as 32 bit integer blind cast * set_flt() - set value as float */ -//stat_t set_nul(nvObj_t *nv) { return (STAT_PARAMETER_IS_READ_ONLY); } -stat_t set_nul(nvObj_t *nv) { return (STAT_OK); } // hack until JSON is refactored +stat_t set_nul(nvObj_t *nv) { + nv->valuetype = TYPE_NULL; + return (STAT_PARAMETER_IS_READ_ONLY); // this is what it should be +// return (STAT_OK); // hack until JSON is refactored +} stat_t set_ui8(nvObj_t *nv) { *((uint8_t *)GET_TABLE_WORD(target)) = nv->value; diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index c102aad2..eeaad3a3 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -102,14 +102,14 @@ static stat_t get_tick(nvObj_t *nv); // get system tick count * the %f in the corresponding format string to set text mode display precision */ const cfgItem_t cfgArray[] = { - // group token flags p, print_func, get_func, set_func, target for get/set, default value - { "sys", "fb", _fipn,2, hw_print_fb, get_flt, set_nul, (float *)&cs.fw_build, G2CORE_FIRMWARE_BUILD }, // MUST BE FIRST! - { "sys", "fbs",_fn, 2, hw_print_fbs,hw_get_fbs,set_nul, (float *)&cs.null, 0 }, - { "sys", "fbc",_fn, 2, hw_print_fbc,hw_get_fbc,set_nul, (float *)&cs.null, 0 }, - { "sys", "fv", _fipn,2, hw_print_fv, get_flt, set_nul, (float *)&cs.fw_version, G2CORE_FIRMWARE_VERSION }, - { "sys", "hp", _fipn,0, hw_print_hp, get_flt, set_flt, (float *)&cs.hw_platform, G2CORE_HARDWARE_PLATFORM }, - { "sys", "hv", _fipn,0, hw_print_hv, get_flt, hw_set_hv,(float *)&cs.hw_version, G2CORE_HARDWARE_VERSION }, - { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_nul, (float *)&cs.null, 0 }, // device ID (ASCII signature) + // group token flags p, print_func, get_func, set_func, target for get/set, default value + { "sys", "fb", _fipn,2, hw_print_fb, get_flt, set_nul, (float *)&cs.fw_build, G2CORE_FIRMWARE_BUILD }, // MUST BE FIRST! + { "sys", "fbs",_fn, 2, hw_print_fbs, hw_get_fbs, set_nul, (float *)&cs.null, 0 }, + { "sys", "fbc",_fn, 2, hw_print_fbc, hw_get_fbc, set_nul, (float *)&cs.null, 0 }, + { "sys", "fv", _fipn,2, hw_print_fv, get_flt, set_nul, (float *)&cs.fw_version, G2CORE_FIRMWARE_VERSION }, + { "sys", "hp", _fipn,0, hw_print_hp, get_flt, set_nul, (float *)&cs.hw_platform, G2CORE_HARDWARE_PLATFORM }, + { "sys", "hv", _fipn,0, hw_print_hv, get_flt, set_nul, (float *)&cs.hw_version, G2CORE_HARDWARE_VERSION }, + { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_nul, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_nul,(float *)&cs.null, 0 }, // combined machine state @@ -603,19 +603,19 @@ const cfgItem_t cfgArray[] = { { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, - { "sys","sl", _fipn, 0, cm_print_sl, get_ui8, set_01, (float *)&cm->soft_limit_enable, SOFT_LIMIT_ENABLE }, - { "sys","lim", _fipn,0, cm_print_lim, get_ui8, set_01, (float *)&cm->limit_enable, HARD_LIMIT_ENABLE }, - { "sys","saf", _fipn,0, cm_print_saf, get_ui8, set_01, (float *)&cm->safety_interlock_enable, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable - { "sys","mfoe",_fipn,0, cm_print_mfoe,get_ui8, set_01, (float *)&cm->gmx.mfo_enable, FEED_OVERRIDE_ENABLE}, - { "sys","mfo", _fipn,3, cm_print_mfo, get_flt,cm_set_mfo,(float *)&cm->gmx.mfo_factor, FEED_OVERRIDE_FACTOR}, - { "sys","mtoe",_fipn,0, cm_print_mtoe,get_ui8, set_01, (float *)&cm->gmx.mto_enable, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","mto", _fipn,3, cm_print_mto, get_flt,cm_set_mto,(float *)&cm->gmx.mto_factor, TRAVERSE_OVERRIDE_FACTOR}, - { "sys","mt", _fipn,2, st_print_mt, get_flt, st_set_mt,(float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, - { "", "me", _f0, 0, st_print_me, get_nul, st_set_me,(float *)&cs.null, 0 }, // GET or SET to enable motors - { "", "md", _f0, 0, st_print_md, get_nul, st_set_md,(float *)&cs.null, 0 }, // GET or SET to disable motors + { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, + { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, + { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, + { "sys","lim", _fipn,0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, + { "sys","saf", _fipn,0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, + { "sys","froe",_fipn,0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, + { "sys","fro", _fipn,3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, + { "sys","troe",_fipn,0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","tro", _fipn,3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","mt", _fipn,2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, + { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors + { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors +// { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable // Spindle functions { "sys","spep",_fipn,0, cm_print_spep,get_ui8, set_01, (float *)&spindle.enable_polarity, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index e161831e..c9503fa0 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -34,6 +34,8 @@ #include "util.h" #include "xio.h" +#define JOGGING_START_VELOCITY ((float)10.0) + /**** Jogging singleton structure ****/ struct jmJoggingSingleton { // persistent jogging runtime variables diff --git a/g2core/plan_arc.h b/g2core/plan_arc.h index 77910258..6f65a871 100644 --- a/g2core/plan_arc.h +++ b/g2core/plan_arc.h @@ -30,6 +30,8 @@ #define ARC_RADIUS_ERROR_MIN ((float)0.005) // min mm where 1% rule applies #define ARC_RADIUS_TOLERANCE ((float)0.001) // 0.1% radius variance test +#define CHORDAL_TOLERANCE_MIN (0.001) // values below this are not accepted + typedef struct arArcSingleton { // persistent planner and runtime variables magic_t magic_start; uint8_t run_state; // runtime state machine sequence From e324cb49366fb7abc1a3ce006e8d8857f1c9d680 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 11 Dec 2016 17:47:19 -0500 Subject: [PATCH 033/283] Fixing some tests --- g2core/config_app.cpp | 3 ++- g2core/json_parser.cpp | 6 ++++-- g2core/settings/settings_default.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index eeaad3a3..771490c7 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -643,7 +643,7 @@ const cfgItem_t cfgArray[] = { { "sys","jv", _fipn, 0, js_print_jv, get_ui8, json_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY }, { "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_0123, (float *)&qr.queue_report_verbosity, QUEUE_REPORT_VERBOSITY }, { "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity,STATUS_REPORT_VERBOSITY }, - { "sys","si", _fipn, 0, sr_print_si, get_int32, sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, + { "sys","si", _fipn, 0, sr_print_si, get_int32,sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco @@ -1078,6 +1078,7 @@ stat_t get_int(nvObj_t *nv, const uint8_t value) { stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { if ((nv->value < low) || (nv->value > high)) { + nv->valuetype = TYPE_NULL; return (STAT_INPUT_VALUE_RANGE_ERROR); } value = nv->value; diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index c2605b89..3dbb2c87 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -614,8 +614,10 @@ void json_print_response(uint8_t status) stat_t json_set_jv(nvObj_t *nv) { - if ((uint8_t)nv->value >= JV_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} - js.json_verbosity = (jsonVerbosity)nv->value; +// if ((uint8_t)nv->value >= JV_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} +// js.json_verbosity = (jsonVerbosity)nv->value; + + ritorno (set_int(nv, (uint8_t &)js.json_verbosity, 0, JV_MAX_VALUE)); js.echo_json_footer = false; js.echo_json_messages = false; diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 3512f0b7..cea98cf3 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -153,7 +153,7 @@ #endif #ifndef STATUS_REPORT_MIN_MS -#define STATUS_REPORT_MIN_MS 200 // (no JSON) milliseconds - enforces a viable minimum +#define STATUS_REPORT_MIN_MS 100 // (no JSON) milliseconds - enforces a viable minimum #endif #ifndef STATUS_REPORT_INTERVAL_MS From d86fbe35ca2563b5f5fc2665014483cbc17837f5 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 12 Dec 2016 07:49:34 -0500 Subject: [PATCH 034/283] Continue to refactor accessors to remove them as a block to removing singletons; added error messages for inout values under/over range; added accessors for text verbosity --- g2core/config.cpp | 2 +- g2core/config_app.cpp | 37 +++++++++++++++++++++++++++++-------- g2core/g2core.cppproj | 8 ++++---- g2core/json_parser.cpp | 12 +++++------- g2core/json_parser.h | 4 ++-- g2core/text_parser.cpp | 13 +++++++++++++ g2core/text_parser.h | 3 +++ 7 files changed, 57 insertions(+), 22 deletions(-) mode change 100755 => 100644 g2core/json_parser.h mode change 100755 => 100644 g2core/text_parser.h diff --git a/g2core/config.cpp b/g2core/config.cpp index e6e73585..786ea4c2 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -682,7 +682,7 @@ nvObj_t *nv_add_string(const char *token, const char *string) // add a string ob nvObj_t *nv_add_conditional_message(const char *string) // conditionally add a message object to the body { - if ((js.json_mode == JSON_MODE) && (js.echo_json_messages != true)) { return (NULL);} + if ((js.json_mode == JSON_MODE) && (js.echo_json_messages != true)) { return (NULL); } return(nv_add_string((const char *)"msg", string)); } diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 771490c7..6d8f3a90 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -637,10 +637,10 @@ const cfgItem_t cfgArray[] = { // Communications and reporting parameters #ifdef __TEXT_MODE - { "sys","tv", _fipn, 0, tx_print_tv, get_ui8, set_01, (float *)&txt.text_verbosity, TEXT_VERBOSITY }, + { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, #endif - { "sys","ej", _fipn, 0, js_print_ej, get_ui8, json_set_ej,(float *)&cs.comm_mode, COMM_MODE }, - { "sys","jv", _fipn, 0, js_print_jv, get_ui8, json_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY }, + { "sys","ej", _fipn, 0, js_print_ej, get_ui8, js_set_ej,(float *)&cs.comm_mode, COMM_MODE }, + { "sys","jv", _fipn, 0, js_print_jv, get_ui8, js_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY }, { "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_0123, (float *)&qr.queue_report_verbosity, QUEUE_REPORT_VERBOSITY }, { "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity,STATUS_REPORT_VERBOSITY }, { "sys","si", _fipn, 0, sr_print_si, get_int32,sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, @@ -1055,10 +1055,21 @@ stat_t set_float(nvObj_t *nv, float &value) { } stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { + + char msg[64]; + process_incoming_float(nv); // conditional unit conversion - if ((nv->value < low) || (nv->value > high)) { + if (nv->value < low) { + sprintf(msg, "Input is less than minimum value %0.4f", low); + nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; - return (STAT_INPUT_VALUE_RANGE_ERROR); + return (STAT_INPUT_LESS_THAN_MIN_VALUE); + } + if (nv->value > high) { + sprintf(msg, "Input is more than maximum value %0.4f", high); + nv_add_conditional_message(msg); + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_EXCEEDS_MAX_VALUE); } value = nv->value; return (STAT_OK); @@ -1077,11 +1088,21 @@ stat_t get_int(nvObj_t *nv, const uint8_t value) { stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { - if ((nv->value < low) || (nv->value > high)) { + char msg[64]; + + if (nv->value < low) { + sprintf(msg, "Input is less than minimum value %d", (int)low); + nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; - return (STAT_INPUT_VALUE_RANGE_ERROR); + return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - value = nv->value; + if (nv->value > high) { + sprintf(msg, "Input is more than maximum value %d", (int)high); + nv_add_conditional_message(msg); + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + value = nv->value; // note: valuetype = TYPE_INT already set return (STAT_OK); } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 504c10bd..bf644c0b 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 7992324 SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800036434 + J41800030015 0x284E0A60 - 2000000 + 7992324 diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 3dbb2c87..51f14269 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -609,14 +609,11 @@ void json_print_response(uint8_t status) ***********************************************************************************/ /* - * json_set_jv() + * js_set_jv() */ -stat_t json_set_jv(nvObj_t *nv) +stat_t js_set_jv(nvObj_t *nv) { -// if ((uint8_t)nv->value >= JV_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} -// js.json_verbosity = (jsonVerbosity)nv->value; - ritorno (set_int(nv, (uint8_t &)js.json_verbosity, 0, JV_MAX_VALUE)); js.echo_json_footer = false; @@ -640,11 +637,12 @@ stat_t json_set_jv(nvObj_t *nv) } /* - * json_set_ej() - set JSON communications mode + * js_set_ej() - set JSON communications mode */ -stat_t json_set_ej(nvObj_t *nv) +stat_t js_set_ej(nvObj_t *nv) { +// ritorno (set_int(nv, cs.comm_mode, TEXT_MODE, AUTO_MODE)); if ((nv->value < TEXT_MODE) || (nv->value > AUTO_MODE)) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_VALUE_RANGE_ERROR); diff --git a/g2core/json_parser.h b/g2core/json_parser.h old mode 100755 new mode 100644 index e379ede3..e80ca5bf --- a/g2core/json_parser.h +++ b/g2core/json_parser.h @@ -88,8 +88,8 @@ void json_print_object(nvObj_t *nv); void json_print_response(uint8_t status); void json_print_list(stat_t status, uint8_t flags); -stat_t json_set_jv(nvObj_t *nv); -stat_t json_set_ej(nvObj_t *nv); +stat_t js_set_jv(nvObj_t *nv); +stat_t js_set_ej(nvObj_t *nv); #ifdef __TEXT_MODE diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index c731553d..7e085664 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -282,4 +282,17 @@ void text_print(nvObj_t *nv, const char *format) { static const char fmt_tv[] = "[tv] text verbosity%15d [0=silent,1=verbose]\n"; void tx_print_tv(nvObj_t *nv) { text_print(nv, fmt_tv);} // TYPE_INT +/*********************************************************************************** + * CONFIGURATION AND INTERFACE FUNCTIONS + * Functions to get and set variables from the cfgArray table + ***********************************************************************************/ + +/* + * txt_get_tv() - get text verbosity setting + * txt_set_tv() - set text verbosity + */ + +stat_t txt_get_tv(nvObj_t *nv) { return (get_int(nv, txt.text_verbosity)); } +stat_t txt_set_tv(nvObj_t *nv) { return (set_int(nv, txt.text_verbosity, TV_SILENT, TV_VERBOSE)); } + #endif // __TEXT_MODE diff --git a/g2core/text_parser.h b/g2core/text_parser.h old mode 100755 new mode 100644 index 6c300c94..2b37ea11 --- a/g2core/text_parser.h +++ b/g2core/text_parser.h @@ -95,4 +95,7 @@ stat_t text_parser_stub(char* str); void text_response_stub(const stat_t status, char* buf); void text_print_list_stub(stat_t status, uint8_t flags); +stat_t txt_get_tv(nvObj_t *nv); +stat_t txt_set_tv(nvObj_t *nv); + #endif // End of include guard: TEXT_PARSER_H_ONCE From 1eb5cad4c8a6e8b07cf1d01e3f2d26214014c68f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 12 Dec 2016 08:47:45 -0500 Subject: [PATCH 035/283] Intermediate commit for system version information refactor --- g2core/board/Archim/Archim-pinout.h | 3 +- g2core/board/Archim/board_stepper.cpp | 1 + g2core/board/Archim/board_stepper.h | 1 + g2core/board/Archim/board_xio.cpp | 1 + g2core/board/Archim/board_xio.h | 1 + g2core/board/Archim/hardware.cpp | 1 + g2core/board/Archim/hardware.h | 10 +++--- g2core/board/Archim/motate_pin_assignments.h | 3 +- g2core/board/G2v9/hardware.cpp | 38 +++++++++----------- g2core/board/G2v9/hardware.h | 23 ++++-------- g2core/board/sbv300/hardware.h | 5 --- g2core/config.h | 2 ++ g2core/config_app.cpp | 18 +++++++--- g2core/controller.cpp | 5 ++- g2core/controller.h | 7 ++-- g2core/g2core_info.h | 6 ++-- g2core/text_parser.cpp | 1 + 17 files changed, 64 insertions(+), 62 deletions(-) mode change 100755 => 100644 g2core/board/Archim/Archim-pinout.h mode change 100755 => 100644 g2core/board/Archim/board_stepper.cpp mode change 100755 => 100644 g2core/board/Archim/board_stepper.h mode change 100755 => 100644 g2core/board/Archim/board_xio.h mode change 100755 => 100644 g2core/board/Archim/hardware.cpp mode change 100755 => 100644 g2core/board/Archim/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/G2v9/hardware.cpp mode change 100755 => 100644 g2core/controller.h diff --git a/g2core/board/Archim/Archim-pinout.h b/g2core/board/Archim/Archim-pinout.h old mode 100755 new mode 100644 index 1d49ac1a..a6dd4523 --- a/g2core/board/Archim/Archim-pinout.h +++ b/g2core/board/Archim/Archim-pinout.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the Archim boards + * motate_pin_assignments.h - pin assignments + * For: g2core Archim boards * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/Archim/board_stepper.cpp b/g2core/board/Archim/board_stepper.cpp old mode 100755 new mode 100644 index b4c254c5..0c02da3f --- a/g2core/board/Archim/board_stepper.cpp +++ b/g2core/board/Archim/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: g2core Archim boards * This file is part of g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/Archim/board_stepper.h b/g2core/board/Archim/board_stepper.h old mode 100755 new mode 100644 index d59d6a2c..952578a2 --- a/g2core/board/Archim/board_stepper.h +++ b/g2core/board/Archim/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: g2core Archim boards * This file is part of g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/Archim/board_xio.cpp b/g2core/board/Archim/board_xio.cpp index 87ab4dd3..00f4d55c 100644 --- a/g2core/board/Archim/board_xio.cpp +++ b/g2core/board/Archim/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: g2core Archim boards * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/Archim/board_xio.h b/g2core/board/Archim/board_xio.h old mode 100755 new mode 100644 index 09f20fef..e948e18c --- a/g2core/board/Archim/board_xio.h +++ b/g2core/board/Archim/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: g2core Archim boards * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/Archim/hardware.cpp b/g2core/board/Archim/hardware.cpp old mode 100755 new mode 100644 index 11d740ef..896e4ae3 --- a/g2core/board/Archim/hardware.cpp +++ b/g2core/board/Archim/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: g2core Archim boards * This file is part of the g2core project * * Copyright (c) 2010 - 2015 Alden S. Hart, Jr. diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 9e88aee5..02de6df8 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -1,6 +1,7 @@ /* * hardware.h - system hardware configuration - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: g2core Archim boards + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -61,10 +62,9 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// +/************************* + * Motate Setup * + *************************/ #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... diff --git a/g2core/board/Archim/motate_pin_assignments.h b/g2core/board/Archim/motate_pin_assignments.h old mode 100755 new mode 100644 index 01226ae7..ecfef31d --- a/g2core/board/Archim/motate_pin_assignments.h +++ b/g2core/board/Archim/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the g2core Archim boards + * motate_pin_assignments.h + * For: g2core Archim boards * This file is part of the g2core project * * Copyright (c) 2013-2016 Robert Giseburt diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/hardware.cpp old mode 100755 new mode 100644 index 45d63c37..f17b9425 --- a/g2core/board/G2v9/hardware.cpp +++ b/g2core/board/G2v9/hardware.cpp @@ -94,15 +94,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, cs.hw_platform)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, cs.hw_version)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -140,20 +143,13 @@ stat_t hw_get_id(nvObj_t *nv) /* * hw_flash() - invoke FLASH loader from command input */ + stat_t hw_flash(nvObj_t *nv) { hw_flash_loader(); return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - /*********************************************************************************** * TEXT MODE SUPPORT @@ -163,21 +159,19 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; +static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; static const char fmt_fbs[] = "[fbs] firmware build \"%32s\"\n"; static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; +static const char fmt_hp[] = "[hp] hardware platform%15s\n"; +static const char fmt_hv[] = "[hv] hardware version%16s\n"; static const char fmt_id[] = "[id] g2core ID%21s\n"; void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT +void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT +void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING +void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index 7668b21d..7d857a81 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -37,20 +37,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "g2v9" // cannot exceed 15 bytes!!! +#define G2CORE_HARDWARE_VERSION "k" // cannot exceed 15 bytes!!! /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -177,6 +165,11 @@ stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t *nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); + stat_t hw_get_fbs(nvObj_t *nv); stat_t hw_get_fbc(nvObj_t *nv); stat_t hw_set_hv(nvObj_t *nv); @@ -188,7 +181,6 @@ stat_t hw_get_id(nvObj_t *nv); void hw_print_fbs(nvObj_t *nv); void hw_print_fbc(nvObj_t *nv); void hw_print_fv(nvObj_t *nv); - void hw_print_cv(nvObj_t *nv); void hw_print_hp(nvObj_t *nv); void hw_print_hv(nvObj_t *nv); void hw_print_id(nvObj_t *nv); @@ -199,7 +191,6 @@ stat_t hw_get_id(nvObj_t *nv); #define hw_print_fbs tx_print_stub #define hw_print_fbc tx_print_stub #define hw_print_fv tx_print_stub - #define hw_print_cv tx_print_stub #define hw_print_hp tx_print_stub #define hw_print_hv tx_print_stub #define hw_print_id tx_print_stub diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h index 0c1ce429..b98181c4 100644 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -61,11 +61,6 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// - #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... #include "MotateServiceCall.h" // for ServiceCall<> diff --git a/g2core/config.h b/g2core/config.h index 3be9d07b..9695cef0 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -363,6 +363,8 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving an integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); +stat_t get_string(nvObj_t *nv, const char *str); + // diagnostics void nv_dump_nv(nvObj_t *nv); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 6d8f3a90..772c4b1a 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -102,13 +102,13 @@ static stat_t get_tick(nvObj_t *nv); // get system tick count * the %f in the corresponding format string to set text mode display precision */ const cfgItem_t cfgArray[] = { - // group token flags p, print_func, get_func, set_func, target for get/set, default value - { "sys", "fb", _fipn,2, hw_print_fb, get_flt, set_nul, (float *)&cs.fw_build, G2CORE_FIRMWARE_BUILD }, // MUST BE FIRST! + // group token flags p, print_func, get_func, set_func, get/set target, default value + { "sys", "fb", _fipn,2, hw_print_fb, hw_get_fb, set_nul, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! + { "sys", "fv", _fipn,2, hw_print_fv, hw_get_fv, set_nul, (float *)&cs.null, 0 }, { "sys", "fbs",_fn, 2, hw_print_fbs, hw_get_fbs, set_nul, (float *)&cs.null, 0 }, { "sys", "fbc",_fn, 2, hw_print_fbc, hw_get_fbc, set_nul, (float *)&cs.null, 0 }, - { "sys", "fv", _fipn,2, hw_print_fv, get_flt, set_nul, (float *)&cs.fw_version, G2CORE_FIRMWARE_VERSION }, - { "sys", "hp", _fipn,0, hw_print_hp, get_flt, set_nul, (float *)&cs.hw_platform, G2CORE_HARDWARE_PLATFORM }, - { "sys", "hv", _fipn,0, hw_print_hv, get_flt, set_nul, (float *)&cs.hw_version, G2CORE_HARDWARE_VERSION }, + { "sys", "hp", _fipn,0, hw_print_hp, hw_get_hp, set_nul, (float *)&cs.null, 0 }, + { "sys", "hv", _fipn,0, hw_print_hv, hw_get_hv, set_nul, (float *)&cs.null, 0 }, { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_nul, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) @@ -1106,7 +1106,15 @@ stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { return (STAT_OK); } +/* + * get_string() - boilerplate for retrieving a string value + */ +stat_t get_string(nvObj_t *nv, const char *str) +{ + nv->valuetype = TYPE_STRING; + return (nv_copy_string(nv, str)); +} /* * nv_group_is_prefixed() - hack diff --git a/g2core/controller.cpp b/g2core/controller.cpp index b41f37ff..3ac3fe02 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -95,7 +95,10 @@ void controller_init() cs.comm_mode = comm_mode; // restore parameters cs.fw_build = G2CORE_FIRMWARE_BUILD; // set up identification cs.fw_version = G2CORE_FIRMWARE_VERSION; - cs.hw_platform = G2CORE_HARDWARE_PLATFORM; // NB: HW version is set from EEPROM +// cs.hw_platform = G2CORE_HARDWARE_PLATFORM; + strncpy(cs.hw_platform, G2CORE_HARDWARE_PLATFORM, HARDWARE_STRING); + strncpy(cs.hw_version, G2CORE_HARDWARE_VERSION, HARDWARE_STRING); + cs.controller_state = CONTROLLER_STARTUP; // ready to run startup lines if (xio_connected()) { cs.controller_state = CONTROLLER_CONNECTED; diff --git a/g2core/controller.h b/g2core/controller.h old mode 100755 new mode 100644 index e7e2f01e..10d8b930 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -32,6 +32,7 @@ #define SAVED_BUFFER_LEN 80 // saved buffer size (for reporting only) #define MAXED_BUFFER_LEN 255 // same as streaming RX buffer size as a worst case #define OUTPUT_BUFFER_LEN 512 // text buffer size +#define HARDWARE_STRING 16 // max length for hw platform and version is 15 chars #define LED_NORMAL_BLINK_RATE 3000 // blink rate for normal operation (in ms) #define LED_ALARM_BLINK_RATE 750 // blink rate for alarm state (in ms) @@ -54,8 +55,10 @@ typedef struct controllerSingleton { // main TG controller struct // system identification values float fw_build; // firmware build number float fw_version; // firmware version number - float hw_platform; // hardware compatibility - platform type - float hw_version; // hardware compatibility - platform revision +// float hw_platform; // hardware compatibility - platform type +// float hw_version; // hardware compatibility - platform revision + char hw_platform[HARDWARE_STRING]; // hardware compatibility - platform type + char hw_version[HARDWARE_STRING]; // hardware compatibility - platform revision // system state variables csControllerState controller_state; diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index f9a5344a..6f43755e 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -22,14 +22,12 @@ #define G2CORE_INFO_H_ONCE #define G2CORE_FIRMWARE_BUILD 100.12 // Changes to USB serial for SAMS70 and SAM8X targets +#define G2CORE_FIRMWARE_VERSION 0.99 // firmware major version + #ifdef GIT_VERSION #define G2CORE_FIRMWARE_BUILD_STRING GIT_VERSION #else #define G2CORE_FIRMWARE_BUILD_STRING "unknown" #endif -#define G2CORE_FIRMWARE_VERSION 0.99 // firmware major version -#define G2CORE_HARDWARE_PLATFORM HW_PLATFORM_V9 // hardware platform indicator (2 = Native Arduino Due) -#define G2CORE_HARDWARE_VERSION HW_VERSION_TINYGV9K // hardware platform revision number -#define G2CORE_HARDWARE_VERSION_MAX (G2CORE_HARDWARE_VERSION) #endif // G2CORE_INFO_H_ONCE diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index 7e085664..c8abcd85 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -282,6 +282,7 @@ void text_print(nvObj_t *nv, const char *format) { static const char fmt_tv[] = "[tv] text verbosity%15d [0=silent,1=verbose]\n"; void tx_print_tv(nvObj_t *nv) { text_print(nv, fmt_tv);} // TYPE_INT + /*********************************************************************************** * CONFIGURATION AND INTERFACE FUNCTIONS * Functions to get and set variables from the cfgArray table From 78f2a9273f26df2e54f20d8f32d2bcea28c41cf9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 12 Dec 2016 09:38:42 -0500 Subject: [PATCH 036/283] Fixed a bug in text mode displays of string data --- g2core/board/G2v9/hardware.cpp | 8 ++++---- g2core/config_app.cpp | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/hardware.cpp index f17b9425..d1fa874a 100644 --- a/g2core/board/G2v9/hardware.cpp +++ b/g2core/board/G2v9/hardware.cpp @@ -160,11 +160,11 @@ stat_t hw_flash(nvObj_t *nv) static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%32s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; +static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; +static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; static const char fmt_hp[] = "[hp] hardware platform%15s\n"; -static const char fmt_hv[] = "[hv] hardware version%16s\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; +static const char fmt_hv[] = "[hv] hardware version%13s\n"; +static const char fmt_id[] = "[id] g2core ID%37s\n"; void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 772c4b1a..6a6e2990 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -105,10 +105,10 @@ const cfgItem_t cfgArray[] = { // group token flags p, print_func, get_func, set_func, get/set target, default value { "sys", "fb", _fipn,2, hw_print_fb, hw_get_fb, set_nul, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! { "sys", "fv", _fipn,2, hw_print_fv, hw_get_fv, set_nul, (float *)&cs.null, 0 }, - { "sys", "fbs",_fn, 2, hw_print_fbs, hw_get_fbs, set_nul, (float *)&cs.null, 0 }, - { "sys", "fbc",_fn, 2, hw_print_fbc, hw_get_fbc, set_nul, (float *)&cs.null, 0 }, - { "sys", "hp", _fipn,0, hw_print_hp, hw_get_hp, set_nul, (float *)&cs.null, 0 }, - { "sys", "hv", _fipn,0, hw_print_hv, hw_get_hv, set_nul, (float *)&cs.null, 0 }, + { "sys", "fbs",_fn, 0, hw_print_fbs, hw_get_fbs, set_nul, (float *)&cs.null, 0 }, + { "sys", "fbc",_fn, 0, hw_print_fbc, hw_get_fbc, set_nul, (float *)&cs.null, 0 }, + { "sys", "hp", _fn, 0, hw_print_hp, hw_get_hp, set_nul, (float *)&cs.null, 0 }, + { "sys", "hv", _fn, 0, hw_print_hv, hw_get_hv, set_nul, (float *)&cs.null, 0 }, { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_nul, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) @@ -1012,6 +1012,8 @@ stat_t set_flu(nvObj_t *nv) void process_incoming_float(nvObj_t *nv) { + if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type + uint8_t f; f = GET_TABLE_BYTE(flags); // if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? @@ -1024,10 +1026,13 @@ void process_incoming_float(nvObj_t *nv) } } -void process_outgoing_float(nvObj_t *nv) +void process_outgoing_float(nvObj_t *nv) { + if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type + if (isnan((double)nv->value) || isinf((double)nv->value)) { return; } // trap illegal float values + ///+++ transform these checks into NaN or INF strings with an error return? + uint8_t f; - if (isnan((double)nv->value) || isinf((double)nv->value)) return; // illegal float values f = GET_TABLE_BYTE(flags); if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? if (cm_get_units_mode(MODEL) == INCHES) { @@ -1041,6 +1046,7 @@ void process_outgoing_float(nvObj_t *nv) nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; } + stat_t get_float(nvObj_t *nv, const float value) { nv->value = value; nv->valuetype = TYPE_FLOAT; From 6722e1fa99c7259e348b5955cd0016e50bc57a1d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 12 Dec 2016 14:26:55 -0500 Subject: [PATCH 037/283] Changed hardware platform and hardware version to strings --- g2core/board/Archim/Archim-pinout.h | 2 +- g2core/board/Archim/board_stepper.cpp | 2 +- g2core/board/Archim/board_stepper.h | 2 +- g2core/board/Archim/board_xio.cpp | 2 +- g2core/board/Archim/board_xio.h | 2 +- g2core/board/Archim/hardware.cpp | 56 +++++++-------- g2core/board/Archim/hardware.h | 59 +++++++-------- g2core/board/Archim/motate_pin_assignments.h | 2 +- g2core/board/ArduinoDue/board_stepper.cpp | 1 + g2core/board/ArduinoDue/board_stepper.h | 1 + g2core/board/ArduinoDue/board_xio.cpp | 1 + g2core/board/ArduinoDue/board_xio.h | 1 + g2core/board/ArduinoDue/gShield-pinout.h | 3 +- g2core/board/ArduinoDue/hardware.cpp | 69 ++++++++---------- g2core/board/ArduinoDue/hardware.h | 37 ++++------ .../board/ArduinoDue/motate_pin_assignments.h | 3 +- .../board/ArduinoDue/shopbotShield-pinout.h | 1 + g2core/board/G2v9/G2v9k-pinout.h | 1 + g2core/board/G2v9/board_stepper.cpp | 1 + g2core/board/G2v9/board_stepper.h | 1 + g2core/board/G2v9/board_xio.cpp | 1 + g2core/board/G2v9/board_xio.h | 1 + g2core/board/G2v9/hardware.cpp | 47 ++++++------ g2core/board/G2v9/hardware.h | 39 +++++----- g2core/board/G2v9/motate_pin_assignments.h | 3 +- g2core/board/gquadratic/board_stepper.cpp | 1 + g2core/board/gquadratic/board_stepper.h | 1 + g2core/board/gquadratic/board_xio.cpp | 1 + g2core/board/gquadratic/board_xio.h | 1 + g2core/board/gquadratic/gquadratic-b-pinout.h | 1 + g2core/board/gquadratic/hardware.cpp | 56 +++++++-------- g2core/board/gquadratic/hardware.h | 72 ++++++++----------- .../board/gquadratic/motate_pin_assignments.h | 3 +- g2core/board/gquintic/board_stepper.cpp | 1 + g2core/board/gquintic/board_stepper.h | 1 + g2core/board/gquintic/board_xio.cpp | 1 + g2core/board/gquintic/board_xio.h | 1 + g2core/board/gquintic/gquintic-b-pinout.h | 1 + g2core/board/gquintic/hardware.cpp | 56 +++++++-------- g2core/board/gquintic/hardware.h | 37 ++++------ .../board/gquintic/motate_pin_assignments.h | 3 +- g2core/board/printrboardg2/board_stepper.cpp | 1 + g2core/board/printrboardg2/board_stepper.h | 1 + g2core/board/printrboardg2/board_xio.cpp | 1 + g2core/board/printrboardg2/board_xio.h | 1 + g2core/board/printrboardg2/hardware.cpp | 56 +++++++-------- g2core/board/printrboardg2/hardware.h | 66 ++++++++--------- .../printrboardg2/motate_pin_assignments.h | 3 +- .../printrboardg2/printrboardG2v3-pinout.h | 1 + g2core/board/sbv300/board_stepper.cpp | 1 + g2core/board/sbv300/board_stepper.h | 1 + g2core/board/sbv300/board_xio.cpp | 1 + g2core/board/sbv300/board_xio.h | 1 + g2core/board/sbv300/hardware.cpp | 55 +++++++------- g2core/board/sbv300/hardware.h | 34 ++++----- g2core/board/sbv300/motate_pin_assignments.h | 3 +- g2core/board/sbv300/sbv300-pinout.h | 1 + g2core/controller.cpp | 3 - g2core/controller.h | 5 -- 59 files changed, 367 insertions(+), 443 deletions(-) mode change 100755 => 100644 g2core/board/ArduinoDue/board_stepper.cpp mode change 100755 => 100644 g2core/board/ArduinoDue/board_stepper.h mode change 100755 => 100644 g2core/board/ArduinoDue/board_xio.cpp mode change 100755 => 100644 g2core/board/ArduinoDue/board_xio.h mode change 100755 => 100644 g2core/board/ArduinoDue/gShield-pinout.h mode change 100755 => 100644 g2core/board/ArduinoDue/hardware.cpp mode change 100755 => 100644 g2core/board/ArduinoDue/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/ArduinoDue/shopbotShield-pinout.h mode change 100755 => 100644 g2core/board/G2v9/G2v9k-pinout.h mode change 100755 => 100644 g2core/board/G2v9/board_stepper.cpp mode change 100755 => 100644 g2core/board/G2v9/board_stepper.h mode change 100755 => 100644 g2core/board/G2v9/board_xio.cpp mode change 100755 => 100644 g2core/board/G2v9/board_xio.h mode change 100755 => 100644 g2core/board/G2v9/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/gquadratic/board_stepper.cpp mode change 100755 => 100644 g2core/board/gquadratic/board_stepper.h mode change 100755 => 100644 g2core/board/gquadratic/board_xio.cpp mode change 100755 => 100644 g2core/board/gquadratic/board_xio.h mode change 100755 => 100644 g2core/board/gquadratic/gquadratic-b-pinout.h mode change 100755 => 100644 g2core/board/gquadratic/hardware.cpp mode change 100755 => 100644 g2core/board/gquadratic/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/gquintic/board_stepper.cpp mode change 100755 => 100644 g2core/board/gquintic/board_stepper.h mode change 100755 => 100644 g2core/board/gquintic/board_xio.cpp mode change 100755 => 100644 g2core/board/gquintic/board_xio.h mode change 100755 => 100644 g2core/board/gquintic/gquintic-b-pinout.h mode change 100755 => 100644 g2core/board/gquintic/hardware.cpp mode change 100755 => 100644 g2core/board/gquintic/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/printrboardg2/board_stepper.cpp mode change 100755 => 100644 g2core/board/printrboardg2/board_stepper.h mode change 100755 => 100644 g2core/board/printrboardg2/board_xio.cpp mode change 100755 => 100644 g2core/board/printrboardg2/board_xio.h mode change 100755 => 100644 g2core/board/printrboardg2/hardware.cpp mode change 100755 => 100644 g2core/board/printrboardg2/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/printrboardg2/printrboardG2v3-pinout.h mode change 100755 => 100644 g2core/board/sbv300/board_stepper.cpp mode change 100755 => 100644 g2core/board/sbv300/board_stepper.h mode change 100755 => 100644 g2core/board/sbv300/board_xio.cpp mode change 100755 => 100644 g2core/board/sbv300/board_xio.h mode change 100755 => 100644 g2core/board/sbv300/hardware.cpp mode change 100755 => 100644 g2core/board/sbv300/motate_pin_assignments.h mode change 100755 => 100644 g2core/board/sbv300/sbv300-pinout.h diff --git a/g2core/board/Archim/Archim-pinout.h b/g2core/board/Archim/Archim-pinout.h index a6dd4523..566d26e1 100644 --- a/g2core/board/Archim/Archim-pinout.h +++ b/g2core/board/Archim/Archim-pinout.h @@ -1,6 +1,6 @@ /* * motate_pin_assignments.h - pin assignments - * For: g2core Archim boards + * For: /board/Archim * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/Archim/board_stepper.cpp b/g2core/board/Archim/board_stepper.cpp index 0c02da3f..df6f01a0 100644 --- a/g2core/board/Archim/board_stepper.cpp +++ b/g2core/board/Archim/board_stepper.cpp @@ -1,6 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp - * For: g2core Archim boards + * For: /board/Archim * This file is part of g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/Archim/board_stepper.h b/g2core/board/Archim/board_stepper.h index 952578a2..2b13fc69 100644 --- a/g2core/board/Archim/board_stepper.h +++ b/g2core/board/Archim/board_stepper.h @@ -1,6 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h - * For: g2core Archim boards + * For: /board/Archim * This file is part of g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/Archim/board_xio.cpp b/g2core/board/Archim/board_xio.cpp index 00f4d55c..e2e5206f 100644 --- a/g2core/board/Archim/board_xio.cpp +++ b/g2core/board/Archim/board_xio.cpp @@ -1,6 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific - * For: g2core Archim boards + * For: /board/Archim * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/Archim/board_xio.h b/g2core/board/Archim/board_xio.h index e948e18c..1fdaddf7 100644 --- a/g2core/board/Archim/board_xio.h +++ b/g2core/board/Archim/board_xio.h @@ -1,6 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific - * For: g2core Archim boards + * For: /board/Archim * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/Archim/hardware.cpp b/g2core/board/Archim/hardware.cpp index 896e4ae3..fc71ff3b 100644 --- a/g2core/board/Archim/hardware.cpp +++ b/g2core/board/Archim/hardware.cpp @@ -1,6 +1,6 @@ /* * hardware.cpp - general hardware support functions - * For: g2core Archim boards + * For: /board/Archim * This file is part of the g2core project * * Copyright (c) 2010 - 2015 Alden S. Hart, Jr. @@ -93,15 +93,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -145,15 +148,6 @@ stat_t hw_flash(nvObj_t *nv) return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table @@ -161,22 +155,20 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 02de6df8..493e0fd8 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -1,6 +1,6 @@ /* * hardware.h - system hardware configuration - * For: g2core Archim boards + * For: /board/Archim * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project @@ -37,20 +37,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "Archim" +#define G2CORE_HARDWARE_VERSION "na" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -174,32 +162,33 @@ stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t* nv); -stat_t hw_get_fbs(nvObj_t* nv); -stat_t hw_get_fbc(nvObj_t* nv); -stat_t hw_set_hv(nvObj_t* nv); -stat_t hw_get_id(nvObj_t* nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); +stat_t hw_get_fbs(nvObj_t *nv); +stat_t hw_get_fbc(nvObj_t *nv); +stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE -void hw_print_fb(nvObj_t* nv); -void hw_print_fbs(nvObj_t* nv); -void hw_print_fbc(nvObj_t* nv); -void hw_print_fv(nvObj_t* nv); -void hw_print_cv(nvObj_t* nv); -void hw_print_hp(nvObj_t* nv); -void hw_print_hv(nvObj_t* nv); -void hw_print_id(nvObj_t* nv); + void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); + void hw_print_fbs(nvObj_t *nv); + void hw_print_fbc(nvObj_t *nv); + void hw_print_hp(nvObj_t *nv); + void hw_print_hv(nvObj_t *nv); + void hw_print_id(nvObj_t *nv); #else -#define hw_print_fb tx_print_stub -#define hw_print_fbs tx_print_stub -#define hw_print_fbc tx_print_stub -#define hw_print_fv tx_print_stub -#define hw_print_cv tx_print_stub -#define hw_print_hp tx_print_stub -#define hw_print_hv tx_print_stub -#define hw_print_id tx_print_stub + #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub + #define hw_print_fbs tx_print_stub + #define hw_print_fbc tx_print_stub + #define hw_print_hp tx_print_stub + #define hw_print_hv tx_print_stub + #define hw_print_id tx_print_stub #endif // __TEXT_MODE diff --git a/g2core/board/Archim/motate_pin_assignments.h b/g2core/board/Archim/motate_pin_assignments.h index ecfef31d..a4562464 100644 --- a/g2core/board/Archim/motate_pin_assignments.h +++ b/g2core/board/Archim/motate_pin_assignments.h @@ -1,6 +1,6 @@ /* * motate_pin_assignments.h - * For: g2core Archim boards + * For: /board/Archim * This file is part of the g2core project * * Copyright (c) 2013-2016 Robert Giseburt diff --git a/g2core/board/ArduinoDue/board_stepper.cpp b/g2core/board/ArduinoDue/board_stepper.cpp old mode 100755 new mode 100644 index 0583e4e7..ee53a1fb --- a/g2core/board/ArduinoDue/board_stepper.cpp +++ b/g2core/board/ArduinoDue/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/ArduinoDue/board_stepper.h b/g2core/board/ArduinoDue/board_stepper.h old mode 100755 new mode 100644 index 25c5d01b..a1e9e328 --- a/g2core/board/ArduinoDue/board_stepper.h +++ b/g2core/board/ArduinoDue/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/ArduinoDue/board_xio.cpp b/g2core/board/ArduinoDue/board_xio.cpp old mode 100755 new mode 100644 index 7f2a0774..9221ca55 --- a/g2core/board/ArduinoDue/board_xio.cpp +++ b/g2core/board/ArduinoDue/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/ArduinoDue/board_xio.h b/g2core/board/ArduinoDue/board_xio.h old mode 100755 new mode 100644 index 31afd8c8..8503d859 --- a/g2core/board/ArduinoDue/board_xio.h +++ b/g2core/board/ArduinoDue/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/ArduinoDue/gShield-pinout.h b/g2core/board/ArduinoDue/gShield-pinout.h old mode 100755 new mode 100644 index 314ef41e..d10dfeba --- a/g2core/board/ArduinoDue/gShield-pinout.h +++ b/g2core/board/ArduinoDue/gShield-pinout.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for g2 v9 boards + * motate_pin_assignments.h - pin assignments + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/ArduinoDue/hardware.cpp b/g2core/board/ArduinoDue/hardware.cpp old mode 100755 new mode 100644 index c688872a..e4b3662d --- a/g2core/board/ArduinoDue/hardware.cpp +++ b/g2core/board/ArduinoDue/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. @@ -94,15 +95,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -111,15 +115,15 @@ stat_t hw_get_fbs(nvObj_t *nv) stat_t hw_get_fbc(nvObj_t *nv) { nv->valuetype = TYPE_STRING; - #ifdef SETTINGS_FILE - #define settings_file_string1(s) #s - #define settings_file_string2(s) settings_file_string1(s) +#ifdef SETTINGS_FILE +#define settings_file_string1(s) #s +#define settings_file_string2(s) settings_file_string1(s) ritorno(nv_copy_string(nv, settings_file_string2(SETTINGS_FILE))); - #undef settings_file_string1 - #undef settings_file_string2 - #else +#undef settings_file_string1 +#undef settings_file_string2 +#else ritorno(nv_copy_string(nv, "")); - #endif + #endif return (STAT_OK); } @@ -146,15 +150,6 @@ stat_t hw_flash(nvObj_t *nv) return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table @@ -162,22 +157,20 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h index e6022d85..3c9590ba 100644 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -1,6 +1,7 @@ /* * hardware.h - system hardware configuration - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: /board/ArduinoDue + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -36,20 +37,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "ArduinoDue" +#define G2CORE_HARDWARE_VERSION "na" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -61,10 +50,9 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// +/************************* + * Motate Setup * + *************************/ // ARM specific code start here @@ -176,18 +164,20 @@ stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t *nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); stat_t hw_get_fbs(nvObj_t *nv); stat_t hw_get_fbc(nvObj_t *nv); -stat_t hw_set_hv(nvObj_t *nv); stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); void hw_print_fbs(nvObj_t *nv); void hw_print_fbc(nvObj_t *nv); - void hw_print_fv(nvObj_t *nv); - void hw_print_cv(nvObj_t *nv); void hw_print_hp(nvObj_t *nv); void hw_print_hv(nvObj_t *nv); void hw_print_id(nvObj_t *nv); @@ -195,10 +185,9 @@ stat_t hw_get_id(nvObj_t *nv); #else #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub #define hw_print_fbs tx_print_stub #define hw_print_fbc tx_print_stub - #define hw_print_fv tx_print_stub - #define hw_print_cv tx_print_stub #define hw_print_hp tx_print_stub #define hw_print_hv tx_print_stub #define hw_print_id tx_print_stub diff --git a/g2core/board/ArduinoDue/motate_pin_assignments.h b/g2core/board/ArduinoDue/motate_pin_assignments.h old mode 100755 new mode 100644 index 0df31f5e..9a5ab0e6 --- a/g2core/board/ArduinoDue/motate_pin_assignments.h +++ b/g2core/board/ArduinoDue/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the g2core shopbotShield boards + * motate_pin_assignments.h - pin assignments + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2013-2016 Robert Giseburt diff --git a/g2core/board/ArduinoDue/shopbotShield-pinout.h b/g2core/board/ArduinoDue/shopbotShield-pinout.h old mode 100755 new mode 100644 index b9ba361e..769e0668 --- a/g2core/board/ArduinoDue/shopbotShield-pinout.h +++ b/g2core/board/ArduinoDue/shopbotShield-pinout.h @@ -1,5 +1,6 @@ /* * shopbotShield-pinout.h - board pinout specification + * For: /board/ArduinoDue * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/G2v9/G2v9k-pinout.h b/g2core/board/G2v9/G2v9k-pinout.h old mode 100755 new mode 100644 index 2e37c76b..8dabc6b6 --- a/g2core/board/G2v9/G2v9k-pinout.h +++ b/g2core/board/G2v9/G2v9k-pinout.h @@ -1,5 +1,6 @@ /* * g2v9k-pinout.h - board pinout specification + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/G2v9/board_stepper.cpp b/g2core/board/G2v9/board_stepper.cpp old mode 100755 new mode 100644 index 0583e4e7..d5730c0f --- a/g2core/board/G2v9/board_stepper.cpp +++ b/g2core/board/G2v9/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/G2v9/board_stepper.h b/g2core/board/G2v9/board_stepper.h old mode 100755 new mode 100644 index 25c5d01b..8ea314cd --- a/g2core/board/G2v9/board_stepper.h +++ b/g2core/board/G2v9/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/G2v9/board_xio.cpp b/g2core/board/G2v9/board_xio.cpp old mode 100755 new mode 100644 index 09ccaf80..34f394fa --- a/g2core/board/G2v9/board_xio.cpp +++ b/g2core/board/G2v9/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/G2v9/board_xio.h b/g2core/board/G2v9/board_xio.h old mode 100755 new mode 100644 index 09f20fef..97a2ce14 --- a/g2core/board/G2v9/board_xio.h +++ b/g2core/board/G2v9/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/hardware.cpp index d1fa874a..6522ee56 100644 --- a/g2core/board/G2v9/hardware.cpp +++ b/g2core/board/G2v9/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. @@ -103,8 +104,8 @@ void _get_id(char *id) stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } -stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, cs.hw_platform)); } -stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, cs.hw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* @@ -114,15 +115,15 @@ stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_ST stat_t hw_get_fbc(nvObj_t *nv) { nv->valuetype = TYPE_STRING; - #ifdef SETTINGS_FILE - #define settings_file_string1(s) #s - #define settings_file_string2(s) settings_file_string1(s) +#ifdef SETTINGS_FILE +#define settings_file_string1(s) #s +#define settings_file_string2(s) settings_file_string1(s) ritorno(nv_copy_string(nv, settings_file_string2(SETTINGS_FILE))); - #undef settings_file_string1 - #undef settings_file_string2 - #else +#undef settings_file_string1 +#undef settings_file_string2 +#else ritorno(nv_copy_string(nv, "")); - #endif +#endif return (STAT_OK); } @@ -158,20 +159,20 @@ stat_t hw_flash(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; -static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; -static const char fmt_hp[] = "[hp] hardware platform%15s\n"; -static const char fmt_hv[] = "[hv] hardware version%13s\n"; -static const char fmt_id[] = "[id] g2core ID%37s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index 7d857a81..7532b254 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -1,7 +1,7 @@ /* * hardware.h - system hardware configuration - * for: /board/g2v9 - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: /board/g2v9 + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -37,8 +37,8 @@ /*--- Hardware platform enumerations ---*/ -#define G2CORE_HARDWARE_PLATFORM "g2v9" // cannot exceed 15 bytes!!! -#define G2CORE_HARDWARE_VERSION "k" // cannot exceed 15 bytes!!! +#define G2CORE_HARDWARE_PLATFORM "g2v9" +#define G2CORE_HARDWARE_VERSION "k" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -50,12 +50,9 @@ #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// - -// ARM specific code start here +/************************* + * Motate Setup * + *************************/ #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... @@ -172,28 +169,28 @@ stat_t hw_get_hv(nvObj_t *nv); stat_t hw_get_fbs(nvObj_t *nv); stat_t hw_get_fbc(nvObj_t *nv); -stat_t hw_set_hv(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE - void hw_print_fb(nvObj_t *nv); + void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); void hw_print_fbs(nvObj_t *nv); void hw_print_fbc(nvObj_t *nv); - void hw_print_fv(nvObj_t *nv); - void hw_print_hp(nvObj_t *nv); - void hw_print_hv(nvObj_t *nv); - void hw_print_id(nvObj_t *nv); + void hw_print_hp(nvObj_t *nv); + void hw_print_hv(nvObj_t *nv); + void hw_print_id(nvObj_t *nv); #else - #define hw_print_fb tx_print_stub + #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub #define hw_print_fbs tx_print_stub #define hw_print_fbc tx_print_stub - #define hw_print_fv tx_print_stub - #define hw_print_hp tx_print_stub - #define hw_print_hv tx_print_stub - #define hw_print_id tx_print_stub + #define hw_print_hp tx_print_stub + #define hw_print_hv tx_print_stub + #define hw_print_id tx_print_stub #endif // __TEXT_MODE diff --git a/g2core/board/G2v9/motate_pin_assignments.h b/g2core/board/G2v9/motate_pin_assignments.h old mode 100755 new mode 100644 index 4239e8e0..cf3f4f4a --- a/g2core/board/G2v9/motate_pin_assignments.h +++ b/g2core/board/G2v9/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the g2core g2v9 boards + * motate_pin_assignments.h - pin assignments + * For: /board/g2v9 * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/gquadratic/board_stepper.cpp b/g2core/board/gquadratic/board_stepper.cpp old mode 100755 new mode 100644 index bc927558..4fef4c3b --- a/g2core/board/gquadratic/board_stepper.cpp +++ b/g2core/board/gquadratic/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/gquadratic/board_stepper.h b/g2core/board/gquadratic/board_stepper.h old mode 100755 new mode 100644 index 6e044efa..f8b2bb75 --- a/g2core/board/gquadratic/board_stepper.h +++ b/g2core/board/gquadratic/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/gquadratic/board_xio.cpp b/g2core/board/gquadratic/board_xio.cpp old mode 100755 new mode 100644 index 8b4835b2..80506161 --- a/g2core/board/gquadratic/board_xio.cpp +++ b/g2core/board/gquadratic/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/gquadratic/board_xio.h b/g2core/board/gquadratic/board_xio.h old mode 100755 new mode 100644 index 09f20fef..0c526b5d --- a/g2core/board/gquadratic/board_xio.h +++ b/g2core/board/gquadratic/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/gquadratic/gquadratic-b-pinout.h b/g2core/board/gquadratic/gquadratic-b-pinout.h old mode 100755 new mode 100644 index 0eaa3c5d..e6b536e0 --- a/g2core/board/gquadratic/gquadratic-b-pinout.h +++ b/g2core/board/gquadratic/gquadratic-b-pinout.h @@ -1,5 +1,6 @@ /* * gquadratic-b-pinout.h - board pinout specification + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2016 Robert Giseburt diff --git a/g2core/board/gquadratic/hardware.cpp b/g2core/board/gquadratic/hardware.cpp old mode 100755 new mode 100644 index f40a7928..2963d328 --- a/g2core/board/gquadratic/hardware.cpp +++ b/g2core/board/gquadratic/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2010 - 2015 Alden S. Hart, Jr. @@ -162,15 +163,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -214,15 +218,6 @@ stat_t hw_flash(nvObj_t *nv) return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table @@ -230,22 +225,21 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE + diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index dc87fbee..b26e95e0 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -1,6 +1,7 @@ /* * hardware.h - system hardware configuration - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: /board/gQuadratic + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -37,20 +38,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "gQuadtratic" +#define G2CORE_HARDWARE_VERSION "b" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -62,12 +51,9 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// - -// ARM specific code start here +/************************* + * Motate Setup * + *************************/ #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... @@ -172,33 +158,35 @@ stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t* nv); -stat_t hw_get_fbs(nvObj_t* nv); -stat_t hw_get_fbc(nvObj_t* nv); -stat_t hw_set_hv(nvObj_t* nv); -stat_t hw_get_id(nvObj_t* nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); +stat_t hw_get_fbs(nvObj_t *nv); +stat_t hw_get_fbc(nvObj_t *nv); +stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE -void hw_print_fb(nvObj_t* nv); -void hw_print_fbs(nvObj_t* nv); -void hw_print_fbc(nvObj_t* nv); -void hw_print_fv(nvObj_t* nv); -void hw_print_cv(nvObj_t* nv); -void hw_print_hp(nvObj_t* nv); -void hw_print_hv(nvObj_t* nv); -void hw_print_id(nvObj_t* nv); + void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); + void hw_print_fbs(nvObj_t *nv); + void hw_print_fbc(nvObj_t *nv); + void hw_print_hp(nvObj_t *nv); + void hw_print_hv(nvObj_t *nv); + void hw_print_id(nvObj_t *nv); #else -#define hw_print_fb tx_print_stub -#define hw_print_fbs tx_print_stub -#define hw_print_fbc tx_print_stub -#define hw_print_fv tx_print_stub -#define hw_print_cv tx_print_stub -#define hw_print_hp tx_print_stub -#define hw_print_hv tx_print_stub -#define hw_print_id tx_print_stub + #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub + #define hw_print_fbs tx_print_stub + #define hw_print_fbc tx_print_stub + #define hw_print_hp tx_print_stub + #define hw_print_hv tx_print_stub + #define hw_print_id tx_print_stub + +#endif // __TEXT_MODE -#endif // __TEXT_MODE #endif // end of include guard: HARDWARE_H_ONCE diff --git a/g2core/board/gquadratic/motate_pin_assignments.h b/g2core/board/gquadratic/motate_pin_assignments.h old mode 100755 new mode 100644 index 9cc268e7..7ee305ba --- a/g2core/board/gquadratic/motate_pin_assignments.h +++ b/g2core/board/gquadratic/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the gQuadratic boards + * motate_pin_assignments.h - pin assignments + * For: /board/gQuadratic * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/gquintic/board_stepper.cpp b/g2core/board/gquintic/board_stepper.cpp old mode 100755 new mode 100644 index 8168f538..a68fff49 --- a/g2core/board/gquintic/board_stepper.cpp +++ b/g2core/board/gquintic/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/gquintic/board_stepper.h b/g2core/board/gquintic/board_stepper.h old mode 100755 new mode 100644 index 23b8c4db..1183d87d --- a/g2core/board/gquintic/board_stepper.h +++ b/g2core/board/gquintic/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/gquintic/board_xio.cpp b/g2core/board/gquintic/board_xio.cpp old mode 100755 new mode 100644 index 8b4835b2..be4fdc48 --- a/g2core/board/gquintic/board_xio.cpp +++ b/g2core/board/gquintic/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/gquintic/board_xio.h b/g2core/board/gquintic/board_xio.h old mode 100755 new mode 100644 index 09f20fef..89e7257b --- a/g2core/board/gquintic/board_xio.h +++ b/g2core/board/gquintic/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h old mode 100755 new mode 100644 index 75d7c52e..e0f9280e --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -1,5 +1,6 @@ /* * gquintic-a-pinout.h - board pinout specification + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2016 Robert Giseburt diff --git a/g2core/board/gquintic/hardware.cpp b/g2core/board/gquintic/hardware.cpp old mode 100755 new mode 100644 index e11d595c..a30ed2f4 --- a/g2core/board/gquintic/hardware.cpp +++ b/g2core/board/gquintic/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2010 - 2015 Alden S. Hart, Jr. @@ -96,15 +97,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -148,14 +152,6 @@ stat_t hw_flash(nvObj_t *nv) return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - /*********************************************************************************** * TEXT MODE SUPPORT @@ -164,22 +160,20 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING -#endif //__TEXT_MODE +#endif //__TEXT_MODE \ No newline at end of file diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index 5bd64ad3..a095c264 100644 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -1,6 +1,7 @@ /* * hardware.h - system hardware configuration - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: /board/gQuintic + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -37,20 +38,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "gQuintic" +#define G2CORE_HARDWARE_VERSION "b" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -62,10 +51,9 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// +/************************* + * Motate Setup * + *************************/ #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... @@ -172,18 +160,20 @@ stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t *nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); stat_t hw_get_fbs(nvObj_t *nv); stat_t hw_get_fbc(nvObj_t *nv); -stat_t hw_set_hv(nvObj_t *nv); stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); void hw_print_fbs(nvObj_t *nv); void hw_print_fbc(nvObj_t *nv); - void hw_print_fv(nvObj_t *nv); - void hw_print_cv(nvObj_t *nv); void hw_print_hp(nvObj_t *nv); void hw_print_hv(nvObj_t *nv); void hw_print_id(nvObj_t *nv); @@ -191,10 +181,9 @@ stat_t hw_get_id(nvObj_t *nv); #else #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub #define hw_print_fbs tx_print_stub #define hw_print_fbc tx_print_stub - #define hw_print_fv tx_print_stub - #define hw_print_cv tx_print_stub #define hw_print_hp tx_print_stub #define hw_print_hv tx_print_stub #define hw_print_id tx_print_stub diff --git a/g2core/board/gquintic/motate_pin_assignments.h b/g2core/board/gquintic/motate_pin_assignments.h old mode 100755 new mode 100644 index af029d31..57f73a0b --- a/g2core/board/gquintic/motate_pin_assignments.h +++ b/g2core/board/gquintic/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the gQuintic boards + * motate_pin_assignments.h - pin assignments + * For: /board/gQuintic * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/printrboardg2/board_stepper.cpp b/g2core/board/printrboardg2/board_stepper.cpp old mode 100755 new mode 100644 index 0583e4e7..66155f9f --- a/g2core/board/printrboardg2/board_stepper.cpp +++ b/g2core/board/printrboardg2/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/printrboardg2/board_stepper.h b/g2core/board/printrboardg2/board_stepper.h old mode 100755 new mode 100644 index 25c5d01b..4e9029b6 --- a/g2core/board/printrboardg2/board_stepper.h +++ b/g2core/board/printrboardg2/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/printrboardg2/board_xio.cpp b/g2core/board/printrboardg2/board_xio.cpp old mode 100755 new mode 100644 index 8b4835b2..9e657713 --- a/g2core/board/printrboardg2/board_xio.cpp +++ b/g2core/board/printrboardg2/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/printrboardg2/board_xio.h b/g2core/board/printrboardg2/board_xio.h old mode 100755 new mode 100644 index 6bc4421f..65e9c1e0 --- a/g2core/board/printrboardg2/board_xio.h +++ b/g2core/board/printrboardg2/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/printrboardg2/hardware.cpp b/g2core/board/printrboardg2/hardware.cpp old mode 100755 new mode 100644 index 178fbfdd..cf70c826 --- a/g2core/board/printrboardg2/hardware.cpp +++ b/g2core/board/printrboardg2/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. @@ -42,8 +43,6 @@ #include "neopixel.h" - - namespace LEDs { NeoPixel rgbw_leds {NeoPixelOrder::GRBW}; @@ -199,15 +198,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -251,14 +253,6 @@ stat_t hw_flash(nvObj_t *nv) return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - stat_t _get_leds(nvObj_t *nv) { nv->valuetype = TYPE_INT; @@ -348,22 +342,20 @@ stat_t _set_leds(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/printrboardg2/hardware.h b/g2core/board/printrboardg2/hardware.h index 44f970e9..44fa5c77 100644 --- a/g2core/board/printrboardg2/hardware.h +++ b/g2core/board/printrboardg2/hardware.h @@ -1,6 +1,7 @@ /* * hardware.h - system hardware configuration - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: /board/printrboardg2 + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -36,20 +37,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "printerboardg2" +#define G2CORE_HARDWARE_VERSION "c" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -61,10 +50,9 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels - -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// +/************************* + * Motate Setup * + *************************/ #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... @@ -169,42 +157,44 @@ static OutputPin mist_enable_pin; * Function Prototypes (Common) * ********************************/ -void hardware_init(void); // master hardware init -stat_t hardware_periodic(); // callback from the main loop (time sensitive) +void hardware_init(void); // master hardware init +stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t *nv); -stat_t hw_get_fbs(nvObj_t *nv); -stat_t hw_get_fbc(nvObj_t *nv); -stat_t hw_set_hv(nvObj_t *nv); -stat_t hw_get_id(nvObj_t *nv); - #define TEMPORARY_HAS_LEDS 1 stat_t _get_leds(nvObj_t *nv); stat_t _set_leds(nvObj_t *nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); +stat_t hw_get_fbs(nvObj_t *nv); +stat_t hw_get_fbc(nvObj_t *nv); +stat_t hw_get_id(nvObj_t *nv); + #ifdef __TEXT_MODE - void hw_print_fb(nvObj_t *nv); + void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); void hw_print_fbs(nvObj_t *nv); void hw_print_fbc(nvObj_t *nv); - void hw_print_fv(nvObj_t *nv); - void hw_print_cv(nvObj_t *nv); - void hw_print_hp(nvObj_t *nv); - void hw_print_hv(nvObj_t *nv); - void hw_print_id(nvObj_t *nv); + void hw_print_hp(nvObj_t *nv); + void hw_print_hv(nvObj_t *nv); + void hw_print_id(nvObj_t *nv); #else - #define hw_print_fb tx_print_stub + #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub #define hw_print_fbs tx_print_stub #define hw_print_fbc tx_print_stub - #define hw_print_fv tx_print_stub - #define hw_print_cv tx_print_stub - #define hw_print_hp tx_print_stub - #define hw_print_hv tx_print_stub - #define hw_print_id tx_print_stub + #define hw_print_hp tx_print_stub + #define hw_print_hv tx_print_stub + #define hw_print_id tx_print_stub #endif // __TEXT_MODE + #endif // end of include guard: HARDWARE_H_ONCE diff --git a/g2core/board/printrboardg2/motate_pin_assignments.h b/g2core/board/printrboardg2/motate_pin_assignments.h old mode 100755 new mode 100644 index d82bcb26..74e862e5 --- a/g2core/board/printrboardg2/motate_pin_assignments.h +++ b/g2core/board/printrboardg2/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the printrboardg2 boards + * motate_pin_assignments.h - pin assignments + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/printrboardg2/printrboardG2v3-pinout.h b/g2core/board/printrboardg2/printrboardG2v3-pinout.h old mode 100755 new mode 100644 index 85df15db..cc2db4a0 --- a/g2core/board/printrboardg2/printrboardG2v3-pinout.h +++ b/g2core/board/printrboardg2/printrboardG2v3-pinout.h @@ -1,5 +1,6 @@ /* * printrbaordG2v3-pinout.h - board pinout specification + * For: /board/printrboardg2 * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/sbv300/board_stepper.cpp b/g2core/board/sbv300/board_stepper.cpp old mode 100755 new mode 100644 index 0583e4e7..cc3e0ec6 --- a/g2core/board/sbv300/board_stepper.cpp +++ b/g2core/board/sbv300/board_stepper.cpp @@ -1,5 +1,6 @@ /* * board_stepper.cpp - board-specific code for stepper.cpp + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/sbv300/board_stepper.h b/g2core/board/sbv300/board_stepper.h old mode 100755 new mode 100644 index 25c5d01b..19e8ae4d --- a/g2core/board/sbv300/board_stepper.h +++ b/g2core/board/sbv300/board_stepper.h @@ -1,5 +1,6 @@ /* * board_stepper.h - board-specific code for stepper.h + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart, Jr. diff --git a/g2core/board/sbv300/board_xio.cpp b/g2core/board/sbv300/board_xio.cpp old mode 100755 new mode 100644 index 8b4835b2..0e1bb9c7 --- a/g2core/board/sbv300/board_xio.cpp +++ b/g2core/board/sbv300/board_xio.cpp @@ -1,5 +1,6 @@ /* * board_xio.cpp - extended IO functions that are board-specific + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/sbv300/board_xio.h b/g2core/board/sbv300/board_xio.h old mode 100755 new mode 100644 index 6bc4421f..16910e71 --- a/g2core/board/sbv300/board_xio.h +++ b/g2core/board/sbv300/board_xio.h @@ -1,5 +1,6 @@ /* * board_xio.h - extended IO functions that are board-specific + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2016 Alden S. Hart Jr. diff --git a/g2core/board/sbv300/hardware.cpp b/g2core/board/sbv300/hardware.cpp old mode 100755 new mode 100644 index 7fbf23b7..8014dd03 --- a/g2core/board/sbv300/hardware.cpp +++ b/g2core/board/sbv300/hardware.cpp @@ -1,5 +1,6 @@ /* * hardware.cpp - general hardware support functions + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. @@ -93,15 +94,18 @@ void _get_id(char *id) ***********************************************************************************/ /* + * hw_get_fb() - get firmware build number + * hw_get_fv() - get firmware version number + * hw_get_hp() - get hardware platform string + * hw_get_hv() - get hardware version string * hw_get_fbs() - get firmware build string */ -stat_t hw_get_fbs(nvObj_t *nv) -{ - nv->valuetype = TYPE_STRING; - ritorno(nv_copy_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); - return (STAT_OK); -} +stat_t hw_get_fb(nvObj_t *nv) { return (get_float(nv, cs.fw_build)); } +stat_t hw_get_fv(nvObj_t *nv) { return (get_float(nv, cs.fw_version)); } +stat_t hw_get_hp(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_PLATFORM)); } +stat_t hw_get_hv(nvObj_t *nv) { return (get_string(nv, G2CORE_HARDWARE_VERSION)); } +stat_t hw_get_fbs(nvObj_t *nv) { return (get_string(nv, G2CORE_FIRMWARE_BUILD_STRING)); } /* * hw_get_fbc() - get configuration settings file @@ -145,15 +149,6 @@ stat_t hw_flash(nvObj_t *nv) return(STAT_OK); } -/* - * hw_set_hv() - set hardware version number - */ -stat_t hw_set_hv(nvObj_t *nv) -{ - return (STAT_OK); -} - - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table @@ -161,22 +156,20 @@ stat_t hw_set_hv(nvObj_t *nv) #ifdef __TEXT_MODE -static const char fmt_fb[] = "[fb] firmware build %18.2f\n"; -static const char fmt_fbs[] = "[fbs] firmware build \"%s\"\n"; -static const char fmt_fbc[] = "[fbc] firmware config \"%s\"\n"; -static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; -static const char fmt_cv[] = "[cv] configuration version%11.2f\n"; -static const char fmt_hp[] = "[hp] hardware platform%15.2f\n"; -static const char fmt_hv[] = "[hv] hardware version%16.2f\n"; -static const char fmt_id[] = "[id] g2core ID%21s\n"; + static const char fmt_fb[] = "[fb] firmware build%18.2f\n"; + static const char fmt_fv[] = "[fv] firmware version%16.2f\n"; + static const char fmt_fbs[] = "[fbs] firmware build%34s\n"; + static const char fmt_fbc[] = "[fbc] firmware config%33s\n"; + static const char fmt_hp[] = "[hp] hardware platform%15s\n"; + static const char fmt_hv[] = "[hv] hardware version%13s\n"; + static const char fmt_id[] = "[id] g2core ID%37s\n"; -void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT -void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING -void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING -void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT -void hw_print_cv(nvObj_t *nv) { text_print(nv, fmt_cv);} // TYPE_FLOAT -void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_FLOAT -void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_FLOAT -void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING + void hw_print_fb(nvObj_t *nv) { text_print(nv, fmt_fb);} // TYPE_FLOAT + void hw_print_fv(nvObj_t *nv) { text_print(nv, fmt_fv);} // TYPE_FLOAT + void hw_print_fbs(nvObj_t *nv) { text_print(nv, fmt_fbs);} // TYPE_STRING + void hw_print_fbc(nvObj_t *nv) { text_print(nv, fmt_fbc);} // TYPE_STRING + void hw_print_hp(nvObj_t *nv) { text_print(nv, fmt_hp);} // TYPE_STRING + void hw_print_hv(nvObj_t *nv) { text_print(nv, fmt_hv);} // TYPE_STRING + void hw_print_id(nvObj_t *nv) { text_print(nv, fmt_id);} // TYPE_STRING #endif //__TEXT_MODE diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h index b98181c4..53bbad85 100644 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -1,6 +1,7 @@ /* * hardware.h - system hardware configuration - * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version + * For: /board/sbv300 + * THIS FILE IS HARDWARE PLATFORM SPECIFIC - ARM version * * This file is part of the g2core project * @@ -36,20 +37,8 @@ /*--- Hardware platform enumerations ---*/ -enum hwPlatform { - HM_PLATFORM_NONE = 0, - HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards. - HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due - HW_PLATFORM_V9 // G2 code base on v9 boards -}; - -#define HW_VERSION_TINYGV6 6 -#define HW_VERSION_TINYGV7 7 -#define HW_VERSION_TINYGV8 8 - -#define HW_VERSION_TINYGV9I 4 -#define HW_VERSION_TINYGV9K 5 - +#define G2CORE_HARDWARE_PLATFORM "sbv300" +#define G2CORE_HARDWARE_VERSION "k" /***** Axes, motors & PWM channels used by the application *****/ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: @@ -61,6 +50,10 @@ enum hwPlatform { #define COORDS 6 // number of supported coordinate systems (1-6) #define PWMS 2 // number of supported PWM channels +/************************* + * Motate Setup * + *************************/ + #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... #include "MotateServiceCall.h" // for ServiceCall<> @@ -169,18 +162,20 @@ stat_t hardware_periodic(); // callback from the main loop (time sensitive) void hw_hard_reset(void); stat_t hw_flash(nvObj_t *nv); +stat_t hw_get_fb(nvObj_t *nv); +stat_t hw_get_fv(nvObj_t *nv); +stat_t hw_get_hp(nvObj_t *nv); +stat_t hw_get_hv(nvObj_t *nv); stat_t hw_get_fbs(nvObj_t *nv); stat_t hw_get_fbc(nvObj_t *nv); -stat_t hw_set_hv(nvObj_t *nv); stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE void hw_print_fb(nvObj_t *nv); + void hw_print_fv(nvObj_t *nv); void hw_print_fbs(nvObj_t *nv); void hw_print_fbc(nvObj_t *nv); - void hw_print_fv(nvObj_t *nv); - void hw_print_cv(nvObj_t *nv); void hw_print_hp(nvObj_t *nv); void hw_print_hv(nvObj_t *nv); void hw_print_id(nvObj_t *nv); @@ -188,10 +183,9 @@ stat_t hw_get_id(nvObj_t *nv); #else #define hw_print_fb tx_print_stub + #define hw_print_fv tx_print_stub #define hw_print_fbs tx_print_stub #define hw_print_fbc tx_print_stub - #define hw_print_fv tx_print_stub - #define hw_print_cv tx_print_stub #define hw_print_hp tx_print_stub #define hw_print_hv tx_print_stub #define hw_print_id tx_print_stub diff --git a/g2core/board/sbv300/motate_pin_assignments.h b/g2core/board/sbv300/motate_pin_assignments.h old mode 100755 new mode 100644 index de1a5dc7..4df93de6 --- a/g2core/board/sbv300/motate_pin_assignments.h +++ b/g2core/board/sbv300/motate_pin_assignments.h @@ -1,5 +1,6 @@ /* - * motate_pin_assignments.h - pin assignments for the shopbot sbv300 boards + * motate_pin_assignments.h - pin assignments + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/board/sbv300/sbv300-pinout.h b/g2core/board/sbv300/sbv300-pinout.h old mode 100755 new mode 100644 index d46b9cf4..c003b9ca --- a/g2core/board/sbv300/sbv300-pinout.h +++ b/g2core/board/sbv300/sbv300-pinout.h @@ -1,5 +1,6 @@ /* * sbv300-pinout.h - board pinout specification + * For: /board/sbv300 * This file is part of the g2core project * * Copyright (c) 2013 - 2016 Robert Giseburt diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 3ac3fe02..13a42227 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -95,9 +95,6 @@ void controller_init() cs.comm_mode = comm_mode; // restore parameters cs.fw_build = G2CORE_FIRMWARE_BUILD; // set up identification cs.fw_version = G2CORE_FIRMWARE_VERSION; -// cs.hw_platform = G2CORE_HARDWARE_PLATFORM; - strncpy(cs.hw_platform, G2CORE_HARDWARE_PLATFORM, HARDWARE_STRING); - strncpy(cs.hw_version, G2CORE_HARDWARE_VERSION, HARDWARE_STRING); cs.controller_state = CONTROLLER_STARTUP; // ready to run startup lines if (xio_connected()) { diff --git a/g2core/controller.h b/g2core/controller.h index 10d8b930..d2ed690e 100644 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -32,7 +32,6 @@ #define SAVED_BUFFER_LEN 80 // saved buffer size (for reporting only) #define MAXED_BUFFER_LEN 255 // same as streaming RX buffer size as a worst case #define OUTPUT_BUFFER_LEN 512 // text buffer size -#define HARDWARE_STRING 16 // max length for hw platform and version is 15 chars #define LED_NORMAL_BLINK_RATE 3000 // blink rate for normal operation (in ms) #define LED_ALARM_BLINK_RATE 750 // blink rate for alarm state (in ms) @@ -55,10 +54,6 @@ typedef struct controllerSingleton { // main TG controller struct // system identification values float fw_build; // firmware build number float fw_version; // firmware version number -// float hw_platform; // hardware compatibility - platform type -// float hw_version; // hardware compatibility - platform revision - char hw_platform[HARDWARE_STRING]; // hardware compatibility - platform type - char hw_version[HARDWARE_STRING]; // hardware compatibility - platform revision // system state variables csControllerState controller_state; From d17d59c7bb25e04bad022c8f900a49672d695ccb Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 12 Dec 2016 15:56:52 -0500 Subject: [PATCH 038/283] Testing comm variables settings. Added in32 functions; Some fixes to ej and jv --- g2core/board/G2v9/hardware.h | 2 -- g2core/config.h | 9 ++++--- g2core/config_app.cpp | 46 ++++++++++++++++++++++++++------- g2core/controller.h | 6 ++--- g2core/json_parser.cpp | 49 ++++++++++++++++++++---------------- g2core/json_parser.h | 8 +++--- g2core/report.cpp | 39 +++++++++++++--------------- g2core/report.h | 8 ++++++ 8 files changed, 103 insertions(+), 64 deletions(-) mode change 100755 => 100644 g2core/report.h diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index 7532b254..5ca740d8 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -166,10 +166,8 @@ stat_t hw_get_fb(nvObj_t *nv); stat_t hw_get_fv(nvObj_t *nv); stat_t hw_get_hp(nvObj_t *nv); stat_t hw_get_hv(nvObj_t *nv); - stat_t hw_get_fbs(nvObj_t *nv); stat_t hw_get_fbc(nvObj_t *nv); -stat_t hw_get_hv(nvObj_t *nv); stat_t hw_get_id(nvObj_t *nv); #ifdef __TEXT_MODE diff --git a/g2core/config.h b/g2core/config.h index 9695cef0..dc6cdbcd 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -356,12 +356,15 @@ stat_t set_flu(nvObj_t *nv); // set floating point number void process_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values void process_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units -stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving raw floating point value -stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion + +stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving raw floating point value +stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); -stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving an integer value +stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving 8 bit integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); +stat_t get_int32(nvObj_t *nv, const uint32_t value); // boilerplate for retrieving 32 bit integer value +stat_t set_int32(nvObj_t *nv, uint32_t &value, uint32_t low, uint32_t high); stat_t get_string(nvObj_t *nv, const char *str); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 6a6e2990..e2fe6443 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -639,11 +639,11 @@ const cfgItem_t cfgArray[] = { #ifdef __TEXT_MODE { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, #endif - { "sys","ej", _fipn, 0, js_print_ej, get_ui8, js_set_ej,(float *)&cs.comm_mode, COMM_MODE }, - { "sys","jv", _fipn, 0, js_print_jv, get_ui8, js_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY }, - { "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_0123, (float *)&qr.queue_report_verbosity, QUEUE_REPORT_VERBOSITY }, - { "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity,STATUS_REPORT_VERBOSITY }, - { "sys","si", _fipn, 0, sr_print_si, get_int32,sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, + { "sys","ej", _fipn, 0, js_print_ej, js_get_ej, js_set_ej, (float *)&cs.null, COMM_MODE }, + { "sys","jv", _fipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, + { "sys","qv", _fipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, + { "sys","sv", _fipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, + { "sys","si", _fipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco @@ -1082,8 +1082,10 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { } /* - * get_int() - boilerplate for retrieving an integer value - * set_int() - boilerplate for setting an integer value with range checking + * get_int() - boilerplate for retrieving 8 bit integer value + * set_int() - boilerplate for setting 8 bit integer value with range checking + * get_int32() - boilerplate for retrieving 32 bit integer value + * set_int32() - boilerplate for setting 32 bit integer value with range checking */ stat_t get_int(nvObj_t *nv, const uint8_t value) { @@ -1097,13 +1099,39 @@ stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { char msg[64]; if (nv->value < low) { - sprintf(msg, "Input is less than minimum value %d", (int)low); + sprintf(msg, "Input is less than minimum value %d", low); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } if (nv->value > high) { - sprintf(msg, "Input is more than maximum value %d", (int)high); + sprintf(msg, "Input is more than maximum value %d", high); + nv_add_conditional_message(msg); + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + value = nv->value; // note: valuetype = TYPE_INT already set + return (STAT_OK); +} + +stat_t get_int32(nvObj_t *nv, const uint32_t value) { + nv->value = value; + nv->valuetype = TYPE_INT; + return STAT_OK; +} + +stat_t set_int32(nvObj_t *nv, uint32_t &value, uint32_t low, uint32_t high) { + + char msg[64]; + + if (nv->value < low) { + sprintf(msg, "Input is less than minimum value %lu", low); + nv_add_conditional_message(msg); + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_LESS_THAN_MIN_VALUE); + } + if (nv->value > high) { + sprintf(msg, "Input is more than maximum value %lu", high); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); diff --git a/g2core/controller.h b/g2core/controller.h index d2ed690e..b2015bba 100644 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -61,10 +61,10 @@ typedef struct controllerSingleton { // main TG controller struct uint32_t led_blink_rate; // used to flash indicator LED // communications state variables - // cs.comm_mode is the setting for the communications more - // js.json_mode is the actual current mode (see also js.json_now) + // cs.comm_mode is the setting for the communications mode + // js.json_mode is the actual current mode commMode comm_mode; // ej: 0=text mode sticky, 1=JSON mode sticky, 2=auto mode - commMode comm_request_mode; // mode of request (may be different thatn the setting) + commMode comm_request_mode; // mode of request (may be different than the setting) // controller serial buffers char *bufp; // pointer to primary or secondary in buffer diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 51f14269..b6570737 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -97,7 +97,7 @@ void json_parser(char *str) if (status == STAT_COMPLETE) { // skip the print if returning from something that already did it. return; } - nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_FORMAT); + nv_print_list(status, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT); sr_request_status_report(SR_REQUEST_TIMED); // generate incremental status report to show any changes } @@ -609,12 +609,36 @@ void json_print_response(uint8_t status) ***********************************************************************************/ /* - * js_set_jv() + * js_get_ej() - get JSON communications mode + * js_set_ej() - set JSON communications mode + * + * This one is a bit different: + * - cs.comm_mode is the setting for the *communications mode* (persistent) + * - js.json_mode is the actual current mode + * + * If comm_mode is set to TEXT_MORE (0) or JSON_MODE (1) then json_mode should also be changed + * If comm_mode is set to AUTO_MORE (0) then json_mode should not be changed */ +stat_t js_get_ej(nvObj_t *nv) { return(get_int(nv, cs.comm_mode)); } +stat_t js_set_ej(nvObj_t *nv) +{ + ritorno (set_int(nv, (uint8_t &)cs.comm_mode, TEXT_MODE, AUTO_MODE)); + if (commMode(nv->value) < AUTO_MODE) { // set json_mode to 0 or 1, but don't change it if comm_mode == 2 + js.json_mode = commMode(nv->value); + } + return (STAT_OK); +} + +/* + * js_get_jv() - get JSON verbosity + * js_set_jv() - set JSON verbosity and related flags + */ + +stat_t js_get_jv(nvObj_t *nv) { return(get_int(nv, js.json_verbosity)); } stat_t js_set_jv(nvObj_t *nv) { - ritorno (set_int(nv, (uint8_t &)js.json_verbosity, 0, JV_MAX_VALUE)); + ritorno (set_int(nv, (uint8_t &)js.json_verbosity, JV_SILENT, JV_MAX_VALUE)); js.echo_json_footer = false; js.echo_json_messages = false; @@ -636,25 +660,6 @@ stat_t js_set_jv(nvObj_t *nv) return(STAT_OK); } -/* - * js_set_ej() - set JSON communications mode - */ - -stat_t js_set_ej(nvObj_t *nv) -{ -// ritorno (set_int(nv, cs.comm_mode, TEXT_MODE, AUTO_MODE)); - if ((nv->value < TEXT_MODE) || (nv->value > AUTO_MODE)) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - - // set json_mode to 0 or 1, but don't change it if comm_mode == 2 - if (commMode(nv->value) < AUTO_MODE) { - js.json_mode = commMode(nv->value); - } - return (set_ui8(nv)); -} - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table diff --git a/g2core/json_parser.h b/g2core/json_parser.h index e80ca5bf..82170d35 100644 --- a/g2core/json_parser.h +++ b/g2core/json_parser.h @@ -50,9 +50,9 @@ typedef enum { JV_VERBOSE, // [5] returns footer, messages, config commands, gcode blocks JV_EXCEPTIONS, // [6] returns only on messages, configs, and non-zero status JV_STATUS, // [7] returns status and any messages in abbreviated format - JV_STATUS_COUNT, // [8] returns status, count and messages in abbreviated format - JV_MAX_VALUE + JV_STATUS_COUNT // [8] returns status, count and messages in abbreviated format } jsonVerbosity; +#define JV_MAX_VALUE JV_STATUS_COUNT typedef enum { // json output print modes JSON_NO_PRINT = 0, // don't print anything if you find yourself in JSON mode @@ -88,8 +88,10 @@ void json_print_object(nvObj_t *nv); void json_print_response(uint8_t status); void json_print_list(stat_t status, uint8_t flags); -stat_t js_set_jv(nvObj_t *nv); +stat_t js_get_ej(nvObj_t *nv); stat_t js_set_ej(nvObj_t *nv); +stat_t js_get_jv(nvObj_t *nv); +stat_t js_set_jv(nvObj_t *nv); #ifdef __TEXT_MODE diff --git a/g2core/report.cpp b/g2core/report.cpp index ea5757a4..4439e493 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -412,41 +412,33 @@ static uint8_t _populate_filtered_status_report() /* * Wrappers and Setters - for calling from nvArray table * - * sr_get() - run status report - * sr_set() - set status report elements - * sr_set_si() - set status report interval + * sr_get() - run status report + * sr_set() - set status report elements + * sr_get_sv() - get status report verbosity + * sr_set_sv() - set status report verbosity + * sr_get_si() - get status report interval + * sr_set_si() - set status report interval */ -stat_t sr_get(nvObj_t *nv) -{ - return (_populate_unfiltered_status_report()); -} +stat_t sr_get(nvObj_t *nv) { return (_populate_unfiltered_status_report()); } +stat_t sr_set(nvObj_t *nv) { return (sr_set_status_report(nv)); } -stat_t sr_set(nvObj_t *nv) -{ - return (sr_set_status_report(nv)); -} - -stat_t sr_set_si(nvObj_t *nv) -{ - if (nv->value < STATUS_REPORT_MIN_MS) { - nv->value = STATUS_REPORT_MIN_MS; - } - set_int32(nv); - return(STAT_OK); -} +stat_t sr_get_sv(nvObj_t *nv) { return(get_int(nv, (uint8_t &)sr.status_report_verbosity)); } +stat_t sr_set_sv(nvObj_t *nv) { return(set_int(nv, (uint8_t &)sr.status_report_verbosity, SR_OFF, SR_VERBOSE)); } +stat_t sr_get_si(nvObj_t *nv) { return(get_int32(nv, sr.status_report_interval)); } +stat_t sr_set_si(nvObj_t *nv) { return(set_int32(nv, sr.status_report_interval, STATUS_REPORT_MIN_MS, STATUS_REPORT_MAX_MS)); } /********************* * TEXT MODE SUPPORT * *********************/ #ifdef __TEXT_MODE -static const char fmt_si[] = "[si] status interval%14d ms\n"; static const char fmt_sv[] = "[sv] status report verbosity%6d [0=off,1=filtered,2=verbose]\n"; +static const char fmt_si[] = "[si] status interval%14d ms\n"; void sr_print_sr(nvObj_t *nv) { _populate_unfiltered_status_report();} -void sr_print_si(nvObj_t *nv) { text_print(nv, fmt_si);} void sr_print_sv(nvObj_t *nv) { text_print(nv, fmt_sv);} +void sr_print_si(nvObj_t *nv) { text_print(nv, fmt_si);} #endif // __TEXT_MODE @@ -595,6 +587,9 @@ stat_t qo_get(nvObj_t *nv) return (STAT_OK); } +stat_t qr_get_qv(nvObj_t *nv) { return(get_int(nv, (uint8_t &)qr.queue_report_verbosity)); } +stat_t qr_set_qv(nvObj_t *nv) { return(set_int(nv, (uint8_t &)qr.queue_report_verbosity, QR_OFF, QR_TRIPLE)); } + /***************************************************************************** * JOB ID REPORTS * diff --git a/g2core/report.h b/g2core/report.h old mode 100755 new mode 100644 index 01e7ad1e..31514a73 --- a/g2core/report.h +++ b/g2core/report.h @@ -36,6 +36,7 @@ #define SR_THROTTLE_COUNT 4 // scale back filtered SR's during time-constrained intervals #define MIN_ARC_QR_INTERVAL 200 // minimum interval between QRs during arc generation (in system ticks) +#define STATUS_REPORT_MAX_MS (MAX_LONG/1000) typedef enum { // status report enable, verbosity and request type SR_OFF = 0, // no reports @@ -112,6 +113,10 @@ stat_t sr_run_text_status_report(void); stat_t sr_get(nvObj_t *nv); stat_t sr_set(nvObj_t *nv); + +stat_t sr_get_sv(nvObj_t *nv); +stat_t sr_set_sv(nvObj_t *nv); +stat_t sr_get_si(nvObj_t *nv); stat_t sr_set_si(nvObj_t *nv); void qr_init_queue_report(void); @@ -125,6 +130,9 @@ stat_t qr_get(nvObj_t *nv); stat_t qi_get(nvObj_t *nv); stat_t qo_get(nvObj_t *nv); +stat_t qr_get_qv(nvObj_t *nv); +stat_t qr_set_qv(nvObj_t *nv); + #ifdef __TEXT_MODE void sr_print_sr(nvObj_t *nv); From 56b17d7b047d1e377ad64459d60b8e09a5c36bb1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 13 Dec 2016 07:41:32 -0500 Subject: [PATCH 039/283] Refactoring motor settings - mt, ma, sa --- g2core/config_app.cpp | 86 +++++++++++++++++++++---------------------- g2core/gpio.cpp | 2 +- g2core/stepper.cpp | 31 ++++++++++++---- g2core/stepper.h | 4 ++ 4 files changed, 71 insertions(+), 52 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index e2fe6443..7613838b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -157,7 +157,7 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // B work offset { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // C work offset - { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 },// homing state, invoke homing cycle + { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // X homed - Homing status group { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Y homed { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Z homed @@ -196,72 +196,72 @@ const cfgItem_t cfgArray[] = { #endif // Motor parameters - { "1","1ma",_fip, 0, st_print_ma, get_ui8, set_ui8, (float *)&st_cfg.mot[MOTOR_1].motor_map, M1_MOTOR_MAP }, - { "1","1sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_1].step_angle, M1_STEP_ANGLE }, + { "1","1ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, + { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, { "1","1tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_1].travel_rev, M1_TRAVEL_PER_REV }, { "1","1mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_1].microsteps, M1_MICROSTEPS }, { "1","1su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, - { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, + { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, { "1","1pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_1].power_level, M1_POWER_LEVEL }, // { "1","1pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, // { "1","1mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, #if (MOTORS >= 2) - { "2","2ma",_fip, 0, st_print_ma, get_ui8, set_ui8, (float *)&st_cfg.mot[MOTOR_2].motor_map, M2_MOTOR_MAP }, - { "2","2sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_2].step_angle, M2_STEP_ANGLE }, + { "2","2ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, + { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, { "2","2tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_2].travel_rev, M2_TRAVEL_PER_REV }, { "2","2mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_2].microsteps, M2_MICROSTEPS }, { "2","2su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, - { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, + { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, { "2","2pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_2].power_level, M2_POWER_LEVEL}, // { "2","2pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, // { "2","2mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 3) - { "3","3ma",_fip, 0, st_print_ma, get_ui8, set_ui8, (float *)&st_cfg.mot[MOTOR_3].motor_map, M3_MOTOR_MAP }, - { "3","3sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_3].step_angle, M3_STEP_ANGLE }, + { "3","3ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, + { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, { "3","3tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_3].travel_rev, M3_TRAVEL_PER_REV }, { "3","3mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_3].microsteps, M3_MICROSTEPS }, { "3","3su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, - { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, + { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, { "3","3pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_3].power_level, M3_POWER_LEVEL }, // { "3","3pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, // { "3","3mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 4) - { "4","4ma",_fip, 0, st_print_ma, get_ui8, set_ui8, (float *)&st_cfg.mot[MOTOR_4].motor_map, M4_MOTOR_MAP }, - { "4","4sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_4].step_angle, M4_STEP_ANGLE }, + { "4","4ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, + { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, { "4","4tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_4].travel_rev, M4_TRAVEL_PER_REV }, { "4","4mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_4].microsteps, M4_MICROSTEPS }, { "4","4su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, - { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, + { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, { "4","4pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_4].power_level, M4_POWER_LEVEL }, // { "4","4pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, // { "4","4mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 5) - { "5","5ma",_fip, 0, st_print_ma, get_ui8, set_ui8, (float *)&st_cfg.mot[MOTOR_5].motor_map, M5_MOTOR_MAP }, - { "5","5sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_5].step_angle, M5_STEP_ANGLE }, + { "5","5ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, + { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, { "5","5tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_5].travel_rev, M5_TRAVEL_PER_REV }, { "5","5mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_5].microsteps, M5_MICROSTEPS }, { "5","5su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, - { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, + { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, { "5","5pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_5].power_level, M5_POWER_LEVEL }, // { "5","5pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, // { "5","5mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_5].motor_timeout, M5_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 6) - { "6","6ma",_fip, 0, st_print_ma, get_ui8, set_ui8, (float *)&st_cfg.mot[MOTOR_6].motor_map, M6_MOTOR_MAP }, - { "6","6sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_6].step_angle, M6_STEP_ANGLE }, + { "6","6ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, + { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, { "6","6tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_6].travel_rev, M6_TRAVEL_PER_REV }, { "6","6mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_6].microsteps, M6_MICROSTEPS }, { "6","6su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, - { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, + { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, { "6","6pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_6].power_level, M6_POWER_LEVEL }, // { "6","6pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, // { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, @@ -430,19 +430,19 @@ const cfgItem_t cfgArray[] = { #endif // digital output configs - { "do1", "do1mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[0].mode, DO1_MODE }, - { "do2", "do2mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[1].mode, DO2_MODE }, - { "do3", "do3mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[2].mode, DO3_MODE }, - { "do4", "do4mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[3].mode, DO4_MODE }, - { "do5", "do5mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[4].mode, DO5_MODE }, - { "do6", "do6mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[5].mode, DO6_MODE }, - { "do7", "do7mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[6].mode, DO7_MODE }, - { "do8", "do8mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[7].mode, DO8_MODE }, - { "do9", "do9mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[8].mode, DO9_MODE }, - { "do10","do10mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[9].mode, DO10_MODE }, - { "do11","do11mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[10].mode, DO11_MODE }, - { "do12","do12mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[11].mode, DO12_MODE }, - { "do13","do13mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[12].mode, DO13_MODE }, + { "do1", "do1mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[0].mode, DO1_MODE }, + { "do2", "do2mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[1].mode, DO2_MODE }, + { "do3", "do3mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[2].mode, DO3_MODE }, + { "do4", "do4mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[3].mode, DO4_MODE }, + { "do5", "do5mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[4].mode, DO5_MODE }, + { "do6", "do6mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[5].mode, DO6_MODE }, + { "do7", "do7mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[6].mode, DO7_MODE }, + { "do8", "do8mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[7].mode, DO8_MODE }, + { "do9", "do9mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[8].mode, DO9_MODE }, + { "do10","do10mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[9].mode, DO10_MODE }, + { "do11","do11mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[10].mode, DO11_MODE }, + { "do12","do12mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[11].mode, DO12_MODE }, + { "do13","do13mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[12].mode, DO13_MODE }, // Digital output state readers (default to non-active) { "out","out1", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, @@ -459,16 +459,16 @@ const cfgItem_t cfgArray[] = { { "out","out12", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, // PWM settings - { "p1","p1frq",_fip, 0, pwm_print_p1frq, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].frequency, P1_PWM_FREQUENCY }, - { "p1","p1csl",_fip, 0, pwm_print_p1csl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_speed_lo, P1_CW_SPEED_LO }, - { "p1","p1csh",_fip, 0, pwm_print_p1csh, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_speed_hi, P1_CW_SPEED_HI }, - { "p1","p1cpl",_fip, 3, pwm_print_p1cpl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_phase_lo, P1_CW_PHASE_LO }, - { "p1","p1cph",_fip, 3, pwm_print_p1cph, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_phase_hi, P1_CW_PHASE_HI }, - { "p1","p1wsl",_fip, 0, pwm_print_p1wsl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_speed_lo, P1_CCW_SPEED_LO }, - { "p1","p1wsh",_fip, 0, pwm_print_p1wsh, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_speed_hi, P1_CCW_SPEED_HI }, - { "p1","p1wpl",_fip, 3, pwm_print_p1wpl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_phase_lo, P1_CCW_PHASE_LO }, - { "p1","p1wph",_fip, 3, pwm_print_p1wph, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_phase_hi, P1_CCW_PHASE_HI }, - { "p1","p1pof",_fip, 3, pwm_print_p1pof, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].phase_off, P1_PWM_PHASE_OFF }, + { "p1","p1frq",_fip, 0, pwm_print_p1frq, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].frequency, P1_PWM_FREQUENCY }, + { "p1","p1csl",_fip, 0, pwm_print_p1csl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_speed_lo, P1_CW_SPEED_LO }, + { "p1","p1csh",_fip, 0, pwm_print_p1csh, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_speed_hi, P1_CW_SPEED_HI }, + { "p1","p1cpl",_fip, 3, pwm_print_p1cpl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_phase_lo, P1_CW_PHASE_LO }, + { "p1","p1cph",_fip, 3, pwm_print_p1cph, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_phase_hi, P1_CW_PHASE_HI }, + { "p1","p1wsl",_fip, 0, pwm_print_p1wsl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_speed_lo, P1_CCW_SPEED_LO }, + { "p1","p1wsh",_fip, 0, pwm_print_p1wsh, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_speed_hi, P1_CCW_SPEED_HI }, + { "p1","p1wpl",_fip, 3, pwm_print_p1wpl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_phase_lo, P1_CCW_PHASE_LO }, + { "p1","p1wph",_fip, 3, pwm_print_p1wph, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].ccw_phase_hi, P1_CCW_PHASE_HI }, + { "p1","p1pof",_fip, 3, pwm_print_p1pof, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].phase_off, P1_PWM_PHASE_OFF }, // temperature configs - pid active values (read-only) // NOTICE: If you change these PID group keys, you MUST change the get/set functions too!! @@ -612,7 +612,7 @@ const cfgItem_t cfgArray[] = { { "sys","fro", _fipn,3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, { "sys","troe",_fipn,0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, { "sys","tro", _fipn,3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, - { "sys","mt", _fipn,2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, + { "sys","mt", _fipn,2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors // { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 18992875..21ed1d96 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -462,7 +462,7 @@ static stat_t _input_set_helper(nvObj_t *nv, const int8_t lower_bound, const int if ((nv->value < lower_bound) || (nv->value >= upper_bound)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } - set_ui8(nv); // will this work in -1 is a valid value? + set_ui8(nv); // will this work if -1 is a valid value? if (cm_get_machine_state() != MACHINE_INITIALIZING) { inputs_reset(); } diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index f013059a..3dd5c0d3 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -815,7 +815,7 @@ static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps) * _get_motor() - helper to return motor number as an index or -1 if na */ -static int8_t _get_motor(const index_t index) +static int8_t _motor(const index_t index) { char *ptr; char motors[] = {"123456"}; @@ -835,12 +835,16 @@ static int8_t _get_motor(const index_t index) static void _set_motor_steps_per_unit(nvObj_t *nv) { - uint8_t m = _get_motor(nv->index); + uint8_t m = _motor(nv->index); st_cfg.mot[m].units_per_step = (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle) / (360 * st_cfg.mot[m].microsteps); st_cfg.mot[m].steps_per_unit = 1/st_cfg.mot[m].units_per_step; } /* PER-MOTOR FUNCTIONS + * + * st_get_ma() - get motor axis mapping + * st_set_ma() - set motor axis mapping + * st_get_sa() - get motor step angle * st_set_sa() - set motor step angle * st_set_tr() - set travel per motor revolution * st_set_mi() - set motor microsteps @@ -849,6 +853,11 @@ static void _set_motor_steps_per_unit(nvObj_t *nv) * st_set_pl() - set motor power level */ +stat_t st_get_ma(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].motor_map)); } +stat_t st_set_ma(nvObj_t *nv) { return(set_int(nv, st_cfg.mot[_motor(nv->index)].motor_map, 0, AXES)); } + +stat_t st_get_sa(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].step_angle)); } + stat_t st_set_sa(nvObj_t *nv) // motor step angle { set_flt(nv); @@ -872,13 +881,13 @@ stat_t st_set_mi(nvObj_t *nv) // motor microsteps } set_ui8(nv); // set it anyway, even if it's unsupported _set_motor_steps_per_unit(nv); - _set_hw_microsteps(_get_motor(nv->index), (uint8_t)nv->value); + _set_hw_microsteps(_motor(nv->index), (uint8_t)nv->value); return (STAT_OK); } stat_t st_set_su(nvObj_t *nv) // motor steps per unit (direct) { - uint8_t m = _get_motor(nv->index); + uint8_t m = _motor(nv->index); // Do the unit conversion here (rather than using set_flu) because it's a reciprocal value if ((m <= 3) && (cm_get_units_mode(MODEL) == INCHES)) { nv->value *= INCHES_PER_MM; @@ -904,7 +913,7 @@ stat_t st_set_pm(nvObj_t *nv) // set motor power mode { if (nv->value >= MOTOR_POWER_MODE_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - uint8_t motor = _get_motor(nv->index); + uint8_t motor = _motor(nv->index); if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; Motors[motor]->setPowerMode((stPowerMode)nv->value); @@ -917,7 +926,7 @@ stat_t st_get_pm(nvObj_t *nv) // get motor power mode { if (nv->value >= MOTOR_POWER_MODE_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - uint8_t motor = _get_motor(nv->index); + uint8_t motor = _motor(nv->index); if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; nv->value = (float)Motors[motor]->getPowerMode(); @@ -939,7 +948,7 @@ stat_t st_set_pl(nvObj_t *nv) // motor power level } set_flt(nv); // set power_setting value in the motor config struct (st) - uint8_t motor = _get_motor(nv->index); + uint8_t motor = _motor(nv->index); st_cfg.mot[motor].power_level_scaled = (nv->value * POWER_LEVEL_SCALE_FACTOR); st_run.mot[motor].power_level_dynamic = (st_cfg.mot[motor].power_level_scaled); Motors[motor]->setPowerLevel(st_cfg.mot[motor].power_level_scaled); @@ -968,6 +977,7 @@ stat_t st_get_pwr(nvObj_t *nv) /* GLOBAL FUNCTIONS (SYSTEM LEVEL) * + * st_get_mt() - get motor timeout in seconds * st_set_mt() - set motor timeout in seconds * st_set_md() - disable motor power * st_set_me() - enable motor power @@ -977,12 +987,17 @@ stat_t st_get_pwr(nvObj_t *nv) * Setting a value from 1 to MOTORS will enable or disable that motor only */ +stat_t st_get_mt(nvObj_t *nv) { return(get_float(nv, st_cfg.motor_power_timeout)); } +stat_t st_set_mt(nvObj_t *nv) { return(set_float_range(nv, st_cfg.motor_power_timeout, + MOTOR_TIMEOUT_SECONDS_MAX, + MOTOR_TIMEOUT_SECONDS_MIN)); } +/* stat_t st_set_mt(nvObj_t *nv) { st_cfg.motor_power_timeout = min(MOTOR_TIMEOUT_SECONDS_MAX, max(nv->value, MOTOR_TIMEOUT_SECONDS_MIN)); return (STAT_OK); } - +*/ stat_t st_set_me(nvObj_t *nv) // Make sure this function is not part of initialization --> f00 { for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { diff --git a/g2core/stepper.h b/g2core/stepper.h index eb585f59..7fe57686 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -579,6 +579,9 @@ void st_request_out_of_band_dwell(float microseconds); //stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time); stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time); +stat_t st_get_ma(nvObj_t *nv); +stat_t st_set_ma(nvObj_t *nv); +stat_t st_get_sa(nvObj_t *nv); stat_t st_set_sa(nvObj_t *nv); stat_t st_set_tr(nvObj_t *nv); stat_t st_set_mi(nvObj_t *nv); @@ -588,6 +591,7 @@ stat_t st_get_pm(nvObj_t *nv); stat_t st_set_pl(nvObj_t *nv); stat_t st_get_pwr(nvObj_t *nv); +stat_t st_get_mt(nvObj_t *nv); stat_t st_set_mt(nvObj_t *nv); stat_t st_set_md(nvObj_t *nv); stat_t st_set_me(nvObj_t *nv); From 4af4aa7fed340be2d77cfaa2c5d69940468a3ac9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 13 Dec 2016 08:21:50 -0500 Subject: [PATCH 040/283] Refactoring motor settings - tr, mi (mi is incomplete) --- g2core/config_app.cpp | 24 ++++++++++++------------ g2core/stepper.cpp | 25 +++++++++++++++++-------- g2core/stepper.h | 3 +++ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 7613838b..bef30edc 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -198,8 +198,8 @@ const cfgItem_t cfgArray[] = { // Motor parameters { "1","1ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, - { "1","1tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_1].travel_rev, M1_TRAVEL_PER_REV }, - { "1","1mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_1].microsteps, M1_MICROSTEPS }, + { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, + { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, { "1","1su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, @@ -209,8 +209,8 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 2) { "2","2ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, - { "2","2tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_2].travel_rev, M2_TRAVEL_PER_REV }, - { "2","2mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_2].microsteps, M2_MICROSTEPS }, + { "2","2tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, + { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, { "2","2su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, @@ -221,8 +221,8 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 3) { "3","3ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, - { "3","3tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_3].travel_rev, M3_TRAVEL_PER_REV }, - { "3","3mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_3].microsteps, M3_MICROSTEPS }, + { "3","3tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, + { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, { "3","3su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, @@ -233,8 +233,8 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 4) { "4","4ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, - { "4","4tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_4].travel_rev, M4_TRAVEL_PER_REV }, - { "4","4mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_4].microsteps, M4_MICROSTEPS }, + { "4","4tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, + { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, { "4","4su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, @@ -245,8 +245,8 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 5) { "5","5ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, - { "5","5tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_5].travel_rev, M5_TRAVEL_PER_REV }, - { "5","5mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_5].microsteps, M5_MICROSTEPS }, + { "5","5tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, + { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, { "5","5su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, @@ -257,8 +257,8 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 6) { "6","6ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, - { "6","6tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_6].travel_rev, M6_TRAVEL_PER_REV }, - { "6","6mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_6].microsteps, M6_MICROSTEPS }, + { "6","6tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, + { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, { "6","6su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 3dd5c0d3..b0c2b241 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -846,40 +846,49 @@ static void _set_motor_steps_per_unit(nvObj_t *nv) * st_set_ma() - set motor axis mapping * st_get_sa() - get motor step angle * st_set_sa() - set motor step angle + * st_get_tr() - get travel per motor revolution * st_set_tr() - set travel per motor revolution + * st_get_mi() - get motor microsteps * st_set_mi() - set motor microsteps + * * st_set_pm() - set motor power mode * st_get_pm() - get motor power mode * st_set_pl() - set motor power level */ +// motor axis mapping stat_t st_get_ma(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].motor_map)); } stat_t st_set_ma(nvObj_t *nv) { return(set_int(nv, st_cfg.mot[_motor(nv->index)].motor_map, 0, AXES)); } -stat_t st_get_sa(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].step_angle)); } - -stat_t st_set_sa(nvObj_t *nv) // motor step angle +// step angle +stat_t st_get_sa(nvObj_t *nv) { return(get_float(nv, st_cfg.mot[_motor(nv->index)].step_angle)); } +stat_t st_set_sa(nvObj_t *nv) { - set_flt(nv); + ritorno(set_float_range(nv, st_cfg.mot[_motor(nv->index)].step_angle, 0.001, 360)); _set_motor_steps_per_unit(nv); return(STAT_OK); } -stat_t st_set_tr(nvObj_t *nv) // motor travel per revolution +// travel per revolution +stat_t st_get_tr(nvObj_t *nv) { return(get_float(nv, st_cfg.mot[_motor(nv->index)].travel_rev)); } +stat_t st_set_tr(nvObj_t *nv) { - set_flu(nv); + ritorno(set_float_range(nv, st_cfg.mot[_motor(nv->index)].travel_rev, 0.0001, 1000000)); _set_motor_steps_per_unit(nv); return(STAT_OK); } -stat_t st_set_mi(nvObj_t *nv) // motor microsteps +// microsteps +stat_t st_get_mi(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].microsteps)); } +stat_t st_set_mi(nvObj_t *nv) { uint8_t mi = (uint8_t)nv->value; if ((mi != 1) && (mi != 2) && (mi != 4) && (mi != 8) && (mi != 16) && (mi != 32)) { nv_add_conditional_message((const char *)"*** WARNING *** Setting non-standard microstep value"); } - set_ui8(nv); // set it anyway, even if it's unsupported + // set it anyway, even if it's unsupported + ritorno(set_int(nv, st_cfg.mot[_motor(nv->index)].microsteps, 1, 255)); _set_motor_steps_per_unit(nv); _set_hw_microsteps(_motor(nv->index), (uint8_t)nv->value); return (STAT_OK); diff --git a/g2core/stepper.h b/g2core/stepper.h index 7fe57686..36c650a7 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -583,8 +583,11 @@ stat_t st_get_ma(nvObj_t *nv); stat_t st_set_ma(nvObj_t *nv); stat_t st_get_sa(nvObj_t *nv); stat_t st_set_sa(nvObj_t *nv); +stat_t st_get_tr(nvObj_t *nv); stat_t st_set_tr(nvObj_t *nv); +stat_t st_get_mi(nvObj_t *nv); stat_t st_set_mi(nvObj_t *nv); + stat_t st_set_su(nvObj_t *nv); stat_t st_set_pm(nvObj_t *nv); stat_t st_get_pm(nvObj_t *nv); From 9f6036d2c4557e8287d5086a7546f8a5881dba0a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 13 Dec 2016 11:29:34 -0500 Subject: [PATCH 041/283] Added set_noop() to fix up mi settings; added error 117 for device not active errors --- g2core/config.cpp | 9 ++++++++- g2core/config.h | 3 ++- g2core/config_app.cpp | 40 +++++++++++++++++++++------------------- g2core/error.h | 4 ++-- g2core/stepper.cpp | 3 ++- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/g2core/config.cpp b/g2core/config.cpp index 786ea4c2..1bd30616 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -239,7 +239,8 @@ stat_t get_flt(nvObj_t *nv) } /* Generic sets() - * set_nul() - set nothing + * set_noop() - set nothing and return OK + * set_nul() - set nothing and return READ_ONLY error * set_ui8() - set value as 8 bit uint8_t value * set_int8() - set value as an 8 bit int8_t value * set_01() - set a 0 or 1 uint8_t value with validation @@ -250,11 +251,17 @@ stat_t get_flt(nvObj_t *nv) * set_flt() - set value as float */ +stat_t set_noop(nvObj_t *nv) { + nv->valuetype = TYPE_NULL; + return (STAT_OK); // hack until JSON is refactored +} + stat_t set_nul(nvObj_t *nv) { nv->valuetype = TYPE_NULL; return (STAT_PARAMETER_IS_READ_ONLY); // this is what it should be // return (STAT_OK); // hack until JSON is refactored } + stat_t set_ui8(nvObj_t *nv) { *((uint8_t *)GET_TABLE_WORD(target)) = nv->value; diff --git a/g2core/config.h b/g2core/config.h index dc6cdbcd..82a7184f 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -317,7 +317,8 @@ bool nv_index_lt_groups(index_t index); // (see config_app.c) bool nv_group_is_prefixed(char *group); // generic internal functions and accessors -stat_t set_nul(nvObj_t *nv); // set nothing +stat_t set_noop(nvObj_t *nv); // set nothing and return OK +stat_t set_nul(nvObj_t *nv); // set nothing and return READ_ONLY error stat_t set_ui8(nvObj_t *nv); // set uint8_t value stat_t set_int8(nvObj_t *nv); // set signed 8 bit integer stat_t set_01(nvObj_t *nv); // set a 0 or 1 value with validation diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index bef30edc..e146fc94 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -198,8 +198,8 @@ const cfgItem_t cfgArray[] = { // Motor parameters { "1","1ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, - { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, - { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, + { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, + { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, { "1","1su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, @@ -655,22 +655,22 @@ const cfgItem_t cfgArray[] = { { "", "gc", _f0, 0, tx_print_nul, gc_get_gc,gc_run_gc,(float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports - { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports - { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available - { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue - { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue - { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing - { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush - { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets - { "", "msg", _f0, 0, tx_print_str, get_nul, set_nul, (float *)&cs.null, 0 }, // string for generic messages - { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm - { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic - { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown - { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state - { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" - { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic - { "", "tram", _f0,0, cm_print_tram, cm_get_tram,cm_set_tram, (float *)&cs.null, 0 },// SET to attempt setting rotation matrix from probes - { "", "defa",_f0, 0, tx_print_nul, help_defa, set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen + { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports + { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available + { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue + { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue + { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing + { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush + { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets + { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages + { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm + { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic + { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown + { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state + { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" + { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic + { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes + { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, { "", "switch",_f0,0, tx_print_nul, get_nul, mp_switch_q, (float *)&cs.null,0 }, { "", "return",_f0,0, tx_print_nul, get_nul, mp_return_q, (float *)&cs.null,0 }, @@ -1110,7 +1110,8 @@ stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - value = nv->value; // note: valuetype = TYPE_INT already set + value = nv->value; + nv->valuetype = TYPE_INT; return (STAT_OK); } @@ -1137,6 +1138,7 @@ stat_t set_int32(nvObj_t *nv, uint32_t &value, uint32_t low, uint32_t high) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } value = nv->value; // note: valuetype = TYPE_INT already set + nv->valuetype = TYPE_INT; return (STAT_OK); } diff --git a/g2core/error.h b/g2core/error.h index 8d4ca4ec..6bfbce34 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -204,7 +204,7 @@ char *get_status_message(stat_t status); #define STAT_MAX_DEPTH_EXCEEDED 115 // JSON exceeded maximum nesting depth #define STAT_VALUE_TYPE_ERROR 116 // JSON value does not agree with variable type -#define STAT_ERROR_117 117 +#define STAT_ERROR_DEVICE_NOT_ACTIVE 117 // Device cannot receive commands at this time #define STAT_ERROR_118 118 #define STAT_ERROR_119 119 @@ -501,7 +501,7 @@ static const char stat_113[] = "JSON string too long"; static const char stat_114[] = "JSON txt fields cannot be nested"; static const char stat_115[] = "JSON maximum nesting depth exceeded"; static const char stat_116[] = "JSON value does not agree with variable type"; -static const char stat_117[] = "117"; +static const char stat_117[] = "Device not active"; static const char stat_118[] = "118"; static const char stat_119[] = "119"; diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index b0c2b241..fd994209 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -894,7 +894,8 @@ stat_t st_set_mi(nvObj_t *nv) return (STAT_OK); } -stat_t st_set_su(nvObj_t *nv) // motor steps per unit (direct) +// motor steps per unit (direct) +stat_t st_set_su(nvObj_t *nv) { uint8_t m = _motor(nv->index); // Do the unit conversion here (rather than using set_flu) because it's a reciprocal value From e70f003d7757b73a334d7f8c24607ef38c77064b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 13 Dec 2016 19:31:30 -0500 Subject: [PATCH 042/283] Refactored motor su setting to use new getter/setter code --- g2core/canonical_machine.cpp | 11 ++++-- g2core/canonical_machine.h | 1 + g2core/config_app.cpp | 70 ++++++++++++++++++++---------------- g2core/g2core.cppproj | 8 ++--- g2core/stepper.cpp | 48 ++++++++++++++++--------- g2core/stepper.h | 8 +++-- 6 files changed, 91 insertions(+), 55 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 7d292cb5..5632b1ba 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2084,6 +2084,7 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; * _coord() - return coordinate system number or -1 if error * cm_get_axis_char() - return ASCII char for axis given the axis number * cm_get_axis_type() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) + * cm_get_axis_type_by_axis() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) */ static int8_t _axis(const index_t index) @@ -2121,9 +2122,13 @@ char cm_get_axis_char(const int8_t axis) cmAxisType cm_get_axis_type(const index_t index) { - int8_t axis = _axis(index); - if (axis >= AXIS_A) return (AXIS_TYPE_ROTARY); - if (axis == -1) return (AXIS_TYPE_UNDEFINED); + return (cm_get_axis_type_by_axis(_axis(index))); +} + +cmAxisType cm_get_axis_type_by_axis(const int8_t axis) +{ + if (axis >= AXIS_A) { return (AXIS_TYPE_ROTARY); } + if (axis == -1) { return (AXIS_TYPE_UNDEFINED); } return (AXIS_TYPE_LINEAR); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 26f8c06c..26224296 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -424,6 +424,7 @@ float cm_get_jogging_dest(void); // get jogging d char cm_get_axis_char(const int8_t axis); cmAxisType cm_get_axis_type(const index_t index); +cmAxisType cm_get_axis_type_by_axis(const int8_t axis); stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index e146fc94..61b380a0 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -200,7 +200,7 @@ const cfgItem_t cfgArray[] = { { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, - { "1","1su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, + { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, { "1","1pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_1].power_level, M1_POWER_LEVEL }, @@ -211,7 +211,7 @@ const cfgItem_t cfgArray[] = { { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, { "2","2tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, - { "2","2su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, + { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M2_STEPS_PER_UNIT }, { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, { "2","2pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_2].power_level, M2_POWER_LEVEL}, @@ -223,7 +223,7 @@ const cfgItem_t cfgArray[] = { { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, { "3","3tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, - { "3","3su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, + { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M3_STEPS_PER_UNIT }, { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, { "3","3pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_3].power_level, M3_POWER_LEVEL }, @@ -235,7 +235,7 @@ const cfgItem_t cfgArray[] = { { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, { "4","4tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, - { "4","4su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, + { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M4_STEPS_PER_UNIT }, { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, { "4","4pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_4].power_level, M4_POWER_LEVEL }, @@ -247,7 +247,7 @@ const cfgItem_t cfgArray[] = { { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, { "5","5tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, - { "5","5su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, + { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M5_STEPS_PER_UNIT }, { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, { "5","5pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_5].power_level, M5_POWER_LEVEL }, @@ -259,7 +259,7 @@ const cfgItem_t cfgArray[] = { { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, { "6","6tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, - { "6","6su",_fipi,5, st_print_su, get_flt, st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, + { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M6_STEPS_PER_UNIT }, { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, { "6","6pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_6].power_level, M6_POWER_LEVEL }, @@ -997,28 +997,22 @@ stat_t set_flu(nvObj_t *nv) /* * process_incoming_float() - pre-process an incoming floating point number for canonical units * process_outgoing_float() - pre-process an outgoing floating point number for units display - * get_float() - boilerplate for retrieving raw floating point value - * set_float() - boilerplate for setting a floating point value with unit conversion - * set_float_range() - set a floating point value with inclusive range check * - * get_float() returns a raw float value in internal canonical units (e.g. mm, degrees) - * without units conversion. If conversion is required call preprocess_outgoing_float() - * afterwards. The text mode and JSON display routines do this, so you generally don't - * have to worry about this. - * - * set_float() is designed to capture incoming float values, so it performs unit conversion. - * set_float_range() perfoems an inclusive range test on the CONVERTED value + * Incoming floats are destined for SET operations.perform conditional unit conversion if + * the flags indicate. Note that SU (inverse conversion) is not converted here, but in the + * set_su function. + * + * Outgoing floats are the raw values from GET operations, destined for text or JSON display. + * These are conditionally unit converted, including SU. */ void process_incoming_float(nvObj_t *nv) { if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type - uint8_t f; - f = GET_TABLE_BYTE(flags); -// if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? - if (f & F_CONVERT) { // unit conversion required? - if (cm_get_units_mode(MODEL) == INCHES) { // If inn inches mode + uint8_t flags = GET_TABLE_BYTE(flags); + if (flags & F_CONVERT) { // is unit conversion required? + if (cm_get_units_mode(MODEL) == INCHES) { // if in inches mode if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... nv->value *= MM_PER_INCH; // convert to canonical millimeter units } @@ -1032,21 +1026,37 @@ void process_outgoing_float(nvObj_t *nv) if (isnan((double)nv->value) || isinf((double)nv->value)) { return; } // trap illegal float values ///+++ transform these checks into NaN or INF strings with an error return? - uint8_t f; - f = GET_TABLE_BYTE(flags); - if (f & (F_CONVERT | F_ICONVERT)) { // unit conversion required? - if (cm_get_units_mode(MODEL) == INCHES) { - if(f & F_ICONVERT) { - nv->value *= MM_PER_INCH; - } else { + // We may need one of two types of units conversion, but only if in inches mode + if (cm_get_units_mode(MODEL) == INCHES) { + uint8_t flags = GET_TABLE_BYTE(flags); + if (flags & F_CONVERT) { // standard units conversion + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { nv->value *= INCHES_PER_MM; - } - } + } + } else if (flags & F_ICONVERT) { // inverse units conversion + if (st_get_axis_type_by_motor(nv->index) == AXIS_TYPE_LINEAR) { // axis motor is mapped to + nv->value *= MM_PER_INCH; + } + } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; } +/* + * get_float() - boilerplate for retrieving raw floating point value + * set_float() - boilerplate for setting a floating point value with unit conversion + * set_float_range() - set a floating point value with inclusive range check + * + * get_float() returns a raw float value in internal canonical units (e.g. mm, degrees) + * without units conversion. If conversion is required call preprocess_outgoing_float() + * afterwards. The text mode and JSON display routines do this, so you generally don't + * have to worry about this. + * + * set_float() is designed to capture incoming float values, so it performs unit conversion. + * set_float_range() perfoems an inclusive range test on the CONVERTED value + */ + stat_t get_float(nvObj_t *nv, const float value) { nv->value = value; nv->valuetype = TYPE_FLOAT; diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index bf644c0b..d57acc1f 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 7992324 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 7992324 + 10000000 diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index fd994209..bf7e2ef7 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -812,7 +812,7 @@ static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps) ***********************************************************************************/ /* HELPERS - * _get_motor() - helper to return motor number as an index or -1 if na + * _motor() - motor number as an index or -1 if na */ static int8_t _motor(const index_t index) @@ -828,16 +828,24 @@ static int8_t _motor(const index_t index) return (ptr - motors); } +cmAxisType st_get_axis_type_by_motor(const index_t index) +{ + return (cm_get_axis_type_by_axis(st_cfg.mot[_motor(index)].motor_map)); +} + /* * _set_motor_steps_per_unit() - what it says * This function will need to be rethought if microstep morphing is implemented */ -static void _set_motor_steps_per_unit(nvObj_t *nv) +static float _set_motor_steps_per_unit(nvObj_t *nv) { uint8_t m = _motor(nv->index); - st_cfg.mot[m].units_per_step = (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle) / (360 * st_cfg.mot[m].microsteps); + st_cfg.mot[m].units_per_step = (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle) / + (360 * st_cfg.mot[m].microsteps); + st_cfg.mot[m].steps_per_unit = 1/st_cfg.mot[m].units_per_step; + return (st_cfg.mot[m].steps_per_unit); } /* PER-MOTOR FUNCTIONS @@ -895,27 +903,35 @@ stat_t st_set_mi(nvObj_t *nv) } // motor steps per unit (direct) +stat_t st_get_su(nvObj_t *nv) +{ + return(get_float(nv, st_cfg.mot[_motor(nv->index)].steps_per_unit)); +} + stat_t st_set_su(nvObj_t *nv) { - uint8_t m = _motor(nv->index); - // Do the unit conversion here (rather than using set_flu) because it's a reciprocal value - if ((m <= 3) && (cm_get_units_mode(MODEL) == INCHES)) { - nv->value *= INCHES_PER_MM; - } - + // Don't set a zero or negative value - just calculate based on sa, tr, and mi + // This way, if STEPS_PER_UNIT is set to 0 it is unused and we get the computed value if(nv->value <= 0) { - // Don't set a zero or negative value - just calculate based on sa,tr,mi - // This way, if we set the STEPS_PER_UNIT to default to 0, it is unused and we get the computed value - _set_motor_steps_per_unit(nv); + nv->value = _set_motor_steps_per_unit(nv); return(STAT_OK); } - - set_flt(nv); + + // Do unit conversion here because it's a reciprocal value (rather than process_incoming_float()) + uint8_t m = _motor(nv->index); + if (cm_get_units_mode(MODEL) == INCHES) { + uint8_t a = st_cfg.mot[m].motor_map; + if (cm_get_axis_type_by_axis(a) == AXIS_TYPE_LINEAR) { + nv->value *= INCHES_PER_MM; + } + } + st_cfg.mot[m].steps_per_unit = nv->value; st_cfg.mot[m].units_per_step = 1.0/st_cfg.mot[m].steps_per_unit; + // Scale TR so all the other values make sense // You could scale any one of the other values, but TR makes the most sense - st_cfg.mot[m].travel_rev = (360.0*st_cfg.mot[m].microsteps)/(st_cfg.mot[m].steps_per_unit*st_cfg.mot[m].step_angle); - + st_cfg.mot[m].travel_rev = (360.0 * st_cfg.mot[m].microsteps) / + (st_cfg.mot[m].steps_per_unit * st_cfg.mot[m].step_angle); return(STAT_OK); } diff --git a/g2core/stepper.h b/g2core/stepper.h index 36c650a7..50f8ce7f 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -576,9 +576,10 @@ void st_prep_null(void); void st_prep_command(void *bf); // use a void pointer since we don't know about mpBuf_t yet) void st_prep_dwell(float microseconds); void st_request_out_of_band_dwell(float microseconds); -//stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time); stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time); +cmAxisType st_get_axis_type_by_motor(const index_t index); + stat_t st_get_ma(nvObj_t *nv); stat_t st_set_ma(nvObj_t *nv); stat_t st_get_sa(nvObj_t *nv); @@ -588,10 +589,13 @@ stat_t st_set_tr(nvObj_t *nv); stat_t st_get_mi(nvObj_t *nv); stat_t st_set_mi(nvObj_t *nv); +stat_t st_get_su(nvObj_t *nv); stat_t st_set_su(nvObj_t *nv); -stat_t st_set_pm(nvObj_t *nv); stat_t st_get_pm(nvObj_t *nv); +stat_t st_set_pm(nvObj_t *nv); +stat_t st_get_pl(nvObj_t *nv); stat_t st_set_pl(nvObj_t *nv); + stat_t st_get_pwr(nvObj_t *nv); stat_t st_get_mt(nvObj_t *nv); From 85044a216c4d78dd4bce9ce6dba9a9bfffc9a420 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 13 Dec 2016 20:35:59 -0500 Subject: [PATCH 043/283] Refactored po, pl - tested all settings --- g2core/config_app.cpp | 51 ++++++++++++++++++----------------- g2core/stepper.cpp | 63 +++++++++++++++++-------------------------- g2core/stepper.h | 6 +++-- 3 files changed, 55 insertions(+), 65 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 61b380a0..ef41c185 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -200,23 +200,23 @@ const cfgItem_t cfgArray[] = { { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, - { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, - { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, + { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M1_STEPS_PER_UNIT }, + { "1","1po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M1_POLARITY }, { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, - { "1","1pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_1].power_level, M1_POWER_LEVEL }, -// { "1","1pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, -// { "1","1mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, + { "1","1pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M1_POWER_LEVEL }, +// { "1","1pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, +// { "1","1mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, #if (MOTORS >= 2) { "2","2ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, { "2","2tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M2_STEPS_PER_UNIT }, - { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, + { "2","2po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M2_POLARITY }, { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, - { "2","2pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_2].power_level, M2_POWER_LEVEL}, -// { "2","2pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, -// { "2","2mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, + { "2","2pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M2_POWER_LEVEL}, +// { "2","2pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, +// { "2","2mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 3) { "3","3ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, @@ -224,11 +224,11 @@ const cfgItem_t cfgArray[] = { { "3","3tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M3_STEPS_PER_UNIT }, - { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, + { "3","3po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M3_POLARITY }, { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, - { "3","3pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_3].power_level, M3_POWER_LEVEL }, -// { "3","3pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, -// { "3","3mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, + { "3","3pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M3_POWER_LEVEL }, +// { "3","3pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, +// { "3","3mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 4) { "4","4ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, @@ -236,11 +236,11 @@ const cfgItem_t cfgArray[] = { { "4","4tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M4_STEPS_PER_UNIT }, - { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, + { "4","4po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M4_POLARITY }, { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, - { "4","4pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_4].power_level, M4_POWER_LEVEL }, -// { "4","4pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, -// { "4","4mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, + { "4","4pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M4_POWER_LEVEL }, +// { "4","4pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, +// { "4","4mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 5) { "5","5ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, @@ -248,10 +248,10 @@ const cfgItem_t cfgArray[] = { { "5","5tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M5_STEPS_PER_UNIT }, - { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, + { "5","5po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M5_POLARITY }, { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, - { "5","5pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_5].power_level, M5_POWER_LEVEL }, -// { "5","5pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, + { "5","5pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M5_POWER_LEVEL }, +// { "5","5pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, // { "5","5mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_5].motor_timeout, M5_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 6) @@ -260,11 +260,11 @@ const cfgItem_t cfgArray[] = { { "6","6tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M6_STEPS_PER_UNIT }, - { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, + { "6","6po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M6_POLARITY }, { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, - { "6","6pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_6].power_level, M6_POWER_LEVEL }, -// { "6","6pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, -// { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, + { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M6_POWER_LEVEL }, +// { "6","6pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, +// { "6","6mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, #endif // Axis parameters { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, @@ -612,7 +612,8 @@ const cfgItem_t cfgArray[] = { { "sys","fro", _fipn,3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, { "sys","troe",_fipn,0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, { "sys","tro", _fipn,3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, - { "sys","mt", _fipn,2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, +// { "sys","mt", _fipn,2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, + { "sys","mt", _fipn,2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors // { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index bf7e2ef7..3b2bbee3 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -935,50 +935,43 @@ stat_t st_set_su(nvObj_t *nv) return(STAT_OK); } -stat_t st_set_pm(nvObj_t *nv) // set motor power mode +// polarity +stat_t st_get_po(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].polarity)); } +stat_t st_set_po(nvObj_t *nv) { return(set_int(nv, st_cfg.mot[_motor(nv->index)].polarity, 0, 1)); } + +// power management mode +stat_t st_get_pm(nvObj_t *nv) { - if (nv->value >= MOTOR_POWER_MODE_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - - uint8_t motor = _motor(nv->index); - if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; - - Motors[motor]->setPowerMode((stPowerMode)nv->value); - // We do this *here* in order for this to take effect immediately. - // setPowerMode() sets the value and also executes it. - return (STAT_OK); -} - -stat_t st_get_pm(nvObj_t *nv) // get motor power mode -{ - if (nv->value >= MOTOR_POWER_MODE_MAX_VALUE) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - - uint8_t motor = _motor(nv->index); - if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; - - nv->value = (float)Motors[motor]->getPowerMode(); + nv->value = (float)Motors[_motor(nv->index)]->getPowerMode(); nv->valuetype = TYPE_INT; return (STAT_OK); } +stat_t st_set_pm(nvObj_t *nv) +{ + // Test the value without setting it, then setPowerMode() now + // to both set and take effect immediately. + ritorno(set_int(nv, (uint8_t &)cs.null, 0, MOTOR_POWER_MODE_MAX_VALUE )); + Motors[_motor(nv->index)]->setPowerMode((stPowerMode)nv->value); + return (STAT_OK); +} + /* + * st_get_pl() - get motor power level * st_set_pl() - set motor power level * * Input value may vary from 0.000 to 1.000 The setting is scaled to allowable PWM range. * This function sets both the scaled and dynamic power levels, and applies the * scaled value to the vref. */ -stat_t st_set_pl(nvObj_t *nv) // motor power level +stat_t st_get_pl(nvObj_t *nv) { return(get_float(nv, st_cfg.mot[_motor(nv->index)].power_level)); } +stat_t st_set_pl(nvObj_t *nv) { - if ((nv->value < (float)0.0) || (nv->value > (float)1.0)) { - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - set_flt(nv); // set power_setting value in the motor config struct (st) - - uint8_t motor = _motor(nv->index); - st_cfg.mot[motor].power_level_scaled = (nv->value * POWER_LEVEL_SCALE_FACTOR); - st_run.mot[motor].power_level_dynamic = (st_cfg.mot[motor].power_level_scaled); - Motors[motor]->setPowerLevel(st_cfg.mot[motor].power_level_scaled); - + uint8_t m = _motor(nv->index); + ritorno(set_float_range(nv, st_cfg.mot[m].power_level, 0.0, 1.0)); + st_cfg.mot[m].power_level_scaled = (nv->value * POWER_LEVEL_SCALE_FACTOR); + st_run.mot[m].power_level_dynamic = (st_cfg.mot[m].power_level_scaled); + Motors[m]->setPowerLevel(st_cfg.mot[m].power_level_scaled); return(STAT_OK); } @@ -1017,13 +1010,7 @@ stat_t st_get_mt(nvObj_t *nv) { return(get_float(nv, st_cfg.motor_power_timeout) stat_t st_set_mt(nvObj_t *nv) { return(set_float_range(nv, st_cfg.motor_power_timeout, MOTOR_TIMEOUT_SECONDS_MAX, MOTOR_TIMEOUT_SECONDS_MIN)); } -/* -stat_t st_set_mt(nvObj_t *nv) -{ - st_cfg.motor_power_timeout = min(MOTOR_TIMEOUT_SECONDS_MAX, max(nv->value, MOTOR_TIMEOUT_SECONDS_MIN)); - return (STAT_OK); -} -*/ + stat_t st_set_me(nvObj_t *nv) // Make sure this function is not part of initialization --> f00 { for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { diff --git a/g2core/stepper.h b/g2core/stepper.h index 50f8ce7f..a56385a3 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -278,9 +278,9 @@ typedef enum { MOTOR_DISABLED = 0, // motor enable is deactivated MOTOR_ALWAYS_POWERED, // motor is always powered while machine is ON MOTOR_POWERED_IN_CYCLE, // motor fully powered during cycles, de-powered out of cycle - MOTOR_POWERED_ONLY_WHEN_MOVING, // motor only powered while moving - idles shortly after it's stopped - even in cycle - MOTOR_POWER_MODE_MAX_VALUE // for input range checking + MOTOR_POWERED_ONLY_WHEN_MOVING // motor only powered while moving - idles shortly after it's stopped - even in cycle } stPowerMode; +#define MOTOR_POWER_MODE_MAX_VALUE MOTOR_POWERED_ONLY_WHEN_MOVING // Stepper power management settings #define Vcc 3.3 // volts @@ -591,6 +591,8 @@ stat_t st_set_mi(nvObj_t *nv); stat_t st_get_su(nvObj_t *nv); stat_t st_set_su(nvObj_t *nv); +stat_t st_get_po(nvObj_t *nv); +stat_t st_set_po(nvObj_t *nv); stat_t st_get_pm(nvObj_t *nv); stat_t st_set_pm(nvObj_t *nv); stat_t st_get_pl(nvObj_t *nv); From 642236dbd9129543f310bf7f3e3b8e149b7b4b86 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 18 Dec 2016 08:51:35 -0500 Subject: [PATCH 044/283] Moved arc structure into canonical machine; Testing refactored canonical machine settings --- g2core/canonical_machine.cpp | 6 +- g2core/canonical_machine.h | 41 +++++++- g2core/g2core.cppproj | 4 +- g2core/plan_arc.cpp | 196 ++++++++++++++++++----------------- g2core/plan_arc.h | 4 +- 5 files changed, 148 insertions(+), 103 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 5632b1ba..a718f846 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -767,15 +767,15 @@ void canonical_machine_init_assertions(void) cm->magic_end = MAGICNUM; cm->gmx.magic_start = MAGICNUM; cm->gmx.magic_end = MAGICNUM; - arc.magic_start = MAGICNUM; - arc.magic_end = MAGICNUM; + cm->arc.magic_start = MAGICNUM; + cm->arc.magic_end = MAGICNUM; } stat_t canonical_machine_test_assertions(void) { if ((BAD_MAGIC(cm->magic_start)) || (BAD_MAGIC(cm->magic_end)) || (BAD_MAGIC(cm->gmx.magic_start)) || (BAD_MAGIC(cm->gmx.magic_end)) || - (BAD_MAGIC(arc.magic_start)) || (BAD_MAGIC(arc.magic_end))) { + (BAD_MAGIC(cm->arc.magic_start)) || (BAD_MAGIC(cm->arc.magic_end))) { return(cm_panic(STAT_CANONICAL_MACHINE_ASSERTION_FAILURE, "canonical_machine_test_assertions()")); } return (STAT_OK); diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 26224296..ea88ebb3 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -176,6 +176,43 @@ typedef struct cmAxis { float zero_backoff; // backoff from switches for machine zero } cfgAxis_t; +typedef struct arArcSingleton { // persistent planner and runtime variables + magic_t magic_start; + uint8_t run_state; // runtime state machine sequence + + float position[AXES]; // accumulating runtime position + float offset[3]; // arc IJK offsets + + float length; // length of line or helix in mm + float radius; // Raw R value, or computed via offsets + float theta; // starting angle of arc + float angular_travel; // travel along the arc in radians + float planar_travel; // travel in arc plane in mm + float linear_travel; // travel along linear axis of arc in mm + bool full_circle; // True if full circle arcs specified + float rotations; // number of full rotations to add (P value + sign) + + cmAxes plane_axis_0; // arc plane axis 0 - e.g. X for G17 + cmAxes plane_axis_1; // arc plane axis 1 - e.g. Y for G17 + cmAxes linear_axis; // linear axis (normal to plane) + + float segments; // number of segments in arc or blend + int32_t segment_count; // count of running segments + float segment_theta; // angular motion per segment + float segment_linear_travel; // linear motion per segment + float center_0; // center of circle at plane axis 0 (e.g. X for G17) + float center_1; // center of circle at plane axis 1 (e.g. Y for G17) + + GCodeState_t gm; // Gcode state struct is passed for each arc segment. + // Usage: + // uint32_t linenum; // line number of the arc feed move - same for each segment + // float target[AXES]; // arc segment target + // float work_offset[AXES]; // offset from machine coord system for reporting (same for each segment) + // float block_time; // segment_time: constant time per aline segment + + magic_t magic_end; +} arc_t; + typedef struct cmMachine { // struct to manage canonical machine globals and state magic_t magic_start; // magic number to test memory integrity @@ -230,7 +267,8 @@ typedef struct cmMachine { // struct to manage canonical machin float jogging_dest; // jogging destination as a relative move from current position - /**** Model states ****/ + /**** Model state structures ****/ + arc_t arc; // arc parameters GCodeState_t *am; // active Gcode model is maintained by state management GCodeState_t gm; // core gcode model state GCodeStateX_t gmx; // extended gcode model state @@ -243,6 +281,7 @@ typedef struct cmMachine { // struct to manage canonical machin extern cmMachine_t *cm; // pointer to active canonical machine extern cmMachine_t cm0; // canonical machine primary machine extern cmMachine_t cm1; // canonical machine secondary machine +//extern arc_t arc; /***************************************************************************** * FUNCTION PROTOTYPES diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index d57acc1f..c8cc86a8 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index e6639897..47e7cf57 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -26,7 +26,7 @@ // Allocate arc planner singleton structure -arc_t arc; +//arc_t arc; // Local functions @@ -49,8 +49,8 @@ static stat_t _test_arc_soft_limits(void); */ void cm_arc_init() { - arc.magic_start = MAGICNUM; - arc.magic_end = MAGICNUM; + cm->arc.magic_start = MAGICNUM; + cm->arc.magic_end = MAGICNUM; } /* @@ -61,7 +61,7 @@ void cm_arc_init() void cm_abort_arc() { - arc.run_state = BLOCK_INACTIVE; + cm->arc.run_state = BLOCK_INACTIVE; } /* @@ -75,24 +75,24 @@ void cm_abort_arc() stat_t cm_arc_callback() { - if (arc.run_state == BLOCK_INACTIVE) { + if (cm->arc.run_state == BLOCK_INACTIVE) { return (STAT_NOOP); } if (mp_planner_is_full(ACTIVE_Q)) { return (STAT_EAGAIN); } - arc.theta += arc.segment_theta; - arc.gm.target[arc.plane_axis_0] = arc.center_0 + sin(arc.theta) * arc.radius; - arc.gm.target[arc.plane_axis_1] = arc.center_1 + cos(arc.theta) * arc.radius; - arc.gm.target[arc.linear_axis] += arc.segment_linear_travel; + cm->arc.theta += cm->arc.segment_theta; + cm->arc.gm.target[cm->arc.plane_axis_0] = cm->arc.center_0 + sin(cm->arc.theta) * cm->arc.radius; + cm->arc.gm.target[cm->arc.plane_axis_1] = cm->arc.center_1 + cos(cm->arc.theta) * cm->arc.radius; + cm->arc.gm.target[cm->arc.linear_axis] += cm->arc.segment_linear_travel; - mp_aline(&arc.gm); // run the line - copy_vector(arc.position, arc.gm.target); // update arc current position + mp_aline(&(cm->arc.gm)); // run the line + copy_vector(cm->arc.position, cm->arc.gm.target); // update arc current position - if (--arc.segment_count > 0) { + if (--(cm->arc.segment_count) > 0) { return (STAT_EAGAIN); } - arc.run_state = BLOCK_INACTIVE; + cm->arc.run_state = BLOCK_INACTIVE; return (STAT_OK); } @@ -142,41 +142,41 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // Set the arc plane for the current G17/G18/G19 setting and test arc specification // Plane axis 0 and 1 are the arc plane, the linear axis is normal to the arc plane. if (cm->gm.select_plane == CANON_PLANE_XY) { // G17 - the vast majority of arcs are in the G17 (XY) plane - arc.plane_axis_0 = AXIS_X; - arc.plane_axis_1 = AXIS_Y; - arc.linear_axis = AXIS_Z; + cm->arc.plane_axis_0 = AXIS_X; + cm->arc.plane_axis_1 = AXIS_Y; + cm->arc.linear_axis = AXIS_Z; } else if (cm->gm.select_plane == CANON_PLANE_XZ) { // G18 - arc.plane_axis_0 = AXIS_X; - arc.plane_axis_1 = AXIS_Z; - arc.linear_axis = AXIS_Y; + cm->arc.plane_axis_0 = AXIS_X; + cm->arc.plane_axis_1 = AXIS_Z; + cm->arc.linear_axis = AXIS_Y; } else if (cm->gm.select_plane == CANON_PLANE_YZ) { // G19 - arc.plane_axis_0 = AXIS_Y; - arc.plane_axis_1 = AXIS_Z; - arc.linear_axis = AXIS_X; + cm->arc.plane_axis_0 = AXIS_Y; + cm->arc.plane_axis_1 = AXIS_Z; + cm->arc.linear_axis = AXIS_X; } else { return(cm_panic(STAT_ACTIVE_PLANE_IS_MISSING, "cm_arc_feed() impossible value")); // plane axis has impossible value } // test if no endpoints are specified in the selected plane - arc.full_circle = false; // initial condition - if (!(target_f[arc.plane_axis_0] || target_f[arc.plane_axis_1])) { + cm->arc.full_circle = false; // initial condition + if (!(target_f[cm->arc.plane_axis_0] || target_f[cm->arc.plane_axis_1])) { if (radius_f) { // in radius mode arcs missing both endpoints is an error return (STAT_ARC_AXIS_MISSING_FOR_SELECTED_PLANE); } else { - arc.full_circle = true; // in center format arc this specifies a full circle + cm->arc.full_circle = true; // in center format arc this specifies a full circle } } // test radius arcs for radius tolerance if (radius_f) { - arc.radius = _to_millimeters(radius); // set radius to internal format (mm) - if (fabs(arc.radius) < MIN_ARC_RADIUS) { // radius value must be > minimum radius + cm->arc.radius = _to_millimeters(radius); // set radius to internal format (mm) + if (fabs(cm->arc.radius) < MIN_ARC_RADIUS) { // radius value must be > minimum radius return (STAT_ARC_RADIUS_OUT_OF_TOLERANCE); } } else { // test that center format absolute distance mode arcs have both offsets specified if (cm->gm.arc_distance_mode == ABSOLUTE_MODE) { - if (!(offset_f[arc.plane_axis_0] && offset_f[arc.plane_axis_1])) { // if one or both offsets are missing + if (!(offset_f[cm->arc.plane_axis_0] && offset_f[cm->arc.plane_axis_1])) { // if one or both offsets are missing return (STAT_ARC_OFFSETS_MISSING_FOR_SELECTED_PLANE); } } @@ -190,12 +190,12 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en if (floor(P_word) - (P_word) > 0) { return (STAT_P_WORD_IS_NOT_AN_INTEGER); } - arc.rotations = P_word; + cm->arc.rotations = P_word; } else { - if (arc.full_circle) { // arc rotations default to 1 for full circles - arc.rotations = 1; + if (cm->arc.full_circle) { // arc rotations default to 1 for full circles + cm->arc.rotations = 1; } else { - arc.rotations = 0; // no rotations + cm->arc.rotations = 0; // no rotations } } @@ -213,24 +213,24 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // *** now get down to the rest of the work setting up the arc for execution *** cm->gm.motion_mode = motion_mode; - cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to gm - memcpy(&arc.gm, &cm->gm, sizeof(GCodeState_t)); // copy GCode context to arc singleton - some will be overwritten to run segments - copy_vector(arc.position, cm->gmx.position); // set initial arc position from gcode model + cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to gm + memcpy(&(cm->arc.gm), &cm->gm, sizeof(GCodeState_t)); // copy GCode context to arc singleton - some will be overwritten to run segments + copy_vector(cm->arc.position, cm->gmx.position); // set initial arc position from gcode model // setup offsets - arc.offset[OFS_I] = _to_millimeters(offset[OFS_I]); // copy offsets with conversion to canonical form (mm) - arc.offset[OFS_J] = _to_millimeters(offset[OFS_J]); - arc.offset[OFS_K] = _to_millimeters(offset[OFS_K]); + cm->arc.offset[OFS_I] = _to_millimeters(offset[OFS_I]); // copy offsets with conversion to canonical form (mm) + cm->arc.offset[OFS_J] = _to_millimeters(offset[OFS_J]); + cm->arc.offset[OFS_K] = _to_millimeters(offset[OFS_K]); - if (arc.gm.arc_distance_mode == ABSOLUTE_MODE) { // adjust offsets if in absolute mode - arc.offset[OFS_I] -= arc.position[AXIS_X]; - arc.offset[OFS_J] -= arc.position[AXIS_Y]; - arc.offset[OFS_K] -= arc.position[AXIS_Z]; + if (cm->arc.gm.arc_distance_mode == ABSOLUTE_MODE) { // adjust offsets if in absolute mode + cm->arc.offset[OFS_I] -= cm->arc.position[AXIS_X]; + cm->arc.offset[OFS_J] -= cm->arc.position[AXIS_Y]; + cm->arc.offset[OFS_K] -= cm->arc.position[AXIS_Z]; } - if ((fp_ZERO(arc.offset[OFS_I])) && // it's an error if no offsets are provided - (fp_ZERO(arc.offset[OFS_J])) && - (fp_ZERO(arc.offset[OFS_K]))) { + if ((fp_ZERO(cm->arc.offset[OFS_I])) && // it's an error if no offsets are provided + (fp_ZERO(cm->arc.offset[OFS_J])) && + (fp_ZERO(cm->arc.offset[OFS_K]))) { return (cm_alarm(STAT_ARC_OFFSETS_MISSING_FOR_SELECTED_PLANE, "arc offsets missing or zero")); } @@ -241,12 +241,12 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en stat_t status = _test_arc_soft_limits(); if (status != STAT_OK) { cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - copy_vector(cm->gm.target, arc.position); // reset model position - return (cm_alarm(status, "arc soft_limits")); // throw an alarm + copy_vector(cm->gm.target, cm->arc.position); // reset model position + return (cm_alarm(status, "arc soft_limits")); // throw an alarm } - cm_cycle_start(); // if not already started - arc.run_state = BLOCK_ACTIVE; // enable arc to be run from the callback + cm_cycle_start(); // if not already started + cm->arc.run_state = BLOCK_ACTIVE; // enable arc to be run from the callback cm_finalize_move(); return (STAT_OK); } @@ -275,7 +275,7 @@ static stat_t _compute_arc(const bool radius_f) if (radius_f) { // indicates a radius arc _compute_arc_offsets_from_radius(); } else { // compute start radius - arc.radius = hypotf(-arc.offset[arc.plane_axis_0], -arc.offset[arc.plane_axis_1]); + cm->arc.radius = hypotf(-cm->arc.offset[cm->arc.plane_axis_0], -cm->arc.offset[cm->arc.plane_axis_1]); } // Test arc specification for correctness according to: @@ -285,68 +285,74 @@ static stat_t _compute_arc(const bool radius_f) // center by more than (.05 inch/.5 mm) OR ((.0005 inch/.005mm) AND .1% of radius)." // Compute end radius from the center of circle (offsets) to target endpoint - float end_0 = arc.gm.target[arc.plane_axis_0] - arc.position[arc.plane_axis_0] - arc.offset[arc.plane_axis_0]; - float end_1 = arc.gm.target[arc.plane_axis_1] - arc.position[arc.plane_axis_1] - arc.offset[arc.plane_axis_1]; - float err = fabs(hypotf(end_0, end_1) - arc.radius); // end radius - start radius + float end_0 = cm->arc.gm.target[cm->arc.plane_axis_0] - + cm->arc.position[cm->arc.plane_axis_0] - + cm->arc.offset[cm->arc.plane_axis_0]; + + float end_1 = cm->arc.gm.target[cm->arc.plane_axis_1] - + cm->arc.position[cm->arc.plane_axis_1] - + cm->arc.offset[cm->arc.plane_axis_1]; + + float err = fabs(hypotf(end_0, end_1) - cm->arc.radius); // end radius - start radius if ((err > ARC_RADIUS_ERROR_MAX) || - ((err > ARC_RADIUS_ERROR_MIN) && (err > arc.radius * ARC_RADIUS_TOLERANCE))) { + ((err > ARC_RADIUS_ERROR_MIN) && (err > cm->arc.radius * ARC_RADIUS_TOLERANCE))) { return (STAT_ARC_HAS_IMPOSSIBLE_CENTER_POINT); } // Compute the angular travel // Calculate the theta angle of the current position (theta is also needed for calculating center point) // Note: gcc atan2 reverses args, i.e.: atan2(Y,X) - arc.theta = atan2(-arc.offset[arc.plane_axis_0], -arc.offset[arc.plane_axis_1]); + cm->arc.theta = atan2(-cm->arc.offset[cm->arc.plane_axis_0], -cm->arc.offset[cm->arc.plane_axis_1]); // Compute angular travel if not a full circle arc - if (!arc.full_circle) { - arc.angular_travel = atan2(end_0, end_1) - arc.theta; // travel = theta_end - theta_start + if (!cm->arc.full_circle) { + cm->arc.angular_travel = atan2(end_0, end_1) - cm->arc.theta; // travel = theta_end - theta_start // correct for atan2 output quadrants - if (arc.gm.motion_mode == MOTION_MODE_CW_ARC) { - if (arc.angular_travel <= 0) { arc.angular_travel += 2*M_PI; } + if (cm->arc.gm.motion_mode == MOTION_MODE_CW_ARC) { + if (cm->arc.angular_travel <= 0) { cm->arc.angular_travel += 2*M_PI; } } else { - if (arc.angular_travel > 0) { arc.angular_travel -= 2*M_PI; } + if (cm->arc.angular_travel > 0) { cm->arc.angular_travel -= 2*M_PI; } } // add in travel for rotations - if (arc.angular_travel >= 0) { arc.angular_travel += 2*M_PI * arc.rotations; } - else { arc.angular_travel -= 2*M_PI * arc.rotations; } + if (cm->arc.angular_travel >= 0) { cm->arc.angular_travel += 2*M_PI * cm->arc.rotations; } + else { cm->arc.angular_travel -= 2*M_PI * cm->arc.rotations; } } // Compute full-circle arcs else { - if (arc.gm.motion_mode == MOTION_MODE_CCW_ARC) { arc.rotations *= -1; } - arc.angular_travel = 2 * M_PI * arc.rotations; + if (cm->arc.gm.motion_mode == MOTION_MODE_CCW_ARC) { cm->arc.rotations *= -1; } + cm->arc.angular_travel = 2 * M_PI * cm->arc.rotations; } // Trap zero movement arcs - if (fp_ZERO(arc.angular_travel)) { + if (fp_ZERO(cm->arc.angular_travel)) { return (STAT_ARC_ENDPOINT_IS_STARTING_POINT); } // Calculate travel in the plane and the depth axis of the helix // Length is the total mm of travel of the helix (or just the planar arc) - arc.linear_travel = arc.gm.target[arc.linear_axis] - arc.position[arc.linear_axis]; - arc.planar_travel = arc.angular_travel * arc.radius; - arc.length = hypotf(arc.planar_travel, fabs(arc.linear_travel)); + cm->arc.linear_travel = cm->arc.gm.target[cm->arc.linear_axis] - cm->arc.position[cm->arc.linear_axis]; + cm->arc.planar_travel = cm->arc.angular_travel * cm->arc.radius; + cm->arc.length = hypotf(cm->arc.planar_travel, fabs(cm->arc.linear_travel)); // Find the minimum number of segments that meet accuracy and time constraints... // Note: removed segment_length test as segment_time accounts for this (build 083.37) float arc_time; float segments_for_minimum_time = _estimate_arc_time(arc_time) * (MICROSECONDS_PER_MINUTE / MIN_ARC_SEGMENT_USEC); - float segments_for_chordal_accuracy = arc.length / sqrt(4*cm->chordal_tolerance * (2 * arc.radius - cm->chordal_tolerance)); - arc.segments = floor(min(segments_for_chordal_accuracy, segments_for_minimum_time)); - arc.segments = max(arc.segments, (float)1.0); //...but is at least 1 segment + float segments_for_chordal_accuracy = cm->arc.length / sqrt(4*cm->chordal_tolerance * (2 * cm->arc.radius - cm->chordal_tolerance)); + cm->arc.segments = floor(min(segments_for_chordal_accuracy, segments_for_minimum_time)); + cm->arc.segments = max(cm->arc.segments, (float)1.0); //...but is at least 1 segment - if (arc.gm.feed_rate_mode == INVERSE_TIME_MODE) { - arc.gm.feed_rate /= arc.segments; + if (cm->arc.gm.feed_rate_mode == INVERSE_TIME_MODE) { + cm->arc.gm.feed_rate /= cm->arc.segments; } // setup the rest of the arc parameters - arc.segment_count = (int32_t)arc.segments; - arc.segment_theta = arc.angular_travel / arc.segments; - arc.segment_linear_travel = arc.linear_travel / arc.segments; - arc.center_0 = arc.position[arc.plane_axis_0] - sin(arc.theta) * arc.radius; - arc.center_1 = arc.position[arc.plane_axis_1] - cos(arc.theta) * arc.radius; - arc.gm.target[arc.linear_axis] = arc.position[arc.linear_axis]; // initialize the linear target + cm->arc.segment_count = (int32_t)cm->arc.segments; + cm->arc.segment_theta = cm->arc.angular_travel / cm->arc.segments; + cm->arc.segment_linear_travel = cm->arc.linear_travel / cm->arc.segments; + cm->arc.center_0 = cm->arc.position[cm->arc.plane_axis_0] - sin(cm->arc.theta) * cm->arc.radius; + cm->arc.center_1 = cm->arc.position[cm->arc.plane_axis_1] - cos(cm->arc.theta) * cm->arc.radius; + cm->arc.gm.target[cm->arc.linear_axis] = cm->arc.position[cm->arc.linear_axis]; // initialize the linear target return (STAT_OK); } @@ -428,8 +434,8 @@ static stat_t _compute_arc(const bool radius_f) static void _compute_arc_offsets_from_radius() { // Calculate the change in position along each selected axis - float x = arc.gm.target[arc.plane_axis_0] - arc.position[arc.plane_axis_0]; - float y = arc.gm.target[arc.plane_axis_1] - arc.position[arc.plane_axis_1]; + float x = cm->arc.gm.target[cm->arc.plane_axis_0] - cm->arc.position[cm->arc.plane_axis_0]; + float y = cm->arc.gm.target[cm->arc.plane_axis_1] - cm->arc.position[cm->arc.plane_axis_1]; // *** From Forrest Green - Other Machine Co, 3/27/14 // If the distance between endpoints is greater than the arc diameter, disc will be @@ -440,13 +446,13 @@ static void _compute_arc_offsets_from_radius() // risks obscuring g-code errors where the radius is actually too small (they will be // treated as half circles), but ensures that all valid arcs end up reasonably close // to their intended paths regardless of any numerical issues. - float disc = 4 * square(arc.radius) - (square(x) + square(y)); + float disc = 4 * square(cm->arc.radius) - (square(x) + square(y)); // h_x2_div_d == -(h * 2 / d) float h_x2_div_d = (disc > 0) ? -sqrt(disc) / hypotf(x,y) : 0; // Invert the sign of h_x2_div_d if circle is counter clockwise (see header notes) - if (arc.gm.motion_mode == MOTION_MODE_CCW_ARC) { + if (cm->arc.gm.motion_mode == MOTION_MODE_CCW_ARC) { h_x2_div_d = -h_x2_div_d; } @@ -455,15 +461,15 @@ static void _compute_arc_offsets_from_radius() // single Gcode block. By inverting the sign of h_x2_div_d the center of the circles is // placed on the opposite side of the line of travel and thus we get the inadvisably // long arcs as prescribed. - if (arc.radius < 0) { + if (cm->arc.radius < 0) { h_x2_div_d = -h_x2_div_d; - arc.radius *= -1; // and flip the radius sign while you are at it + cm->arc.radius *= -1; // and flip the radius sign while you are at it } // Complete the operation by calculating the actual center of the arc - arc.offset[arc.plane_axis_0] = (x-(y*h_x2_div_d))/2; - arc.offset[arc.plane_axis_1] = (y+(x*h_x2_div_d))/2; - arc.offset[arc.linear_axis] = 0; + cm->arc.offset[cm->arc.plane_axis_0] = (x-(y*h_x2_div_d))/2; + cm->arc.offset[cm->arc.plane_axis_1] = (y+(x*h_x2_div_d))/2; + cm->arc.offset[cm->arc.linear_axis] = 0; } /* @@ -479,17 +485,17 @@ static void _compute_arc_offsets_from_radius() static float _estimate_arc_time (float arc_time) { // Determine move time at requested feed rate - if (arc.gm.feed_rate_mode == INVERSE_TIME_MODE) { - arc_time = arc.gm.feed_rate; // inverse feed rate has been normalized to minutes + if (cm->arc.gm.feed_rate_mode == INVERSE_TIME_MODE) { + arc_time = cm->arc.gm.feed_rate; // inverse feed rate has been normalized to minutes } else { - arc_time = arc.length / cm->gm.feed_rate; + arc_time = cm->arc.length / cm->gm.feed_rate; } // Downgrade the time if there is a rate-limiting axis - arc_time = max(arc_time, (float)fabs(arc.planar_travel/cm->a[arc.plane_axis_0].feedrate_max)); - arc_time = max(arc_time, (float)fabs(arc.planar_travel/cm->a[arc.plane_axis_1].feedrate_max)); - if (fabs(arc.linear_travel) > 0) { - arc_time = max(arc_time, (float)fabs(arc.linear_travel/cm->a[arc.linear_axis].feedrate_max)); + arc_time = max(arc_time, (float)fabs(cm->arc.planar_travel/cm->a[cm->arc.plane_axis_0].feedrate_max)); + arc_time = max(arc_time, (float)fabs(cm->arc.planar_travel/cm->a[cm->arc.plane_axis_1].feedrate_max)); + if (fabs(cm->arc.linear_travel) > 0) { + arc_time = max(arc_time, (float)fabs(cm->arc.linear_travel/cm->a[cm->arc.linear_axis].feedrate_max)); } return (arc_time); } diff --git a/g2core/plan_arc.h b/g2core/plan_arc.h index 6f65a871..5e2f0dc8 100644 --- a/g2core/plan_arc.h +++ b/g2core/plan_arc.h @@ -31,7 +31,7 @@ #define ARC_RADIUS_TOLERANCE ((float)0.001) // 0.1% radius variance test #define CHORDAL_TOLERANCE_MIN (0.001) // values below this are not accepted - +/* typedef struct arArcSingleton { // persistent planner and runtime variables magic_t magic_start; uint8_t run_state; // runtime state machine sequence @@ -69,7 +69,7 @@ typedef struct arArcSingleton { // persistent planner and runtim magic_t magic_end; } arc_t; extern arc_t arc; - +*/ /* arc function prototypes */ void cm_arc_init(void); From 58fab2567bc099755b3cb391f244b3ec879c6664 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 18 Dec 2016 16:19:20 -0500 Subject: [PATCH 045/283] Fixed bug in TR; simplified axis type functions --- g2core/canonical_machine.cpp | 30 +++++++++++++++++------------- g2core/canonical_machine.h | 1 - g2core/config_app.cpp | 3 ++- g2core/g2core.cppproj | 4 ++-- g2core/stepper.cpp | 25 ++++++------------------- g2core/stepper.h | 2 -- 6 files changed, 27 insertions(+), 38 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a718f846..b4065a48 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2080,22 +2080,26 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; /***** AXIS HELPERS ***************************************************************** - * _axis() - return axis number or -1 if not an axis + * _axis() - return axis number or -1 if not an axis 9works for mapped motors as well) * _coord() - return coordinate system number or -1 if error * cm_get_axis_char() - return ASCII char for axis given the axis number * cm_get_axis_type() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) - * cm_get_axis_type_by_axis() - return axis type (0 if axis is linear, 1 if rotary, -1 if NA) + * Works for Axis parameters, and motors. Maps from motor to axis */ static int8_t _axis(const index_t index) { + // if the leading character of the token is a number it's a motor + char c = cfgArray[index].token[0]; + if (isdigit(cfgArray[index].token[0])) { + return(st_cfg.mot[c-0x31].motor_map); + } + + // otherwise it's an axis. Or an error. char *ptr; - char tmp[TOKEN_LEN+1]; char axes[] = {"xyzabc"}; - - strncpy(tmp, cfgArray[index].token, TOKEN_LEN); // kind of a hack. Looks for an axis - if ((ptr = strchr(axes, tmp[0])) == NULL) { // character in the 0 and 3 positions - if ((ptr = strchr(axes, tmp[3])) == NULL) { // to accommodate 'xam' and 'g54x' styles + if ((ptr = strchr(axes, c)) == NULL) { // test the character in the 0 and 3 positions + if ((ptr = strchr(axes, cfgArray[index].token[3])) == NULL) { // to accommodate 'xam' and 'g54x' styles return (-1); } } @@ -2122,16 +2126,16 @@ char cm_get_axis_char(const int8_t axis) cmAxisType cm_get_axis_type(const index_t index) { - return (cm_get_axis_type_by_axis(_axis(index))); -} - -cmAxisType cm_get_axis_type_by_axis(const int8_t axis) -{ + uint8_t axis = _axis(index); if (axis >= AXIS_A) { return (AXIS_TYPE_ROTARY); } if (axis == -1) { return (AXIS_TYPE_UNDEFINED); } return (AXIS_TYPE_LINEAR); } - +/* +cmAxisType cm_get_axis_type_by_axis(const int8_t axis) +{ +} +*/ /**** Functions called directly from cfgArray table - mostly wrappers **** * _get_msg_helper() - helper to get string values * diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index ea88ebb3..3e607141 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -463,7 +463,6 @@ float cm_get_jogging_dest(void); // get jogging d char cm_get_axis_char(const int8_t axis); cmAxisType cm_get_axis_type(const index_t index); -cmAxisType cm_get_axis_type_by_axis(const int8_t axis); stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index ef41c185..2977f40b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1035,7 +1035,8 @@ void process_outgoing_float(nvObj_t *nv) nv->value *= INCHES_PER_MM; } } else if (flags & F_ICONVERT) { // inverse units conversion - if (st_get_axis_type_by_motor(nv->index) == AXIS_TYPE_LINEAR) { // axis motor is mapped to +// if (st_get_axis_type_by_motor(nv->index) == AXIS_TYPE_LINEAR) { // axis motor is mapped to + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // axis motor is mapped to nv->value *= MM_PER_INCH; } } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index c8cc86a8..d57acc1f 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 3b2bbee3..845a2998 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -817,20 +817,8 @@ static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps) static int8_t _motor(const index_t index) { - char *ptr; - char motors[] = {"123456"}; - char tmp[GROUP_LEN+1]; - - strcpy(tmp, cfgArray[index].group); - if ((ptr = strchr(motors, tmp[0])) == NULL) { - return (-1); - } - return (ptr - motors); -} - -cmAxisType st_get_axis_type_by_motor(const index_t index) -{ - return (cm_get_axis_type_by_axis(st_cfg.mot[_motor(index)].motor_map)); + char c = cfgArray[index].token[0]; + return (isdigit(c) ? c-0x31 : -1 ); // 0x30 + 1 offsets motor 1 to == 0 } /* @@ -918,13 +906,12 @@ stat_t st_set_su(nvObj_t *nv) } // Do unit conversion here because it's a reciprocal value (rather than process_incoming_float()) - uint8_t m = _motor(nv->index); if (cm_get_units_mode(MODEL) == INCHES) { - uint8_t a = st_cfg.mot[m].motor_map; - if (cm_get_axis_type_by_axis(a) == AXIS_TYPE_LINEAR) { + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { nv->value *= INCHES_PER_MM; } } + uint8_t m = _motor(nv->index); st_cfg.mot[m].steps_per_unit = nv->value; st_cfg.mot[m].units_per_step = 1.0/st_cfg.mot[m].steps_per_unit; @@ -1008,8 +995,8 @@ stat_t st_get_pwr(nvObj_t *nv) stat_t st_get_mt(nvObj_t *nv) { return(get_float(nv, st_cfg.motor_power_timeout)); } stat_t st_set_mt(nvObj_t *nv) { return(set_float_range(nv, st_cfg.motor_power_timeout, - MOTOR_TIMEOUT_SECONDS_MAX, - MOTOR_TIMEOUT_SECONDS_MIN)); } + MOTOR_TIMEOUT_SECONDS_MIN, + MOTOR_TIMEOUT_SECONDS_MAX)); } stat_t st_set_me(nvObj_t *nv) // Make sure this function is not part of initialization --> f00 { diff --git a/g2core/stepper.h b/g2core/stepper.h index a56385a3..09508594 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -578,8 +578,6 @@ void st_prep_dwell(float microseconds); void st_request_out_of_band_dwell(float microseconds); stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time); -cmAxisType st_get_axis_type_by_motor(const index_t index); - stat_t st_get_ma(nvObj_t *nv); stat_t st_set_ma(nvObj_t *nv); stat_t st_get_sa(nvObj_t *nv); From ff09f5ce23be3fcd67fef2bd67cfea1097026082 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 23 Dec 2016 07:56:59 -0500 Subject: [PATCH 046/283] Interim commit --- g2core/canonical_machine.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index b4065a48..d309b53c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -698,8 +698,8 @@ stat_t cm_test_soft_limits(const float target[]) void canonical_machine_init() { + // NoteL cm* was assignd in main() // If you can assume all memory has been zeroed by a hard reset you don't need this code: -// memset(&cm, 0, sizeof(cm)); // do not reset canonicalMachineSingleton once it's been initialized memset(cm, 0, sizeof(cm0)); // do not reset canonicalMachineSingleton once it's been initialized memset(&cm->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status memset(&gc.gn, 0, sizeof(GCodeInput_t)); @@ -2131,11 +2131,7 @@ cmAxisType cm_get_axis_type(const index_t index) if (axis == -1) { return (AXIS_TYPE_UNDEFINED); } return (AXIS_TYPE_LINEAR); } -/* -cmAxisType cm_get_axis_type_by_axis(const int8_t axis) -{ -} -*/ + /**** Functions called directly from cfgArray table - mostly wrappers **** * _get_msg_helper() - helper to get string values * From 68fab723995f2df27d36c5a5c6a519c8c8bed994 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 5 Jan 2017 15:57:07 -0500 Subject: [PATCH 047/283] Fixed some merge errors in configuration code --- g2core/board/Archim/hardware.h | 4 +- g2core/board/gquadratic/hardware.h | 11 +- g2core/canonical_machine.cpp | 42 +-- g2core/canonical_machine.h | 421 +---------------------------- g2core/config.h | 12 +- g2core/config_app.cpp | 375 ++++++++++++------------- g2core/gcode.h | 14 +- g2core/json_parser.cpp | 6 +- g2core/text_parser.cpp | 4 +- 9 files changed, 202 insertions(+), 687 deletions(-) diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 2bfa2255..57560f43 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index 9642b841..d18efe5b 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -56,13 +56,6 @@ * Motate Setup * *************************/ -//////////////////////////// -/////// ARM VERSION //////// -//////////////////////////// - -// ARM specific code start here ->>>>>>> refs/heads/edge - #include "MotatePins.h" #include "MotateTimers.h" // for TimerChanel<> and related... #include "MotateServiceCall.h" // for ServiceCall<> diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index aec0ec43..69cfe2f2 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2395,27 +2395,16 @@ stat_t cm_get_am(nvObj_t *nv) stat_t cm_set_am(nvObj_t *nv) // axis mode { - nv->valuetype = TYPE_NULL; if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { if (nv->value > AXIS_MODE_LINEAR_MAX) { - return (STAT_INPUT_VALUE_RANGE_ERROR); + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_EXCEEDS_MAX_VALUE); } } else { if (nv->value > AXIS_MODE_ROTARY_MAX) { - return (STAT_INPUT_VALUE_RANGE_ERROR); -/*======= - if (cm_get_axis_type(nv->index) == 0) { // linear - if (nv->value > AXIS_MODE_MAX_LINEAR) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - } else { - if (nv->value > AXIS_MODE_MAX_ROTARY) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); ->>>>>>> refs/heads/edge -*/ - } } nv->valuetype = TYPE_INT; cm->a[_axis(nv->index)].axis_mode = (cmAxisMode)nv->value; @@ -2428,21 +2417,6 @@ stat_t cm_get_tm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].tr stat_t cm_set_tm(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_max)); } stat_t cm_get_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].radius)); } stat_t cm_set_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].radius)); } -/* -stat_t cm_set_hi(nvObj_t *nv) -{ - if (nv->value < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value > D_IN_CHANNELS) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - set_ui8(nv); - return (STAT_OK); -} -*/ /**** Axis Jerk Primitives * cm_get_axis_jerk() - returns jerk for an axis @@ -2493,7 +2467,7 @@ stat_t cm_get_vm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].ve stat_t cm_set_vm(nvObj_t *nv) { uint8_t axis = _axis(nv->index); - set_float(nv, cm->a[axis].velocity_max); + ritorno(set_float_range(nv, cm->a[axis].velocity_max, 0, MAX_LONG)); cm->a[axis].recip_velocity_max = 1/nv->value; return(STAT_OK); } @@ -2502,7 +2476,7 @@ stat_t cm_get_fr(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].fe stat_t cm_set_fr(nvObj_t *nv) { uint8_t axis = _axis(nv->index); - set_float(nv, cm->a[axis].feedrate_max); + ritorno(set_float_range(nv, cm->a[axis].feedrate_max, 0, MAX_LONG)); cm->a[axis].recip_feedrate_max = 1/nv->value; return(STAT_OK); } @@ -2540,9 +2514,9 @@ stat_t cm_set_hi(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv->index)].homi stat_t cm_get_hd(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv->index)].homing_dir)); } stat_t cm_set_hd(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv->index)].homing_dir, 0, 1)); } stat_t cm_get_sv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].search_velocity)); } -stat_t cm_set_sv(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].search_velocity)); } +stat_t cm_set_sv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->index)].search_velocity, 0, MAX_LONG)); } stat_t cm_get_lv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].latch_velocity)); } -stat_t cm_set_lv(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].latch_velocity)); } +stat_t cm_set_lv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->index)].latch_velocity, 0, MAX_LONG)); } stat_t cm_get_lb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].latch_backoff)); } stat_t cm_set_lb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].latch_backoff)); } stat_t cm_get_zb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].zero_backoff)); } @@ -2816,7 +2790,7 @@ static void _print_axis_ui8(nvObj_t *nv, const char *format) static void _print_axis_flt(nvObj_t *nv, const char *format) { char *units; - if (cm_get_axis_type(nv->index) == 0) { // linear + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { units = (char *)GET_UNITS(MODEL); } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); @@ -2828,7 +2802,7 @@ static void _print_axis_flt(nvObj_t *nv, const char *format) static void _print_axis_coord_flt(nvObj_t *nv, const char *format) { char *units; - if (cm_get_axis_type(nv->index) == 0) { // linear + if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { units = (char *)GET_UNITS(MODEL); } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 411ce0d8..12e5493d 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -146,358 +146,6 @@ typedef enum { // queue flush state machine FLUSH_REQUESTED, // flush has been requested but not started yet } cmQueueFlushState; -/*======= - * The difference between NextAction and MotionMode is that NextAction is - * used by the current block, and may carry non-modal commands, whereas - * MotionMode persists across blocks (as G modal group 1) - */ -/* -typedef enum { // these are in order to optimized CASE statement - NEXT_ACTION_DEFAULT = 0, // Must be zero (invokes motion modes) - NEXT_ACTION_DWELL, // G4 - NEXT_ACTION_SET_G10_DATA, // G10 - NEXT_ACTION_GOTO_G28_POSITION, // G28 go to machine position - NEXT_ACTION_SET_G28_POSITION, // G28.1 set position in abs coordinates - NEXT_ACTION_SEARCH_HOME, // G28.2 homing cycle - NEXT_ACTION_SET_ABSOLUTE_ORIGIN, // G28.3 origin set - NEXT_ACTION_HOMING_NO_SET, // G28.4 homing cycle with no coordinate setting - NEXT_ACTION_GOTO_G30_POSITION, // G30 go to machine position - NEXT_ACTION_SET_G30_POSITION, // G30.1 set position in abs coordinates - NEXT_ACTION_STRAIGHT_PROBE_ERR, // G38.2 - NEXT_ACTION_STRAIGHT_PROBE, // G38.3 - NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR,// G38.4 - NEXT_ACTION_STRAIGHT_PROBE_AWAY, // G38.5 - NEXT_ACTION_SET_TL_OFFSET, // G43 - NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET,// G43.2 - NEXT_ACTION_CANCEL_TL_OFFSET, // G49 - NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92 - NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1 - NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2 - NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3 - NEXT_ACTION_JSON_COMMAND_SYNC, // M100 - NEXT_ACTION_JSON_WAIT // M101 -} cmNextAction; - -typedef enum { // G Modal Group 1 - MOTION_MODE_STRAIGHT_TRAVERSE=0, // G0 - straight traverse - MOTION_MODE_STRAIGHT_FEED, // G1 - straight feed - MOTION_MODE_CW_ARC, // G2 - clockwise arc feed - MOTION_MODE_CCW_ARC, // G3 - counter-clockwise arc feed - MOTION_MODE_CANCEL_MOTION_MODE, // G80 - MOTION_MODE_STRAIGHT_PROBE, // G38.2 - MOTION_MODE_CANNED_CYCLE_81, // G81 - drilling - MOTION_MODE_CANNED_CYCLE_82, // G82 - drilling with dwell - MOTION_MODE_CANNED_CYCLE_83, // G83 - peck drilling - MOTION_MODE_CANNED_CYCLE_84, // G84 - right hand tapping - MOTION_MODE_CANNED_CYCLE_85, // G85 - boring, no dwell, feed out - MOTION_MODE_CANNED_CYCLE_86, // G86 - boring, spindle stop, rapid out - MOTION_MODE_CANNED_CYCLE_87, // G87 - back boring - MOTION_MODE_CANNED_CYCLE_88, // G88 - boring, spindle stop, manual out - MOTION_MODE_CANNED_CYCLE_89 // G89 - boring, dwell, feed out -} cmMotionMode; - -typedef enum { // Used for detecting gcode errors. See NIST section 3.4 - MODAL_GROUP_G0 = 0, // {G10,G28,G28.1,G92} non-modal axis commands (note 1) - MODAL_GROUP_G1, // {G0,G1,G2,G3,G80} motion - MODAL_GROUP_G2, // {G17,G18,G19} plane selection - MODAL_GROUP_G3, // {G90,G91} distance mode - MODAL_GROUP_G5, // {G93,G94} feed rate mode - MODAL_GROUP_G6, // {G20,G21} units - MODAL_GROUP_G7, // {G40,G41,G42} cutter radius compensation - MODAL_GROUP_G8, // {G43,G49} tool length offset - MODAL_GROUP_G9, // {G98,G99} return mode in canned cycles - MODAL_GROUP_G12, // {G54,G55,G56,G57,G58,G59} coordinate system selection - MODAL_GROUP_G13, // {G61,G61.1,G64} path control mode - MODAL_GROUP_M4, // {M0,M1,M2,M30,M60} stopping - MODAL_GROUP_M6, // {M6} tool change - MODAL_GROUP_M7, // {M3,M4,M5} spindle turning - MODAL_GROUP_M8, // {M7,M8,M9} coolant (M7 & M8 may be active together) - MODAL_GROUP_M9 // {M48,M49} speed/feed override switches -} cmModalGroup; -#define MODAL_GROUP_COUNT (MODAL_GROUP_M9+1) -// Note 1: Our G0 omits G4,G30,G53,G92.1,G92.2,G92.3 as these have no axis components to error check - -typedef enum { // canonical plane - translates to: - // axis_0 axis_1 axis_2 - CANON_PLANE_XY = 0, // G17 X Y Z - CANON_PLANE_XZ, // G18 X Z Y - CANON_PLANE_YZ // G19 Y Z X -} cmCanonicalPlane; - -typedef enum { - INCHES = 0, // G20 - MILLIMETERS, // G21 - DEGREES // ABC axes (this value used for displays only) -} cmUnitsMode; - -typedef enum { - ABSOLUTE_COORDS = 0, // machine coordinate system - G54, // G54 coordinate system - G55, // G55 coordinate system - G56, // G56 coordinate system - G57, // G57 coordinate system - G58, // G58 coordinate system - G59 // G59 coordinate system -} cmCoordSystem; -#define COORD_SYSTEM_MAX G59 // set this manually to the last one - -typedef enum { - ABSOLUTE_OVERRIDE_OFF = 0,// G53 enabled - ABSOLUTE_OVERRIDE_ON -} cmAbsoluteOverride; - -typedef enum { // G Modal Group 13 - PATH_EXACT_PATH = 0, // G61 - hits corners but does not stop if it does not need to. - PATH_EXACT_STOP, // G61.1 - stops at all corners - PATH_CONTINUOUS // G64 and typically the default mode -} cmPathControl; - -typedef enum { - ABSOLUTE_DISTANCE_MODE = 0, // G90 / G90.1 - INCREMENTAL_DISTANCE_MODE // G91 / G91.1 -} cmDistanceMode; - -typedef enum { - INVERSE_TIME_MODE = 0, // G93 - UNITS_PER_MINUTE_MODE, // G94 - UNITS_PER_REVOLUTION_MODE// G95 (unimplemented) -} cmFeedRateMode; - -typedef enum { - ORIGIN_OFFSET_SET=0, // G92 - set origin offsets - ORIGIN_OFFSET_CANCEL, // G92.1 - zero out origin offsets - ORIGIN_OFFSET_SUSPEND, // G92.2 - do not apply offsets, but preserve the values - ORIGIN_OFFSET_RESUME // G92.3 - resume application of the suspended offsets -} cmOriginOffset; - -typedef enum { - PROGRAM_STOP = 0, - PROGRAM_END -} cmProgramFlow; - -typedef enum { // used for spindle and arc dir - DIRECTION_CW = 0, - DIRECTION_CCW -} cmDirection; - -typedef enum { // axis types - AXIS_TYPE_UNDEFINED=-2, // invalid type - AXIS_TYPE_SYSTEM=-1, // token is global system token, not axis - AXIS_TYPE_LINEAR, // linear axis - AXIS_TYPE_ROTARY // rotary axis -} cmAxisType; - -typedef enum { // axis modes (ordered: see _cm_get_feed_time()) - AXIS_DISABLED = 0, // kill axis - AXIS_STANDARD, // axis in coordinated motion w/standard behaviors - AXIS_INHIBITED, // axis is computed but not activated - AXIS_RADIUS // rotary axis calibrated to circumference -} cmAxisMode; -#define AXIS_MODE_MAX_LINEAR AXIS_INHIBITED -#define AXIS_MODE_MAX_ROTARY AXIS_RADIUS -*/ -/***************************************************************************** - * GCODE MODEL - The following GCodeModel/GCodeInput structs are used: - * - * - gm is the core Gcode model state. It keeps the internal gcode state model in - * normalized, canonical form. All values are unit converted (to mm) and in the - * machine coordinate system (absolute coordinate system). Gm is owned by the - * canonical machine layer and should be accessed only through cm_ routines. - * - * The gm core struct is copied and passed as context to the runtime where it is - * used for planning, move execution, feedholds, and reporting. - * - * - gmx is the extended gcode model variables that are only used by the canonical - * machine and do not need to be passed further down. It keeps "global" gcode - * state that does not change when you go down through the planner to the runtime. - * Other Gcode model state is kept in the singletons for various sub-systems, such - * as arcs, spindle, coolant, and others (i.e. not ALL gcode global state is in gmx) - * - * - gn is used by the gcode interpreter and is re-initialized for each - * gcode block.It accepts data in the new gcode block in the formats - * present in the block (pre-normalized forms). During initialization - * some state elements are necessarily restored from gm. - * - * - gf is used by the gcode parser interpreter to hold flags for any data - * that has changed in gn during the parse. cm.gf.target[] values are also used - * by the canonical machine during set_target(). - * - * - cfg (config struct in config.h) is also used heavily and contains some - * values that might be considered to be Gcode model values. The distinction - * is that all values in the config are persisted and restored, whereas the - * gm structs are transient. So cfg has the G54 - G59 offsets, but gm has the - * G92 offsets. cfg has the power-on / reset gcode default values, but gm has - * the operating state for the values (which may have changed). - */ -/* -typedef struct GCodeState { // Gcode model state - used by model, planning and runtime - uint32_t linenum; // Gcode block line number - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, - // G82, G83 G84, G85, G86, G87, G88, G89 - - float target[AXES]; // XYZABC where the move should go - float target_comp[AXES]; // summation compensation (Kahan) overflow value - float work_offset[AXES]; // offset from the work coordinate system (for reporting only) - - float feed_rate; // F - normalized to millimeters/minute or in inverse time mode - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... - - cmFeedRateMode feed_rate_mode; // See cmFeedRateMode for settings - cmCanonicalPlane select_plane; // G17,G18,G19 - values to set plane to - cmUnitsMode units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - cmPathControl path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - cmDistanceMode distance_mode; // G90=use absolute coords, G91=incremental movement - cmDistanceMode arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - cmAbsoluteOverride absolute_override;// G53 TRUE = move using machine coordinates - this block only - cmCoordSystem coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t tool; // G // M6 tool change - moves "tool_select" to "tool" - uint8_t tool_select; // G // T value - T sets this value - - void reset() { - linenum = 0; - motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; - - for (uint8_t i = 0; i< AXES; i++) { - target[i] = 0.0; - work_offset[i] = 0.0; - } - - feed_rate = 0.0; - parameter = 0.0; - - feed_rate_mode = INVERSE_TIME_MODE; - select_plane = CANON_PLANE_XY; - units_mode = INCHES; - path_control = PATH_EXACT_PATH; - distance_mode = ABSOLUTE_DISTANCE_MODE; - arc_distance_mode = ABSOLUTE_DISTANCE_MODE; - absolute_override = ABSOLUTE_OVERRIDE_OFF; - coord_system = ABSOLUTE_COORDS; - tool = 0; - tool_select = 0; - - }; -} GCodeState_t; - -typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used by model and arcs - uint16_t magic_start; // magic number to test memory integrity - uint8_t next_action; // handles G modal group 1 moves & non-modals - uint8_t program_flow; // used only by the gcode_parser - - float position[AXES]; // XYZABC model position (Note: not used in gn or gf) - float origin_offset[AXES]; // XYZABC G92 offsets (Note: not used in gn or gf) - float g28_position[AXES]; // XYZABC stored machine position for G28 - float g30_position[AXES]; // XYZABC stored machine position for G30 - - bool m48_enable; // master feedrate / spindle speed override enable - bool mfo_enable; // feedrate override enable - float mfo_factor; // 1.0000 x F feed rate. Go up or down from there - bool mto_enable; // traverse override enable - float mto_factor; // valid from 0.05 to 1.00 - - bool origin_offset_enable; // G92 offsets enabled/disabled. 0=disabled, 1=enabled - bool block_delete_switch; // set true to enable block deletes (true is default) - -// unimplemented gcode parameters -// float cutter_radius; // D - cutter radius compensation (0 is off) -// float cutter_length; // H - cutter length compensation (0 is off) - - uint16_t magic_end; - -} GCodeStateX_t; - -typedef struct GCodeInput { // Gcode model inputs - meaning depends on context - - uint8_t next_action; // handles G modal group 1 moves & non-modals - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 - // G83, G84, G85, G86, G87, G88, G89 - - uint8_t program_flow; // used only by the gcode_parser - uint32_t linenum; // N word - float target[AXES]; // XYZABC where the move should go - - uint8_t H_word; // H word - used by G43s - uint8_t L_word; // L word - used by G10s - - float feed_rate; // F - normalized to millimeters/minute - uint8_t feed_rate_mode; // See cmFeedRateMode for settings - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... - float arc_radius; // R - radius value in arc radius mode - float arc_offset[3]; // IJK - used by arc commands - - bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_enable; // M50 feedrate override enable - bool mto_enable; // Mxx traverse override enable - bool sso_enable; // M51 spindle speed override enable - - uint8_t select_plane; // G17,G18,G19 - values to set plane to - uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - uint8_t coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement - uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode - uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) - uint8_t tool; // Tool after T and M6 (tool_select and tool_change) - uint8_t tool_select; // T value - T sets this value - uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" - uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) - uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) - - uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - float spindle_speed; // in RPM - float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there - uint8_t spindle_override_enable; // TRUE = override enabled - -// unimplemented gcode parameters -// float cutter_radius; // D - cutter radius compensation (0 is off) - -} GCodeInput_t; - -typedef struct GCodeFlags { // Gcode model input flags - bool next_action; - bool motion_mode; - bool modals[MODAL_GROUP_COUNT]; - bool program_flow; - bool linenum; - bool target[AXES]; - - bool H_word; - bool L_word; - bool feed_rate; - bool feed_rate_mode; - - bool m48_enable; - bool mfo_enable; - bool mto_enable; - bool sso_enable; - - bool select_plane; - bool units_mode; - bool coord_system; - bool path_control; - bool distance_mode; - bool arc_distance_mode; - bool origin_offset_mode; - bool absolute_override; - bool tool; - bool tool_select; - bool tool_change; - bool mist_coolant; - bool flood_coolant; - - bool spindle_control; - bool spindle_speed; - bool spindle_override_factor; - bool spindle_override_enable; - - bool parameter; - bool arc_radius; - bool arc_offset[3]; -} GCodeFlags_t; ->>>>>>> refs/heads/edge -*/ - /***************************************************************************** * CANONICAL MACHINE STRUCTURES */ @@ -988,74 +636,7 @@ stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non- void cm_print_zb(nvObj_t *nv); void cm_print_cofs(nvObj_t *nv); void cm_print_cpos(nvObj_t *nv); -/*======= - void cm_print_vel(nvObj_t *nv); // model state reporting - void cm_print_feed(nvObj_t *nv); - void cm_print_line(nvObj_t *nv); - void cm_print_stat(nvObj_t *nv); - void cm_print_macs(nvObj_t *nv); - void cm_print_cycs(nvObj_t *nv); - void cm_print_mots(nvObj_t *nv); - void cm_print_hold(nvObj_t *nv); - void cm_print_home(nvObj_t *nv); - void cm_print_hom(nvObj_t *nv); - void cm_print_unit(nvObj_t *nv); - void cm_print_coor(nvObj_t *nv); - void cm_print_momo(nvObj_t *nv); - void cm_print_plan(nvObj_t *nv); - void cm_print_path(nvObj_t *nv); - void cm_print_dist(nvObj_t *nv); - void cm_print_admo(nvObj_t *nv); - void cm_print_frmo(nvObj_t *nv); - void cm_print_tool(nvObj_t *nv); - void cm_print_g92e(nvObj_t *nv); - - void cm_print_gpl(nvObj_t *nv); // Gcode defaults - void cm_print_gun(nvObj_t *nv); - void cm_print_gco(nvObj_t *nv); - void cm_print_gpa(nvObj_t *nv); - void cm_print_gdi(nvObj_t *nv); - - void cm_print_lin(nvObj_t *nv); // generic print for linear values - void cm_print_pos(nvObj_t *nv); // print runtime work position in prevailing units - void cm_print_mpo(nvObj_t *nv); // print runtime work position always in MM uints - void cm_print_ofs(nvObj_t *nv); // print runtime work offset always in MM uints - void cm_print_tof(nvObj_t *nv); // print tool length offset - - void cm_print_jt(nvObj_t *nv); // global CM settings - void cm_print_ct(nvObj_t *nv); - void cm_print_sl(nvObj_t *nv); - void cm_print_lim(nvObj_t *nv); - void cm_print_saf(nvObj_t *nv); - - void cm_print_m48e(nvObj_t *nv); - void cm_print_mfoe(nvObj_t *nv); - void cm_print_mfo(nvObj_t *nv); - void cm_print_mtoe(nvObj_t *nv); - void cm_print_mto(nvObj_t *nv); - - void cm_print_tram(nvObj_t *nv); // print if the axis has been rotated - - void cm_print_am(nvObj_t *nv); // axis print functions - void cm_print_fr(nvObj_t *nv); - void cm_print_vm(nvObj_t *nv); - void cm_print_tm(nvObj_t *nv); - void cm_print_tn(nvObj_t *nv); - void cm_print_jm(nvObj_t *nv); - void cm_print_jh(nvObj_t *nv); - void cm_print_ra(nvObj_t *nv); - - void cm_print_hi(nvObj_t *nv); - void cm_print_hd(nvObj_t *nv); - void cm_print_sv(nvObj_t *nv); - void cm_print_lv(nvObj_t *nv); - void cm_print_lb(nvObj_t *nv); - void cm_print_zb(nvObj_t *nv); - void cm_print_cofs(nvObj_t *nv); - void cm_print_cpos(nvObj_t *nv); ->>>>>>> refs/heads/edge -*/ - + #else // __TEXT_MODE #define cm_print_vel tx_print_stub // model state reporting diff --git a/g2core/config.h b/g2core/config.h index acefaefb..865848aa 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -2,7 +2,7 @@ * config.h - configuration sub-system generic part (see config_app for application part) * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -357,14 +357,14 @@ void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion -void process_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values -void process_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units +void convert_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values +void convert_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units -stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving raw floating point value -stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion +stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrieving raw floating point value +stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); -stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving 8 bit integer value +stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving 8 bit integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); stat_t get_int32(nvObj_t *nv, const uint32_t value); // boilerplate for retrieving 32 bit integer value stat_t set_int32(nvObj_t *nv, uint32_t &value, uint32_t low, uint32_t high); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 308cf8b2..c291a1a4 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -2,8 +2,8 @@ * config_app.cpp - application-specific part of configuration data * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2016 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -103,75 +103,75 @@ static stat_t get_tick(nvObj_t *nv); // get system tick count */ const cfgItem_t cfgArray[] = { // group token flags p, print_func, get_func, set_func, get/set target, default value - { "sys", "fb", _fipn,2, hw_print_fb, hw_get_fb, set_nul, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! - { "sys", "fv", _fipn,2, hw_print_fv, hw_get_fv, set_nul, (float *)&cs.null, 0 }, - { "sys", "fbs",_fn, 0, hw_print_fbs, hw_get_fbs, set_nul, (float *)&cs.null, 0 }, - { "sys", "fbc",_fn, 0, hw_print_fbc, hw_get_fbc, set_nul, (float *)&cs.null, 0 }, - { "sys", "hp", _fn, 0, hw_print_hp, hw_get_hp, set_nul, (float *)&cs.null, 0 }, - { "sys", "hv", _fn, 0, hw_print_hv, hw_get_hv, set_nul, (float *)&cs.null, 0 }, - { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_nul, (float *)&cs.null, 0 }, // device ID (ASCII signature) + { "sys", "fb", _fipn,2, hw_print_fb, hw_get_fb, set_ro, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! + { "sys", "fv", _fipn,2, hw_print_fv, hw_get_fv, set_ro, (float *)&cs.null, 0 }, + { "sys", "fbs",_fn, 0, hw_print_fbs, hw_get_fbs, set_ro, (float *)&cs.null, 0 }, + { "sys", "fbc",_fn, 0, hw_print_fbc, hw_get_fbc, set_ro, (float *)&cs.null, 0 }, + { "sys", "hp", _fn, 0, hw_print_hp, hw_get_hp, set_ro, (float *)&cs.null, 0 }, + { "sys", "hv", _fn, 0, hw_print_hv, hw_get_hv, set_ro, (float *)&cs.null, 0 }, + { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) - { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_nul,(float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_nul,(float *)&cs.null, 0 }, // Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_nul,(float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_nul,(float *)&cs.null, 0 }, // current velocity - { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_nul,(float *)&cs.null, 0 }, // feed rate - { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_nul,(float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_nul,(float *)&cs.null, 0 }, // cycle state - { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_nul,(float *)&cs.null, 0 }, // motion state - { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_nul,(float *)&cs.null, 0 }, // feedhold state - { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_nul,(float *)&cs.null, 0 }, // units mode - { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_nul,(float *)&cs.null, 0 }, // coordinate system - { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_nul,(float *)&cs.null, 0 }, // motion mode - { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_nul,(float *)&cs.null, 0 }, // plane select - { "", "path",_f0, 0, cm_print_path, cm_get_path, set_nul,(float *)&cs.null, 0 }, // path control mode - { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_nul,(float *)&cs.null, 0 }, // distance mode - { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_nul,(float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_nul,(float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_nul,(float *)&cs.null, 0 }, // active tool -// { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_nul,(float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_ro, (float *)&cs.null, 0 }, // Model line number + { "", "line",_fi, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number + { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity + { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate + { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state + { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state + { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state + { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state + { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode + { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system + { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode + { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select + { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode + { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode + { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode + { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode + { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool +// { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif - { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul, (float *)&cs.null, 0 }, // C machine position + { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position + { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position + { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position + { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position + { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position + { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position - { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_nul, (float *)&cs.null, 0 }, // C work position + { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position + { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position + { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position + { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position + { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position + { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position - { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // X work offset - { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // Y work offset - { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // Z work offset - { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // A work offset - { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // B work offset - { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul, (float *)&cs.null, 0 }, // C work offset + { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset + { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset + { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Z work offset + { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // A work offset + { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset + { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_nul, (float *)&cs.null, 0 }, // C homed + { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group + { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Y homed + { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Z homed + { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // A homed + { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // B homed + { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed - { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_nul, (float *)&cs.null, 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // X probe results - { "prb","prby",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // Y probe results - { "prb","prbz",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // Z probe results - { "prb","prba",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // A probe results - { "prb","prbb",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // B probe results - { "prb","prbc",_f0, 3, tx_print_nul, cm_get_prb, set_nul, (float *)&cs.null, 0 }, // C probe results + { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state + { "prb","prbx",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results + { "prb","prby",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results + { "prb","prbz",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results + { "prb","prba",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // A probe results + { "prb","prbb",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // B probe results + { "prb","prbc",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // C probe results { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in X axis { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Y axis @@ -180,19 +180,19 @@ const cfgItem_t cfgArray[] = { { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in B axis { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in C axis - { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts - { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts + { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, #if (MOTORS > 2) - { "pwr","pwr3",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr3",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, #endif #if (MOTORS > 3) - { "pwr","pwr4",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr4",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, #endif #if (MOTORS > 4) - { "pwr","pwr5",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr5",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, #endif #if (MOTORS > 5) - { "pwr","pwr6",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr6",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, #endif // Motor parameters @@ -408,25 +408,25 @@ const cfgItem_t cfgArray[] = { #endif // Digital input state readers - { "in","in1", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in2", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in3", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in4", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in5", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in6", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in7", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in8", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in1", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in2", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in3", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in4", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in5", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in6", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in7", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in8", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #if (D_IN_CHANNELS >= 9) - { "in","in9", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in9", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif #if (D_IN_CHANNELS >= 10) - { "in","in10", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in10", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif #if (D_IN_CHANNELS >= 11) - { "in","in11", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in11", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif #if (D_IN_CHANNELS >= 12) - { "in","in12", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in12", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif // digital output configs @@ -574,27 +574,27 @@ const cfgItem_t cfgArray[] = { { "g59","g59b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, { "g59","g59c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, - { "g92","g92x",_fic, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 },// G92 handled differently - { "g92","g92y",_fic, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, - { "g92","g92z",_fic, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, - { "g92","g92a",_fi, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, - { "g92","g92b",_fi, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, - { "g92","g92c",_fi, 3, cm_print_cofs, cm_get_g92, set_nul, (float *)&cs.null, 0 }, + { "g92","g92x",_fic, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently + { "g92","g92y",_fic, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92z",_fic, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92a",_fi, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92b",_fi, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92c",_fi, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fic, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 },// g28 handled differently - { "g28","g28y",_fic, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, - { "g28","g28z",_fic, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, - { "g28","g28a",_fi, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, - { "g28","g28b",_fi, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, - { "g28","g28c",_fi, 3, cm_print_cpos, cm_get_g28, set_nul, (float *)&cs.null, 0 }, + { "g28","g28x",_fic, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently + { "g28","g28y",_fic, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28z",_fic, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28a",_fi, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28b",_fi, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28c",_fi, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g30","g30x",_fic, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 },// g30 handled differently - { "g30","g30y",_fic, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, - { "g30","g30z",_fic, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, - { "g30","g30a",_fi, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, - { "g30","g30b",_fi, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, - { "g30","g30c",_fi, 3, cm_print_cpos, cm_get_g30, set_nul, (float *)&cs.null, 0 }, + { "g30","g30x",_fic, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently + { "g30","g30y",_fic, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30z",_fic, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30a",_fi, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30b",_fi, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30c",_fi, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, /* // Default values for current tool length offsets (not configurable, set to zero) @@ -956,67 +956,67 @@ const cfgItem_t cfgArray[] = { { "", "clc",_f0, 0, tx_print_nul, st_clc, st_clc, (float *)&cs.null, 0 }, // clear diagnostic step counters // { "", "_dam",_f0, 0, tx_print_nul, cm_dam, cm_dam, (float *)&cs.null, 0 }, // dump active model - { "_te","_tex",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_X], 0 }, // X target endpoint - { "_te","_tey",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_Y], 0 }, - { "_te","_tez",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_Z], 0 }, - { "_te","_tea",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_A], 0 }, - { "_te","_teb",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_B], 0 }, - { "_te","_tec",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_C], 0 }, + { "_te","_tex",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_X], 0 }, // X target endpoint + { "_te","_tey",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_Y], 0 }, + { "_te","_tez",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_Z], 0 }, + { "_te","_tea",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_A], 0 }, + { "_te","_teb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_B], 0 }, + { "_te","_tec",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_C], 0 }, - { "_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_X], 0 }, // X target runtime - { "_tr","_try",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_Y], 0 }, - { "_tr","_trz",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_Z], 0 }, - { "_tr","_tra",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_A], 0 }, - { "_tr","_trb",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_B], 0 }, - { "_tr","_trc",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_C], 0 }, + { "_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_X], 0 }, // X target runtime + { "_tr","_try",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_Y], 0 }, + { "_tr","_trz",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_Z], 0 }, + { "_tr","_tra",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_A], 0 }, + { "_tr","_trb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_B], 0 }, + { "_tr","_trc",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_C], 0 }, #if (MOTORS >= 1) - { "_ts","_ts1",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target_steps[MOTOR_1], 0 }, // Motor 1 target steps - { "_ps","_ps1",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.position_steps[MOTOR_1], 0 }, // Motor 1 position steps - { "_cs","_cs1",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.commanded_steps[MOTOR_1], 0 }, // Motor 1 commanded steps (delayed steps) - { "_es","_es1",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.encoder_steps[MOTOR_1], 0 }, // Motor 1 encoder steps - { "_xs","_xs1",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&st_pre.mot[MOTOR_1].corrected_steps, 0 }, // Motor 1 correction steps applied - { "_fe","_fe1",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.following_error[MOTOR_1], 0 }, // Motor 1 following error in steps + { "_ts","_ts1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_1], 0 }, // Motor 1 target steps + { "_ps","_ps1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_1], 0 }, // Motor 1 position steps + { "_cs","_cs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_1], 0 }, // Motor 1 commanded steps (delayed steps) + { "_es","_es1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_1], 0 }, // Motor 1 encoder steps + { "_xs","_xs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_1].corrected_steps, 0 }, // Motor 1 correction steps applied + { "_fe","_fe1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_1], 0 }, // Motor 1 following error in steps #endif #if (MOTORS >= 2) - { "_ts","_ts2",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target_steps[MOTOR_2], 0 }, - { "_ps","_ps2",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.position_steps[MOTOR_2], 0 }, - { "_cs","_cs2",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.commanded_steps[MOTOR_2], 0 }, - { "_es","_es2",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.encoder_steps[MOTOR_2], 0 }, - { "_xs","_xs2",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&st_pre.mot[MOTOR_2].corrected_steps, 0 }, - { "_fe","_fe2",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.following_error[MOTOR_2], 0 }, + { "_ts","_ts2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_2], 0 }, + { "_ps","_ps2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_2], 0 }, + { "_cs","_cs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_2], 0 }, + { "_es","_es2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_2], 0 }, + { "_xs","_xs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_2].corrected_steps, 0 }, + { "_fe","_fe2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_2], 0 }, #endif #if (MOTORS >= 3) - { "_ts","_ts3",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target_steps[MOTOR_3], 0 }, - { "_ps","_ps3",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.position_steps[MOTOR_3], 0 }, - { "_cs","_cs3",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.commanded_steps[MOTOR_3], 0 }, - { "_es","_es3",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.encoder_steps[MOTOR_3], 0 }, - { "_xs","_xs3",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&st_pre.mot[MOTOR_3].corrected_steps, 0 }, - { "_fe","_fe3",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.following_error[MOTOR_3], 0 }, + { "_ts","_ts3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_3], 0 }, + { "_ps","_ps3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_3], 0 }, + { "_cs","_cs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_3], 0 }, + { "_es","_es3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_3], 0 }, + { "_xs","_xs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_3].corrected_steps, 0 }, + { "_fe","_fe3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_3], 0 }, #endif #if (MOTORS >= 4) - { "_ts","_ts4",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target_steps[MOTOR_4], 0 }, - { "_ps","_ps4",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.position_steps[MOTOR_4], 0 }, - { "_cs","_cs4",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.commanded_steps[MOTOR_4], 0 }, - { "_es","_es4",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.encoder_steps[MOTOR_4], 0 }, - { "_xs","_xs4",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&st_pre.mot[MOTOR_4].corrected_steps, 0 }, - { "_fe","_fe4",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.following_error[MOTOR_4], 0 }, + { "_ts","_ts4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_4], 0 }, + { "_ps","_ps4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_4], 0 }, + { "_cs","_cs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_4], 0 }, + { "_es","_es4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_4], 0 }, + { "_xs","_xs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_4].corrected_steps, 0 }, + { "_fe","_fe4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_4], 0 }, #endif #if (MOTORS >= 5) - { "_ts","_ts5",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target_steps[MOTOR_5], 0 }, - { "_ps","_ps5",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.position_steps[MOTOR_5], 0 }, - { "_cs","_cs5",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.commanded_steps[MOTOR_5], 0 }, - { "_es","_es5",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.encoder_steps[MOTOR_5], 0 }, - { "_xs","_xs6",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&st_pre.mot[MOTOR_5].corrected_steps, 0 }, - { "_fe","_fe5",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.following_error[MOTOR_5], 0 }, + { "_ts","_ts5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_5], 0 }, + { "_ps","_ps5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_5], 0 }, + { "_cs","_cs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_5], 0 }, + { "_es","_es5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_5], 0 }, + { "_xs","_xs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_5].corrected_steps, 0 }, + { "_fe","_fe5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_5], 0 }, #endif #if (MOTORS >= 6) - { "_ts","_ts6",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target_steps[MOTOR_6], 0 }, - { "_ps","_ps6",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.position_steps[MOTOR_6], 0 }, - { "_cs","_cs6",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.commanded_steps[MOTOR_6], 0 }, - { "_es","_es6",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.encoder_steps[MOTOR_6], 0 }, - { "_xs","_xs5",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&st_pre.mot[MOTOR_6].corrected_steps, 0 }, - { "_fe","_fe6",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.following_error[MOTOR_6], 0 }, + { "_ts","_ts6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_6], 0 }, + { "_ps","_ps6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_6], 0 }, + { "_cs","_cs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_6], 0 }, + { "_es","_es6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_6], 0 }, + { "_xs","_xs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_6].corrected_steps, 0 }, + { "_fe","_fe6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_6], 0 }, #endif #endif // __DIAGNOSTIC_PARAMETERS @@ -1062,7 +1062,7 @@ const cfgItem_t cfgArray[] = { { "","se37",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[37],0 }, { "","se38",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[38],0 }, { "","se39",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[39],0 }, - // Count is 40, since se00 counts as one. +// Count is 40, since se00 counts as one. // Group lookups - must follow the single-valued entries for proper sub-string matching // *** Must agree with NV_COUNT_GROUPS below *** @@ -1262,81 +1262,58 @@ stat_t set_flu(nvObj_t *nv) return(STAT_OK); } -stat_t set_flup(nvObj_t *nv) -{ - if (nv->value < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - return (set_flu(nv)); -} - -stat_t set_fltp(nvObj_t *nv) -{ - if (nv->value < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - return (set_flt(nv)); -} - /* - * process_incoming_float() - pre-process an incoming floating point number for canonical units - * process_outgoing_float() - pre-process an outgoing floating point number for units display + * convert_incoming_float() - pre-process an incoming floating point number for canonical units + * convert_outgoing_float() - pre-process an outgoing floating point number for units display * - * Incoming floats are destined for SET operations.perform conditional unit conversion if - * the flags indicate. Note that SU (inverse conversion) is not converted here, but in the - * set_su function. - * + * Incoming floats are destined for SET operations. * Outgoing floats are the raw values from GET operations, destined for text or JSON display. - * These are conditionally unit converted, including SU. + * + * Apologies in advance for these twisty little functions. These functions are used to + * convert incoming floats into the native, canonical form of a parameter (mm, or whatever) + * and outgoing floats into a display format appropriate to the units mode in effect. + * They use the flags in the config table and other cues to determine what type of conversion + * to perform. + * + * The conversions are complicated by the fact that only linear axes actually convert - + * rotaries do not - unless they are in radius mode. Plus, determining the axis for a motor + * requires unraveling the motor mapping (handled in cm_get_axis_type()). Also, there are + * global SYS group values that are not associated with any axis. Lastly, the + * steps-per-unit value (1su) is actually kept in inverse conversion form, as its native + * form would be units-per-step. */ -void process_incoming_float(nvObj_t *nv) -{ - if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type - - uint8_t flags = GET_TABLE_BYTE(flags); - if (flags & F_CONVERT) { // is unit conversion required? - if (cm_get_units_mode(MODEL) == INCHES) { // if in inches mode - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // ...and a linear axis... - nv->value *= MM_PER_INCH; // convert to canonical millimeter units - } - } - } -} - -void process_outgoing_float(nvObj_t *nv) +static void _convert(nvObj_t *nv, float conversion_factor) { if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type if (isnan((double)nv->value) || isinf((double)nv->value)) { return; } // trap illegal float values ///+++ transform these checks into NaN or INF strings with an error return? - // We may need one of two types of units conversion, but only if in inches mode if (cm_get_units_mode(MODEL) == INCHES) { - uint8_t flags = GET_TABLE_BYTE(flags); - if (flags & F_CONVERT) { // standard units conversion - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { - nv->value *= INCHES_PER_MM; + cmAxisType axis_type = cm_get_axis_type(nv->index); // linear, rotary, global or error + if ((axis_type == AXIS_TYPE_LINEAR) || (axis_type == AXIS_TYPE_SYSTEM)) { + if (cfgArray[nv->index].flags & F_CONVERT) { // standard units conversion + nv->value *= conversion_factor; + } else + if (cfgArray[nv->index].flags & F_ICONVERT) { // inverse units conversion + nv->value /= conversion_factor; } - } else if (flags & F_ICONVERT) { // inverse units conversion -// if (st_get_axis_type_by_motor(nv->index) == AXIS_TYPE_LINEAR) { // axis motor is mapped to - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { // axis motor is mapped to - nv->value *= MM_PER_INCH; - } - } - } + } + } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; } +void convert_incoming_float(nvObj_t *nv) { return(_convert (nv, MM_PER_INCH)); } +void convert_outgoing_float(nvObj_t *nv) { return(_convert (nv, INCHES_PER_MM)); } + /* * get_float() - boilerplate for retrieving raw floating point value * set_float() - boilerplate for setting a floating point value with unit conversion * set_float_range() - set a floating point value with inclusive range check * * get_float() returns a raw float value in internal canonical units (e.g. mm, degrees) - * without units conversion. If conversion is required call preprocess_outgoing_float() + * without units conversion. If conversion is required call convert_outgoing_float() * afterwards. The text mode and JSON display routines do this, so you generally don't * have to worry about this. * @@ -1352,7 +1329,7 @@ stat_t get_float(nvObj_t *nv, const float value) { } stat_t set_float(nvObj_t *nv, float &value) { - process_incoming_float(nv); + convert_incoming_float(nv); value = nv->value; return (STAT_OK); } @@ -1361,7 +1338,7 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { char msg[64]; - process_incoming_float(nv); // conditional unit conversion + convert_incoming_float(nv); // conditional unit conversion if (nv->value < low) { sprintf(msg, "Input is less than minimum value %0.4f", low); nv_add_conditional_message(msg); diff --git a/g2core/gcode.h b/g2core/gcode.h index 50c8b33b..94917883 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -2,7 +2,7 @@ * gcode.h - rs274/ngc Gcode model and parser support * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -157,7 +157,7 @@ typedef enum { // used for spindle and arc dir DIRECTION_CCW } cmDirection; -typedef enum { // axis types +typedef enum { // axis types. Enum must be in this order AXIS_TYPE_SYSTEM=-2, // no axis, system parameter AXIS_TYPE_UNDEFINED=-1, // invalid type AXIS_TYPE_LINEAR, // linear axis @@ -276,12 +276,7 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used bool origin_offset_enable; // G92 offsets enabled/disabled. 0=disabled, 1=enabled bool block_delete_switch; // set true to enable block deletes (true is default) -// unimplemented gcode parameters -// float cutter_radius; // D - cutter radius compensation (0 is off) -// float cutter_length; // H - cutter length compensation (0 is off) - uint16_t magic_end; - } GCodeStateX_t; @@ -327,11 +322,6 @@ typedef struct GCodeInput { // Gcode model inputs - meaning depends float spindle_speed; // in RPM float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there uint8_t spindle_override_enable; // TRUE = override enabled - - // unimplemented gcode parameters - // float cutter_radius; // D - cutter radius compensation (0 is off) - // float cutter_length; // H - cutter length compensation (0 is off) - } GCodeInput_t; typedef struct GCodeFlags { // Gcode model input flags diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index d02096b0..cfd04bc5 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -2,8 +2,8 @@ * json_parser.cpp - JSON parser * This file is part of the g2core project * - * Copyright (c) 2011 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2016 Rob Giseburt + * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -420,7 +420,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) need_a_comma = false; break; } - case (TYPE_FLOAT): { process_outgoing_float(nv); + case (TYPE_FLOAT): { convert_outgoing_float(nv); str += floattoa(str, nv->value, nv->precision); break; } diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index c8abcd85..2757f0fa 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -2,7 +2,7 @@ * text_parser.cpp - text parser * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -196,7 +196,7 @@ void text_print_multiline_formatted(nvObj_t *nv) { for (uint8_t i=0; ivaluetype != TYPE_PARENT) { - process_outgoing_float(nv); + convert_outgoing_float(nv); nv_print(nv); } if ((nv = nv->nx) == NULL) return; From 67227440e77072436d4965c140416e9fac3868a1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 5 Jan 2017 18:09:53 -0500 Subject: [PATCH 048/283] More testing --- g2core/canonical_machine.cpp | 39 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 69cfe2f2..ea54d604 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2169,12 +2169,23 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; /***** AXIS HELPERS ***************************************************************** - * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) * _coord() - return coordinate system number or -1 if error - * cm_get_axis_char() - return ASCII char for axis given the axis number + * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) * cm_get_axis_type() - return linear axis (0), rotary axis (1) or error (-1) + * cm_get_axis_char() - return ASCII char for axis given the axis number */ +static int8_t _coord(char *token) // extract coordinate system from 3rd character +{ + char *ptr; + char coord_list[] = {"456789"}; + + if ((ptr = strchr(coord_list, token[2])) == NULL) { // test the 3rd character against the string + return (-1); + } + return (ptr - coord_list); +} + /* _axis() * * Cases that are handled by _get_axis(): @@ -2214,15 +2225,16 @@ static int8_t _axis(const index_t index) return (ptr - axes); } -static int8_t _coord(char *token) // extract coordinate system from 3rd character +cmAxisType cm_get_axis_type(const index_t index) { - char *ptr; - char coord_list[] = {"456789"}; - - if ((ptr = strchr(coord_list, token[2])) == NULL) { // test the 3rd character against the string - return (-1); + int8_t axis = _axis(index); + if (axis <= AXIS_TYPE_UNDEFINED) { + return ((cmAxisType)axis); } - return (ptr - coord_list); + if (axis >= AXIS_A) { + return (AXIS_TYPE_ROTARY); + } + return (AXIS_TYPE_LINEAR); } char cm_get_axis_char(const int8_t axis) @@ -2232,15 +2244,6 @@ char cm_get_axis_char(const int8_t axis) return (axis_char[axis]); } -cmAxisType cm_get_axis_type(const index_t index) -{ - int8_t axis = _axis(index); - if (axis == AXIS_TYPE_UNDEFINED) { return (AXIS_TYPE_UNDEFINED); } - if (axis == AXIS_TYPE_SYSTEM) { return (AXIS_TYPE_SYSTEM); } - if (axis >= AXIS_A) { return (AXIS_TYPE_ROTARY); } - return (AXIS_TYPE_LINEAR); -} - /**** Functions called directly from cfgArray table - mostly wrappers **** * _get_msg_helper() - helper to get string values * From 2e89061bd81d168dfdbf57ecabacd036759acb03 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 6 Jan 2017 11:43:20 -0500 Subject: [PATCH 049/283] interim commit - working on integrating tool offsets --- g2core/canonical_machine.cpp | 10 +++++++--- g2core/config.cpp | 13 ++++++++----- g2core/config_app.cpp | 28 ++++++++++++++-------------- g2core/main.cpp | 4 ++-- g2core/settings/settings_default.h | 2 +- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ea54d604..a0bee3a0 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2360,9 +2360,9 @@ stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_a stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv->index)]));} -/************************************ - **** AXIS GET AND SET FUNCTIONS **** - ************************************/ +/***************************************************** + **** TOOL TABLE AND OFFSET GET AND SET FUNCTIONS **** + *****************************************************/ stat_t cm_get_tof(nvObj_t *nv) { @@ -2378,6 +2378,10 @@ stat_t cm_set_tof(nvObj_t *nv) return (STAT_OK); } +/************************************ + **** AXIS GET AND SET FUNCTIONS **** + ************************************/ + /* * AXIS GET AND SET FUNCTIONS * diff --git a/g2core/config.cpp b/g2core/config.cpp index 9f77dc08..c1c2b970 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -2,7 +2,7 @@ * config.cpp - application independent configuration handling * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -67,7 +67,8 @@ stat_t nv_set(nvObj_t *nv) if (nv->index >= nv_index_max()) { return(STAT_INTERNAL_RANGE_ERROR); } - return (((fptrCmd)GET_TABLE_WORD(set))(nv)); + return (((fptrCmd)cfgArray[nv->index].set)(nv)); +// return (((fptrCmd)GET_TABLE_WORD(set))(nv)); } stat_t nv_get(nvObj_t *nv) @@ -75,7 +76,8 @@ stat_t nv_get(nvObj_t *nv) if (nv->index >= nv_index_max()) { return(STAT_INTERNAL_RANGE_ERROR); } - return (((fptrCmd)GET_TABLE_WORD(get))(nv)); + return (((fptrCmd)cfgArray[nv->index].get)(nv)); +// return (((fptrCmd)GET_TABLE_WORD(get))(nv)); } void nv_print(nvObj_t *nv) @@ -83,7 +85,8 @@ void nv_print(nvObj_t *nv) if (nv->index >= nv_index_max()) { return; } - ((fptrCmd)GET_TABLE_WORD(print))(nv); + ((fptrCmd)cfgArray[nv->index].print)(nv); +// ((fptrCmd)GET_TABLE_WORD(print))(nv); } stat_t nv_persist(nvObj_t *nv) @@ -128,7 +131,7 @@ static void _set_defa(nvObj_t *nv, bool print) cm_set_units_mode(MILLIMETERS); // must do inits in MM mode for (nv->index=0; nv_index_is_single(nv->index); nv->index++) { if (GET_TABLE_BYTE(flags) & F_INITIALIZE) { - nv->value = GET_TABLE_FLOAT(def_value); + nv->value = cfgArray[nv->index].def_value; strncpy(nv->token, cfgArray[nv->index].token, TOKEN_LEN); nv_set(nv); nv_persist(nv); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index c291a1a4..e57fa3ed 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -612,12 +612,12 @@ const cfgItem_t cfgArray[] = { { "tl","tlb",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_B], 0 }, { "tl","tlc",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_C], 0 }, */ - { "tl","tlx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tl","tly",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tl","tlz",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tl","tla",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tl","tlb",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tl","tlc",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofy",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofz",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofa",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofb",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofc",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, // Tool table offsets { "tt1","tt1x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_X], TT1_X_OFFSET }, @@ -1130,7 +1130,7 @@ const cfgItem_t cfgArray[] = { { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position // +9 = 45 - { "","tl",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tl offsets + { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // curren tool offsets { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets @@ -1140,13 +1140,13 @@ const cfgItem_t cfgArray[] = { { "","tt7",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt8",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt9",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets // +17 = 62 { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group diff --git a/g2core/main.cpp b/g2core/main.cpp index 0f346c26..1535ffe2 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -2,8 +2,8 @@ * main.cpp - g2core - An embedded rs274/ngc CNC controller * This file is part of the g2core project. * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 5157aaab..09f6bd6c 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -2,7 +2,7 @@ * settings_default.h - default machine profile - Set for Shapeoko2 * This file is part of the g2core project * - * Copyright (c) 2012 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the From cb8b824cce0d566f373e252848ac641d38b7fee8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 6 Jan 2017 12:17:47 -0500 Subject: [PATCH 050/283] Fixed a bug in tool offset initialization; redid group counts to dev-169 style --- g2core/config_app.cpp | 89 +++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index e57fa3ed..6556ad3d 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1073,27 +1073,37 @@ const cfgItem_t cfgArray[] = { // - Optional DIAGNOSTIC_PARAMETERS // - Uber groups (count these separately) +#define FIXED_GROUPS 2 { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // system group { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PWM 1 group - // 2 - { "","1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor groups - { "","2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, -#if (MOTORS >= 5) - { "","5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, -#endif -#if (MOTORS >= 6) - { "","6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, -#endif - // +4 = 6 + +#define AXIS_GROUPS AXES { "","x", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis groups { "","y", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","z", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","a", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","b", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","c", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +6 = 12 + +#define MOTOR_GROUPS MOTORS + { "","1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor groups +#if (MOTORS >= 2) + { "","2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, +#endif +#if (MOTORS >= 3) + { "","3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, +#endif +#if (MOTORS >= 4) + { "","4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, +#endif +#if (MOTORS >= 5) + { "","5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, +#endif +#if (MOTORS >= 6) + { "","6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, +#endif + +#define DIGITAL_IN_GROUPS 10 { "","in", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input state { "","di1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input configs { "","di2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, @@ -1104,7 +1114,8 @@ const cfgItem_t cfgArray[] = { { "","di7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","di8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","di9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +10 = 22 + +#define DIGITAL_OUT_GROUPS 14 { "","out", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output state { "","do1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output configs { "","do2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, @@ -1119,7 +1130,8 @@ const cfgItem_t cfgArray[] = { { "","do11", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","do12", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","do13", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +14 = 36 + +#define COORDINATE_OFFSET_GROUPS 9 { "","g54",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // coord offset groups { "","g55",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","g56",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, @@ -1129,8 +1141,9 @@ const cfgItem_t cfgArray[] = { { "","g92",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // origin offsets { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position - // +9 = 45 - { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // curren tool offsets + +#define TOOL_OFFSET_GROUPS 33 + { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // current tool offsets { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets @@ -1147,7 +1160,24 @@ const cfgItem_t cfgArray[] = { { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - // +17 = 62 + { "","tt17",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt18",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt19",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt20",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt21",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt22",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt23",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt24",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt25",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt26",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt27",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt29",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt31",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tt32",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + +#define MACHINE_STATE_GROUPS 8 { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group { "","ofs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work offset group @@ -1156,22 +1186,25 @@ const cfgItem_t cfgArray[] = { { "","pwr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor power enagled group { "","jog",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis jogging state group { "","jid",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // job ID group - // +8 = 70 + +#define TEMPERATURE_GROUPS 6 { "","he1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 1 group { "","he2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 2 group { "","he3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 3 group { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 1 group { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 2 group { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 3 group - // +6 = 76 #ifdef __USER_DATA +#define USER_DATA_GROUPS 4 { "","uda", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group { "","udb", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group { "","udc", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group { "","udd", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group #endif + #ifdef __DIAGNOSTIC_PARAMETERS +#define DIAGNOSTIC_GROUPS 8 { "","_te",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // target axis endpoint group { "","_tr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // target axis runtime group { "","_ts",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // target motor steps group @@ -1182,6 +1215,7 @@ const cfgItem_t cfgArray[] = { { "","_fe",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // following error group #endif +#define NV_COUNT_UBER_GROUPS 6 // Uber-group (groups of groups, for text-mode displays only) // *** Must agree with NV_COUNT_UBER_GROUPS below **** { "", "m", _f0, 0, tx_print_nul, _do_motors, set_nul,(float *)&cs.null,0 }, @@ -1193,7 +1227,7 @@ const cfgItem_t cfgArray[] = { }; /***** Make sure these defines line up with any changes in the above table *****/ - +/* #define NV_COUNT_UBER_GROUPS 6 // count of uber-groups, above #define FIXED_GROUPS 92 // count of fixed groups, excluding optional groups @@ -1223,6 +1257,19 @@ const cfgItem_t cfgArray[] = { #define TEMPERATURE_GROUPS 6 #define NV_COUNT_GROUPS (FIXED_GROUPS + MOTOR_GROUP_5 + MOTOR_GROUP_6 + USER_DATA_GROUPS + DIAGNOSTIC_GROUPS + TEMPERATURE_GROUPS) +*/ + +#define NV_COUNT_GROUPS (FIXED_GROUPS \ + + AXIS_GROUPS \ + + MOTOR_GROUPS \ + + DIGITAL_IN_GROUPS \ + + DIGITAL_OUT_GROUPS \ + + COORDINATE_OFFSET_GROUPS \ + + TOOL_OFFSET_GROUPS \ + + MACHINE_STATE_GROUPS \ + + TEMPERATURE_GROUPS \ + + USER_DATA_GROUPS \ + + DIAGNOSTIC_GROUPS) /* */ #define NV_INDEX_MAX (sizeof(cfgArray) / sizeof(cfgItem_t)) From c6138819dd7df95bc8b80c2a0330ed6c99c521ea Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 6 Jan 2017 13:39:31 -0500 Subject: [PATCH 051/283] Updated initialization flags in config table, and added a Zero initialization to some parameters; added ABC axes to make block config for testing. --- g2core/config.cpp | 19 +- g2core/config.h | 4 +- g2core/config_app.cpp | 552 ++++++++++++--------------- g2core/settings/settings_makeblock.h | 55 ++- 4 files changed, 320 insertions(+), 310 deletions(-) diff --git a/g2core/config.cpp b/g2core/config.cpp index c1c2b970..4ef94f40 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -68,7 +68,6 @@ stat_t nv_set(nvObj_t *nv) return(STAT_INTERNAL_RANGE_ERROR); } return (((fptrCmd)cfgArray[nv->index].set)(nv)); -// return (((fptrCmd)GET_TABLE_WORD(set))(nv)); } stat_t nv_get(nvObj_t *nv) @@ -77,7 +76,6 @@ stat_t nv_get(nvObj_t *nv) return(STAT_INTERNAL_RANGE_ERROR); } return (((fptrCmd)cfgArray[nv->index].get)(nv)); -// return (((fptrCmd)GET_TABLE_WORD(get))(nv)); } void nv_print(nvObj_t *nv) @@ -86,7 +84,6 @@ void nv_print(nvObj_t *nv) return; } ((fptrCmd)cfgArray[nv->index].print)(nv); -// ((fptrCmd)GET_TABLE_WORD(print))(nv); } stat_t nv_persist(nvObj_t *nv) @@ -128,13 +125,19 @@ void config_init() static void _set_defa(nvObj_t *nv, bool print) { - cm_set_units_mode(MILLIMETERS); // must do inits in MM mode + cm_set_units_mode(MILLIMETERS); // must do inits in MM mode for (nv->index=0; nv_index_is_single(nv->index); nv->index++) { - if (GET_TABLE_BYTE(flags) & F_INITIALIZE) { - nv->value = cfgArray[nv->index].def_value; + if (cfgArray[nv->index].flags & F_INITIALIZE) { + if (cfgArray[nv->index].flags & F_ZERO) { + nv->value = 0; + } else { + nv->value = cfgArray[nv->index].def_value; + } strncpy(nv->token, cfgArray[nv->index].token, TOKEN_LEN); - nv_set(nv); - nv_persist(nv); + cfgArray[nv->index].set(nv); // run the set method, nv_set(nv); + if (cfgArray[nv->index].flags & F_PERSIST) { + nv_persist(nv); + } } } sr_init_status_report(); // reset status reports diff --git a/g2core/config.h b/g2core/config.h index 865848aa..d71b2830 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -169,7 +169,6 @@ ***********************************************************************************/ // Sizing and footprints // chose one based on # of elements in cfgArray -//typedef uint8_t index_t; // use this if there are < 256 indexed objects typedef uint16_t index_t; // use this if there are > 255 indexed objects // defines allocated from stack (not-pre-allocated) @@ -223,6 +222,7 @@ typedef enum { // value typing for config and JSON #define F_NOSTRIP 0x04 // do not strip the group prefix from the token #define F_CONVERT 0x08 // set if unit conversion is required #define F_ICONVERT 0x10 // set if unit conversion is required AND value is an inverse quantity +#define F_ZERO 0x20 // initialize to zero (requires F_INITIALIZE set as well) #define _f0 0x00 #define _fi (F_INITIALIZE) @@ -231,6 +231,8 @@ typedef enum { // value typing for config and JSON #define _fc (F_CONVERT) #define _fic (F_INITIALIZE | F_CONVERT) #define _fip (F_INITIALIZE | F_PERSIST) +#define _fiz (F_INITIALIZE | F_ZERO) +#define _fizc (F_INITIALIZE | F_ZERO | F_CONVERT) #define _fipc (F_INITIALIZE | F_PERSIST | F_CONVERT) #define _fipn (F_INITIALIZE | F_PERSIST | F_NOSTRIP) #define _fipi (F_INITIALIZE | F_PERSIST | F_ICONVERT) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 6556ad3d..18ee3a50 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -95,16 +95,17 @@ static stat_t get_tick(nvObj_t *nv); // get system tick count * cannot exceed TOKEN_LEN. String functions working on the table assume these * rules are followed and do not check lengths or perform other validation. * - * - If the count of lines in cfgArray exceeds 255 (which it does) you need to - * ensure index_t is uint16_t in the config.h file (and not uint8_t). - * * - The precision value 'p' only affects JSON responses. You need to also set * the %f in the corresponding format string to set text mode display precision + * + * - Unit conversions are now conditional, and handled by convert_incoming_float() + * and convert_outgoing_float(). Apply conversion flags to all axes, not just linear, + * as rotary axes may be treated as linear if in radius mode, so the flag is needed. */ const cfgItem_t cfgArray[] = { // group token flags p, print_func, get_func, set_func, get/set target, default value - { "sys", "fb", _fipn,2, hw_print_fb, hw_get_fb, set_ro, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! - { "sys", "fv", _fipn,2, hw_print_fv, hw_get_fv, set_ro, (float *)&cs.null, 0 }, + { "sys", "fb", _fn, 2, hw_print_fb, hw_get_fb, set_ro, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! + { "sys", "fv", _fn, 2, hw_print_fv, hw_get_fv, set_ro, (float *)&cs.null, 0 }, { "sys", "fbs",_fn, 0, hw_print_fbs, hw_get_fbs, set_ro, (float *)&cs.null, 0 }, { "sys", "fbc",_fn, 0, hw_print_fbc, hw_get_fbc, set_ro, (float *)&cs.null, 0 }, { "sys", "hp", _fn, 0, hw_print_hp, hw_get_hp, set_ro, (float *)&cs.null, 0 }, @@ -112,43 +113,43 @@ const cfgItem_t cfgArray[] = { { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) - { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_ro, (float *)&cs.null, 0 }, // Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity - { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool + { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "n", _f0, 0, cm_print_line, cm_get_mline,set_ro, (float *)&cs.null, 0 }, // Model line number + { "", "line",_f0, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number + { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity + { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate + { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state + { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state + { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state + { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state + { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode + { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system + { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode + { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select + { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode + { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode + { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode + { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode + { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool // { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS - { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs + { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif - { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position + { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position + { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position + { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position + { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position + { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position + { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position - { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position + { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position + { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position + { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position + { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position + { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position + { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset @@ -199,8 +200,8 @@ const cfgItem_t cfgArray[] = { { "1","1ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, - { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M1_STEPS_PER_UNIT }, + { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, { "1","1po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M1_POLARITY }, { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, { "1","1pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M1_POWER_LEVEL }, @@ -210,8 +211,8 @@ const cfgItem_t cfgArray[] = { { "2","2ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, { "2","2tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, - { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M2_STEPS_PER_UNIT }, + { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, { "2","2po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M2_POLARITY }, { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, { "2","2pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M2_POWER_LEVEL}, @@ -222,8 +223,8 @@ const cfgItem_t cfgArray[] = { { "3","3ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, { "3","3tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, - { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M3_STEPS_PER_UNIT }, + { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, { "3","3po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M3_POLARITY }, { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, { "3","3pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M3_POWER_LEVEL }, @@ -234,8 +235,8 @@ const cfgItem_t cfgArray[] = { { "4","4ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, { "4","4tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, - { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M4_STEPS_PER_UNIT }, + { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, { "4","4po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M4_POLARITY }, { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, { "4","4pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M4_POWER_LEVEL }, @@ -246,8 +247,8 @@ const cfgItem_t cfgArray[] = { { "5","5ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, { "5","5tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, - { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M5_STEPS_PER_UNIT }, + { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, { "5","5po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M5_POLARITY }, { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, { "5","5pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M5_POWER_LEVEL }, @@ -258,8 +259,8 @@ const cfgItem_t cfgArray[] = { { "6","6ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, { "6","6tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, - { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M6_STEPS_PER_UNIT }, + { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, { "6","6po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M6_POLARITY }, { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M6_POWER_LEVEL }, @@ -310,49 +311,49 @@ const cfgItem_t cfgArray[] = { { "z","zzb",_fipc, 3, cm_print_zb, cm_get_lb, cm_set_zb, (float *)&cs.null, Z_ZERO_BACKOFF }, { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, - { "a","avm",_fip, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, A_VELOCITY_MAX }, - { "a","afr",_fip, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, A_FEEDRATE_MAX }, - { "a","atn",_fip, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, - { "a","atm",_fip, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, A_TRAVEL_MAX }, - { "a","ajm",_fip, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, A_JERK_MAX }, - { "a","ajh",_fip, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, A_JERK_HIGH_SPEED }, + { "a","avm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, A_VELOCITY_MAX }, + { "a","afr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, A_FEEDRATE_MAX }, + { "a","atn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, + { "a","atm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, A_TRAVEL_MAX }, + { "a","ajm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, A_JERK_MAX }, + { "a","ajh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, A_JERK_HIGH_SPEED }, { "a","ara",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, A_RADIUS}, { "a","ahi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, A_HOMING_INPUT }, { "a","ahd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, A_HOMING_DIRECTION }, - { "a","asv",_fip, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, A_SEARCH_VELOCITY }, - { "a","alv",_fip, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, A_LATCH_VELOCITY }, - { "a","alb",_fip, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, - { "a","azb",_fip, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, + { "a","asv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, A_SEARCH_VELOCITY }, + { "a","alv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, A_LATCH_VELOCITY }, + { "a","alb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, + { "a","azb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, - { "b","bvm",_fip, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, B_VELOCITY_MAX }, - { "b","bfr",_fip, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, B_FEEDRATE_MAX }, - { "b","btn",_fip, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, - { "b","btm",_fip, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, B_TRAVEL_MAX }, - { "b","bjm",_fip, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, B_JERK_MAX }, - { "b","bjh",_fip, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, B_JERK_HIGH_SPEED }, + { "b","bvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, B_VELOCITY_MAX }, + { "b","bfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, B_FEEDRATE_MAX }, + { "b","btn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, + { "b","btm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, B_TRAVEL_MAX }, + { "b","bjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, B_JERK_MAX }, + { "b","bjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, B_JERK_HIGH_SPEED }, { "b","bra",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, B_RADIUS }, { "b","bhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, B_HOMING_INPUT }, { "b","bhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, B_HOMING_DIRECTION }, - { "b","bsv",_fip, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, B_SEARCH_VELOCITY }, - { "b","blv",_fip, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, B_LATCH_VELOCITY }, - { "b","blb",_fip, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, - { "b","bzb",_fip, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, + { "b","bsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, B_SEARCH_VELOCITY }, + { "b","blv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, B_LATCH_VELOCITY }, + { "b","blb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, + { "b","bzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, - { "c","cvm",_fip, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, C_VELOCITY_MAX }, - { "c","cfr",_fip, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, C_FEEDRATE_MAX }, - { "c","ctn",_fip, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, - { "c","ctm",_fip, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, C_TRAVEL_MAX }, - { "c","cjm",_fip, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, C_JERK_MAX }, - { "c","cjh",_fip, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, C_JERK_HIGH_SPEED }, + { "c","cvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, C_VELOCITY_MAX }, + { "c","cfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, C_FEEDRATE_MAX }, + { "c","ctn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, + { "c","ctm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, C_TRAVEL_MAX }, + { "c","cjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, C_JERK_MAX }, + { "c","cjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, C_JERK_HIGH_SPEED }, { "c","cra",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, C_RADIUS }, { "c","chi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, C_HOMING_INPUT }, { "c","chd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, C_HOMING_DIRECTION }, - { "c","csv",_fip, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, C_SEARCH_VELOCITY }, - { "c","clv",_fip, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, C_LATCH_VELOCITY }, - { "c","clb",_fip, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, - { "c","czb",_fip, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, + { "c","csv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, C_SEARCH_VELOCITY }, + { "c","clv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, C_LATCH_VELOCITY }, + { "c","clb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, + { "c","czb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, // Digital input configs { "di1","di1mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, @@ -472,17 +473,17 @@ const cfgItem_t cfgArray[] = { // temperature configs - pid active values (read-only) // NOTICE: If you change these PID group keys, you MUST change the get/set functions too!! - { "pid1","pid1p",_f0, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid1","pid1i",_f0, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid1","pid1d",_f0, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid1","pid1p",_fiz, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, + { "pid1","pid1i",_fiz, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, + { "pid1","pid1d",_fiz, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2p",_f0, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2i",_f0, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2d",_f0, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2p",_fiz, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2i",_fiz, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2d",_fiz, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3p",_f0, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3i",_f0, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3d",_f0, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3p",_fiz, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3i",_fiz, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3d",_fiz, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, // temperature configs - heater set values (read-write) // NOTICE: If you change these heater group keys, you MUST change the get/set functions too!! @@ -490,359 +491,343 @@ const cfgItem_t cfgArray[] = { { "he1","he1p", _fi, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H1_DEFAULT_P }, { "he1","he1i", _fi, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H1_DEFAULT_I }, { "he1","he1d", _fi, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H1_DEFAULT_D }, - { "he1","he1st",_f0, 1, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he1","he1t", _f0, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he1","he1op",_f0, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he1","he1tr",_f0, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he1","he1at",_f0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he1","he1an",_f0, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he1","he1fp",_f0, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he1","he1fm",_f0, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he1","he1fl",_f0, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he1","he1fh",_f0, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he1","he1st",_fiz, 1, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, + { "he1","he1t", _fiz, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, + { "he1","he1op",_fiz, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, + { "he1","he1tr",_fiz, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, + { "he1","he1at",_fiz, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, + { "he1","he1an",_fiz, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, + { "he1","he1fp",_fiz, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, + { "he1","he1fm",_fiz, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, + { "he1","he1fl",_fiz, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, + { "he1","he1fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, { "he2","he2e", _fip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H2_DEFAULT_ENABLE }, { "he2","he2p", _fi, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H2_DEFAULT_P }, { "he2","he2i", _fi, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H2_DEFAULT_I }, { "he2","he2d", _fi, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H2_DEFAULT_D }, - { "he2","he2st",_f0, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he2","he2t", _f0, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he2","he2op",_f0, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he2","he2tr",_f0, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he2","he2at",_f0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he2","he2an",_f0, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he2","he2fp",_f0, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he2","he2fm",_f0, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he2","he2fl",_f0, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he2","he2fh",_f0, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he2","he2st",_fiz, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, + { "he2","he2t", _fiz, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, + { "he2","he2op",_fiz, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, + { "he2","he2tr",_fiz, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, + { "he2","he2at",_fiz, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, + { "he2","he2an",_fiz, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, + { "he2","he2fp",_fiz, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, + { "he2","he2fm",_fiz, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, + { "he2","he2fl",_fiz, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, + { "he2","he2fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, { "he3","he3e", _fip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H3_DEFAULT_ENABLE }, { "he3","he3p", _fi, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H3_DEFAULT_P }, { "he3","he3i", _fi, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H3_DEFAULT_I }, { "he3","he3d", _fi, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H3_DEFAULT_D }, - { "he3","he3st",_f0, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he3","he3t", _f0, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he3","he3op",_f0, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he3","he3tr",_f0, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he3","he3at",_f0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he3","he3an",_f0, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he3","he3fp",_f0, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he3","he3fm",_f0, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he3","he3fl",_f0, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he3","he3fh",_f0, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he3","he3st",_fiz, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, + { "he3","he3t", _fiz, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, + { "he3","he3op",_fiz, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, + { "he3","he3tr",_fiz, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, + { "he3","he3at",_fiz, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, + { "he3","he3an",_fiz, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, + { "he3","he3fp",_fiz, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, + { "he3","he3fm",_fiz, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, + { "he3","he3fl",_fiz, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, + { "he3","he3fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, // Coordinate system offsets (G54-G59 and G92) { "g54","g54x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_X_OFFSET }, { "g54","g54y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Y_OFFSET }, { "g54","g54z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Z_OFFSET }, - { "g54","g54a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_A_OFFSET }, - { "g54","g54b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_B_OFFSET }, - { "g54","g54c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_C_OFFSET }, + { "g54","g54a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_A_OFFSET }, + { "g54","g54b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_B_OFFSET }, + { "g54","g54c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_C_OFFSET }, { "g55","g55x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_X_OFFSET }, { "g55","g55y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Y_OFFSET }, { "g55","g55z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Z_OFFSET }, - { "g55","g55a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_A_OFFSET }, - { "g55","g55b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_B_OFFSET }, - { "g55","g55c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_C_OFFSET }, + { "g55","g55a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_A_OFFSET }, + { "g55","g55b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_B_OFFSET }, + { "g55","g55c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_C_OFFSET }, { "g56","g56x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_X_OFFSET }, { "g56","g56y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Y_OFFSET }, { "g56","g56z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Z_OFFSET }, - { "g56","g56a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_A_OFFSET }, - { "g56","g56b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_B_OFFSET }, - { "g56","g56c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_C_OFFSET }, + { "g56","g56a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_A_OFFSET }, + { "g56","g56b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_B_OFFSET }, + { "g56","g56c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_C_OFFSET }, { "g57","g57x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_X_OFFSET }, { "g57","g57y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Y_OFFSET }, { "g57","g57z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Z_OFFSET }, - { "g57","g57a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_A_OFFSET }, - { "g57","g57b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_B_OFFSET }, - { "g57","g57c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_C_OFFSET }, + { "g57","g57a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_A_OFFSET }, + { "g57","g57b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_B_OFFSET }, + { "g57","g57c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_C_OFFSET }, { "g58","g58x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_X_OFFSET }, { "g58","g58y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Y_OFFSET }, { "g58","g58z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Z_OFFSET }, - { "g58","g58a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_A_OFFSET }, - { "g58","g58b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_B_OFFSET }, - { "g58","g58c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_C_OFFSET }, + { "g58","g58a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_A_OFFSET }, + { "g58","g58b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_B_OFFSET }, + { "g58","g58c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_C_OFFSET }, { "g59","g59x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_X_OFFSET }, { "g59","g59y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Y_OFFSET }, { "g59","g59z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Z_OFFSET }, - { "g59","g59a",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_A_OFFSET }, - { "g59","g59b",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, - { "g59","g59c",_fip, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, + { "g59","g59a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_A_OFFSET }, + { "g59","g59b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, + { "g59","g59c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, - { "g92","g92x",_fic, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently - { "g92","g92y",_fic, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92z",_fic, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92a",_fi, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92b",_fi, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92c",_fi, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92x",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently + { "g92","g92y",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92z",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92a",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92b",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92c",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fic, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently - { "g28","g28y",_fic, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28z",_fic, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28a",_fi, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28b",_fi, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28c",_fi, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28x",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently + { "g28","g28y",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28z",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28a",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28b",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28c",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g30","g30x",_fic, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently - { "g30","g30y",_fic, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30z",_fic, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30a",_fi, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30b",_fi, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30c",_fi, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30x",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently + { "g30","g30y",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30z",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30a",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30b",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30c",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, -/* - // Default values for current tool length offsets (not configurable, set to zero) - { "tl","tlx",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->tl_offset[AXIS_X], 0 }, - { "tl","tly",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->tl_offset[AXIS_Y], 0 }, - { "tl","tlz",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm->tl_offset[AXIS_Z], 0 }, - { "tl","tla",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_A], 0 }, - { "tl","tlb",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_B], 0 }, - { "tl","tlc",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_C], 0 }, - - { "tl","tlx",_fipc, 3, cm_print_cofs, cm_get_tof, set_flu,(float *)&cm.tl_offset[AXIS_X], 0 }, - { "tl","tly",_fipc, 3, cm_print_cofs, cm_get_tof, set_flu,(float *)&cm.tl_offset[AXIS_Y], 0 }, - { "tl","tlz",_fipc, 3, cm_print_cofs, cm_get_tof, set_flu,(float *)&cm.tl_offset[AXIS_Z], 0 }, - { "tl","tla",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_A], 0 }, - { "tl","tlb",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_B], 0 }, - { "tl","tlc",_fip, 3, cm_print_cofs, cm_get_tof, set_flt,(float *)&cm.tl_offset[AXIS_C], 0 }, -*/ + // Tool table offsets { "tof","tofx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, { "tof","tofy",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, { "tof","tofz",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofa",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofb",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofc",_fip, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofa",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofb",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofc",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - // Tool table offsets { "tt1","tt1x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_X], TT1_X_OFFSET }, { "tt1","tt1y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_Y], TT1_Y_OFFSET }, { "tt1","tt1z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_Z], TT1_Z_OFFSET }, - { "tt1","tt1a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_A], TT1_A_OFFSET }, - { "tt1","tt1b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_B], TT1_B_OFFSET }, - { "tt1","tt1c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_C], TT1_C_OFFSET }, + { "tt1","tt1a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_A], TT1_A_OFFSET }, + { "tt1","tt1b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_B], TT1_B_OFFSET }, + { "tt1","tt1c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_C], TT1_C_OFFSET }, { "tt2","tt2x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[2][AXIS_X], TT2_X_OFFSET }, { "tt2","tt2y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[2][AXIS_Y], TT2_Y_OFFSET }, { "tt2","tt2z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[2][AXIS_Z], TT2_Z_OFFSET }, - { "tt2","tt2a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_A], TT2_A_OFFSET }, - { "tt2","tt2b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_B], TT2_B_OFFSET }, - { "tt2","tt2c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_C], TT2_C_OFFSET }, + { "tt2","tt2a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_A], TT2_A_OFFSET }, + { "tt2","tt2b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_B], TT2_B_OFFSET }, + { "tt2","tt2c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_C], TT2_C_OFFSET }, { "tt3","tt3x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[3][AXIS_X], TT3_X_OFFSET }, { "tt3","tt3y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[3][AXIS_Y], TT3_Y_OFFSET }, { "tt3","tt3z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[3][AXIS_Z], TT3_Z_OFFSET }, - { "tt3","tt3a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_A], TT3_A_OFFSET }, - { "tt3","tt3b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_B], TT3_B_OFFSET }, - { "tt3","tt3c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_C], TT1_C_OFFSET }, + { "tt3","tt3a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_A], TT3_A_OFFSET }, + { "tt3","tt3b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_B], TT3_B_OFFSET }, + { "tt3","tt3c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_C], TT1_C_OFFSET }, { "tt4","tt4x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[4][AXIS_X], TT4_X_OFFSET }, { "tt4","tt4y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[4][AXIS_Y], TT4_Y_OFFSET }, { "tt4","tt4z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[4][AXIS_Z], TT4_Z_OFFSET }, - { "tt4","tt4a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_A], TT4_A_OFFSET }, - { "tt4","tt4b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_B], TT4_B_OFFSET }, - { "tt4","tt4c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_C], TT4_C_OFFSET }, + { "tt4","tt4a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_A], TT4_A_OFFSET }, + { "tt4","tt4b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_B], TT4_B_OFFSET }, + { "tt4","tt4c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_C], TT4_C_OFFSET }, { "tt5","tt5x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[5][AXIS_X], TT5_X_OFFSET }, { "tt5","tt5y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[5][AXIS_Y], TT5_Y_OFFSET }, { "tt5","tt5z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[5][AXIS_Z], TT5_Z_OFFSET }, - { "tt5","tt5a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_A], TT5_A_OFFSET }, - { "tt5","tt5b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_B], TT5_B_OFFSET }, - { "tt5","tt5c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_C], TT5_C_OFFSET }, + { "tt5","tt5a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_A], TT5_A_OFFSET }, + { "tt5","tt5b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_B], TT5_B_OFFSET }, + { "tt5","tt5c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_C], TT5_C_OFFSET }, { "tt6","tt6x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[6][AXIS_X], TT6_X_OFFSET }, { "tt6","tt6y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[6][AXIS_Y], TT6_Y_OFFSET }, { "tt6","tt6z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[6][AXIS_Z], TT6_Z_OFFSET }, - { "tt6","tt6a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_A], TT6_A_OFFSET }, - { "tt6","tt6b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_B], TT6_B_OFFSET }, - { "tt6","tt6c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_C], TT6_C_OFFSET }, + { "tt6","tt6a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_A], TT6_A_OFFSET }, + { "tt6","tt6b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_B], TT6_B_OFFSET }, + { "tt6","tt6c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_C], TT6_C_OFFSET }, { "tt7","tt7x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[7][AXIS_X], TT7_X_OFFSET }, { "tt7","tt7y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[7][AXIS_Y], TT7_Y_OFFSET }, { "tt7","tt7z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[7][AXIS_Z], TT7_Z_OFFSET }, - { "tt7","tt7a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_A], TT7_A_OFFSET }, - { "tt7","tt7b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_B], TT7_B_OFFSET }, - { "tt7","tt7c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_C], TT7_C_OFFSET }, + { "tt7","tt7a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_A], TT7_A_OFFSET }, + { "tt7","tt7b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_B], TT7_B_OFFSET }, + { "tt7","tt7c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_C], TT7_C_OFFSET }, { "tt8","tt8x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[8][AXIS_X], TT8_X_OFFSET }, { "tt8","tt8y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[8][AXIS_Y], TT8_Y_OFFSET }, { "tt8","tt8z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[8][AXIS_Z], TT8_Z_OFFSET }, - { "tt8","tt8a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_A], TT8_A_OFFSET }, - { "tt8","tt8b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_B], TT8_B_OFFSET }, - { "tt8","tt8c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_C], TT8_C_OFFSET }, + { "tt8","tt8a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_A], TT8_A_OFFSET }, + { "tt8","tt8b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_B], TT8_B_OFFSET }, + { "tt8","tt8c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_C], TT8_C_OFFSET }, { "tt9","tt9x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[9][AXIS_X], TT9_X_OFFSET }, { "tt9","tt9y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[9][AXIS_Y], TT9_Y_OFFSET }, { "tt9","tt9z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[9][AXIS_Z], TT9_Z_OFFSET }, - { "tt9","tt9a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_A], TT9_A_OFFSET }, - { "tt9","tt9b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_B], TT9_B_OFFSET }, - { "tt9","tt9c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_C], TT9_C_OFFSET }, + { "tt9","tt9a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_A], TT9_A_OFFSET }, + { "tt9","tt9b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_B], TT9_B_OFFSET }, + { "tt9","tt9c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_C], TT9_C_OFFSET }, { "tt10","tt10x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[10][AXIS_X], TT10_X_OFFSET }, { "tt10","tt10y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[10][AXIS_Y], TT10_Y_OFFSET }, { "tt10","tt10z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[10][AXIS_Z], TT10_Z_OFFSET }, - { "tt10","tt10a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_A], TT10_A_OFFSET }, - { "tt10","tt10b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_B], TT10_B_OFFSET }, - { "tt10","tt10c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_C], TT10_C_OFFSET }, + { "tt10","tt10a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_A], TT10_A_OFFSET }, + { "tt10","tt10b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_B], TT10_B_OFFSET }, + { "tt10","tt10c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_C], TT10_C_OFFSET }, { "tt11","tt11x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[11][AXIS_X], TT11_X_OFFSET }, { "tt11","tt11y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[11][AXIS_Y], TT11_Y_OFFSET }, { "tt11","tt11z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[11][AXIS_Z], TT11_Z_OFFSET }, - { "tt11","tt11a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_A], TT11_A_OFFSET }, - { "tt11","tt11b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_B], TT11_B_OFFSET }, - { "tt11","tt11c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_C], TT11_C_OFFSET }, + { "tt11","tt11a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_A], TT11_A_OFFSET }, + { "tt11","tt11b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_B], TT11_B_OFFSET }, + { "tt11","tt11c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_C], TT11_C_OFFSET }, { "tt12","tt12x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[12][AXIS_X], TT12_X_OFFSET }, { "tt12","tt12y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[12][AXIS_Y], TT12_Y_OFFSET }, { "tt12","tt12z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[12][AXIS_Z], TT12_Z_OFFSET }, - { "tt12","tt12a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_A], TT12_A_OFFSET }, - { "tt12","tt12b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_B], TT12_B_OFFSET }, - { "tt12","tt12c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_C], TT12_C_OFFSET }, + { "tt12","tt12a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_A], TT12_A_OFFSET }, + { "tt12","tt12b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_B], TT12_B_OFFSET }, + { "tt12","tt12c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_C], TT12_C_OFFSET }, { "tt13","tt13x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[13][AXIS_X], TT13_X_OFFSET }, { "tt13","tt13y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[13][AXIS_Y], TT13_Y_OFFSET }, { "tt13","tt13z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[13][AXIS_Z], TT13_Z_OFFSET }, - { "tt13","tt13a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_A], TT13_A_OFFSET }, - { "tt13","tt13b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_B], TT13_B_OFFSET }, - { "tt13","tt13c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_C], TT13_C_OFFSET }, + { "tt13","tt13a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_A], TT13_A_OFFSET }, + { "tt13","tt13b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_B], TT13_B_OFFSET }, + { "tt13","tt13c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_C], TT13_C_OFFSET }, { "tt14","tt14x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[14][AXIS_X], TT14_X_OFFSET }, { "tt14","tt14y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[14][AXIS_Y], TT14_Y_OFFSET }, { "tt14","tt14z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[14][AXIS_Z], TT14_Z_OFFSET }, - { "tt14","tt14a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_A], TT14_A_OFFSET }, - { "tt14","tt14b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_B], TT14_B_OFFSET }, - { "tt14","tt14c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_C], TT14_C_OFFSET }, + { "tt14","tt14a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_A], TT14_A_OFFSET }, + { "tt14","tt14b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_B], TT14_B_OFFSET }, + { "tt14","tt14c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_C], TT14_C_OFFSET }, { "tt15","tt15x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[15][AXIS_X], TT15_X_OFFSET }, { "tt15","tt15y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[15][AXIS_Y], TT15_Y_OFFSET }, { "tt15","tt15z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[15][AXIS_Z], TT15_Z_OFFSET }, - { "tt15","tt15a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_A], TT15_A_OFFSET }, - { "tt15","tt15b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_B], TT15_B_OFFSET }, - { "tt15","tt15c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_C], TT15_C_OFFSET }, + { "tt15","tt15a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_A], TT15_A_OFFSET }, + { "tt15","tt15b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_B], TT15_B_OFFSET }, + { "tt15","tt15c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_C], TT15_C_OFFSET }, { "tt16","tt16x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[16][AXIS_X], TT16_X_OFFSET }, { "tt16","tt16y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[16][AXIS_Y], TT16_Y_OFFSET }, { "tt16","tt16z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[16][AXIS_Z], TT16_Z_OFFSET }, - { "tt16","tt16a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_A], TT16_A_OFFSET }, - { "tt16","tt16b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_B], TT16_B_OFFSET }, - { "tt16","tt16c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_C], TT16_C_OFFSET }, + { "tt16","tt16a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_A], TT16_A_OFFSET }, + { "tt16","tt16b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_B], TT16_B_OFFSET }, + { "tt16","tt16c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_C], TT16_C_OFFSET }, { "tt17","tt17x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[17][AXIS_X], TT17_X_OFFSET }, { "tt17","tt17y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[17][AXIS_Y], TT17_Y_OFFSET }, { "tt17","tt17z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[17][AXIS_Z], TT17_Z_OFFSET }, - { "tt17","tt17a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_A], TT17_A_OFFSET }, - { "tt17","tt17b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_B], TT17_B_OFFSET }, - { "tt17","tt17c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_C], TT17_C_OFFSET }, + { "tt17","tt17a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_A], TT17_A_OFFSET }, + { "tt17","tt17b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_B], TT17_B_OFFSET }, + { "tt17","tt17c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_C], TT17_C_OFFSET }, { "tt18","tt18x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[18][AXIS_X], TT18_X_OFFSET }, { "tt18","tt18y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[18][AXIS_Y], TT18_Y_OFFSET }, { "tt18","tt18z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[18][AXIS_Z], TT18_Z_OFFSET }, - { "tt18","tt18a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_A], TT18_A_OFFSET }, - { "tt18","tt18b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_B], TT18_B_OFFSET }, - { "tt18","tt18c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_C], TT18_C_OFFSET }, + { "tt18","tt18a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_A], TT18_A_OFFSET }, + { "tt18","tt18b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_B], TT18_B_OFFSET }, + { "tt18","tt18c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_C], TT18_C_OFFSET }, { "tt19","tt19x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[19][AXIS_X], TT19_X_OFFSET }, { "tt19","tt19y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[19][AXIS_Y], TT19_Y_OFFSET }, { "tt19","tt19z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[19][AXIS_Z], TT19_Z_OFFSET }, - { "tt19","tt19a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_A], TT19_A_OFFSET }, - { "tt19","tt19b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_B], TT19_B_OFFSET }, - { "tt19","tt19c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_C], TT19_C_OFFSET }, + { "tt19","tt19a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_A], TT19_A_OFFSET }, + { "tt19","tt19b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_B], TT19_B_OFFSET }, + { "tt19","tt19c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_C], TT19_C_OFFSET }, { "tt20","tt20x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[20][AXIS_X], TT20_X_OFFSET }, { "tt20","tt20y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[20][AXIS_Y], TT20_Y_OFFSET }, { "tt20","tt20z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[20][AXIS_Z], TT20_Z_OFFSET }, - { "tt20","tt20a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_A], TT20_A_OFFSET }, - { "tt20","tt20b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_B], TT20_B_OFFSET }, - { "tt20","tt20c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_C], TT20_C_OFFSET }, + { "tt20","tt20a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_A], TT20_A_OFFSET }, + { "tt20","tt20b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_B], TT20_B_OFFSET }, + { "tt20","tt20c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_C], TT20_C_OFFSET }, { "tt21","tt21x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[21][AXIS_X], TT21_X_OFFSET }, { "tt21","tt21y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[21][AXIS_Y], TT21_Y_OFFSET }, { "tt21","tt21z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[21][AXIS_Z], TT21_Z_OFFSET }, - { "tt21","tt21a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_A], TT21_A_OFFSET }, - { "tt21","tt21b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_B], TT21_B_OFFSET }, - { "tt21","tt21c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_C], TT21_C_OFFSET }, + { "tt21","tt21a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_A], TT21_A_OFFSET }, + { "tt21","tt21b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_B], TT21_B_OFFSET }, + { "tt21","tt21c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_C], TT21_C_OFFSET }, { "tt22","tt22x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[22][AXIS_X], TT22_X_OFFSET }, { "tt22","tt22y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[22][AXIS_Y], TT22_Y_OFFSET }, { "tt22","tt22z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[22][AXIS_Z], TT22_Z_OFFSET }, - { "tt22","tt22a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_A], TT22_A_OFFSET }, - { "tt22","tt22b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_B], TT22_B_OFFSET }, - { "tt22","tt22c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_C], TT22_C_OFFSET }, + { "tt22","tt22a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_A], TT22_A_OFFSET }, + { "tt22","tt22b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_B], TT22_B_OFFSET }, + { "tt22","tt22c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_C], TT22_C_OFFSET }, { "tt23","tt23x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[23][AXIS_X], TT23_X_OFFSET }, { "tt23","tt23y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[23][AXIS_Y], TT23_Y_OFFSET }, { "tt23","tt23z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[23][AXIS_Z], TT23_Z_OFFSET }, - { "tt23","tt23a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_A], TT23_A_OFFSET }, - { "tt23","tt23b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_B], TT23_B_OFFSET }, - { "tt23","tt23c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_C], TT23_C_OFFSET }, + { "tt23","tt23a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_A], TT23_A_OFFSET }, + { "tt23","tt23b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_B], TT23_B_OFFSET }, + { "tt23","tt23c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_C], TT23_C_OFFSET }, { "tt24","tt24x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[24][AXIS_X], TT24_X_OFFSET }, { "tt24","tt24y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[24][AXIS_Y], TT24_Y_OFFSET }, { "tt24","tt24z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[24][AXIS_Z], TT24_Z_OFFSET }, - { "tt24","tt24a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_A], TT24_A_OFFSET }, - { "tt24","tt24b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_B], TT24_B_OFFSET }, - { "tt24","tt24c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_C], TT24_C_OFFSET }, + { "tt24","tt24a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_A], TT24_A_OFFSET }, + { "tt24","tt24b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_B], TT24_B_OFFSET }, + { "tt24","tt24c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_C], TT24_C_OFFSET }, { "tt25","tt25x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[25][AXIS_X], TT25_X_OFFSET }, { "tt25","tt25y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[25][AXIS_Y], TT25_Y_OFFSET }, { "tt25","tt25z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[25][AXIS_Z], TT25_Z_OFFSET }, - { "tt25","tt25a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_A], TT25_A_OFFSET }, - { "tt25","tt25b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_B], TT25_B_OFFSET }, - { "tt25","tt25c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_C], TT25_C_OFFSET }, + { "tt25","tt25a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_A], TT25_A_OFFSET }, + { "tt25","tt25b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_B], TT25_B_OFFSET }, + { "tt25","tt25c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_C], TT25_C_OFFSET }, { "tt26","tt26x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[26][AXIS_X], TT26_X_OFFSET }, { "tt26","tt26y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[26][AXIS_Y], TT26_Y_OFFSET }, { "tt26","tt26z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[26][AXIS_Z], TT26_Z_OFFSET }, - { "tt26","tt26a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_A], TT26_A_OFFSET }, - { "tt26","tt26b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_B], TT26_B_OFFSET }, - { "tt26","tt26c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_C], TT26_C_OFFSET }, + { "tt26","tt26a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_A], TT26_A_OFFSET }, + { "tt26","tt26b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_B], TT26_B_OFFSET }, + { "tt26","tt26c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_C], TT26_C_OFFSET }, { "tt27","tt27x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[27][AXIS_X], TT27_X_OFFSET }, { "tt27","tt27y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[27][AXIS_Y], TT27_Y_OFFSET }, { "tt27","tt27z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[27][AXIS_Z], TT27_Z_OFFSET }, - { "tt27","tt27a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_A], TT27_A_OFFSET }, - { "tt27","tt27b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_B], TT27_B_OFFSET }, - { "tt27","tt27c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_C], TT27_C_OFFSET }, + { "tt27","tt27a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_A], TT27_A_OFFSET }, + { "tt27","tt27b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_B], TT27_B_OFFSET }, + { "tt27","tt27c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_C], TT27_C_OFFSET }, { "tt28","tt28x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[28][AXIS_X], TT28_X_OFFSET }, { "tt28","tt28y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[28][AXIS_Y], TT28_Y_OFFSET }, { "tt28","tt28z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[28][AXIS_Z], TT28_Z_OFFSET }, - { "tt28","tt28a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_A], TT28_A_OFFSET }, - { "tt28","tt28b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_B], TT28_B_OFFSET }, - { "tt28","tt28c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_C], TT28_C_OFFSET }, + { "tt28","tt28a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_A], TT28_A_OFFSET }, + { "tt28","tt28b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_B], TT28_B_OFFSET }, + { "tt28","tt28c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_C], TT28_C_OFFSET }, { "tt29","tt29x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[29][AXIS_X], TT29_X_OFFSET }, { "tt29","tt29y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[29][AXIS_Y], TT29_Y_OFFSET }, { "tt29","tt29z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[29][AXIS_Z], TT29_Z_OFFSET }, - { "tt29","tt29a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_A], TT29_A_OFFSET }, - { "tt29","tt29b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_B], TT29_B_OFFSET }, - { "tt29","tt29c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_C], TT29_C_OFFSET }, + { "tt29","tt29a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_A], TT29_A_OFFSET }, + { "tt29","tt29b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_B], TT29_B_OFFSET }, + { "tt29","tt29c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_C], TT29_C_OFFSET }, { "tt30","tt30x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[30][AXIS_X], TT30_X_OFFSET }, { "tt30","tt30y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[30][AXIS_Y], TT30_Y_OFFSET }, { "tt30","tt30z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[30][AXIS_Z], TT30_Z_OFFSET }, - { "tt30","tt30a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_A], TT30_A_OFFSET }, - { "tt30","tt30b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_B], TT30_B_OFFSET }, - { "tt30","tt30c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_C], TT30_C_OFFSET }, + { "tt30","tt30a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_A], TT30_A_OFFSET }, + { "tt30","tt30b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_B], TT30_B_OFFSET }, + { "tt30","tt30c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_C], TT30_C_OFFSET }, { "tt31","tt31x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[31][AXIS_X], TT31_X_OFFSET }, { "tt31","tt31y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[31][AXIS_Y], TT31_Y_OFFSET }, { "tt31","tt31z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[31][AXIS_Z], TT31_Z_OFFSET }, - { "tt31","tt31a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_A], TT31_A_OFFSET }, - { "tt31","tt31b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_B], TT31_B_OFFSET }, - { "tt31","tt31c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_C], TT31_C_OFFSET }, + { "tt31","tt31a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_A], TT31_A_OFFSET }, + { "tt31","tt31b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_B], TT31_B_OFFSET }, + { "tt31","tt31c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_C], TT31_C_OFFSET }, { "tt32","tt32x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[32][AXIS_X], TT32_X_OFFSET }, { "tt32","tt32y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[32][AXIS_Y], TT32_Y_OFFSET }, { "tt32","tt32z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[32][AXIS_Z], TT32_Z_OFFSET }, - { "tt32","tt32a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_A], TT32_A_OFFSET }, - { "tt32","tt32b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_B], TT32_B_OFFSET }, - { "tt32","tt32c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_C], TT32_C_OFFSET }, + { "tt32","tt32a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_A], TT32_A_OFFSET }, + { "tt32","tt32b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_B], TT32_B_OFFSET }, + { "tt32","tt32c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_C], TT32_C_OFFSET }, // this is a 128bit UUID for identifying a previously committed job state { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, @@ -872,16 +857,16 @@ const cfgItem_t cfgArray[] = { { "sys","spdw",_fipn,2, cm_print_spdw,get_flt, set_flt, (float *)&spindle.dwell_seconds, SPINDLE_DWELL_TIME }, { "sys","ssoe",_fipn,0, cm_print_ssoe,get_ui8, set_01, (float *)&spindle.sso_enable, SPINDLE_OVERRIDE_ENABLE}, { "sys","sso", _fipn,3, cm_print_sso, get_flt,cm_set_sso,(float *)&spindle.sso_factor, SPINDLE_OVERRIDE_FACTOR}, - { "", "spe", _f0, 0, cm_print_spe, get_ui8, set_nul, (float *)&spindle.enable, 0 }, // get spindle enable - { "", "spd", _f0, 0, cm_print_spd, get_ui8,cm_set_dir,(float *)&spindle.direction, 0 }, // get spindle direction - { "", "sps", _f0, 0, cm_print_sps, get_flt, set_nul, (float *)&spindle.speed, 0 }, // get spindle speed + { "", "spe", _fiz, 0, cm_print_spe, get_ui8, set_nul, (float *)&spindle.enable, 0 }, // get spindle enable + { "", "spd", _fiz, 0, cm_print_spd, get_ui8,cm_set_dir,(float *)&spindle.direction, 0 }, // get spindle direction + { "", "sps", _fiz, 0, cm_print_sps, get_flt, set_nul, (float *)&spindle.speed, 0 }, // get spindle speed // Coolant functions { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, { "sys","coph",_fipn,0, cm_print_coph,get_ui8, set_01, (float *)&coolant.pause_on_hold, COOLANT_PAUSE_ON_HOLD }, - { "", "com", _f0, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable - { "", "cof", _f0, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable + { "", "com", _fiz, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable + { "", "cof", _fiz, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable // Communications and reporting parameters #ifdef __TEXT_MODE @@ -1227,37 +1212,6 @@ const cfgItem_t cfgArray[] = { }; /***** Make sure these defines line up with any changes in the above table *****/ -/* -#define NV_COUNT_UBER_GROUPS 6 // count of uber-groups, above -#define FIXED_GROUPS 92 // count of fixed groups, excluding optional groups - -#if (MOTORS >= 5) -#define MOTOR_GROUP_5 1 -#else -#define MOTOR_GROUP_5 0 -#endif - -#if (MOTORS >= 6) -#define MOTOR_GROUP_6 1 -#else -#define MOTOR_GROUP_6 0 -#endif - -#ifdef __USER_DATA -#define USER_DATA_GROUPS 4 // count of user data groups only -#else -#define USER_DATA_GROUPS 0 -#endif - -#ifdef __DIAGNOSTIC_PARAMETERS -#define DIAGNOSTIC_GROUPS 8 // count of diagnostic groups only -#else -#define DIAGNOSTIC_GROUPS 0 -#endif - -#define TEMPERATURE_GROUPS 6 -#define NV_COUNT_GROUPS (FIXED_GROUPS + MOTOR_GROUP_5 + MOTOR_GROUP_6 + USER_DATA_GROUPS + DIAGNOSTIC_GROUPS + TEMPERATURE_GROUPS) -*/ #define NV_COUNT_GROUPS (FIXED_GROUPS \ + AXIS_GROUPS \ diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 613c0daf..79b591be 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -2,7 +2,7 @@ * settings_makeblock.h - makeblock engraving table * This file is part of the g2core project * - * Copyright (c) 2016 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -52,7 +52,7 @@ // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE @@ -153,3 +153,54 @@ #define Z_LATCH_VELOCITY 25 #define Z_LATCH_BACKOFF 4 #define Z_ZERO_BACKOFF 2 + +#define A_AXIS_MODE AXIS_STANDARD +#define A_VELOCITY_MAX (360 * 25.4) +#define A_FEEDRATE_MAX A_VELOCITY_MAX +#define A_TRAVEL_MIN -1 // degrees +#define A_TRAVEL_MAX -1 // same value means infinite, no limit +#define A_JERK_MAX (2 * 25.4) +#define A_JERK_HIGH_SPEED A_JERK_MAX +#define A_RADIUS 1.0 +#define A_HOMING_INPUT 0 +#define A_HOMING_DIRECTION 0 +#define A_SEARCH_VELOCITY (60 * 25.4) +#define A_LATCH_VELOCITY (30 * 25.4) +#define A_LATCH_BACKOFF (0.125 * 25.4) +#define A_ZERO_BACKOFF (0.375 * 25.4) +#define A_HOMING_INPUT 0 +#define A_HOMING_DIR 0 + +#define B_AXIS_MODE AXIS_DISABLED +#define B_VELOCITY_MAX (360 * 25.4) +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MAX -1 +#define B_TRAVEL_MIN -1 +#define B_JERK_MAX (2 * 25.4) +#define B_JERK_HIGH_SPEED B_JERK_MAX +#define B_RADIUS 1 +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY (60 * 25.4) +#define B_LATCH_VELOCITY (30 * 25.4) +#define B_LATCH_BACKOFF (0.125 * 25.4) +#define B_ZERO_BACKOFF (0.375 * 25.4) +#define B_HOMING_INPUT 0 +#define B_HOMING_DIR 0 + +#define C_AXIS_MODE AXIS_DISABLED +#define C_VELOCITY_MAX (360 * 25.4) +#define C_FEEDRATE_MAX C_VELOCITY_MAX +#define C_TRAVEL_MAX -1 +#define C_TRAVEL_MIN -1 +#define C_JERK_MAX (2 * 25.4) +#define C_JERK_HIGH_SPEED C_JERK_MAX +#define C_RADIUS 1 +#define C_HOMING_INPUT 0 +#define C_HOMING_DIRECTION 0 +#define C_SEARCH_VELOCITY (60 * 25.4) +#define C_LATCH_VELOCITY (30 * 25.4) +#define C_LATCH_BACKOFF (0.125 * 25.4) +#define C_ZERO_BACKOFF (0.375 * 25.4) +#define C_HOMING_INPUT 0 +#define C_HOMING_DIR 0 \ No newline at end of file From d66cb8b16aa715a33e263f40d42437110c454bb2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 9 Jan 2017 11:21:14 -0500 Subject: [PATCH 052/283] Prep for on feedhold context switch; Minor change to buffer structure; Added designators to gQuintic pinouts --- g2core/board/gquintic/gquintic-b-pinout.h | 173 +++++++++++----------- g2core/canonical_machine.cpp | 27 ++++ g2core/canonical_machine.h | 4 +- g2core/config_app.cpp | 4 +- g2core/g2core_info.h | 2 +- g2core/gpio.cpp | 6 +- g2core/planner.cpp | 24 +-- g2core/planner.h | 120 +++++++++++++-- 8 files changed, 229 insertions(+), 131 deletions(-) diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h index e0f9280e..3cbc5736 100644 --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -3,8 +3,8 @@ * For: /board/gQuintic * This file is part of the g2core project * - * Copyright (c) 2016 Robert Giseburt - * Copyright (c) 2016 Alden S. Hart Jr. + * Copyright (c) 2016 - 2017 Robert Giseburt + * Copyright (c) 2016 - 2017 Alden S. Hart Jr. * * This file is part of the Motate Library. * @@ -117,99 +117,94 @@ namespace Motate { -// Unused: -// -// -// -// -// +// All DO and DI and ADC board pinouts are for gQuintic Rev B +// Designators agree with silkscreen on board -_MAKE_MOTATE_PIN(kLED_RGBWPixelPinNumber, 'A', 0); // -_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 1); // -_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'A', 2); // -_MAKE_MOTATE_PIN(kI2C1_SDAPinNumber, 'A', 3); // -_MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); // -_MAKE_MOTATE_PIN(kOutput11_PinNumber, 'A', 5); // -_MAKE_MOTATE_PIN(kExternalClock1_PinNumber, 'A', 6); // CPU_CLK -_MAKE_MOTATE_PIN(kOutput7_PinNumber, 'A', 7); // -_MAKE_MOTATE_PIN(kSerial_RTSPinNumber, 'A', 8); // -_MAKE_MOTATE_PIN(kSerial_RXPinNumber, 'A', 9); // -_MAKE_MOTATE_PIN(kSerial_TXPinNumber, 'A', 10); // -_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'A', 11); // -_MAKE_MOTATE_PIN(kOutput6_PinNumber, 'A', 12); // -_MAKE_MOTATE_PIN(kOutput8_PinNumber, 'A', 13); // -_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'A', 14); // -_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 15); // -_MAKE_MOTATE_PIN(kOutput4_PinNumber, 'A', 16); // -_MAKE_MOTATE_PIN(kADC3_PinNumber, 'A', 17); // -_MAKE_MOTATE_PIN(kADC2_PinNumber, 'A', 18); // -_MAKE_MOTATE_PIN(kADC1_PinNumber, 'A', 19); // -_MAKE_MOTATE_PIN(kADC0_PinNumber, 'A', 20); // -_MAKE_MOTATE_PIN(kSerial_CTSPinNumber, 'A', 21); // -_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A', 22); // -_MAKE_MOTATE_PIN(kOutput10_PinNumber, 'A', 23); // -_MAKE_MOTATE_PIN(kSocket3_EnablePinNumber, 'A', 24); // -_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'A', 25); // -_MAKE_MOTATE_PIN(kOutput5_PinNumber, 'A', 26); // On Timer 2! -_MAKE_MOTATE_PIN(kSocket3_StepPinNumber, 'A', 27); // On Timer 2! -_MAKE_MOTATE_PIN(kUnassigned1, 'A', 28); // DIAG1 -_MAKE_MOTATE_PIN(kUnassigned2, 'A', 29); // -_MAKE_MOTATE_PIN(kInput1_PinNumber, 'A', 30); // -_MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); // +_MAKE_MOTATE_PIN(kLED_RGBWPixelPinNumber, 'A', 0); // DO12 +_MAKE_MOTATE_PIN(kOutput1_PinNumber, 'A', 1); // DO1 +_MAKE_MOTATE_PIN(kOutput2_PinNumber, 'A', 2); // DO2 +_MAKE_MOTATE_PIN(kI2C1_SDAPinNumber, 'A', 3); // SDA +_MAKE_MOTATE_PIN(kI2C1_SCLPinNumber, 'A', 4); // SCK +_MAKE_MOTATE_PIN(kOutput11_PinNumber, 'A', 5); // DO11 +_MAKE_MOTATE_PIN(kExternalClock1_PinNumber, 'A',6); // CPU_CLK (internal signal, not brought out) +_MAKE_MOTATE_PIN(kOutput7_PinNumber, 'A', 7); // DO7 +_MAKE_MOTATE_PIN(kSerial_RTSPinNumber, 'A', 8); // RTS +_MAKE_MOTATE_PIN(kSerial_RXPinNumber, 'A', 9); // RX +_MAKE_MOTATE_PIN(kSerial_TXPinNumber, 'A', 10); // TX +_MAKE_MOTATE_PIN(kSocket2_EnablePinNumber, 'A',11); // M2 ENAB +_MAKE_MOTATE_PIN(kOutput6_PinNumber, 'A', 12); // DO6 +_MAKE_MOTATE_PIN(kOutput8_PinNumber, 'A', 13); // DO8 +_MAKE_MOTATE_PIN(kSocket1_StepPinNumber, 'A', 14); // M1 Step +_MAKE_MOTATE_PIN(kOutput3_PinNumber, 'A', 15); // DO3 +_MAKE_MOTATE_PIN(kOutput4_PinNumber, 'A', 16); // DO4 +_MAKE_MOTATE_PIN(kADC3_PinNumber, 'A', 17); // ADC4 +_MAKE_MOTATE_PIN(kADC2_PinNumber, 'A', 18); // ADC3 +_MAKE_MOTATE_PIN(kADC1_PinNumber, 'A', 19); // ADC2 +_MAKE_MOTATE_PIN(kADC0_PinNumber, 'A', 20); // ADC1 +_MAKE_MOTATE_PIN(kSerial_CTSPinNumber, 'A', 21); // CTS +_MAKE_MOTATE_PIN(kSocket1_EnablePinNumber, 'A',22); // M1 ENAB +_MAKE_MOTATE_PIN(kOutput10_PinNumber, 'A', 23); // DO10 +_MAKE_MOTATE_PIN(kSocket3_EnablePinNumber, 'A',24); // M3 ENAB +_MAKE_MOTATE_PIN(kSocket2_DirPinNumber, 'A', 25); // M2 DIR +_MAKE_MOTATE_PIN(kOutput5_PinNumber, 'A', 26); // DO5 (On Timer 2!) +_MAKE_MOTATE_PIN(kSocket3_StepPinNumber, 'A', 27); // M3 DIR (On Timer 2!) +_MAKE_MOTATE_PIN(kUnassigned1, 'A', 28); // DIAG1 (internal signal) +_MAKE_MOTATE_PIN(kUnassigned2, 'A', 29); // (not present on S70) +_MAKE_MOTATE_PIN(kInput1_PinNumber, 'A', 30); // DI1 +_MAKE_MOTATE_PIN(kInput4_PinNumber, 'A', 31); // DI4 -_MAKE_MOTATE_PIN(kInput12_PinNumber, 'B', 0); // -_MAKE_MOTATE_PIN(kInput11_PinNumber, 'B', 1); // -_MAKE_MOTATE_PIN(kSocket1_SPISlaveSelectPinNumber, 'B', 2); // -_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'B', 3); // -//_MAKE_MOTATE_PIN( , 'B', 4); // TDI -//_MAKE_MOTATE_PIN( , 'B', 5); // TRACESDO -//_MAKE_MOTATE_PIN( , 'B', 6); // SWDIO -//_MAKE_MOTATE_PIN( , 'B', 7); // SWDCLK -//_MAKE_MOTATE_PIN( , 'B', 8); // XOUT -//_MAKE_MOTATE_PIN( , 'B', 9); // XIN -//_MAKE_MOTATE_PIN( , 'B', 10); // USB_D- -//_MAKE_MOTATE_PIN( , 'B', 11); // USB_D+ -//_MAKE_MOTATE_PIN( , 'B', 12); // ERASE -_MAKE_MOTATE_PIN(kLED_USBRXPinNumber, 'B', 13); // LED_1 (Heartbeat) - PWM2 -_MAKE_MOTATE_PIN(kSocket4_SPISlaveSelectPinNumber, 'B', 14); // NOT CONNECTED +_MAKE_MOTATE_PIN(kInput12_PinNumber, 'B', 0); // DI12 +_MAKE_MOTATE_PIN(kInput11_PinNumber, 'B', 1); // DI11 +_MAKE_MOTATE_PIN(kSocket1_SPISlaveSelectPinNumber,'B',2); // SPI Slave select 0 (multiplexed) +_MAKE_MOTATE_PIN(kOutputSAFE_PinNumber, 'B', 3); // SAFI (SAFE pulses) +//_MAKE_MOTATE_PIN( , 'B', 4); // TDI +//_MAKE_MOTATE_PIN( , 'B', 5); // TRACESDO +//_MAKE_MOTATE_PIN( , 'B', 6); // SWDIO +//_MAKE_MOTATE_PIN( , 'B', 7); // SWDCLK +//_MAKE_MOTATE_PIN( , 'B', 8); // XOUT +//_MAKE_MOTATE_PIN( , 'B', 9); // XIN +//_MAKE_MOTATE_PIN( , 'B', 10); // USB_D- +//_MAKE_MOTATE_PIN( , 'B', 11); // USB_D+ +//_MAKE_MOTATE_PIN( , 'B', 12); // ERASE +_MAKE_MOTATE_PIN(kLED_USBRXPinNumber, 'B', 13); // LED_1 (Heartbeat) - PWM2 +_MAKE_MOTATE_PIN(kSocket4_SPISlaveSelectPinNumber, 'B', 14); // not connected - -//_MAKE_MOTATE_PIN( , 'D', 0); // USB_VBUS -_MAKE_MOTATE_PIN(kInput9_PinNumber, 'D', 1); // -_MAKE_MOTATE_PIN(kInput10_PinNumber, 'D', 2); // -_MAKE_MOTATE_PIN(kInput8_PinNumber, 'D', 3); // -_MAKE_MOTATE_PIN(kInput7_PinNumber, 'D', 4); // -_MAKE_MOTATE_PIN(kInput6_PinNumber, 'D', 5); // -_MAKE_MOTATE_PIN(kInput5_PinNumber, 'D', 6); // -_MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 7); // -_MAKE_MOTATE_PIN(kInput2_PinNumber, 'D', 8); // ] -_MAKE_MOTATE_PIN(kUnassigned3, 'D', 9); // DIAG0 -_MAKE_MOTATE_PIN(kUnassigned4, 'D', 10); // -_MAKE_MOTATE_PIN(kSocket5_StepPinNumber, 'D', 11); // -_MAKE_MOTATE_PIN(kSocket3_SPISlaveSelectPinNumber, 'D', 12); // -_MAKE_MOTATE_PIN(kSocket5_DirPinNumber, 'D', 13); // -_MAKE_MOTATE_PIN(kSocket5_EnablePinNumber, 'D', 14); // -_MAKE_MOTATE_PIN(kUnassigned5, 'D', 15); // -_MAKE_MOTATE_PIN(kSocket4_StepPinNumber, 'D', 16); // -_MAKE_MOTATE_PIN(kSocket4_DirPinNumber, 'D', 17); // -_MAKE_MOTATE_PIN(kSocket3_DirPinNumber, 'D', 18); // -_MAKE_MOTATE_PIN(kUnassigned6, 'D', 19); // -_MAKE_MOTATE_PIN(kSPI0_MISOPinNumber, 'D', 20); // -_MAKE_MOTATE_PIN(kSPI0_MOSIPinNumber, 'D', 21); // -_MAKE_MOTATE_PIN(kSPI0_SCKPinNumber, 'D', 22); // -_MAKE_MOTATE_PIN(kUnassigned7, 'D', 23); // -_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 24); // -_MAKE_MOTATE_PIN(kSocket2_SPISlaveSelectPinNumber, 'D', 25); // -_MAKE_MOTATE_PIN(kOutput9_PinNumber, 'D', 26); // -_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 27); // -_MAKE_MOTATE_PIN(kSocket4_EnablePinNumber, 'D', 28); // -_MAKE_MOTATE_PIN(kUnassigned8, 'D', 29); // -_MAKE_MOTATE_PIN(kUnassigned9, 'D', 30); // INTERRUPT_OUT -_MAKE_MOTATE_PIN(kUnassigned10, 'D', 31); // +//_MAKE_MOTATE_PIN( ,' D', 0); // USB_VBUS +_MAKE_MOTATE_PIN(kInput9_PinNumber, 'D', 1); // DI9 +_MAKE_MOTATE_PIN(kInput10_PinNumber,'D', 2); // DI10 +_MAKE_MOTATE_PIN(kInput8_PinNumber, 'D', 3); // DI8 +_MAKE_MOTATE_PIN(kInput7_PinNumber, 'D', 4); // DI7 +_MAKE_MOTATE_PIN(kInput6_PinNumber, 'D', 5); // DI6 +_MAKE_MOTATE_PIN(kInput5_PinNumber, 'D', 6); // DI5 +_MAKE_MOTATE_PIN(kInput3_PinNumber, 'D', 7); // DI3 +_MAKE_MOTATE_PIN(kInput2_PinNumber, 'D', 8); // DI2 +_MAKE_MOTATE_PIN(kUnassigned3, 'D', 9); // DIAG0 +_MAKE_MOTATE_PIN(kUnassigned4, 'D', 10); // not connected +_MAKE_MOTATE_PIN(kSocket5_StepPinNumber, 'D', 11); // M5 STEP +_MAKE_MOTATE_PIN(kSocket3_SPISlaveSelectPinNumber, 'D',12); // SPI Slave select 2 (multiplexed) +_MAKE_MOTATE_PIN(kSocket5_DirPinNumber, 'D', 13); // M5 DIR +_MAKE_MOTATE_PIN(kSocket5_EnablePinNumber, 'D',14); // M5 ENAB +_MAKE_MOTATE_PIN(kUnassigned5, 'D', 15); // not connected +_MAKE_MOTATE_PIN(kSocket4_StepPinNumber, 'D', 16); // M4 STEP +_MAKE_MOTATE_PIN(kSocket4_DirPinNumber, 'D', 17); // M4 DIR +_MAKE_MOTATE_PIN(kSocket3_DirPinNumber, 'D', 18); // M3 STEP +_MAKE_MOTATE_PIN(kUnassigned6, 'D', 19); // not connected +_MAKE_MOTATE_PIN(kSPI0_MISOPinNumber, 'D', 20); // MISO +_MAKE_MOTATE_PIN(kSPI0_MOSIPinNumber, 'D', 21); // MOSI +_MAKE_MOTATE_PIN(kSPI0_SCKPinNumber, 'D', 22); // CLK +_MAKE_MOTATE_PIN(kUnassigned7, 'D', 23); // not connected +_MAKE_MOTATE_PIN(kSocket2_StepPinNumber, 'D', 24); // M2 STEP +_MAKE_MOTATE_PIN(kSocket2_SPISlaveSelectPinNumber, 'D',25); // SPI Slave select 1 (multiplexed) +_MAKE_MOTATE_PIN(kOutput9_PinNumber, 'D', 26); // DO9 +_MAKE_MOTATE_PIN(kSocket1_DirPinNumber, 'D', 27); // M1 DIR +_MAKE_MOTATE_PIN(kSocket4_EnablePinNumber, 'D',28); // M4 ENAB +_MAKE_MOTATE_PIN(kUnassigned8, 'D', 29); // (not present on S70) +_MAKE_MOTATE_PIN(kUnassigned9, 'D', 30); // supposed to become INT (INTERRUPT_OUT) +_MAKE_MOTATE_PIN(kUnassigned10, 'D', 31); // not connected } // namespace Motate -// We then allow each chip-type to have it's onw function definitions +// We then allow each chip-type to have it's own function definitions // that will refer to these pin assignments. #include "motate_chip_pin_functions.h" diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a0bee3a0..698b42c0 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -265,6 +265,33 @@ void cm_set_model_linenum(const uint32_t linenum) nv_add_object((const char *)"n"); // then add the line number to the nv list } +/* + * cm_switch() - switch canonical machine to a different machine + * cm_return() - return canoncial machine to origincal machine + */ +stat_t cm_switch(nvObj_t *nv) +{ +/* + if (nv->value < PRIMARY_Q) { + return (STAT_INPUT_LESS_THAN_MIN_VALUE); + } + if (nv->value < SECONDARY_Q) { + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + mb.return_q = mb.active_q; + mb.active_q = (uint8_t)nv->value; +*/ + return (STAT_OK); +} + +stat_t cm_return(nvObj_t *nv) // if value == true return with offset corrections +{ +/* + mb.active_q = mb.return_q; +*/ + return (STAT_OK); +} + /*********************************************************************************** * COORDINATE SYSTEMS AND OFFSETS * Functions to get, set and report coordinate systems and work offsets diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 12e5493d..90e0a3ca 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -222,7 +222,6 @@ typedef struct cmMachine { // struct to manage canonical machin // Coordinate systems and offsets float offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 float tl_offset[AXES]; // current tool length offset -// float tt_offset[TOOLS+1][AXES]; // persistent tool table offsets // Axis settings cfgAxis_t a[AXES]; @@ -300,6 +299,9 @@ cmHomingState cm_get_homing_state(void); cmProbeState cm_get_probe_state(void); uint8_t cm_get_jogging_state(void); +stat_t cm_switch(nvObj_t *nv); +stat_t cm_return(nvObj_t *nv); + void cm_set_motion_state(const cmMotionState motion_state); uint32_t cm_get_linenum(const GCodeState_t *gcode_state); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 18ee3a50..9bdfbaa9 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -905,8 +905,8 @@ const cfgItem_t cfgArray[] = { { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, - { "", "switch",_f0,0, tx_print_nul, get_nul, mp_switch_q, (float *)&cs.null,0 }, - { "", "return",_f0,0, tx_print_nul, get_nul, mp_return_q, (float *)&cs.null,0 }, + { "", "switch",_f0,0, tx_print_nul, get_nul, cm_switch, (float *)&cs.null,0 }, + { "", "return",_f0,0, tx_print_nul, get_nul, cm_return, (float *)&cs.null,0 }, #ifdef __HELP_SCREENS { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index c16606d5..cf2f1c18 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.17 // Added tool offsets (PR #211) +#define G2CORE_FIRMWARE_BUILD 100.18 // This branch has been merged to edge 100.18 #define G2CORE_FIRMWARE_VERSION 0.99 #ifdef GIT_VERSION diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 21ed1d96..03ae7043 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -2,8 +2,8 @@ * gpio.cpp - digital IO handling functions * This file is part of the g2core project * - * Copyright (c) 2015 - 2106 Alden S. Hart, Jr. - * Copyright (c) 2015 - 2016 Robert Giseburt + * Copyright (c) 2015 - 2107 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -481,10 +481,8 @@ static stat_t _output_set_helper(nvObj_t *nv, const int8_t lower_bound, const in return (STAT_OK); } - stat_t io_set_mo(nvObj_t *nv) // input type or disabled { -// return (_io_set_helper(nv, IO_MODE_DISABLED, IO_MODE_MAX)); return (_input_set_helper(nv, IO_ACTIVE_LOW, IO_MODE_MAX)); } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index b2b2f602..e2f0b45e 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -2,8 +2,8 @@ * planner.cpp - Cartesian trajectory planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2016 Rob Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -627,26 +627,6 @@ void mp_planner_time_accounting() UPDATE_MP_DIAGNOSTICS //+++++ } -/* - * mp_switch_q() - switch planner to different quue - * mp_return_q() - return from a planner queue switch - */ -stat_t mp_switch_q(nvObj_t *nv) -{ - if ((nv->value < PRIMARY_Q) || (nv->value < SECONDARY_Q)) { - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - mb.return_q = mb.active_q; - mb.active_q = (uint8_t)nv->value; - return (STAT_OK); -} - -stat_t mp_return_q(nvObj_t *nv) // if value == true return with offset corrections -{ - mb.active_q = mb.return_q; - return (STAT_OK); -} - /**** PLANNER BUFFER PRIMITIVES ************************************************************ * * Planner buffers are used to queue and operate on Gcode blocks. Each buffer contains diff --git a/g2core/planner.h b/g2core/planner.h index dbac1cb1..e8b18e40 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -2,8 +2,8 @@ * planner.h - cartesian trajectory planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -250,12 +250,12 @@ typedef enum { /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 -#define SECONDARY_BUFFER_POOL_SIZE ((uint8_t)4) // Secondary planner queue for feedhold operations +#define SECONDARY_BUFFER_POOL_SIZE ((uint8_t)12) // Secondary planner queue for feedhold operations #define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line #define JERK_MULTIPLIER ((float)1000000) // DO NOT CHANGE - must always be 1 million -#define JUNCTION_INTEGRATION_MIN (0.05) // minimum allowable setting -#define JUNCTION_INTEGRATION_MAX (5.00) // maximum allowable setting +#define JUNCTION_INTEGRATION_MIN (0.05) // JT minimum allowable setting +#define JUNCTION_INTEGRATION_MAX (5.00) // JT maximum allowable setting #define MIN_SEGMENT_MS ((float)0.75) // minimum segment milliseconds #define NOM_SEGMENT_MS ((float)1.5) // nominal segment ms (at LEAST MIN_SEGMENT_MS * 2) @@ -293,6 +293,8 @@ typedef enum { #define Veq2_lo 1.0 #define VELOCITY_ROUGHLY_EQ(v0,v1) ( (v0 > Vthr2) ? fabs(v0-v1) < Veq2_hi : fabs(v0-v1) < Veq2_lo ) +/* Diagnostics */ + //#define ASCII_ART(s) xio_writeline(s) #define ASCII_ART(s) //#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; } @@ -301,12 +303,12 @@ typedef enum { /* * Planner structures * - * You should be aware of the distinction between 'buffers' and 'blocks' + * Be aware of the distinction between 'buffers' and 'blocks' * Please refer to header comments in for important details on buffers and blocks * - plan_zoid.cpp / mp_calculate_ramps() * - plan_exec.cpp / mp_exec_aline() */ - +/* struct mpBuffer_to_clear { stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function cm_exec_t cm_func; // callback to canonical machine execution function @@ -359,7 +361,7 @@ struct mpBuffer_to_clear { GCodeState_t gm; // Gcode model state - passed from model, used by planner and runtime - // cleasr the above structure + // clears the above structure void reset() { //memset((void *)(this), 0, sizeof(mpBuffer_to_clear)); // slower on the M3. Test for M7 @@ -402,13 +404,110 @@ struct mpBuffer_to_clear { gm.reset(); } }; +*/ -typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for variable usage +//typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for variable usage +typedef struct mpBuffer { // *** CAUTION *** These two pointers are not reset by _clear_buffer() struct mpBuffer *pv; // static pointer to previous buffer struct mpBuffer *nx; // static pointer to next buffer uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging + + stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function + cm_exec_t cm_func; // callback to canonical machine execution function + + //+++++ DIAGNOSTICS for easier debugging + uint32_t linenum; // mirror of bf->gm.linenum + int iterations; + float block_time_ms; + float plannable_time_ms; // time in planner + float plannable_length; // length in planner + uint8_t meet_iterations; // iterations needed in _get_meet_velocity + //+++++ to here + + bufferState buffer_state; // used to manage queuing/dequeuing + blockType block_type; // used to dispatch to run routine + blockState block_state; // move state machine sequence + blockHint hint; // hint the block for zoid and other planning operations. Must be accurate or NO_HINT + + // block parameters + float unit[AXES]; // unit vector for axis scaling & planning + bool axis_flags[AXES]; // set true for axes participating in the move & for command parameters + + bool plannable; // set true when this block can be used for planning + + float length; // total length of line or helix in mm + float block_time; // computed move time for entire block (move) + float override_factor; // feed rate or rapid override factor for this block ("override" is a reserved word) + + // *** SEE NOTES ON THESE VARIABLES, in aline() *** + // We removed all entry_* values. + // To get the entry_* values, look at pv->exit_* or mr.exit_* + float cruise_velocity; // cruise velocity requested & achieved + float exit_velocity; // exit velocity requested for the move + // is also the entry velocity of the *next* move + + float cruise_vset; // cruise velocity requested for move - prior to overrides + float cruise_vmax; // cruise max velocity adjusted for overrides + float exit_vmax; // max exit velocity possible for this move + // is also the maximum entry velocity of the next move + + float absolute_vmax; // fastest this block can move w/o exceeding constraints + float junction_vmax; // maximum the exit velocity can be to go through the junction + // between the NEXT BLOCK AND THIS ONE + + float jerk; // maximum linear jerk term for this move + float jerk_sq; // Jm^2 is used for planning (computed and cached) + float recip_jerk; // 1/Jm used for planning (computed and cached) + float sqrt_j; // sqrt(jM) used for planning (computed and cached) + float q_recip_2_sqrt_j; // (q/(2 sqrt(jM))) where q = (sqrt(10)/(3^(1/4))), used in length computations (computed and cached) + + GCodeState_t gm; // Gcode model state - passed from model, used by planner and runtime + + // clears the above structure + void reset() { + //memset((void *)(this), 0, sizeof(mpBuffer_to_clear)); // slower on the M3. Test for M7 + + bf_func = nullptr; + cm_func = nullptr; + + linenum = 0; + iterations = 0; + block_time_ms = 0; + plannable_time_ms = 0; + plannable_length = 0; + meet_iterations = 0; + + buffer_state = MP_BUFFER_EMPTY; + block_type = BLOCK_TYPE_NULL; + block_state = BLOCK_INACTIVE; + hint = NO_HINT; + + for (uint8_t i = 0; i< AXES; i++) { + unit[i] = 0; + axis_flags[i] = 0; + } + + plannable = false; + length = 0.0; + block_time = 0.0; + override_factor = 0.0; + cruise_velocity = 0.0; + exit_velocity = 0.0; + cruise_vset = 0.0; + cruise_vmax = 0.0; + exit_vmax = 0.0; + absolute_vmax = 0.0; + junction_vmax = 0.0; + jerk = 0.0; + jerk_sq = 0.0; + recip_jerk = 0.0; + sqrt_j = 0.0; + q_recip_2_sqrt_j = 0.0; + gm.reset(); + } + } mpBuf_t; typedef struct mpQueue { // a planner buffer queue @@ -566,9 +665,6 @@ void mp_start_feed_override(const float ramp_time, const float override); void mp_end_feed_override(const float ramp_time); void mp_planner_time_accounting(void); -stat_t mp_switch_q(nvObj_t *nv); -stat_t mp_return_q(nvObj_t *nv); - // planner buffer primitives void mp_init_buffers(void); mpBuf_t * mp_get_w(int8_t q); From e6aca99fa8bb58de4463ff062e0648bef899d675 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 9 Jan 2017 11:52:48 -0500 Subject: [PATCH 053/283] Checkpoint --- g2core/board/gquintic/gquintic-b-pinout.h | 1 - g2core/canonical_machine.cpp | 8 +- g2core/canonical_machine.h | 10 +- g2core/planner.cpp | 13 ++- g2core/planner.h | 112 ++-------------------- 5 files changed, 26 insertions(+), 118 deletions(-) diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h index 3cbc5736..895f901f 100644 --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -84,7 +84,6 @@ #define INPUT12_AVAILABLE 0 #define INPUT13_AVAILABLE 0 - #define ADC0_AVAILABLE 0 #define ADC1_AVAILABLE 0 #define ADC2_AVAILABLE 0 diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 698b42c0..18d6e778 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -113,10 +113,10 @@ **** STRUCTURE ALLOCATIONS ******************************************************** ***********************************************************************************/ -cmMachine_t *cm; // pointer to active canonical machine -cmMachine_t cm0; // canonical machine primary machine -cmMachine_t cm1; // canonical machine secondary machine -cmToolTable_t tt; // global tool table +cmCanonicalMachine_t *cm; // pointer to active canonical machine +cmCanonicalMachine_t cm0; // canonical machine primary machine +cmCanonicalMachine_t cm1; // canonical machine secondary machine +cmToolTable_t tt; // global tool table /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 90e0a3ca..2ba7b699 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -207,7 +207,7 @@ typedef struct arArcSingleton { // persistent planner and runtim magic_t magic_end; } arc_t; -typedef struct cmMachine { // struct to manage canonical machine globals and state +typedef struct cmCanonicalMachine { // struct to manage canonical machine globals and state magic_t magic_start; // magic number to test memory integrity /**** Config variables (PUBLIC) ****/ @@ -269,7 +269,7 @@ typedef struct cmMachine { // struct to manage canonical machin GCodeStateX_t gmx; // extended gcode model state magic_t magic_end; -} cmMachine_t; +} cmCanonicalMachine_t; typedef struct cmToolTable { // struct to keep a global tool table float tt_offset[TOOLS+1][AXES]; // persistent tool table offsets @@ -277,9 +277,9 @@ typedef struct cmToolTable { // struct to keep a global tool tabl /**** Externs - See canonical_machine.cpp for allocation ****/ -extern cmMachine_t *cm; // pointer to active canonical machine -extern cmMachine_t cm0; // canonical machine primary machine -extern cmMachine_t cm1; // canonical machine secondary machine +extern cmCanonicalMachine_t *cm; // pointer to active canonical machine +extern cmCanonicalMachine_t cm0; // canonical machine primary machine +extern cmCanonicalMachine_t cm1; // canonical machine secondary machine extern cmToolTable_t tt; /***************************************************************************** diff --git a/g2core/planner.cpp b/g2core/planner.cpp index e2f0b45e..ec534c15 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -65,11 +65,16 @@ #include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures -mpBufferQueue_t mb; // buffer pool management -mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +mpBufferQueue_t mb; // buffer pool management +mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers mpBuf_t mb_pool1[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers -mpMotionPlannerSingleton_t mp; // context for block planning -mpMotionRuntimeSingleton_t mr; // context for block runtime +mpMotionPlannerHead_t mp; // context for block planning + +//mpMotionPlannerHead_t *mp; // pointer to motion planner +//mpMotionPlannerHead_t mp0; // primary motion planner +//mpMotionPlannerHead_t mp1; // secondary motion planner +mpMotionRuntimeSingleton_t mr; // context for block runtime + #define JSON_COMMAND_BUFFER_SIZE 3 diff --git a/g2core/planner.h b/g2core/planner.h index e8b18e40..d18db589 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -308,105 +308,6 @@ typedef enum { * - plan_zoid.cpp / mp_calculate_ramps() * - plan_exec.cpp / mp_exec_aline() */ -/* -struct mpBuffer_to_clear { - stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function - cm_exec_t cm_func; // callback to canonical machine execution function - - //+++++ DIAGNOSTICS for easier debugging - uint32_t linenum; // mirror of bf->gm.linenum - int iterations; - float block_time_ms; - float plannable_time_ms; // time in planner - float plannable_length; // length in planner - uint8_t meet_iterations; // iterations needed in _get_meet_velocity - //+++++ to here - - bufferState buffer_state; // used to manage queuing/dequeuing - blockType block_type; // used to dispatch to run routine - blockState block_state; // move state machine sequence - blockHint hint; // hint the block for zoid and other planning operations. Must be accurate or NO_HINT - - // block parameters - float unit[AXES]; // unit vector for axis scaling & planning - bool axis_flags[AXES]; // set true for axes participating in the move & for command parameters - - bool plannable; // set true when this block can be used for planning - - float length; // total length of line or helix in mm - float block_time; // computed move time for entire block (move) - float override_factor; // feed rate or rapid override factor for this block ("override" is a reserved word) - - // *** SEE NOTES ON THESE VARIABLES, in aline() *** - // We removed all entry_* values. - // To get the entry_* values, look at pv->exit_* or mr.exit_* - float cruise_velocity; // cruise velocity requested & achieved - float exit_velocity; // exit velocity requested for the move - // is also the entry velocity of the *next* move - - float cruise_vset; // cruise velocity requested for move - prior to overrides - float cruise_vmax; // cruise max velocity adjusted for overrides - float exit_vmax; // max exit velocity possible for this move - // is also the maximum entry velocity of the next move - - float absolute_vmax; // fastest this block can move w/o exceeding constraints - float junction_vmax; // maximum the exit velocity can be to go through the junction - // between the NEXT BLOCK AND THIS ONE - - float jerk; // maximum linear jerk term for this move - float jerk_sq; // Jm^2 is used for planning (computed and cached) - float recip_jerk; // 1/Jm used for planning (computed and cached) - float sqrt_j; // sqrt(jM) used for planning (computed and cached) - float q_recip_2_sqrt_j; // (q/(2 sqrt(jM))) where q = (sqrt(10)/(3^(1/4))), used in length computations (computed and cached) - - GCodeState_t gm; // Gcode model state - passed from model, used by planner and runtime - - // clears the above structure - void reset() { - //memset((void *)(this), 0, sizeof(mpBuffer_to_clear)); // slower on the M3. Test for M7 - - bf_func = nullptr; - cm_func = nullptr; - - linenum = 0; - iterations = 0; - block_time_ms = 0; - plannable_time_ms = 0; - plannable_length = 0; - meet_iterations = 0; - - buffer_state = MP_BUFFER_EMPTY; - block_type = BLOCK_TYPE_NULL; - block_state = BLOCK_INACTIVE; - hint = NO_HINT; - - for (uint8_t i = 0; i< AXES; i++) { - unit[i] = 0; - axis_flags[i] = 0; - } - - plannable = false; - length = 0.0; - block_time = 0.0; - override_factor = 0.0; - cruise_velocity = 0.0; - exit_velocity = 0.0; - cruise_vset = 0.0; - cruise_vmax = 0.0; - exit_vmax = 0.0; - absolute_vmax = 0.0; - junction_vmax = 0.0; - jerk = 0.0; - jerk_sq = 0.0; - recip_jerk = 0.0; - sqrt_j = 0.0; - q_recip_2_sqrt_j = 0.0; - gm.reset(); - } -}; -*/ - -//typedef struct mpBuffer : mpBuffer_to_clear { // See Planning Velocity Notes for variable usage typedef struct mpBuffer { // *** CAUTION *** These two pointers are not reset by _clear_buffer() @@ -490,7 +391,7 @@ typedef struct mpBuffer { } plannable = false; - length = 0.0; + length = 0.0; block_time = 0.0; override_factor = 0.0; cruise_velocity = 0.0; @@ -526,7 +427,7 @@ typedef struct mpBufferQueue { // one or more planner buffer queues mpQueue_t q[2]; // number of queues } mpBufferQueue_t; -typedef struct mpMotionPlannerSingleton { // common variables for planning (move master) +typedef struct mpMotionPlannerHead {// common variables for planning (move master) magic_t magic_start; // magic number to test memory integrity //+++++ DIAGNOSTICS @@ -560,9 +461,12 @@ typedef struct mpMotionPlannerSingleton { // common variables for planning (mov mpBuf_t *p; // planner buffer pointer mpBuf_t *c; // pointer to buffer immediately following critical region mpBuf_t *planning_return; // buffer to return to once back-planning is complete - + + // queue manager + mpBufferQueue_t q; // embed a buffer queue manager + magic_t magic_end; -} mpMotionPlannerSingleton_t; +} mpMotionPlannerHead_t; typedef struct mpBlockRuntimeBuf { // Data structure for just the parts of RunTime that we need to plan a BLOCK struct mpBlockRuntimeBuf *nx; // singly-linked-list @@ -622,7 +526,7 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables // Reference global scope structures extern mpBufferQueue_t mb; // planner buffer queue management -extern mpMotionPlannerSingleton_t mp; // context for block planning +extern mpMotionPlannerHead_t mp; // context for block planning extern mpMotionRuntimeSingleton_t mr; // context for block runtime /* From ddf32df2fdd5ca82f7ac2229727e1953528752d7 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 9 Jan 2017 13:43:41 -0500 Subject: [PATCH 054/283] Many many changes to get the plan bound to a canonical machine. Not working yet for motion. --- g2core/canonical_machine.cpp | 117 ++++++++-------- g2core/canonical_machine.h | 20 +-- g2core/controller.cpp | 8 +- g2core/cycle_homing.cpp | 2 +- g2core/cycle_jogging.cpp | 2 +- g2core/main.cpp | 12 +- g2core/plan_arc.cpp | 2 +- g2core/plan_exec.cpp | 12 +- g2core/plan_line.cpp | 50 +++---- g2core/planner.cpp | 252 ++++++++++++++++++++--------------- g2core/planner.h | 52 +++++--- g2core/report.cpp | 4 +- 12 files changed, 296 insertions(+), 237 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 18d6e778..5cb0b79b 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -113,10 +113,10 @@ **** STRUCTURE ALLOCATIONS ******************************************************** ***********************************************************************************/ -cmCanonicalMachine_t *cm; // pointer to active canonical machine -cmCanonicalMachine_t cm0; // canonical machine primary machine -cmCanonicalMachine_t cm1; // canonical machine secondary machine -cmToolTable_t tt; // global tool table +cmMachine_t *cm; // pointer to active canonical machine +cmMachine_t cm0; // canonical machine primary machine +cmMachine_t cm1; // canonical machine secondary machine +cmToolTable_t tt; // global tool table /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** @@ -488,7 +488,7 @@ stat_t cm_set_tram(nvObj_t *nv) // if passed false/0, we will clear the rotation matrix if (!do_set) { - canonical_machine_reset_rotation(); + canonical_machine_reset_rotation(cm); //++++++ cleanup on aisle 5 return (STAT_OK); } @@ -722,30 +722,22 @@ stat_t cm_test_soft_limits(const float target[]) * run profile initialization beforehand */ -void canonical_machine_init() +void canonical_machine_init(cmMachine_t *m) { // NoteL cm* was assignd in main() // If you can assume all memory has been zeroed by a hard reset you don't need this code: - memset(cm, 0, sizeof(cm0)); // do not reset canonicalMachineSingleton once it's been initialized - memset(&cm->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status - memset(&gc.gn, 0, sizeof(GCodeInput_t)); + memset(m, 0, sizeof(cmMachine_t)); // do not reset canonicalMachine once it's been initialized + memset(&m->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status + + memset(&gc.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs memset(&gc.gf, 0, sizeof(GCodeFlags_t)); - canonical_machine_init_assertions(); // establish assertions + canonical_machine_init_assertions(m); // establish assertions ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer cm_arc_init(); // Note: spindle and coolant inits are independent } -void canonical_machine_reset_rotation() { - memset(&cm->rotation_matrix, 0, sizeof(float)*3*3); - // We must make it an identity matrix for no rotation - cm->rotation_matrix[0][0] = 1.0; - cm->rotation_matrix[1][1] = 1.0; - cm->rotation_matrix[2][2] = 1.0; - cm->rotation_z_offset = 0.0; -} - -void canonical_machine_reset() +void canonical_machine_reset(cmMachine_t *m) { // set gcode defaults cm_set_units_mode(gc.default_units_mode); @@ -760,26 +752,35 @@ void canonical_machine_reset() // NOTE: Should unhome axes here // reset request flags - cm->queue_flush_state = FLUSH_OFF; - cm->end_hold_requested = false; - cm->limit_requested = 0; // resets switch closures that occurred during initialization - cm->safety_interlock_disengaged = 0; // ditto - cm->safety_interlock_reengaged = 0; // ditto - cm->shutdown_requested = 0; // ditto + m->queue_flush_state = FLUSH_OFF; + m->end_hold_requested = false; + m->limit_requested = 0; // resets switch closures that occurred during initialization + m->safety_interlock_disengaged = 0; // ditto + m->safety_interlock_reengaged = 0; // ditto + m->shutdown_requested = 0; // ditto // set initial state and signal that the machine is ready for action - cm->cycle_state = CYCLE_OFF; - cm->motion_state = MOTION_STOP; - cm->hold_state = FEEDHOLD_OFF; - cm->esc_boot_timer = SysTickTimer_getValue(); - cm->gmx.block_delete_switch = true; - cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode - cm->machine_state = MACHINE_READY; + m->cycle_state = CYCLE_OFF; + m->motion_state = MOTION_STOP; + m->hold_state = FEEDHOLD_OFF; + m->esc_boot_timer = SysTickTimer_getValue(); + m->gmx.block_delete_switch = true; + m->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode + m->machine_state = MACHINE_READY; - canonical_machine_reset_rotation(); + canonical_machine_reset_rotation(m); + memset(&m->probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); + memset(&m->probe_results, 0, sizeof(float)*PROBES_STORED*AXES); +} - memset(&cm->probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); - memset(&cm->probe_results, 0, sizeof(float)*PROBES_STORED*AXES); +void canonical_machine_reset_rotation(cmMachine_t *m) { + memset(&cm->rotation_matrix, 0, sizeof(float)*3*3); + + // We must make it an identity matrix for no rotation + m->rotation_matrix[0][0] = 1.0; + m->rotation_matrix[1][1] = 1.0; + m->rotation_matrix[2][2] = 1.0; + m->rotation_z_offset = 0.0; } /* @@ -787,21 +788,21 @@ void canonical_machine_reset() * canonical_machine_test_assertions() - test assertions, return error code if violation exists */ -void canonical_machine_init_assertions(void) +void canonical_machine_init_assertions(cmMachine_t *m) { - cm->magic_start = MAGICNUM; - cm->magic_end = MAGICNUM; - cm->gmx.magic_start = MAGICNUM; - cm->gmx.magic_end = MAGICNUM; - cm->arc.magic_start = MAGICNUM; - cm->arc.magic_end = MAGICNUM; + m->magic_start = MAGICNUM; + m->magic_end = MAGICNUM; + m->gmx.magic_start = MAGICNUM; + m->gmx.magic_end = MAGICNUM; + m->arc.magic_start = MAGICNUM; + m->arc.magic_end = MAGICNUM; } -stat_t canonical_machine_test_assertions(void) +stat_t canonical_machine_test_assertions(cmMachine_t *m) { - if ((BAD_MAGIC(cm->magic_start)) || (BAD_MAGIC(cm->magic_end)) || - (BAD_MAGIC(cm->gmx.magic_start)) || (BAD_MAGIC(cm->gmx.magic_end)) || - (BAD_MAGIC(cm->arc.magic_start)) || (BAD_MAGIC(cm->arc.magic_end))) { + if ((BAD_MAGIC(m->magic_start)) || (BAD_MAGIC(m->magic_end)) || + (BAD_MAGIC(m->gmx.magic_start)) || (BAD_MAGIC(m->gmx.magic_end)) || + (BAD_MAGIC(m->arc.magic_start)) || (BAD_MAGIC(m->arc.magic_end))) { return(cm_panic(STAT_CANONICAL_MACHINE_ASSERTION_FAILURE, "canonical_machine_test_assertions()")); } return (STAT_OK); @@ -904,8 +905,8 @@ void cm_halt_all(void) void cm_halt_motion(void) { mp_halt_runtime(); // stop the runtime. Do this immediately. (Reset is in cm_clear) - canonical_machine_reset(); // reset Gcode model - cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone + canonical_machine_reset(cm); //++++++ // reset Gcode model + cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone cm->motion_state = MOTION_STOP; cm->hold_state = FEEDHOLD_OFF; } @@ -1347,12 +1348,12 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) } cm_set_model_target(target, flags); - ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown - cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state + ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown + cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles - stat_t status = mp_aline(&cm->gm); // send the move to the planner + stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_finalize_move(); - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //+++++ cm_cycle_end(); return (STAT_OK); } @@ -1372,7 +1373,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm const bool flags[]) // all false if no intermediate move { // Go through intermediate point if one is provided - while (mp_planner_is_full(ACTIVE_Q)); // Make sure you have available buffers + while (mp_planner_is_full(mp)); //+++++ // Make sure you have available buffers ritorno(cm_straight_traverse(intermediate_target, flags)); // w/no action if no axis flags // If G20 adjust stored position (always in mm) to inches so traverse will be correct @@ -1385,7 +1386,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm } // Run the stored position move - while (mp_planner_is_full(ACTIVE_Q)); // Make sure you have available buffers + while (mp_planner_is_full(mp)); //+++++ // Make sure you have available buffers uint8_t saved_distance_mode = cm_get_distance_mode(MODEL); cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); // Position was stored in absolute coords @@ -1510,7 +1511,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) cm_finalize_move(); // <-- ONLY safe because we don't care about status... - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(ACTIVE_Q)) { + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //+++++ cm_cycle_end(); return (STAT_OK); } @@ -1839,7 +1840,7 @@ bool cm_has_hold() void cm_start_hold() { - if (mp_has_runnable_buffer(ACTIVE_Q)) { // meaning there's something running + if (mp_has_runnable_buffer(mp)) { //+++++ // meaning there's something running cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected cm_set_motion_state(MOTION_HOLD); @@ -1875,7 +1876,7 @@ void cm_end_hold() void cm_queue_flush() { if (mp_runtime_is_idle()) { // can't flush planner during movement - mp_flush_planner(); + mp_flush_planner(mp); // +++++ Active planner. Potential cleanup for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions cm_set_position(axis, mp_get_runtime_absolute_position(axis)); diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 2ba7b699..fddcaa82 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -207,7 +207,7 @@ typedef struct arArcSingleton { // persistent planner and runtim magic_t magic_end; } arc_t; -typedef struct cmCanonicalMachine { // struct to manage canonical machine globals and state +typedef struct cmMachine { // struct to manage canonical machine globals and state magic_t magic_start; // magic number to test memory integrity /**** Config variables (PUBLIC) ****/ @@ -269,7 +269,7 @@ typedef struct cmCanonicalMachine { // struct to manage canonical machin GCodeStateX_t gmx; // extended gcode model state magic_t magic_end; -} cmCanonicalMachine_t; +} cmMachine_t; typedef struct cmToolTable { // struct to keep a global tool table float tt_offset[TOOLS+1][AXES]; // persistent tool table offsets @@ -277,9 +277,9 @@ typedef struct cmToolTable { // struct to keep a global tool tabl /**** Externs - See canonical_machine.cpp for allocation ****/ -extern cmCanonicalMachine_t *cm; // pointer to active canonical machine -extern cmCanonicalMachine_t cm0; // canonical machine primary machine -extern cmCanonicalMachine_t cm1; // canonical machine secondary machine +extern cmMachine_t *cm; // pointer to active canonical machine +extern cmMachine_t cm0; // canonical machine primary machine +extern cmMachine_t cm1; // canonical machine secondary machine extern cmToolTable_t tt; /***************************************************************************** @@ -340,11 +340,11 @@ stat_t cm_test_soft_limits(const float target[]); /*--- Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc] ---*/ // Initialization and termination (4.3.2) -void canonical_machine_init(void); -void canonical_machine_reset_rotation(void); // NOT in NIST -void canonical_machine_reset(void); -void canonical_machine_init_assertions(void); -stat_t canonical_machine_test_assertions(void); +void canonical_machine_init(cmMachine_t *machine); +void canonical_machine_reset_rotation(cmMachine_t *machine); // NOT in NIST +void canonical_machine_reset(cmMachine_t *machine); +void canonical_machine_init_assertions(cmMachine_t *machine); +stat_t canonical_machine_test_assertions(cmMachine_t *machine); // Alarms and state management stat_t cm_alrm(nvObj_t *nv); // trigger alarm from command input diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 87135210..097bb099 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -201,7 +201,7 @@ static stat_t _dispatch_command() { if (cs.controller_state != CONTROLLER_PAUSED) { devflags_t flags = DEV_IS_BOTH | DEV_IS_MUTED; // expressly state we'll handle muted devices - if ((!mp_planner_is_full(ACTIVE_Q)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { + if ((!mp_planner_is_full(mp)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { //+++++ _dispatch_kernel(flags); } } @@ -377,7 +377,7 @@ static stat_t _sync_to_tx_buffer() static stat_t _sync_to_planner() { - if (mp_planner_is_full(ACTIVE_Q)) { // allow up to N planner buffers for this line + if (mp_planner_is_full(mp)) { // allow up to N planner buffers for this line //+++++ return (STAT_EAGAIN); } return (STAT_OK); @@ -475,8 +475,8 @@ stat_t _test_system_assertions() // these functions will panic if an assertion fails _test_assertions(); // controller assertions (local) config_test_assertions(); - canonical_machine_test_assertions(); - planner_test_assertions(); + canonical_machine_test_assertions(&cm0); // +++++ cleanup later + planner_test_assertions(&mp0); // +++++ cleanup later stepper_test_assertions(); encoder_test_assertions(); xio_test_assertions(); diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index 53542d89..fbec4f6a 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -168,7 +168,7 @@ stat_t cm_homing_cycle_start(void) { hm.set_coordinates = true; // clear rotation matrix - canonical_machine_reset_rotation(); + canonical_machine_reset_rotation(cm); //+++++ cleanup hm.axis = -1; // set to retrieve initial axis hm.func = _homing_axis_start; // bind initial processing function diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index 34b6bb3b..a2f7b4e2 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -132,7 +132,7 @@ stat_t cm_jogging_cycle_callback(void) { return (STAT_EAGAIN); // sync to planner move ends } // if (jog.func == _jogging_axis_ramp_jog && mp_get_buffers_available() < PLANNER_BUFFER_HEADROOM) { - if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(ACTIVE_Q)) { + if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(mp)) { //+++++ return (STAT_EAGAIN); // prevent flooding the queue with jog moves } return (jog.func(jog.axis)); // execute the current jogging move diff --git a/g2core/main.cpp b/g2core/main.cpp index 1535ffe2..b2a487cf 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -101,15 +101,18 @@ void application_init_services(void) void application_init_machine(void) { - cm = &cm0; + cm = &cm0; // set global canonical machine pointer to primary machine cm->machine_state = MACHINE_INITIALIZING; stepper_init(); // stepper subsystem encoder_init(); // virtual encoders gpio_init(); // inputs and outputs pwm_init(); // pulse width modulation drivers - planner_init(); // motion planning subsystem - canonical_machine_init(); // canonical machine + runtime_init(); // runtime execution structure + planner_init(&mp0); //+++++ // motion planning subsystem +// planner_init(&mp1); //+++++ // motion planning subsystem + canonical_machine_init(&cm0); //+++++ cleanup required // canonical machine +// canonical_machine_init(&cm1); //+++++ cleanup required // canonical machine } void application_init_startup(void) @@ -117,7 +120,8 @@ void application_init_startup(void) // start the application controller_init(); // should be first startup init (requires xio_init()) config_init(); // apply the config settings from persistence - canonical_machine_reset(); + canonical_machine_reset(&cm1); // +++++ +// canonical_machine_reset(&cm0); // +++++ spindle_init(); // should be after PWM and canonical machine inits and config_init() spindle_reset(); temperature_init(); diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 5401d0fc..944e3925 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -78,7 +78,7 @@ stat_t cm_arc_callback() if (cm->arc.run_state == BLOCK_INACTIVE) { return (STAT_NOOP); } - if (mp_planner_is_full(ACTIVE_Q)) { + if (mp_planner_is_full(mp)) { //+++++ return (STAT_EAGAIN); } cm->arc.theta += cm->arc.segment_theta; diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index cbedc0c0..2adbff98 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -564,7 +564,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) mp_free_run_buffer(); } - mp_replan_queue(mp_get_r(ACTIVE_Q)); // make it replan all the blocks + mp_replan_queue(mp_get_r()); // make it replan all the blocks // mp_replan_queue(mb.r); // make it replan all the blocks return (STAT_OK); @@ -654,7 +654,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) } else { mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) mr.section_state = SECTION_OFF; - mp.run_time_remaining = 0.0; // it's done, so time goes to zero + mp->run_time_remaining = 0.0; // it's done, so time goes to zero mr.entry_velocity = mr.r->exit_velocity; // feed the old exit into the entry. @@ -694,7 +694,7 @@ stat_t mp_plan_feedhold_move() void mp_exit_hold_state() { cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(ACTIVE_Q)) { + if (mp_has_runnable_buffer(mp)) { //+++++ cm_set_motion_state(MOTION_RUN); sr_request_status_report(SR_REQUEST_IMMEDIATE); } else { @@ -1074,9 +1074,9 @@ static stat_t _exec_aline_segment() } // Update the mb->run_time_remaining -- we know it's missing the current segment's time before it's loaded, that's ok. - mp.run_time_remaining -= mr.segment_time; - if (mp.run_time_remaining < 0) { - mp.run_time_remaining = 0.0; + mp->run_time_remaining -= mr.segment_time; + if (mp->run_time_remaining < 0) { + mp->run_time_remaining = 0.0; } // Call the stepper prep function diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 740b08b7..12a58d05 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -115,7 +115,7 @@ bool mp_get_runtime_busy() } if ((st_runtime_isbusy() == true) || (mr.block_state == BLOCK_ACTIVE) || - (mp_get_r(ACTIVE_Q)->buffer_state > MP_BUFFER_EMPTY)) { + (mp_get_r()->buffer_state > MP_BUFFER_EMPTY)) { return (true); } return (false); @@ -186,7 +186,7 @@ stat_t mp_aline(GCodeState_t* gm_in) target_rotated[5] = gm_in->target[5]; for (uint8_t axis = 0; axis < AXES; axis++) { - axis_length[axis] = target_rotated[axis] - mp.position[axis]; + axis_length[axis] = target_rotated[axis] - mp->position[axis]; if ((flags[axis] = fp_NOT_ZERO(axis_length[axis]))) { // yes, this supposed to be = not == axis_square[axis] = square(axis_length[axis]); length_square += axis_square[axis]; @@ -225,7 +225,7 @@ stat_t mp_aline(GCodeState_t* gm_in) _set_bf_diagnostics(bf); //+++++DIAGNOSTIC // Note: these next lines must remain in exact order. Position must update before committing the buffer. - copy_vector(mp.position, bf->gm.target); // set the planner position + copy_vector(mp->position, bf->gm.target); // set the planner position mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) return (STAT_OK); } @@ -245,8 +245,8 @@ stat_t mp_aline(GCodeState_t* gm_in) void mp_plan_block_list() { - mpBuf_t* bf = mp.p; - bool planned_something = false; + mpBuf_t* bf = mp->p; + bool planned_something = false; while (true) { // unconditional exit condition @@ -256,21 +256,21 @@ void mp_plan_block_list() // OK to replan running buffer during feedhold, but no other times (not supposed to happen) if ((cm->hold_state == FEEDHOLD_OFF) && (bf->buffer_state == MP_BUFFER_RUNNING)) { - mp.p = mp.p->nx; + mp->p = mp->p->nx; return; } bf = _plan_block(bf); // returns next block to plan planned_something = true; - mp.p = bf; //+++++ DIAGNOSTIC - this is not needed but is set here for debugging purposes + mp->p = bf; //+++++ DIAGNOSTIC - this is not needed but is set here for debugging purposes } - if (mp.planner_state > PLANNER_STARTUP) { + if (mp->planner_state > PLANNER_STARTUP) { if (planned_something && (cm->hold_state != FEEDHOLD_HOLD)) { st_request_forward_plan(); // start motion if runtime is not already busy } } - mp.p = bf; // update planner pointer + mp->p = bf; // update planner pointer } /* @@ -281,7 +281,7 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) { // First time blocks - set vmaxes for as many blocks as possible (forward loading of priming blocks) // Note: cruise_vmax was computed in _calculate_vmaxes() in aline() - if (mp.planner_state == PLANNER_PRIMING) { + if (mp->planner_state == PLANNER_PRIMING) { // Timings from *here* if (bf->pv->plannable) { @@ -304,8 +304,8 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) if (bf->nx->plannable) { // read in new buffers until EMPTY return (bf->nx); } - mp.planning_return = bf->nx; // where to return after planning is complete - mp.planner_state = PLANNER_BACK_PLANNING; // start backplanning + mp->planning_return = bf->nx; // where to return after planning is complete + mp->planner_state = PLANNER_BACK_PLANNING; // start backplanning } // Backward Planning Pass @@ -314,7 +314,7 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) // Note: Vmax's are already set by the time you get here // Hint options from back-planning: COMMAND_BLOCK, PERFECT_DECELERATION, PERFECT_CRUISE, MIXED_DECELERATION - if (mp.planner_state == PLANNER_BACK_PLANNING) { + if (mp->planner_state == PLANNER_BACK_PLANNING) { // NOTE: We stop when the previous block is no longer plannable. // We will alter the previous block's exit_velocity. float braking_velocity = 0; // we use this to stre the previous entry velocity, start at 0 @@ -434,8 +434,8 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) } // for loop } // exits with bf pointing to a locked or EMPTY block - mp.planner_state = PLANNER_PRIMING; // revert to initial state - return (mp.planning_return); + mp->planner_state = PLANNER_PRIMING; // revert to initial state + return (mp->planning_return); } /***** ALINE HELPERS ***** @@ -455,22 +455,22 @@ static void _calculate_override(mpBuf_t* bf) // execute ramp to adjust cruise v bf->cruise_vmax = bf->override_factor * bf->cruise_vset; // generate ramp term is a ramp is active - if (mp.ramp_active) { - bf->override_factor += mp.ramp_dvdt * bf->block_time; - if (mp.ramp_dvdt > 0) { // positive is an acceleration ramp - if (bf->override_factor > mp.ramp_target) { - bf->override_factor = mp.ramp_target; - mp.ramp_active = false; // detect end of ramp + if (mp->ramp_active) { + bf->override_factor += mp->ramp_dvdt * bf->block_time; + if (mp->ramp_dvdt > 0) { // positive is an acceleration ramp + if (bf->override_factor > mp->ramp_target) { + bf->override_factor = mp->ramp_target; + mp->ramp_active = false; // detect end of ramp } bf->cruise_velocity *= bf->override_factor; if (bf->cruise_velocity > bf->absolute_vmax) { // test max cruise_velocity bf->cruise_velocity = bf->absolute_vmax; - mp.ramp_active = false; // don't allow exceeding absolute_vmax + mp->ramp_active = false; // don't allow exceeding absolute_vmax } } else { // negative is deceleration ramp - if (bf->override_factor < mp.ramp_target) { - bf->override_factor = mp.ramp_target; - mp.ramp_active = false; + if (bf->override_factor < mp->ramp_target) { + bf->override_factor = mp->ramp_target; + mp->ramp_active = false; } bf->cruise_velocity *= bf->override_factor; // +++++ this is probably wrong // bf->exit_velocity *= bf->mfo_factor; //...but I'm not sure this is right, diff --git a/g2core/planner.cpp b/g2core/planner.cpp index ec534c15..d1ec21f3 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -65,10 +65,12 @@ #include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures -mpBufferQueue_t mb; // buffer pool management -mpBuf_t mb_pool0[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers -mpBuf_t mb_pool1[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers -mpMotionPlannerHead_t mp; // context for block planning +//mpPlannerQueue_t mb; // buffer pool management +mpPlanner_t *mp; // currently active planner (global variable) +mpPlanner_t mp0; // primary planning context +mpPlanner_t mp1; // secondary planning context +mpBuf_t mp0_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +mpBuf_t mp1_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers //mpMotionPlannerHead_t *mp; // pointer to motion planner //mpMotionPlannerHead_t mp0; // primary motion planner @@ -142,20 +144,71 @@ static stat_t _exec_json_wait(mpBuf_t *bf); /* * planner_init() * planner_reset() + * runtime_init() */ -void planner_init() + +// initialize a planner queue +void _init_planner_queue(mpPlanner_t *mpl, mpBuf_t *pool, uint8_t size) +{ + mpBuf_t *pv, *nx; + uint8_t i, nx_i; +// mpQueue_t *b = &mb.q[q]; + mpPlannerQueue_t *q = &(mpl->q); + + memset(q, 0, sizeof(mpPlannerQueue_t)); // clear values, pointers and status + q->magic_start = MAGICNUM; + q->magic_end = MAGICNUM; + + memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool + q->bf = pool; // link the buffer pool first + q->w = pool; // init all buffer pointers + q->r = pool; + q->queue_size = size-1; + q->buffers_available = size; + + pv = &q->bf[size-1]; + for (i=0; i < size; i++) { + q->bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) + nx_i = ((ibf[nx_i]; + q->bf[i].nx = nx; // setup circular list pointers + q->bf[i].pv = pv; + pv = &q->bf[i]; + } + q->bf[size-1].nx = pool; +} + +void planner_init(mpPlanner_t *mpl) { // If you know all memory has been zeroed by a hard reset you don't need these next 2 lines memset(&mp, 0, sizeof(mp)); // clear all values, pointers and status - memset(&mr, 0, sizeof(mr)); // clear all values, pointers and status - planner_init_assertions(); - mp_init_buffers(); - mp.mfo_factor = 1.00; +// memset(&mr, 0, sizeof(mr)); // clear all values, pointers and status + + mp = &mp0; // install the primary planner + _init_planner_queue(mp, mp0_pool, PLANNER_BUFFER_POOL_SIZE); + + planner_init_assertions(mpl); + + mpl->mfo_factor = 1.00; + +// mr.bf[0].nx = &mr.bf[1]; // Handle the two "stub blocks" in the runtime structure. +// mr.bf[1].nx = &mr.bf[0]; +// mr.r = &mr.bf[0]; +// mr.p = &mr.bf[1]; } -void planner_reset() +void planner_reset(mpPlanner_t *mpl) { - planner_init(); + planner_init(mpl); +} + +void runtime_init() { + memset(&mr, 0, sizeof(mr)); // clear all values, pointers and status + + mr.bf[0].nx = &mr.bf[1]; // Handle the two "stub blocks" in the runtime structure. + mr.bf[1].nx = &mr.bf[0]; + mr.r = &mr.bf[0]; + mr.p = &mr.bf[1]; } /* @@ -163,21 +216,19 @@ void planner_reset() * planner_test_assertions() - test assertions, PANIC if violation exists */ -void planner_init_assertions() +void planner_init_assertions(mpPlanner_t *mpl) { // Note: mb magic numbers set up by mp_init_buffers() - mp.magic_start = MAGICNUM; - mp.magic_end = MAGICNUM; + mpl->magic_start = MAGICNUM; + mpl->magic_end = MAGICNUM; mr.magic_start = MAGICNUM; mr.magic_end = MAGICNUM; } -stat_t planner_test_assertions() +stat_t planner_test_assertions(mpPlanner_t *mpl) { if ( -// (BAD_MAGIC(mb.q[0].magic_start)) || (BAD_MAGIC(mb.q[0].magic_end)) || // kind of a hack -// (BAD_MAGIC(mb.q[1].magic_start)) || (BAD_MAGIC(mb.q[1].magic_end)) || // this one, too - (BAD_MAGIC(mp.magic_start)) || (BAD_MAGIC(mp.magic_end)) || + (BAD_MAGIC(mpl->magic_start)) || (BAD_MAGIC(mpl->magic_end)) || (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end)) ) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); @@ -199,7 +250,7 @@ stat_t planner_test_assertions() void mp_halt_runtime() { stepper_reset(); // stop the steppers and dwells - planner_reset(); // reset the planner queues + planner_reset(mp); // reset the active planner } /* @@ -210,10 +261,11 @@ void mp_halt_runtime() * This function is designed to be called during a hold to reset the planner * This function should not generally be called; call cm_queue_flush() instead */ -void mp_flush_planner() +void mp_flush_planner(mpPlanner_t *mpl) { cm_abort_arc(); - mp_init_buffers(); +// mp_init_planner_buffers(mpl); //+++++ + planner_init(mpl); mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to prevent subsequent motion } @@ -242,7 +294,7 @@ void mp_flush_planner() * still close to the starting point. */ -void mp_set_planner_position(uint8_t axis, const float position) { mp.position[axis] = position; } +void mp_set_planner_position(uint8_t axis, const float position) { mp->position[axis] = position; } //+++++ void mp_set_runtime_position(uint8_t axis, const float position) { mr.position[axis] = position; } void mp_set_steps_to_runtime_position() @@ -450,6 +502,7 @@ stat_t mp_exec_out_of_band_dwell(void) * mp_has_runnable_buffer() - true if next buffer is runnable, indicating motion has not stopped. * mp_is_it_phat_city_time() - test if there is time for non-essential processes */ +/* uint8_t mp_get_planner_buffers(int8_t q) // which queue are you interested in? { if (q == ACTIVE_Q) { q = mb.active_q; }; @@ -468,13 +521,29 @@ bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) if (q == ACTIVE_Q) { q = mb.active_q; }; return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } +*/ +uint8_t mp_get_planner_buffers(mpPlanner_t *mpl) // which planner are you interested in? +{ + return (mpl->q.buffers_available); +} + +bool mp_planner_is_full(mpPlanner_t *mpl) // which planner are you interested in? +{ + // We also need to ensure we have room for another JSON command + return ((mpl->q.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0)); +} + +bool mp_has_runnable_buffer(mpPlanner_t *mpl) // which planner are you interested in?) +{ + return (mpl->q.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true +} bool mp_is_phat_city_time() { if(cm->hold_state == FEEDHOLD_HOLD) { return true; } - return ((mp.plannable_time <= 0.0) || (PHAT_CITY_TIME < mp.plannable_time)); + return ((mp->plannable_time <= 0.0) || (PHAT_CITY_TIME < mp->plannable_time)); } /* @@ -514,32 +583,32 @@ bool mp_is_phat_city_time() stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state - if ((mp_get_planner_buffers(ACTIVE_Q) == PLANNER_BUFFER_POOL_SIZE) && // detect and set IDLE state + if ((mp_get_planner_buffers(mp) == PLANNER_BUFFER_POOL_SIZE) && //+++++ // detect and set IDLE state (cm->motion_state == MOTION_STOP) && (cm->hold_state == FEEDHOLD_OFF)) { - mp.planner_state = PLANNER_IDLE; + mp->planner_state = PLANNER_IDLE; return (STAT_OK); } - bool _timed_out = mp.block_timeout.isPast(); + bool _timed_out = mp->block_timeout.isPast(); if (_timed_out) { - mp.block_timeout.clear(); // timer is set on commit_write_buffer() + mp->block_timeout.clear(); // timer is set on commit_write_buffer() } - if (!mp.request_planning && !_timed_out) { // Exit if no request or timeout + if (!mp->request_planning && !_timed_out) { // Exit if no request or timeout return (STAT_OK); } // Process a planner request or timeout - if (mp.planner_state == PLANNER_IDLE) { - mp.p = mp_get_r(ACTIVE_Q); // initialize planner pointer to run buffer - mp.planner_state = PLANNER_STARTUP; + if (mp->planner_state == PLANNER_IDLE) { + mp->p = mp_get_r(); //+++++ // initialize planner pointer to run buffer + mp->planner_state = PLANNER_STARTUP; } - if (mp.planner_state == PLANNER_STARTUP) { - if (!mp_planner_is_full(ACTIVE_Q) && !_timed_out) { + if (mp->planner_state == PLANNER_STARTUP) { + if (!mp_planner_is_full(mp) && !_timed_out) { //+++++ return (STAT_OK); // remain in STARTUP } - mp.planner_state = PLANNER_PRIMING; + mp->planner_state = PLANNER_PRIMING; } mp_plan_block_list(); return (STAT_OK); @@ -559,9 +628,9 @@ void mp_replan_queue(mpBuf_t *bf) } else { // If it's not "planned" then it's either PREPPED or earlier. break; // We don't need to adjust it. } - } while ((bf = mp_get_next_buffer(bf)) != mp_get_r(ACTIVE_Q)); + } while ((bf = mp_get_next_buffer(bf)) != mp_get_r()); //+++++ - mp.request_planning = true; + mp->request_planning = true; } /* @@ -587,21 +656,21 @@ void mp_start_feed_override(const float ramp_time, const float override_factor) { cm->mfo_state = MFO_REQUESTED; - if (mp.planner_state == PLANNER_IDLE) { - mp.mfo_factor = override_factor; // that was easy + if (mp->planner_state == PLANNER_IDLE) { + mp->mfo_factor = override_factor; // that was easy return; } // Assume that the min and max values for override_factor have been validated upstream // SUVAT: V = U+AT ==> A = (V-U)/T - mp.ramp_target = override_factor; - mp.ramp_dvdt = (override_factor - mp.c->override_factor) / ramp_time; - mp.mfo_active = true; + mp->ramp_target = override_factor; + mp->ramp_dvdt = (override_factor - mp->c->override_factor) / ramp_time; + mp->mfo_active = true; - if (fp_NOT_ZERO(mp.ramp_dvdt)) { // do these things only if you actually have a ramp to run - mp.p = mp.c; // re-position the planner pointer - mp.ramp_active = true; - mp.request_planning = true; + if (fp_NOT_ZERO(mp->ramp_dvdt)) { // do these things only if you actually have a ramp to run + mp->p = mp->c; // re-position the planner pointer + mp->ramp_active = true; + mp->request_planning = true; } } @@ -616,18 +685,18 @@ void mp_end_feed_override(const float ramp_time) void mp_planner_time_accounting() { - mpBuf_t *bf = mp_get_r(ACTIVE_Q); // start with run buffer + mpBuf_t *bf = mp_get_r(); //+++++ // start with run buffer // check the run buffer to see if anything is running. Might not be if (bf->buffer_state != MP_BUFFER_RUNNING) { // this is not an error condition return; } - mp.plannable_time = 0; //UPDATE_BF_MS(bf); //+++++ - while ((bf = bf->nx) != mp_get_r(ACTIVE_Q)) { + mp->plannable_time = 0; //UPDATE_BF_MS(bf); //+++++ + while ((bf = bf->nx) != mp_get_r()) { //+++++ if (bf->buffer_state == MP_BUFFER_EMPTY || bf->plannable == true) { break; } - mp.plannable_time += bf->block_time; + mp->plannable_time += bf->block_time; } UPDATE_MP_DIAGNOSTICS //+++++ } @@ -714,46 +783,18 @@ static inline void _clear_buffer(mpBuf_t *bf) bf->reset(); // Call a reset method on the buffer object. } // We'll need something else for C - like bring the method code back into this function. -// initialize a single planner queue -void _init_planner_queue(uint8_t q, mpBuf_t *pool, uint8_t size) +/* +void mp_init_planner_buffers(void) { - mpBuf_t *pv, *nx; - uint8_t i, nx_i; - mpQueue_t *b = &mb.q[q]; +// _init_planner_queue(0, mb_pool0, PLANNER_BUFFER_POOL_SIZE); +// _init_planner_queue(1, mb_pool1, SECONDARY_BUFFER_POOL_SIZE); - memset(b, 0, sizeof(mpQueue_t)); // clear values, pointers and status - b->magic_start = MAGICNUM; - b->magic_end = MAGICNUM; - - memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool - b->bf = pool; // link the buffer pool first - b->w = pool; // init all buffer pointers - b->r = pool; - b->queue_size = size-1; - b->buffers_available = size; - - pv = &b->bf[size-1]; - for (i=0; i < size; i++) { - b->bf[i].buffer_number = i; // number is for diagnostics only (otherwise not used) - nx_i = ((ibf[nx_i]; - b->bf[i].nx = nx; // setup circular list pointers - b->bf[i].pv = pv; - pv = &b->bf[i]; - } - b->bf[size-1].nx = pool; -} - -void mp_init_buffers(void) -{ - _init_planner_queue(0, mb_pool0, PLANNER_BUFFER_POOL_SIZE); - _init_planner_queue(1, mb_pool1, SECONDARY_BUFFER_POOL_SIZE); - - mr.bf[0].nx = &mr.bf[1]; // Now handle the two "stub blocks" in the runtime structure. - mr.bf[1].nx = &mr.bf[0]; - mr.r = &mr.bf[0]; - mr.p = &mr.bf[1]; +// mr.bf[0].nx = &mr.bf[1]; // Now handle the two "stub blocks" in the runtime structure. +// mr.bf[1].nx = &mr.bf[0]; +// mr.r = &mr.bf[0]; +// mr.p = &mr.bf[1]; } +*/ /* * These GET functions are defined here but we use the macros in planner.h instead @@ -761,26 +802,22 @@ mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); } mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } */ -mpBuf_t * mp_get_w(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].w : mb.q[q].w); } -mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : mb.q[q].r); } +//mpBuf_t * mp_get_w(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].w : mb.q[q].w); } +//mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : mb.q[q].r); } + +mpBuf_t * mp_get_w() { return (mp->q.w); } //++++ should this be a DI function? +mpBuf_t * mp_get_r() { return (mp->q.r); } //+++++ ditto mpBuf_t * mp_get_write_buffer() // get & clear a buffer { - mpQueue_t *q = &mb.q[mb.active_q]; +// mpQueue_t *q = &mb.q[mb.active_q]; + mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state == MP_BUFFER_EMPTY) { _clear_buffer(q->w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer q->w->buffer_state = MP_BUFFER_INITIALIZING; q->buffers_available--; - return (mp_get_w(ACTIVE_Q)); -/*======= - if (mb.w->buffer_state == MP_BUFFER_EMPTY) { - _clear_buffer(mb.w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer - mb.w->buffer_state = MP_BUFFER_INITIALIZING; - mb.buffers_available--; - return (mb.w); ->>>>>>> refs/heads/edge -*/ + return (mp_get_w()); } // The no buffer condition always causes a panic - invoked by the caller rpt_exception(STAT_FAILED_TO_GET_PLANNER_BUFFER, "mp_get_write_buffer()"); @@ -789,7 +826,8 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer void mp_unget_write_buffer() // mark buffer as empty and adjust free buffer count { - mpQueue_t *q = &mb.q[mb.active_q]; +// mpQueue_t *q = &mb.q[mb.active_q]; + mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer q->w->buffer_state = MP_BUFFER_EMPTY; @@ -804,7 +842,8 @@ void mp_unget_write_buffer() // mark buffer as empty and adjust free buff void mp_commit_write_buffer(const blockType block_type) { - mpQueue_t *q = &mb.q[mb.active_q]; +// mpQueue_t *q = &mb.q[mb.active_q]; + mpPlannerQueue_t *q = &(mp->q); q->w->block_type = block_type; q->w->block_state = BLOCK_INITIAL_ACTION; @@ -814,16 +853,16 @@ void mp_commit_write_buffer(const blockType block_type) cm_set_motion_state(MOTION_PLANNING); } } else { - if ((mp.planner_state > PLANNER_STARTUP) && (cm->hold_state == FEEDHOLD_OFF)) { + if ((mp->planner_state > PLANNER_STARTUP) && (cm->hold_state == FEEDHOLD_OFF)) { // NB: BEWARE! the requested exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents st_request_forward_plan(); // request an exec if the runtime is not busy } } q->w->plannable = true; // enable block for planning - mp.request_planning = true; + mp->request_planning = true; q->w = q->w->nx; // advance write buffer pointer - mp.block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer + mp->block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer qr_request_queue_report(+1); // request QR and add to "added buffers" count } @@ -834,7 +873,8 @@ void mp_commit_write_buffer(const blockType block_type) // (2) is the buffer in error - i.e. not yet ready for running? mpBuf_t * mp_get_run_buffer() { - mpBuf_t *r = mb.q[mb.active_q].r; +// mpBuf_t *r = mb.q[mb.active_q].r; + mpBuf_t *r = mp->q.r; if (r->buffer_state == MP_BUFFER_EMPTY) { return (NULL); @@ -846,7 +886,9 @@ mpBuf_t * mp_get_run_buffer() // Clearing and advancing must be done atomically as other interrupts may be using the run buffer bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { - mpQueue_t *q = &mb.q[mb.active_q]; +// mpQueue_t *q = &mb.q[mb.active_q]; + mpPlannerQueue_t *q = &(mp->q); + mpBuf_t *r_now = q->r; // save this pointer is to avoid a race condition when clearing the buffer _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) diff --git a/g2core/planner.h b/g2core/planner.h index d18db589..4c15ef8a 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -241,12 +241,13 @@ typedef enum { ZOID_EXIT_3a2 } zoidExitPoint; +/* +++++ REMOVE typedef enum { ACTIVE_Q = -1, // Must be -1 PRIMARY_Q, // must line up with structure indexes SECONDARY_Q } queueType; - +*/ /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 @@ -298,7 +299,7 @@ typedef enum { //#define ASCII_ART(s) xio_writeline(s) #define ASCII_ART(s) //#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; } -#define UPDATE_MP_DIAGNOSTICS { mp.plannable_time_ms = mp.plannable_time*60000; } +#define UPDATE_MP_DIAGNOSTICS { mp->plannable_time_ms = mp->plannable_time*60000; } /* * Planner structures @@ -411,7 +412,7 @@ typedef struct mpBuffer { } mpBuf_t; -typedef struct mpQueue { // a planner buffer queue +typedef struct mpPlannerQueue { // control structure for queue magic_t magic_start; // magic number to test memory integrity mpBuf_t *r; // run buffer pointer mpBuf_t *w; // write buffer pointer @@ -419,15 +420,17 @@ typedef struct mpQueue { // a planner buffer queue uint8_t buffers_available; // running count of available buffers in queue mpBuf_t *bf; // pointer to buffer storage array magic_t magic_end; -} mpQueue_t; +} mpPlannerQueue_t; +/* typedef struct mpBufferQueue { // one or more planner buffer queues uint8_t active_q; // index of currently active queue uint8_t return_q; // index of queue to return to mpQueue_t q[2]; // number of queues } mpBufferQueue_t; +*/ -typedef struct mpMotionPlannerHead {// common variables for planning (move master) +typedef struct mpPlanner { // common variables for a planner context magic_t magic_start; // magic number to test memory integrity //+++++ DIAGNOSTICS @@ -463,10 +466,10 @@ typedef struct mpMotionPlannerHead {// common variables for planning (move maste mpBuf_t *planning_return; // buffer to return to once back-planning is complete // queue manager - mpBufferQueue_t q; // embed a buffer queue manager + mpPlannerQueue_t q; // embed a planner buffer queue manager magic_t magic_end; -} mpMotionPlannerHead_t; +} mpPlanner_t; typedef struct mpBlockRuntimeBuf { // Data structure for just the parts of RunTime that we need to plan a BLOCK struct mpBlockRuntimeBuf *nx; // singly-linked-list @@ -525,8 +528,14 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables } mpMotionRuntimeSingleton_t; // Reference global scope structures -extern mpBufferQueue_t mb; // planner buffer queue management -extern mpMotionPlannerHead_t mp; // context for block planning +//extern mpPlannerQueue_t mb; // planner buffer queue management + +extern mpPlanner_t *mp; // currently active planner (global variable) +extern mpPlanner_t mp0; // primary planning context +extern mpPlanner_t mp1; // secondary planning context +extern mpBuf_t mp0_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +extern mpBuf_t mp1_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers + extern mpMotionRuntimeSingleton_t mr; // context for block runtime /* @@ -535,13 +544,14 @@ extern mpMotionRuntimeSingleton_t mr; // context for block runtime //planner.cpp functions -void planner_init(void); -void planner_reset(void); -void planner_init_assertions(void); -stat_t planner_test_assertions(void); +void planner_init(mpPlanner_t *mpl); +void planner_reset(mpPlanner_t *mpl); +void planner_init_assertions(mpPlanner_t *mpl); +stat_t planner_test_assertions(mpPlanner_t *mpl); +void runtime_init(void); void mp_halt_runtime(void); -void mp_flush_planner(void); +void mp_flush_planner(mpPlanner_t *mpl); void mp_set_planner_position(uint8_t axis, const float position); void mp_set_runtime_position(uint8_t axis, const float position); void mp_set_steps_to_runtime_position(void); @@ -558,9 +568,9 @@ void mp_request_out_of_band_dwell(float seconds); stat_t mp_exec_out_of_band_dwell(void); // planner functions and helpers -uint8_t mp_get_planner_buffers(int8_t q); -bool mp_planner_is_full(int8_t q); -bool mp_has_runnable_buffer(int8_t q); +uint8_t mp_get_planner_buffers(mpPlanner_t *mpl); +bool mp_planner_is_full(mpPlanner_t *mpl); +bool mp_has_runnable_buffer(mpPlanner_t *mpl); bool mp_is_phat_city_time(void); stat_t mp_planner_callback(); @@ -570,9 +580,11 @@ void mp_end_feed_override(const float ramp_time); void mp_planner_time_accounting(void); // planner buffer primitives -void mp_init_buffers(void); -mpBuf_t * mp_get_w(int8_t q); -mpBuf_t * mp_get_r(int8_t q); +//void mp_init_planner_buffers(void); +//mpBuf_t * mp_get_w(int8_t q); +//mpBuf_t * mp_get_r(int8_t q); +mpBuf_t * mp_get_w(void); +mpBuf_t * mp_get_r(void); //mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf); // Use the following macro instead //mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf); // Use the following macro instead diff --git a/g2core/report.cpp b/g2core/report.cpp index ad1d3da6..27cdfb1d 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -483,7 +483,7 @@ void qr_init_queue_report() void qr_request_queue_report(int8_t buffers) { // get buffer depth and added/removed count - qr.buffers_available = mp_get_planner_buffers(ACTIVE_Q); + qr.buffers_available = mp_get_planner_buffers(mp); //+++++ if (buffers > 0) { qr.buffers_added += buffers; } else { @@ -567,7 +567,7 @@ stat_t qr_queue_report_callback() // called by controller dispatcher */ stat_t qr_get(nvObj_t *nv) { - nv->value = (float)mp_get_planner_buffers(ACTIVE_Q); // ensure that manually requested QR count is always up to date + nv->value = (float)mp_get_planner_buffers(mp); //+++++ // ensure that manually requested QR count is always up to date nv->valuetype = TYPE_INT; return (STAT_OK); } From 6a541f51ca660b5bfc5dc6b3055d6fd0719e192e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 10 Jan 2017 09:06:39 -0500 Subject: [PATCH 055/283] Moved MRs under the planner; changed the inits and mr references for this to work. Still have testing and cleanup to go. --- g2core/canonical_machine.cpp | 20 +-- g2core/canonical_machine.h | 2 +- g2core/config_app.cpp | 84 ++++----- g2core/main.cpp | 33 ++-- g2core/plan_exec.cpp | 340 +++++++++++++++++------------------ g2core/plan_line.cpp | 24 +-- g2core/plan_zoid.cpp | 10 +- g2core/planner.cpp | 124 +++++-------- g2core/planner.h | 206 +++++++++++---------- 9 files changed, 407 insertions(+), 436 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 5cb0b79b..ae57f2dd 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -226,7 +226,7 @@ cmCombinedState cm_get_combined_state() /* These getters and setters will work on any gm model with inputs: * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to - * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct + * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ uint32_t cm_get_linenum(const GCodeState_t *gcode_state) { return gcode_state->linenum;} @@ -342,10 +342,10 @@ float cm_get_active_coord_offset(const uint8_t axis) /* * cm_get_work_offset() - return a coord offset from the gcode_state * - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to - * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm->am // active model pointer is maintained by state management + * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct + * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) @@ -356,10 +356,10 @@ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) /* * cm_set_work_offsets() - capture coord offsets from the model into absolute values in the gcode_state * - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to - * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm->am // active model pointer is maintained by state management + * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct + * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ void cm_set_work_offsets(GCodeState_t *gcode_state) @@ -374,7 +374,7 @@ void cm_set_work_offsets(GCodeState_t *gcode_state) * * This function accepts as input: * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct + * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct * * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) * NOTE: Machine position is always returned in mm mode. No units conversion is performed @@ -398,7 +398,7 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax * * This function accepts as input: * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct + * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct * * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) */ @@ -444,7 +444,7 @@ void cm_finalize_move() void cm_update_model_position_from_runtime() { - copy_vector(cm->gmx.position, mr.gm.target); + copy_vector(cm->gmx.position, mr->gm.target); } /* diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index fddcaa82..4f56c927 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -40,7 +40,7 @@ #define MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model #define PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to -#define RUNTIME (GCodeState_t *)&mr.gm // absolute pointer from runtime mm struct +#define RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct #define ACTIVE_MODEL cm->am // active model pointer is maintained by state management #define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 9bdfbaa9..a8dd23c9 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -941,67 +941,67 @@ const cfgItem_t cfgArray[] = { { "", "clc",_f0, 0, tx_print_nul, st_clc, st_clc, (float *)&cs.null, 0 }, // clear diagnostic step counters // { "", "_dam",_f0, 0, tx_print_nul, cm_dam, cm_dam, (float *)&cs.null, 0 }, // dump active model - { "_te","_tex",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_X], 0 }, // X target endpoint - { "_te","_tey",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_Y], 0 }, - { "_te","_tez",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_Z], 0 }, - { "_te","_tea",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_A], 0 }, - { "_te","_teb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_B], 0 }, - { "_te","_tec",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target[AXIS_C], 0 }, + { "_te","_tex",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_X], 0 }, // X target endpoint + { "_te","_tey",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_Y], 0 }, + { "_te","_tez",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_Z], 0 }, + { "_te","_tea",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_A], 0 }, + { "_te","_teb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_B], 0 }, + { "_te","_tec",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_C], 0 }, - { "_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_X], 0 }, // X target runtime - { "_tr","_try",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_Y], 0 }, - { "_tr","_trz",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_Z], 0 }, - { "_tr","_tra",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_A], 0 }, - { "_tr","_trb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_B], 0 }, - { "_tr","_trc",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.gm.target[AXIS_C], 0 }, + { "_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_X], 0 }, // X target runtime + { "_tr","_try",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_Y], 0 }, + { "_tr","_trz",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_Z], 0 }, + { "_tr","_tra",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_A], 0 }, + { "_tr","_trb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_B], 0 }, + { "_tr","_trc",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_C], 0 }, #if (MOTORS >= 1) - { "_ts","_ts1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_1], 0 }, // Motor 1 target steps - { "_ps","_ps1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_1], 0 }, // Motor 1 position steps - { "_cs","_cs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_1], 0 }, // Motor 1 commanded steps (delayed steps) - { "_es","_es1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_1], 0 }, // Motor 1 encoder steps + { "_ts","_ts1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_1], 0 }, // Motor 1 target steps + { "_ps","_ps1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_1], 0 }, // Motor 1 position steps + { "_cs","_cs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_1], 0 }, // Motor 1 commanded steps (delayed steps) + { "_es","_es1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_1], 0 }, // Motor 1 encoder steps { "_xs","_xs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_1].corrected_steps, 0 }, // Motor 1 correction steps applied - { "_fe","_fe1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_1], 0 }, // Motor 1 following error in steps + { "_fe","_fe1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_1], 0 }, // Motor 1 following error in steps #endif #if (MOTORS >= 2) - { "_ts","_ts2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_2], 0 }, - { "_ps","_ps2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_2], 0 }, - { "_cs","_cs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_2], 0 }, - { "_es","_es2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_2], 0 }, + { "_ts","_ts2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_2], 0 }, + { "_ps","_ps2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_2], 0 }, + { "_cs","_cs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_2], 0 }, + { "_es","_es2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_2], 0 }, { "_xs","_xs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_2].corrected_steps, 0 }, - { "_fe","_fe2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_2], 0 }, + { "_fe","_fe2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_2], 0 }, #endif #if (MOTORS >= 3) - { "_ts","_ts3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_3], 0 }, - { "_ps","_ps3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_3], 0 }, - { "_cs","_cs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_3], 0 }, - { "_es","_es3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_3], 0 }, + { "_ts","_ts3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_3], 0 }, + { "_ps","_ps3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_3], 0 }, + { "_cs","_cs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_3], 0 }, + { "_es","_es3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_3], 0 }, { "_xs","_xs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_3].corrected_steps, 0 }, - { "_fe","_fe3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_3], 0 }, + { "_fe","_fe3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_3], 0 }, #endif #if (MOTORS >= 4) - { "_ts","_ts4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_4], 0 }, - { "_ps","_ps4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_4], 0 }, - { "_cs","_cs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_4], 0 }, - { "_es","_es4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_4], 0 }, + { "_ts","_ts4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_4], 0 }, + { "_ps","_ps4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_4], 0 }, + { "_cs","_cs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_4], 0 }, + { "_es","_es4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_4], 0 }, { "_xs","_xs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_4].corrected_steps, 0 }, - { "_fe","_fe4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_4], 0 }, + { "_fe","_fe4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_4], 0 }, #endif #if (MOTORS >= 5) - { "_ts","_ts5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_5], 0 }, - { "_ps","_ps5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_5], 0 }, - { "_cs","_cs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_5], 0 }, - { "_es","_es5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_5], 0 }, + { "_ts","_ts5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_5], 0 }, + { "_ps","_ps5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_5], 0 }, + { "_cs","_cs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_5], 0 }, + { "_es","_es5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_5], 0 }, { "_xs","_xs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_5].corrected_steps, 0 }, - { "_fe","_fe5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_5], 0 }, + { "_fe","_fe5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_5], 0 }, #endif #if (MOTORS >= 6) - { "_ts","_ts6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.target_steps[MOTOR_6], 0 }, - { "_ps","_ps6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.position_steps[MOTOR_6], 0 }, - { "_cs","_cs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.commanded_steps[MOTOR_6], 0 }, - { "_es","_es6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.encoder_steps[MOTOR_6], 0 }, + { "_ts","_ts6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_6], 0 }, + { "_ps","_ps6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_6], 0 }, + { "_cs","_cs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_6], 0 }, + { "_es","_es6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_6], 0 }, { "_xs","_xs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_6].corrected_steps, 0 }, - { "_fe","_fe6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr.following_error[MOTOR_6], 0 }, + { "_fe","_fe6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_6], 0 }, #endif #endif // __DIAGNOSTIC_PARAMETERS diff --git a/g2core/main.cpp b/g2core/main.cpp index b2a487cf..f6858f31 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -94,35 +94,34 @@ extern OutputPin debug_pin3; void application_init_services(void) { - hardware_init(); // system hardware setup - must be first - persistence_init(); // set up EEPROM or other NVM - must be second - xio_init(); // xtended io subsystem - must be third + hardware_init(); // system hardware setup - must be first + persistence_init(); // set up EEPROM or other NVM - must be second + xio_init(); // xtended io subsystem - must be third } void application_init_machine(void) { - cm = &cm0; // set global canonical machine pointer to primary machine + cm = &cm0; // set global canonical machine pointer to primary machine cm->machine_state = MACHINE_INITIALIZING; - stepper_init(); // stepper subsystem - encoder_init(); // virtual encoders - gpio_init(); // inputs and outputs - pwm_init(); // pulse width modulation drivers - runtime_init(); // runtime execution structure - planner_init(&mp0); //+++++ // motion planning subsystem -// planner_init(&mp1); //+++++ // motion planning subsystem - canonical_machine_init(&cm0); //+++++ cleanup required // canonical machine + stepper_init(); // stepper subsystem + encoder_init(); // virtual encoders + gpio_init(); // inputs and outputs + pwm_init(); // pulse width modulation drivers + planner_init(&mp0, mp0_pool, &mr0); //+++++ //primary motion planner +// planner_init(&mp1, mp1_pool, &mr1); //+++++ //secondary motion planner + canonical_machine_init(&cm0); //+++++ cleanup required // canonical machine // canonical_machine_init(&cm1); //+++++ cleanup required // canonical machine } void application_init_startup(void) { // start the application - controller_init(); // should be first startup init (requires xio_init()) - config_init(); // apply the config settings from persistence - canonical_machine_reset(&cm1); // +++++ -// canonical_machine_reset(&cm0); // +++++ - spindle_init(); // should be after PWM and canonical machine inits and config_init() + controller_init(); // should be first startup init (requires xio_init()) + config_init(); // apply the config settings from persistence + canonical_machine_reset(&cm0); // +++++ +// canonical_machine_reset(&cm1); // +++++ + spindle_init(); // should be after PWM and canonical machine inits and config_init() spindle_reset(); temperature_init(); gpio_reset(); diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 2adbff98..d7e8205a 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -2,8 +2,8 @@ * plan_exec.cpp - execution function for acceleration managed lines * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2016 Rob Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -96,16 +96,16 @@ static void _init_forward_diffs(float v_0, float v_1); * that may be in PREPPED or PLANNED states. Processing is always the same. Plan all * PREPPED commands and skip past all PLANNED commands. * - * Note 1: For MOVEs use the exit velocity of the Run block (mr.r->exit_velocity) as the + * Note 1: For MOVEs use the exit velocity of the Run block (mr->r->exit_velocity) as the * entry velocity of the next adjacent move. * - * Note 1a: In this special COMMAND case we trust mr.r->exit_velocity because the + * Note 1a: In this special COMMAND case we trust mr->r->exit_velocity because the * backplanner has already handled this case for us. * - * Note 2: For COMMANDs use the entry velocity of the current runtime (mr.entry_velocity) - * as the entry velocity for the next adjacent move. mr.entry_velocity is almost always 0, + * Note 2: For COMMANDs use the entry velocity of the current runtime (mr->entry_velocity) + * as the entry velocity for the next adjacent move. mr->entry_velocity is almost always 0, * but could be non-0 in a race condition. - * FYI: mr.entry_velocity is set at the end of the last running block in mp_exec_aline(). + * FYI: mr->entry_velocity is set at the end of the last running block in mp_exec_aline(). * * * CASE: @@ -170,11 +170,11 @@ static stat_t _plan_move(mpBuf_t *bf, float entry_velocity) // The block and the buffer are implicitly linked for exec_aline() // // Note that that can only be one PLANNED move at a time. - // This is to help sync mr.p to point to the next planned mr.bf - // mr.p is only advanced in mp_exec_aline(), after mp.r = mr.p. + // This is to help sync mr->p to point to the next planned mr->bf + // mr->p is only advanced in mp_exec_aline(), after mp.r = mr->p. // This code aligns the buffers and the blocks for exec_aline(). - mpBlockRuntimeBuf_t* block = mr.p; // set a local planning block so it doesn't change on you + mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) // diagnostic traps @@ -210,9 +210,9 @@ stat_t mp_forward_plan() // Case 2: Running cases - move bf past run buffer so it acts like case 1 if (bf->buffer_state == MP_BUFFER_RUNNING) { bf = bf->nx; - entry_velocity = mr.r->exit_velocity; // set Note 1 entry_velocity (move cases) + entry_velocity = mr->r->exit_velocity; // set Note 1 entry_velocity (move cases) } else { - entry_velocity = mr.entry_velocity; // set Note 2 entry velocity (command cases) + entry_velocity = mr->entry_velocity; // set Note 2 entry velocity (command cases) } // bf points to command; start cases 1f, 1g, 1h, 1i, 1j, 1k, 2c, 2d, 2e, 2h, 2i, 2j @@ -220,7 +220,7 @@ stat_t mp_forward_plan() bf = _plan_commands(bf); // plan commands or skip past already planned commands // bf now points to the first non-command buffer past the command(s) if ((bf->block_type == BLOCK_TYPE_ALINE) && (bf->buffer_state > MP_BUFFER_PREPPED )) { // case 1i - entry_velocity = mr.r->exit_velocity; // set entry_velocity for Note 1a + entry_velocity = mr->r->exit_velocity; // set entry_velocity for Note 1a } } // bf will always be on a non-command at this point - either a move or empty buffer @@ -295,7 +295,7 @@ stat_t mp_exec_move() // We go ahead and *ask* for a forward planning of the next move. // This won't call mp_plan_move until we leave this function // (and have called mp_exec_aline via bf->bf_func). - // This also allows mp_exec_aline to advance mr.p first. + // This also allows mp_exec_aline to advance mr->p first. st_request_forward_plan(); } @@ -350,7 +350,7 @@ stat_t mp_exec_move() * from _RUN to _OFF on final call * or just remains _OFF * - * mr.block_state transitions on first call from _OFF to one of _HEAD, _BODY, _TAIL + * mr->block_state transitions on first call from _OFF to one of _HEAD, _BODY, _TAIL * Within each section state may be * _NEW - trigger initialization * _RUN1 - run the first part @@ -364,19 +364,19 @@ stat_t mp_exec_move() /* Synchronization of run BUFFER and run BLOCK * * Note first: mp_exec_aline() makes a huge assumption: When it comes time to get a - * new run block (mr.r) it assumes the planner block (mr.p) has been fully planned + * new run block (mr->r) it assumes the planner block (mr->p) has been fully planned * via the JIT forward planning and is ready for use as the new run block. * * The runtime uses 2 structures for the current move or commend, the run BUFFER * from the planner queue (mb.r, aka bf), and the run BLOCK from the runtime - * singleton (mr.r). These structures are synchronized implicitly, but not + * singleton (mr->r). These structures are synchronized implicitly, but not * explicitly referenced, as pointers can lead to race conditions. * See plan_zoid.cpp / mp_calculate_ramps() for more details * * When mp_exec_aline() needs to grab a new planner buffer for a new move or command * (i.e. block state is inactive) it swaps (rolls) the run and planner BLOCKS so that - * mr.p (planner block) is now the mr.r (run block), and the old mr.r block becomes - * available for planning; it becomes mr.p block. + * mr->p (planner block) is now the mr->r (run block), and the old mr->r block becomes + * available for planning; it becomes mr->p block. * * At the same time, it's when finished with its current run buffer (mb.r), it has already * advanced to the next buffer. mp_exec_move() does this at the end of previous move. @@ -405,7 +405,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Initialize all new blocks, regardless of normal or feedhold operation - if (mr.block_state == BLOCK_INACTIVE) { + if (mr->block_state == BLOCK_INACTIVE) { // too short lines have already been removed... // so is the following code is no longer needed ++++ ash @@ -415,16 +415,16 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Start a new move by setting up the runtime singleton (mr) - memcpy(&mr.gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state + memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state bf->block_state = BLOCK_ACTIVE; // note that this buffer is running // note the planner doesn't look at block_state - mr.block_state = BLOCK_INITIAL_ACTION; - mr.section = SECTION_HEAD; - mr.section_state = SECTION_NEW; + mr->block_state = BLOCK_INITIAL_ACTION; + mr->section = SECTION_HEAD; + mr->section_state = SECTION_NEW; - // This is the only place in the system where mr.r and mr.p are allowed to be changed - mr.r = mr.p; // we are now going to run the planning block - mr.p = mr.p->nx; // re-use the old running block as the new planning block + // This is the only place in the system where mr->r and mr->p are allowed to be changed + mr->r = mr->p; // we are now going to run the planning block + mr->p = mr->p->nx; // re-use the old running block as the new planning block // Assumptions that are required for this to work: // entry velocity <= cruise velocity && cruise velocity >= exit velocity @@ -434,60 +434,60 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Here we will check to make sure that the sections are longer than MIN_SEGMENT_TIME - if ((!fp_ZERO(mr.r->head_length)) && (mr.r->head_time < MIN_SEGMENT_TIME)) { + if ((!fp_ZERO(mr->r->head_length)) && (mr->r->head_time < MIN_SEGMENT_TIME)) { // head_time !== body_time // We have to compute the new body time addition. - mr.r->body_length += mr.r->head_length; - mr.r->body_time = mr.r->body_length/mr.r->cruise_velocity; + mr->r->body_length += mr->r->head_length; + mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; - mr.r->head_length = 0; - mr.r->head_time = 0; + mr->r->head_length = 0; + mr->r->head_time = 0; } - if ((!fp_ZERO(mr.r->tail_length)) && (mr.r->tail_time < MIN_SEGMENT_TIME)) { + if ((!fp_ZERO(mr->r->tail_length)) && (mr->r->tail_time < MIN_SEGMENT_TIME)) { // tail_time !== body_time // We have to compute the new body time addition. - mr.r->body_length += mr.r->tail_length; - mr.r->body_time = mr.r->body_length/mr.r->cruise_velocity; + mr->r->body_length += mr->r->tail_length; + mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; - mr.r->tail_length = 0; - mr.r->tail_time = 0; + mr->r->tail_length = 0; + mr->r->tail_time = 0; } // At this point, we've already possibly merged head and/or tail into the body. // If the body is too "short" (brief) still, we *might* be able to add it to a head or tail. // If there's still a head or a tail, we will add the body to whichever there is, maybe both. // We saved it for last since it's the most expensive. - if ((!fp_ZERO(mr.r->body_length)) && (mr.r->body_time < MIN_SEGMENT_TIME)) { + if ((!fp_ZERO(mr->r->body_length)) && (mr->r->body_time < MIN_SEGMENT_TIME)) { // We'll add the time to either the head or the tail or split it - if (mr.r->tail_length > 0) { - if (mr.r->head_length > 0) { + if (mr->r->tail_length > 0) { + if (mr->r->head_length > 0) { // We'll split the body to the head and tail - float body_split = mr.r->body_length/2.0; - mr.r->body_length = 0; - mr.r->body_time = 0; + float body_split = mr->r->body_length/2.0; + mr->r->body_length = 0; + mr->r->body_time = 0; - mr.r->head_length += body_split; - mr.r->tail_length += body_split; + mr->r->head_length += body_split; + mr->r->tail_length += body_split; - mr.r->head_time = (2.0 * mr.r->head_length)/(mr.entry_velocity + mr.r->cruise_velocity); - mr.r->tail_time = (2.0 * mr.r->tail_length)/(mr.r->cruise_velocity + mr.r->exit_velocity); + mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); + mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } else { // We'll put it all in the tail - mr.r->tail_length += mr.r->body_length; - mr.r->body_length = 0; - mr.r->body_time = 0; + mr->r->tail_length += mr->r->body_length; + mr->r->body_length = 0; + mr->r->body_time = 0; - mr.r->tail_time = (2.0 * mr.r->tail_length)/(mr.r->cruise_velocity + mr.r->exit_velocity); + mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } } - else if (mr.r->head_length > 0) { + else if (mr->r->head_length > 0) { // We'll put it all in the head - mr.r->head_length += mr.r->body_length; - mr.r->body_length = 0; - mr.r->body_time = 0; + mr->r->head_length += mr->r->body_length; + mr->r->body_length = 0; + mr->r->body_time = 0; - mr.r->head_time = (2.0 * mr.r->head_length)/(mr.entry_velocity + mr.r->cruise_velocity); + mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); } else { // Uh oh! We have a move that's all body, and is still too short!! @@ -496,15 +496,15 @@ stat_t mp_exec_aline(mpBuf_t *bf) } } - copy_vector(mr.unit, bf->unit); - copy_vector(mr.target, bf->gm.target); // save the final target of the move - copy_vector(mr.axis_flags, bf->axis_flags); + copy_vector(mr->unit, bf->unit); + copy_vector(mr->target, bf->gm.target); // save the final target of the move + copy_vector(mr->axis_flags, bf->axis_flags); // generate the way points for position correction at section ends for (uint8_t axis=0; axishead_length; - mr.waypoint[SECTION_BODY][axis] = mr.position[axis] + mr.unit[axis] * (mr.r->head_length + mr.r->body_length); - mr.waypoint[SECTION_TAIL][axis] = mr.position[axis] + mr.unit[axis] * (mr.r->head_length + mr.r->body_length + mr.r->tail_length); + mr->waypoint[SECTION_HEAD][axis] = mr->position[axis] + mr->unit[axis] * mr->r->head_length; + mr->waypoint[SECTION_BODY][axis] = mr->position[axis] + mr->unit[axis] * (mr->r->head_length + mr->r->body_length); + mr->waypoint[SECTION_TAIL][axis] = mr->position[axis] + mr->unit[axis] * (mr->r->head_length + mr->r->body_length + mr->r->tail_length); } } @@ -552,9 +552,9 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (5) - decelerated to zero // Update the run buffer then force a replan of the whole planner queue if (cm->hold_state == FEEDHOLD_DECEL_END) { - mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - bf->length = get_axis_vector_length(mr.target, mr.position);// reset length + bf->length = get_axis_vector_length(mr->target, mr->position);// reset length //bf->entry_vmax = 0; // set bp+0 as hold point cm->hold_state = FEEDHOLD_PENDING; @@ -573,11 +573,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Cases (1a, 1b), Case (2), Case (4) // Build a tail-only move from here. Decelerate as fast as possible in the space we have. if ((cm->hold_state == FEEDHOLD_SYNC) || - ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr.block_state == BLOCK_INITIAL_ACTION))) { + ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { // Case (3a) - already decelerating, continue the deceleration. - if (mr.section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are - if (fp_ZERO(mr.r->exit_velocity)) { + if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are + if (fp_ZERO(mr->r->exit_velocity)) { cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; @@ -585,51 +585,51 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (3b) - currently accelerating - is simply skipped and waited for // Small exception, if we *just started* the head, then we're not actually accelerating yet. - } else if ((mr.section != SECTION_HEAD) || (mr.section_state == SECTION_NEW)) { - mr.entry_velocity = mr.segment_velocity; + } else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { + mr->entry_velocity = mr->segment_velocity; - mr.section = SECTION_TAIL; - mr.section_state = SECTION_NEW; + mr->section = SECTION_TAIL; + mr->section_state = SECTION_NEW; - mr.r->head_length = 0; - mr.r->body_length = 0; + mr->r->head_length = 0; + mr->r->body_length = 0; - float available_length = get_axis_vector_length(mr.target, mr.position); - mr.r->tail_length = mp_get_target_length(0, mr.r->cruise_velocity, bf); // braking length + float available_length = get_axis_vector_length(mr->target, mr->position); + mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length - if (fp_ZERO(available_length - mr.r->tail_length)) { // (1c) the deceleration time is almost exactly the remaining of the current move + if (fp_ZERO(available_length - mr->r->tail_length)) { // (1c) the deceleration time is almost exactly the remaining of the current move cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - mr.r->tail_length = available_length; - mr.r->exit_velocity = 0; + mr->r->tail_length = available_length; + mr->r->exit_velocity = 0; - } else if (available_length < mr.r->tail_length) { // (1b) the deceleration has to span multiple moves + } else if (available_length < mr->r->tail_length) { // (1b) the deceleration has to span multiple moves cm->hold_state = FEEDHOLD_DECEL_CONTINUE; - mr.r->tail_length = available_length; - mr.r->exit_velocity = mp_get_decel_velocity(mr.r->cruise_velocity, mr.r->tail_length, bf); + mr->r->tail_length = available_length; + mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); } else { // (1a)the deceleration will fit into the current move cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - mr.r->exit_velocity = 0; + mr->r->exit_velocity = 0; } - mr.r->tail_time = mr.r->tail_length*2 / (mr.r->exit_velocity + mr.r->cruise_velocity); + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); } } } - mr.block_state = BLOCK_ACTIVE; + mr->block_state = BLOCK_ACTIVE; // NB: from this point on the contents of the bf buffer do not affect execution //**** main dispatcher to process segments *** stat_t status = STAT_OK; - if (mr.section == SECTION_HEAD) { status = _exec_aline_head(bf);} - else if (mr.section == SECTION_BODY) { status = _exec_aline_body(bf);} - else if (mr.section == SECTION_TAIL) { status = _exec_aline_tail(bf);} + if (mr->section == SECTION_HEAD) { status = _exec_aline_head(bf);} + else if (mr->section == SECTION_BODY) { status = _exec_aline_body(bf);} + else if (mr->section == SECTION_TAIL) { status = _exec_aline_tail(bf);} else { return(cm_panic(STAT_INTERNAL_ERROR, "exec_aline()"));} // never supposed to get here // We can't use the if/else block above, since the head may call body, and body call tail, so we wait till after - if ((mr.section == SECTION_TAIL) // Once we're in the tail, we can't plan the block anymore - || ((mr.section == SECTION_BODY) && (mr.segment_count < 3))) { // or are too close to the end of the body + if ((mr->section == SECTION_TAIL) // Once we're in the tail, we can't plan the block anymore + || ((mr->section == SECTION_BODY) && (mr->segment_count < 3))) { // or are too close to the end of the body bf->plannable = false; } @@ -652,11 +652,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) sr_request_status_report(SR_REQUEST_TIMED); // continue reporting mr buffer // Note that tha'll happen in a lower interrupt level. } else { - mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) - mr.section_state = SECTION_OFF; + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) + mr->section_state = SECTION_OFF; mp->run_time_remaining = 0.0; // it's done, so time goes to zero - mr.entry_velocity = mr.r->exit_velocity; // feed the old exit into the entry. + mr->entry_velocity = mr->r->exit_velocity; // feed the old exit into the entry. if (bf->block_state == BLOCK_ACTIVE) { if (mp_free_run_buffer()) { // returns true of the buffer is empty @@ -836,7 +836,7 @@ static void _init_forward_diffs(const float v_0, const float v_1) // F = Vi - const float h = 1/(mr.segments); + const float h = 1/(mr->segments); const float h_2 = h * h; const float h_3 = h_2 * h; const float h_4 = h_3 * h; @@ -858,11 +858,11 @@ static void _init_forward_diffs(const float v_0, const float v_1) * F_1 = 120 A h^5 */ - mr.forward_diff_5 = const1*Ah_5 + 5.0*Bh_4 + const2*Ch_3; - mr.forward_diff_4 = const3*Ah_5 + 29.0*Bh_4 + 9.0*Ch_3; - mr.forward_diff_3 = 255.0*Ah_5 + 48.0*Bh_4 + 6.0*Ch_3; - mr.forward_diff_2 = 300.0*Ah_5 + 24.0*Bh_4; - mr.forward_diff_1 = 120.0*Ah_5; + mr->forward_diff_5 = const1*Ah_5 + 5.0*Bh_4 + const2*Ch_3; + mr->forward_diff_4 = const3*Ah_5 + 29.0*Bh_4 + 9.0*Ch_3; + mr->forward_diff_3 = 255.0*Ah_5 + 48.0*Bh_4 + 6.0*Ch_3; + mr->forward_diff_2 = 300.0*Ah_5 + 24.0*Bh_4; + mr->forward_diff_1 = 120.0*Ah_5; // Calculate the initial velocity by calculating V(h/2) const float half_h = h * 0.5; // h/2 @@ -874,7 +874,7 @@ static void _init_forward_diffs(const float v_0, const float v_1) const float half_Bh_4 = B * half_h_4; const float half_Ah_5 = A * half_h_5; - mr.segment_velocity = half_Ah_5 + half_Bh_4 + half_Ch_3 + v_0; + mr->segment_velocity = half_Ah_5 + half_Bh_4 + half_Ch_3 + v_0; } /********************************************************************************************* @@ -884,44 +884,44 @@ static void _init_forward_diffs(const float v_0, const float v_1) static stat_t _exec_aline_head(mpBuf_t *bf) { bool first_pass = false; - if (mr.section_state == SECTION_NEW) { // INITIALIZATION + if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; - if (fp_ZERO(mr.r->head_length)) { - mr.section = SECTION_BODY; + if (fp_ZERO(mr->r->head_length)) { + mr->section = SECTION_BODY; return(_exec_aline_body(bf)); // skip ahead to the body generator } - mr.segments = ceil(uSec(mr.r->head_time) / NOM_SEGMENT_USEC);// # of segments for the section - mr.segment_count = (uint32_t)mr.segments; - mr.segment_time = mr.r->head_time / mr.segments; // time to advance for each segment + mr->segments = ceil(uSec(mr->r->head_time) / NOM_SEGMENT_USEC);// # of segments for the section + mr->segment_count = (uint32_t)mr->segments; + mr->segment_time = mr->r->head_time / mr->segments; // time to advance for each segment - if (mr.segment_count == 1) { + if (mr->segment_count == 1) { // We will only have one segment, simply average the velocities - mr.segment_velocity = mr.r->head_length / mr.segment_time; + mr->segment_velocity = mr->r->head_length / mr->segment_time; } else { - _init_forward_diffs(mr.entry_velocity, mr.r->cruise_velocity); // <-- sets inital segment_velocity + _init_forward_diffs(mr->entry_velocity, mr->r->cruise_velocity); // <-- sets inital segment_velocity } - if (mr.segment_time < MIN_SEGMENT_TIME) { - _debug_trap("mr.segment_time < MIN_SEGMENT_TIME"); + if (mr->segment_time < MIN_SEGMENT_TIME) { + _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); return(STAT_OK); // exit without advancing position, say we're done } - mr.section = SECTION_HEAD; - mr.section_state = SECTION_RUNNING; + mr->section = SECTION_HEAD; + mr->section_state = SECTION_RUNNING; } else { - mr.segment_velocity += mr.forward_diff_5; + mr->segment_velocity += mr->forward_diff_5; } if (_exec_aline_segment() == STAT_OK) { // set up for second half - if ((fp_ZERO(mr.r->body_length)) && (fp_ZERO(mr.r->tail_length))) { + if ((fp_ZERO(mr->r->body_length)) && (fp_ZERO(mr->r->tail_length))) { return(STAT_OK); // ends the move } - mr.section = SECTION_BODY; - mr.section_state = SECTION_NEW; + mr->section = SECTION_BODY; + mr->section_state = SECTION_NEW; } else if (!first_pass) { - mr.forward_diff_5 += mr.forward_diff_4; - mr.forward_diff_4 += mr.forward_diff_3; - mr.forward_diff_3 += mr.forward_diff_2; - mr.forward_diff_2 += mr.forward_diff_1; + mr->forward_diff_5 += mr->forward_diff_4; + mr->forward_diff_4 += mr->forward_diff_3; + mr->forward_diff_3 += mr->forward_diff_2; + mr->forward_diff_2 += mr->forward_diff_1; } return(STAT_EAGAIN); } @@ -934,31 +934,31 @@ static stat_t _exec_aline_head(mpBuf_t *bf) */ static stat_t _exec_aline_body(mpBuf_t *bf) { - if (mr.section_state == SECTION_NEW) { - if (fp_ZERO(mr.r->body_length)) { - mr.section = SECTION_TAIL; + if (mr->section_state == SECTION_NEW) { + if (fp_ZERO(mr->r->body_length)) { + mr->section = SECTION_TAIL; return(_exec_aline_tail(bf)); // skip ahead to tail periods } - float body_time = mr.r->body_time; - mr.segments = ceil(uSec(body_time) / NOM_SEGMENT_USEC); - mr.segment_time = body_time / mr.segments; - mr.segment_velocity = mr.r->cruise_velocity; - mr.segment_count = (uint32_t)mr.segments; - if (mr.segment_time < MIN_SEGMENT_TIME) { - _debug_trap("mr.segment_time < MIN_SEGMENT_TIME"); + float body_time = mr->r->body_time; + mr->segments = ceil(uSec(body_time) / NOM_SEGMENT_USEC); + mr->segment_time = body_time / mr->segments; + mr->segment_velocity = mr->r->cruise_velocity; + mr->segment_count = (uint32_t)mr->segments; + if (mr->segment_time < MIN_SEGMENT_TIME) { + _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); return(STAT_OK); // exit without advancing position, say we're done } - mr.section = SECTION_BODY; - mr.section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works + mr->section = SECTION_BODY; + mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done - if (fp_ZERO(mr.r->tail_length)) { + if (fp_ZERO(mr->r->tail_length)) { return(STAT_OK); // ends the move } - mr.section = SECTION_TAIL; - mr.section_state = SECTION_NEW; + mr->section = SECTION_TAIL; + mr->section_state = SECTION_NEW; } return(STAT_EAGAIN); } @@ -970,40 +970,40 @@ static stat_t _exec_aline_body(mpBuf_t *bf) static stat_t _exec_aline_tail(mpBuf_t *bf) { bool first_pass = false; - if (mr.section_state == SECTION_NEW) { // INITIALIZATION + if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; // Mark the block as unplannable bf->plannable = false; - if (fp_ZERO(mr.r->tail_length)) { return(STAT_OK);} // end the move - mr.segments = ceil(uSec(mr.r->tail_time) / NOM_SEGMENT_USEC);// # of segments for the section - mr.segment_count = (uint32_t)mr.segments; - mr.segment_time = mr.r->tail_time / mr.segments; // time to advance for each segment + if (fp_ZERO(mr->r->tail_length)) { return(STAT_OK);} // end the move + mr->segments = ceil(uSec(mr->r->tail_time) / NOM_SEGMENT_USEC);// # of segments for the section + mr->segment_count = (uint32_t)mr->segments; + mr->segment_time = mr->r->tail_time / mr->segments; // time to advance for each segment - if (mr.segment_count == 1) { - mr.segment_velocity = mr.r->tail_length / mr.segment_time; + if (mr->segment_count == 1) { + mr->segment_velocity = mr->r->tail_length / mr->segment_time; } else { - _init_forward_diffs(mr.r->cruise_velocity, mr.r->exit_velocity); // <-- sets inital segment_velocity + _init_forward_diffs(mr->r->cruise_velocity, mr->r->exit_velocity); // <-- sets inital segment_velocity } - if (mr.segment_time < MIN_SEGMENT_TIME) { - _debug_trap("mr.segment_time < MIN_SEGMENT_TIME"); + if (mr->segment_time < MIN_SEGMENT_TIME) { + _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); return(STAT_OK); // exit without advancing position, say we're done // return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position } - mr.section = SECTION_TAIL; - mr.section_state = SECTION_RUNNING; + mr->section = SECTION_TAIL; + mr->section_state = SECTION_RUNNING; } else { - mr.segment_velocity += mr.forward_diff_5; + mr->segment_velocity += mr->forward_diff_5; } if (_exec_aline_segment() == STAT_OK) { return(STAT_OK); // STAT_OK completes the move } else if (!first_pass) { - mr.forward_diff_5 += mr.forward_diff_4; - mr.forward_diff_4 += mr.forward_diff_3; - mr.forward_diff_3 += mr.forward_diff_2; - mr.forward_diff_2 += mr.forward_diff_1; + mr->forward_diff_5 += mr->forward_diff_4; + mr->forward_diff_4 += mr->forward_diff_3; + mr->forward_diff_3 += mr->forward_diff_2; + mr->forward_diff_2 += mr->forward_diff_1; } return(STAT_EAGAIN); } @@ -1037,20 +1037,20 @@ static stat_t _exec_aline_segment() // Otherwise if not at a section waypoint compute target from segment time and velocity // Don't do waypoint correction if you are going into a hold. - if ((--mr.segment_count == 0) && (cm->motion_state != MOTION_HOLD)) { - copy_vector(mr.gm.target, mr.waypoint[mr.section]); + if ((--mr->segment_count == 0) && (cm->motion_state != MOTION_HOLD)) { + copy_vector(mr->gm.target, mr->waypoint[mr->section]); } else { - float segment_length = mr.segment_velocity * mr.segment_time; + float segment_length = mr->segment_velocity * mr->segment_time; // see https://en.wikipedia.org/wiki/Kahan_summation_algorithm // for the summation compensation description for (uint8_t a=0; aunit[a] * segment_length) - mr->gm.target_comp[a]; + float target = mr->position[a] + to_add; + mr->gm.target_comp[a] = (target - mr->position[a]) - to_add; + mr->gm.target[a] = target; #else - mr.gm.target[a] = mr.position[a] + (mr.unit[a] * segment_length); + mr->gm.target[a] = mr->position[a] + (mr->unit[a] * segment_length); #endif } } @@ -1063,26 +1063,26 @@ static stat_t _exec_aline_segment() for (uint8_t m=0; mcommanded_steps[m] = mr->position_steps[m]; // previous segment's position, delayed by 1 segment + mr->position_steps[m] = mr->target_steps[m]; // previous segment's target becomes position + mr->encoder_steps[m] = en_read_encoder(m); // get current encoder position (time aligns to commanded_steps) + mr->following_error[m] = mr->encoder_steps[m] - mr->commanded_steps[m]; } - kn_inverse_kinematics(mr.gm.target, mr.target_steps); // now determine the target steps... + kn_inverse_kinematics(mr->gm.target, mr->target_steps); // now determine the target steps... for (uint8_t m=0; mtarget_steps[m] - mr->position_steps[m]; } // Update the mb->run_time_remaining -- we know it's missing the current segment's time before it's loaded, that's ok. - mp->run_time_remaining -= mr.segment_time; + mp->run_time_remaining -= mr->segment_time; if (mp->run_time_remaining < 0) { mp->run_time_remaining = 0.0; } // Call the stepper prep function - ritorno(st_prep_line(travel_steps, mr.following_error, mr.segment_time)); - copy_vector(mr.position, mr.gm.target); // update position from target - if (mr.segment_count == 0) { + ritorno(st_prep_line(travel_steps, mr->following_error, mr->segment_time)); + copy_vector(mr->position, mr->gm.target); // update position from target + if (mr->segment_count == 0) { return (STAT_OK); // this section has run all its segments } return (STAT_EAGAIN); // this section still has more segments to run diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 12a58d05..8b38bc04 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -74,10 +74,10 @@ static void _set_bf_diagnostics(mpBuf_t* bf) { * that were in effect at move planning time */ -void mp_zero_segment_velocity() { mr.segment_velocity = 0; } -float mp_get_runtime_velocity(void) { return (mr.segment_velocity); } -float mp_get_runtime_absolute_position(uint8_t axis) { return (mr.position[axis]); } -void mp_set_runtime_work_offset(float offset[]) { copy_vector(mr.gm.work_offset, offset); } +void mp_zero_segment_velocity() { mr->segment_velocity = 0; } +float mp_get_runtime_velocity(void) { return (mr->segment_velocity); } +float mp_get_runtime_absolute_position(uint8_t axis) { return (mr->position[axis]); } +void mp_set_runtime_work_offset(float offset[]) { copy_vector(mr->gm.work_offset, offset); } // We have to handle rotation - "rotate" by the transverse of the matrix to got "normal" coordinates float mp_get_runtime_work_position(uint8_t axis) { @@ -87,17 +87,17 @@ float mp_get_runtime_work_position(uint8_t axis) { // target_rotated[2] = a z_1 + b z_2 + c z_3 + z_offset if (axis == AXIS_X) { - return mr.position[0] * cm->rotation_matrix[0][0] + mr.position[1] * cm->rotation_matrix[1][0] + - mr.position[2] * cm->rotation_matrix[2][0] - mr.gm.work_offset[0]; + return mr->position[0] * cm->rotation_matrix[0][0] + mr->position[1] * cm->rotation_matrix[1][0] + + mr->position[2] * cm->rotation_matrix[2][0] - mr->gm.work_offset[0]; } else if (axis == AXIS_Y) { - return mr.position[0] * cm->rotation_matrix[0][1] + mr.position[1] * cm->rotation_matrix[1][1] + - mr.position[2] * cm->rotation_matrix[2][1] - mr.gm.work_offset[1]; + return mr->position[0] * cm->rotation_matrix[0][1] + mr->position[1] * cm->rotation_matrix[1][1] + + mr->position[2] * cm->rotation_matrix[2][1] - mr->gm.work_offset[1]; } else if (axis == AXIS_Z) { - return mr.position[0] * cm->rotation_matrix[0][2] + mr.position[1] * cm->rotation_matrix[1][2] + - mr.position[2] * cm->rotation_matrix[2][2] - cm->rotation_z_offset - mr.gm.work_offset[2]; + return mr->position[0] * cm->rotation_matrix[0][2] + mr->position[1] * cm->rotation_matrix[1][2] + + mr->position[2] * cm->rotation_matrix[2][2] - cm->rotation_z_offset - mr->gm.work_offset[2]; } else { // ABC, UVW, we don't rotate them - return (mr.position[axis] - mr.gm.work_offset[axis]); + return (mr->position[axis] - mr->gm.work_offset[axis]); } } @@ -114,7 +114,7 @@ bool mp_get_runtime_busy() return (false); } if ((st_runtime_isbusy() == true) || - (mr.block_state == BLOCK_ACTIVE) || + (mr->block_state == BLOCK_ACTIVE) || (mp_get_r()->buffer_state > MP_BUFFER_EMPTY)) { return (true); } diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 4c0a1830..577e8752 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -164,7 +164,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent // Here we verify it moving forward, checking to make sure it still is true. // If so, we plan the "ramp" as flat, body-only. if (bf->hint == PERFECT_CRUISE) { - if ((!mp.entry_changed) && fp_EQ(entry_velocity, bf->cruise_vmax)) { + if ((!mp->entry_changed) && fp_EQ(entry_velocity, bf->cruise_vmax)) { // We need to ensure that neither the entry or the exit velocities are // <= the cruise velocity even though there is tolerance in fp_EQ comparison. block->exit_velocity = entry_velocity; @@ -186,7 +186,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent // Quick test to ensure we haven't violated the hint if (entry_velocity > block->exit_velocity) { // We're in a deceleration. - if (mp.entry_changed) { + if (mp->entry_changed) { // If entry_changed, then entry_velocity is lower than the hints expect. // A deceleration will never become an acceleration (post-hinting). // If it is marked as MIXED_DECELERATION, it means the entry was CRUISE_VMAX. @@ -226,7 +226,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent // Reset entry_changed. We won't likely be changing the next block's entry velocity. - mp.entry_changed = false; + mp->entry_changed = false; // Since we are not generally decelerating, this is effectively all of forward planning that we need. @@ -244,7 +244,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent if (accel_velocity < block->exit_velocity) { // still accelerating - mp.entry_changed = true; // we are changing the *next* block's entry velocity + mp->entry_changed = true; // we are changing the *next* block's entry velocity block->exit_velocity = accel_velocity; block->cruise_velocity = accel_velocity; @@ -260,7 +260,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent return (_zoid_exit(bf, ZOID_EXIT_1a)); } else { // it's hit the cusp - mp.entry_changed = false; // we are NOT changing the next block's entry velocity + mp->entry_changed = false; // we are NOT changing the next block's entry velocity block->cruise_velocity = bf->cruise_vmax; diff --git a/g2core/planner.cpp b/g2core/planner.cpp index d1ec21f3..83f6b033 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -65,19 +65,18 @@ #include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures -//mpPlannerQueue_t mb; // buffer pool management -mpPlanner_t *mp; // currently active planner (global variable) -mpPlanner_t mp0; // primary planning context -mpPlanner_t mp1; // secondary planning context + +mpPlanner_t *mp; // currently active planner (global variable) +mpPlanner_t mp0; // primary planning context +mpPlanner_t mp1; // secondary planning context + +mpPlannerRuntime_t *mr; // context for planner block runtime +mpPlannerRuntime_t mr0; // runtime context for primary planner +mpPlannerRuntime_t mr1; // runtime context for secondary planner + mpBuf_t mp0_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers mpBuf_t mp1_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers -//mpMotionPlannerHead_t *mp; // pointer to motion planner -//mpMotionPlannerHead_t mp0; // primary motion planner -//mpMotionPlannerHead_t mp1; // secondary motion planner -mpMotionRuntimeSingleton_t mr; // context for block runtime - - #define JSON_COMMAND_BUFFER_SIZE 3 struct json_command_buffer_t { @@ -152,7 +151,6 @@ void _init_planner_queue(mpPlanner_t *mpl, mpBuf_t *pool, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; -// mpQueue_t *b = &mb.q[q]; mpPlannerQueue_t *q = &(mpl->q); memset(q, 0, sizeof(mpPlannerQueue_t)); // clear values, pointers and status @@ -178,58 +176,46 @@ void _init_planner_queue(mpPlanner_t *mpl, mpBuf_t *pool, uint8_t size) q->bf[size-1].nx = pool; } -void planner_init(mpPlanner_t *mpl) +void planner_init(mpPlanner_t *mpl, mpBuf_t *pool, mpPlannerRuntime_t *mrl) { -// If you know all memory has been zeroed by a hard reset you don't need these next 2 lines - memset(&mp, 0, sizeof(mp)); // clear all values, pointers and status -// memset(&mr, 0, sizeof(mr)); // clear all values, pointers and status + mp = &mp0; // set global pointer to the primary planner + mr = &mr0; // and primary runtime - mp = &mp0; // install the primary planner - _init_planner_queue(mp, mp0_pool, PLANNER_BUFFER_POOL_SIZE); - - planner_init_assertions(mpl); - + // init planner master structure + memset(mpl, 0, sizeof(mpPlanner_t));// clear all values, pointers and status + mpl->magic_start = MAGICNUM; // set boundary condition assertions + mpl->magic_end = MAGICNUM; mpl->mfo_factor = 1.00; - -// mr.bf[0].nx = &mr.bf[1]; // Handle the two "stub blocks" in the runtime structure. -// mr.bf[1].nx = &mr.bf[0]; -// mr.r = &mr.bf[0]; -// mr.p = &mr.bf[1]; + + // init planner queues + mpl->q.bf = pool; // assign puffer pool to queue manager structure + _init_planner_queue(mpl, pool, PLANNER_BUFFER_POOL_SIZE); + + // init runtime structs + mpl->mr = mrl; + memset(mrl, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status + mrl->bf[0].nx = &mrl->bf[1]; // Handle the two "stub blocks" in the runtime structure. + mrl->bf[1].nx = &mrl->bf[0]; + mrl->r = &mrl->bf[0]; + mrl->p = &mrl->bf[1]; + mpl->mr->magic_start = MAGICNUM; // assertions + mpl->mr->magic_end = MAGICNUM; } void planner_reset(mpPlanner_t *mpl) { - planner_init(mpl); -} - -void runtime_init() { - memset(&mr, 0, sizeof(mr)); // clear all values, pointers and status - - mr.bf[0].nx = &mr.bf[1]; // Handle the two "stub blocks" in the runtime structure. - mr.bf[1].nx = &mr.bf[0]; - mr.r = &mr.bf[0]; - mr.p = &mr.bf[1]; + planner_init(mpl, mpl->q.bf, mpl->mr); // reset parent planner and linked Q and MR } /* - * planner_init_assertions() * planner_test_assertions() - test assertions, PANIC if violation exists */ -void planner_init_assertions(mpPlanner_t *mpl) -{ - // Note: mb magic numbers set up by mp_init_buffers() - mpl->magic_start = MAGICNUM; - mpl->magic_end = MAGICNUM; - mr.magic_start = MAGICNUM; - mr.magic_end = MAGICNUM; -} - stat_t planner_test_assertions(mpPlanner_t *mpl) { if ( - (BAD_MAGIC(mpl->magic_start)) || (BAD_MAGIC(mpl->magic_end)) || - (BAD_MAGIC(mr.magic_start)) || (BAD_MAGIC(mr.magic_end)) + (BAD_MAGIC(mpl->magic_start)) || (BAD_MAGIC(mpl->magic_end)) || + (BAD_MAGIC(mpl->mr->magic_start)) || (BAD_MAGIC(mpl->mr->magic_end)) ) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } @@ -256,7 +242,7 @@ void mp_halt_runtime() /* * mp_flush_planner() - flush all moves in the planner and all arcs * - * Does not affect the move currently running in mr. + * Does not affect the move currently running in mr-> * Does not affect mm or gm model positions * This function is designed to be called during a hold to reset the planner * This function should not generally be called; call cm_queue_flush() instead @@ -265,8 +251,9 @@ void mp_flush_planner(mpPlanner_t *mpl) { cm_abort_arc(); // mp_init_planner_buffers(mpl); //+++++ - planner_init(mpl); - mr.block_state = BLOCK_INACTIVE; // invalidate mr buffer to prevent subsequent motion +// planner_init(mpl); //+++++ + planner_reset(mpl); + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to prevent subsequent motion } /* @@ -282,9 +269,9 @@ void mp_flush_planner(mpPlanner_t *mpl) * Keeping track of position is complicated by the fact that moves exist in several reference * frames. The scheme to keep this straight is: * - * - mm.position - start and end position for planning - * - mr.position - current position of runtime segment - * - mr.target - target position of runtime segment + * - mp->position - start and end position for planning + * - mr->position - current position of runtime segment + * - mr->target - target position of runtime segment * * The runtime keeps a lot more data, such as waypoints, step vectors, etc. * See struct mpMoveRuntimeSingleton for details. @@ -295,21 +282,21 @@ void mp_flush_planner(mpPlanner_t *mpl) */ void mp_set_planner_position(uint8_t axis, const float position) { mp->position[axis] = position; } //+++++ -void mp_set_runtime_position(uint8_t axis, const float position) { mr.position[axis] = position; } +void mp_set_runtime_position(uint8_t axis, const float position) { mr->position[axis] = position; } void mp_set_steps_to_runtime_position() { float step_position[MOTORS]; - kn_inverse_kinematics(mr.position, step_position); // convert lengths to steps in floating point + kn_inverse_kinematics(mr->position, step_position); // convert lengths to steps in floating point for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { - mr.target_steps[motor] = step_position[motor]; - mr.position_steps[motor] = step_position[motor]; - mr.commanded_steps[motor] = step_position[motor]; + mr->target_steps[motor] = step_position[motor]; + mr->position_steps[motor] = step_position[motor]; + mr->commanded_steps[motor] = step_position[motor]; en_set_encoder_steps(motor, step_position[motor]); // write steps to encoder register - mr.encoder_steps[motor] = en_read_encoder(motor); + mr->encoder_steps[motor] = en_read_encoder(motor); // These must be zero: - mr.following_error[motor] = 0; + mr->following_error[motor] = 0; st_pre.mot[motor].corrected_steps = 0; } } @@ -485,12 +472,12 @@ static stat_t _exec_dwell(mpBuf_t *bf) //++++ stubbed ++++ void mp_request_out_of_band_dwell(float seconds) { -// mr.out_of_band_dwell_time = seconds; +// mr->out_of_band_dwell_time = seconds; } //++++ stubbed ++++ stat_t mp_exec_out_of_band_dwell(void) { -// return _advance_dwell(mr.out_of_band_dwell_time); +// return _advance_dwell(mr->out_of_band_dwell_time); return 0; } @@ -783,19 +770,6 @@ static inline void _clear_buffer(mpBuf_t *bf) bf->reset(); // Call a reset method on the buffer object. } // We'll need something else for C - like bring the method code back into this function. -/* -void mp_init_planner_buffers(void) -{ -// _init_planner_queue(0, mb_pool0, PLANNER_BUFFER_POOL_SIZE); -// _init_planner_queue(1, mb_pool1, SECONDARY_BUFFER_POOL_SIZE); - -// mr.bf[0].nx = &mr.bf[1]; // Now handle the two "stub blocks" in the runtime structure. -// mr.bf[1].nx = &mr.bf[0]; -// mr.r = &mr.bf[0]; -// mr.p = &mr.bf[1]; - } -*/ - /* * These GET functions are defined here but we use the macros in planner.h instead mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); } diff --git a/g2core/planner.h b/g2core/planner.h index 4c15ef8a..03c54643 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -309,68 +309,69 @@ typedef enum { * - plan_zoid.cpp / mp_calculate_ramps() * - plan_exec.cpp / mp_exec_aline() */ + +//**** Planner Queue Structures **** + typedef struct mpBuffer { // *** CAUTION *** These two pointers are not reset by _clear_buffer() - struct mpBuffer *pv; // static pointer to previous buffer - struct mpBuffer *nx; // static pointer to next buffer - uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging + struct mpBuffer *pv; // static pointer to previous buffer + struct mpBuffer *nx; // static pointer to next buffer + uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function - cm_exec_t cm_func; // callback to canonical machine execution function + cm_exec_t cm_func; // callback to canonical machine execution function //+++++ DIAGNOSTICS for easier debugging - uint32_t linenum; // mirror of bf->gm.linenum + uint32_t linenum; // mirror of bf->gm.linenum int iterations; float block_time_ms; - float plannable_time_ms; // time in planner - float plannable_length; // length in planner - uint8_t meet_iterations; // iterations needed in _get_meet_velocity + float plannable_time_ms; // time in planner + float plannable_length; // length in planner + uint8_t meet_iterations; // iterations needed in _get_meet_velocity //+++++ to here - bufferState buffer_state; // used to manage queuing/dequeuing - blockType block_type; // used to dispatch to run routine - blockState block_state; // move state machine sequence - blockHint hint; // hint the block for zoid and other planning operations. Must be accurate or NO_HINT + bufferState buffer_state; // used to manage queuing/dequeuing + blockType block_type; // used to dispatch to run routine + blockState block_state; // move state machine sequence + blockHint hint; // hint the block for zoid and other planning operations. Must be accurate or NO_HINT // block parameters - float unit[AXES]; // unit vector for axis scaling & planning - bool axis_flags[AXES]; // set true for axes participating in the move & for command parameters + float unit[AXES]; // unit vector for axis scaling & planning + bool axis_flags[AXES]; // set true for axes participating in the move & for command parameters - bool plannable; // set true when this block can be used for planning + bool plannable; // set true when this block can be used for planning - float length; // total length of line or helix in mm - float block_time; // computed move time for entire block (move) - float override_factor; // feed rate or rapid override factor for this block ("override" is a reserved word) + float length; // total length of line or helix in mm + float block_time; // computed move time for entire block (move) + float override_factor; // feed rate or rapid override factor for this block ("override" is a reserved word) // *** SEE NOTES ON THESE VARIABLES, in aline() *** // We removed all entry_* values. - // To get the entry_* values, look at pv->exit_* or mr.exit_* - float cruise_velocity; // cruise velocity requested & achieved - float exit_velocity; // exit velocity requested for the move + // To get the entry_* values, look at pv->exit_* or mr->exit_* + float cruise_velocity; // cruise velocity requested & achieved + float exit_velocity; // exit velocity requested for the move // is also the entry velocity of the *next* move - float cruise_vset; // cruise velocity requested for move - prior to overrides - float cruise_vmax; // cruise max velocity adjusted for overrides - float exit_vmax; // max exit velocity possible for this move + float cruise_vset; // cruise velocity requested for move - prior to overrides + float cruise_vmax; // cruise max velocity adjusted for overrides + float exit_vmax; // max exit velocity possible for this move // is also the maximum entry velocity of the next move - float absolute_vmax; // fastest this block can move w/o exceeding constraints - float junction_vmax; // maximum the exit velocity can be to go through the junction + float absolute_vmax; // fastest this block can move w/o exceeding constraints + float junction_vmax; // maximum the exit velocity can be to go through the junction // between the NEXT BLOCK AND THIS ONE - float jerk; // maximum linear jerk term for this move - float jerk_sq; // Jm^2 is used for planning (computed and cached) - float recip_jerk; // 1/Jm used for planning (computed and cached) - float sqrt_j; // sqrt(jM) used for planning (computed and cached) - float q_recip_2_sqrt_j; // (q/(2 sqrt(jM))) where q = (sqrt(10)/(3^(1/4))), used in length computations (computed and cached) + float jerk; // maximum linear jerk term for this move + float jerk_sq; // Jm^2 is used for planning (computed and cached) + float recip_jerk; // 1/Jm used for planning (computed and cached) + float sqrt_j; // sqrt(jM) used for planning (computed and cached) + float q_recip_2_sqrt_j; // (q/(2 sqrt(jM))) where q = (sqrt(10)/(3^(1/4))), used in length computations (computed and cached) - GCodeState_t gm; // Gcode model state - passed from model, used by planner and runtime + GCodeState_t gm; // Gcode model state - passed from model, used by planner and runtime // clears the above structure void reset() { - //memset((void *)(this), 0, sizeof(mpBuffer_to_clear)); // slower on the M3. Test for M7 - bf_func = nullptr; cm_func = nullptr; @@ -409,85 +410,37 @@ typedef struct mpBuffer { q_recip_2_sqrt_j = 0.0; gm.reset(); } - } mpBuf_t; -typedef struct mpPlannerQueue { // control structure for queue - magic_t magic_start; // magic number to test memory integrity - mpBuf_t *r; // run buffer pointer - mpBuf_t *w; // write buffer pointer - uint8_t queue_size; // total number of buffers, zero-based (e.g. 47 not 48) - uint8_t buffers_available; // running count of available buffers in queue - mpBuf_t *bf; // pointer to buffer storage array +typedef struct mpPlannerQueue { // control structure for queue + magic_t magic_start; // magic number to test memory integrity + mpBuf_t *r; // run buffer pointer + mpBuf_t *w; // write buffer pointer + uint8_t queue_size; // total number of buffers, zero-based (e.g. 47 not 48) + uint8_t buffers_available; // running count of available buffers in queue + mpBuf_t *bf; // pointer to buffer pool (storage array) magic_t magic_end; } mpPlannerQueue_t; -/* -typedef struct mpBufferQueue { // one or more planner buffer queues - uint8_t active_q; // index of currently active queue - uint8_t return_q; // index of queue to return to - mpQueue_t q[2]; // number of queues -} mpBufferQueue_t; -*/ +//**** Planner Runtime structures **** -typedef struct mpPlanner { // common variables for a planner context - magic_t magic_start; // magic number to test memory integrity +typedef struct mpBlockRuntimeBuf { // Data structure for just the parts of RunTime that we need to plan a BLOCK + struct mpBlockRuntimeBuf *nx; // singly-linked-list - //+++++ DIAGNOSTICS - float run_time_remaining_ms; - float plannable_time_ms; - - // planner position - float position[AXES]; // final move position for planning purposes - - // timing variables - float run_time_remaining; // time left in runtime (including running block) - float plannable_time; // time in planner that can actually be planned - - // planner state variables - plannerState planner_state; // current state of planner - bool request_planning; // set true to request backplanning - bool backplanning; // true if planner is in a back-planning pass - bool mfo_active; // true if mfo override is in effect - bool ramp_active; // true when a ramp is occurring - bool entry_changed; // mark if exit_velocity changed to invalidate next block's hint - - // feed overrides and ramp variables (these extend the variables in cm->gmx) - float mfo_factor; // runtime override factor - float ramp_target; - float ramp_dvdt; - - // objects - Timeout block_timeout; // Timeout object for block planning - - // planner pointers - mpBuf_t *p; // planner buffer pointer - mpBuf_t *c; // pointer to buffer immediately following critical region - mpBuf_t *planning_return; // buffer to return to once back-planning is complete - - // queue manager - mpPlannerQueue_t q; // embed a planner buffer queue manager - - magic_t magic_end; -} mpPlanner_t; - -typedef struct mpBlockRuntimeBuf { // Data structure for just the parts of RunTime that we need to plan a BLOCK - struct mpBlockRuntimeBuf *nx; // singly-linked-list - - float head_length; // copies of bf variables of same name + float head_length; // copies of bf variables of same name float body_length; float tail_length; - float head_time; // copies of bf variables of same name + float head_time; // copies of bf variables of same name float body_time; float tail_time; - float cruise_velocity; // velocity at the end of the head and the beginning of the tail - float exit_velocity; // velocity at the end of the move + float cruise_velocity; // velocity at the end of the head and the beginning of the tail + float exit_velocity; // velocity at the end of the move } mpBlockRuntimeBuf_t; -typedef struct mpMotionRuntimeSingleton { // persistent runtime variables -// uint8_t (*run_move)(struct mpMoveRuntimeSingleton *m); // currently running move - left in for reference +typedef struct mpPlannerRuntime { // persistent runtime variables + // uint8_t (*run_move)(struct mpMoveRuntimeSingleton *m); // currently running move - left in for reference magic_t magic_start; // magic number to test memory integrity blockState block_state; // state of the overall move moveSection section; // what section is the move in? @@ -525,10 +478,55 @@ typedef struct mpMotionRuntimeSingleton { // persistent runtime variables GCodeState_t gm; // gcode model state currently executing magic_t magic_end; -} mpMotionRuntimeSingleton_t; +} mpPlannerRuntime_t; + +//**** Master Planner Structure *** + +typedef struct mpPlanner { // common variables for a planner context + magic_t magic_start; // magic number to test memory integrity + + //+++++ DIAGNOSTICS + float run_time_remaining_ms; + float plannable_time_ms; + + // planner position + float position[AXES]; // final move position for planning purposes + + // timing variables + float run_time_remaining; // time left in runtime (including running block) + float plannable_time; // time in planner that can actually be planned + + // planner state variables + plannerState planner_state; // current state of planner + bool request_planning; // set true to request backplanning + bool backplanning; // true if planner is in a back-planning pass + bool mfo_active; // true if mfo override is in effect + bool ramp_active; // true when a ramp is occurring + bool entry_changed; // mark if exit_velocity changed to invalidate next block's hint + + // feed overrides and ramp variables (these extend the variables in cm->gmx) + float mfo_factor; // runtime override factor + float ramp_target; + float ramp_dvdt; + + // objects + Timeout block_timeout; // Timeout object for block planning + + // planner pointers + mpBuf_t *p; // planner buffer pointer + mpBuf_t *c; // pointer to buffer immediately following critical region + mpBuf_t *planning_return; // buffer to return to once back-planning is complete + + // planner queue manager + mpPlannerQueue_t q; // embed a planner buffer queue manager + + // planner runtime + mpPlannerRuntime_t *mr; // bind to mr associated with this planner + + magic_t magic_end; +} mpPlanner_t; // Reference global scope structures -//extern mpPlannerQueue_t mb; // planner buffer queue management extern mpPlanner_t *mp; // currently active planner (global variable) extern mpPlanner_t mp0; // primary planning context @@ -536,7 +534,9 @@ extern mpPlanner_t mp1; // secondary planning co extern mpBuf_t mp0_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers extern mpBuf_t mp1_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers -extern mpMotionRuntimeSingleton_t mr; // context for block runtime +extern mpPlannerRuntime_t *mr; // context for block runtime +extern mpPlannerRuntime_t mr0; // runtime context for primary planner +extern mpPlannerRuntime_t mr1; // runtime context for secondary planner /* * Global Scope Functions @@ -544,11 +544,9 @@ extern mpMotionRuntimeSingleton_t mr; // context for block runtime //planner.cpp functions -void planner_init(mpPlanner_t *mpl); +void planner_init(mpPlanner_t *mpl, mpBuf_t *pool, mpPlannerRuntime_t *mrl); void planner_reset(mpPlanner_t *mpl); -void planner_init_assertions(mpPlanner_t *mpl); stat_t planner_test_assertions(mpPlanner_t *mpl); -void runtime_init(void); void mp_halt_runtime(void); void mp_flush_planner(mpPlanner_t *mpl); From 53d8af3b9f1ae7ea9efd97a337fcedc9d3e8026d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 10 Jan 2017 11:16:46 -0500 Subject: [PATCH 056/283] Fixed queue size error; update local variable naming --- g2core/canonical_machine.cpp | 15 ++-- g2core/canonical_machine.h | 4 +- g2core/controller.cpp | 6 +- .../device/step_dir_driver/step_dir_driver.h | 10 +-- g2core/main.cpp | 14 +-- g2core/planner.cpp | 88 +++++++++---------- g2core/planner.h | 45 +++++----- g2core/stepper.cpp | 11 ++- g2core/stepper.h | 4 +- 9 files changed, 99 insertions(+), 98 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ae57f2dd..ecfa0264 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -114,8 +114,8 @@ ***********************************************************************************/ cmMachine_t *cm; // pointer to active canonical machine -cmMachine_t cm0; // canonical machine primary machine -cmMachine_t cm1; // canonical machine secondary machine +cmMachine_t cm1; // canonical machine primary machine +cmMachine_t cm2; // canonical machine secondary machine cmToolTable_t tt; // global tool table /*********************************************************************************** @@ -724,13 +724,13 @@ stat_t cm_test_soft_limits(const float target[]) void canonical_machine_init(cmMachine_t *m) { - // NoteL cm* was assignd in main() + // Note cm* was assignd in main() // If you can assume all memory has been zeroed by a hard reset you don't need this code: memset(m, 0, sizeof(cmMachine_t)); // do not reset canonicalMachine once it's been initialized - memset(&m->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status +// memset(&m->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status - memset(&gc.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs - memset(&gc.gf, 0, sizeof(GCodeFlags_t)); +// memset(&gc.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs +// memset(&gc.gf, 0, sizeof(GCodeFlags_t)); canonical_machine_init_assertions(m); // establish assertions ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer @@ -739,6 +739,9 @@ void canonical_machine_init(cmMachine_t *m) void canonical_machine_reset(cmMachine_t *m) { + // reset canonical machine assertions + canonical_machine_init_assertions(m); + // set gcode defaults cm_set_units_mode(gc.default_units_mode); cm_set_coord_system(gc.default_coord_system); // NB: queues a block to the planner with the coordinates diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 4f56c927..24c1da8d 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -278,8 +278,8 @@ typedef struct cmToolTable { // struct to keep a global tool tabl /**** Externs - See canonical_machine.cpp for allocation ****/ extern cmMachine_t *cm; // pointer to active canonical machine -extern cmMachine_t cm0; // canonical machine primary machine -extern cmMachine_t cm1; // canonical machine secondary machine +extern cmMachine_t cm1; // canonical machine primary machine +extern cmMachine_t cm2; // canonical machine secondary machine extern cmToolTable_t tt; /***************************************************************************** diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 097bb099..cdae6602 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -475,8 +475,10 @@ stat_t _test_system_assertions() // these functions will panic if an assertion fails _test_assertions(); // controller assertions (local) config_test_assertions(); - canonical_machine_test_assertions(&cm0); // +++++ cleanup later - planner_test_assertions(&mp0); // +++++ cleanup later + canonical_machine_test_assertions(&cm1); // +++++ cleanup later +// canonical_machine_test_assertions(&cm2); // +++++ cleanup later + planner_test_assertions(&mp1); // +++++ cleanup later +// planner_test_assertions(&mp2); // +++++ cleanup later stepper_test_assertions(); encoder_test_assertions(); xio_test_assertions(); diff --git a/g2core/device/step_dir_driver/step_dir_driver.h b/g2core/device/step_dir_driver/step_dir_driver.h index da3cfc1e..1d0ccd28 100644 --- a/g2core/device/step_dir_driver/step_dir_driver.h +++ b/g2core/device/step_dir_driver/step_dir_driver.h @@ -2,8 +2,8 @@ * step_dir_driver.cpp - control over a Step/Direction/Enable stepper motor driver * This file is part of G2 project * - * Copyright (c) 2016 Alden S. Hart, Jr. - * Copyright (c) 2016 Robert Giseburt + * Copyright (c) 2016 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -25,8 +25,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef STEPP_DIR_DRIVER_H_ONCE -#define STEPP_DIR_DRIVER_H_ONCE +#ifndef STEP_DIR_DRIVER_H_ONCE +#define STEP_DIR_DRIVER_H_ONCE #include "MotatePins.h" #include "MotateTimers.h" @@ -146,4 +146,4 @@ struct StepDirStepper final : Stepper { }; }; -#endif // STEPP_DIR_DRIVER_H_ONCE +#endif // STEP_DIR_DRIVER_H_ONCE diff --git a/g2core/main.cpp b/g2core/main.cpp index f6858f31..f48c9df7 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -101,17 +101,17 @@ void application_init_services(void) void application_init_machine(void) { - cm = &cm0; // set global canonical machine pointer to primary machine + cm = &cm1; // set global canonical machine pointer to primary machine cm->machine_state = MACHINE_INITIALIZING; stepper_init(); // stepper subsystem encoder_init(); // virtual encoders gpio_init(); // inputs and outputs pwm_init(); // pulse width modulation drivers - planner_init(&mp0, mp0_pool, &mr0); //+++++ //primary motion planner -// planner_init(&mp1, mp1_pool, &mr1); //+++++ //secondary motion planner - canonical_machine_init(&cm0); //+++++ cleanup required // canonical machine -// canonical_machine_init(&cm1); //+++++ cleanup required // canonical machine + planner_init(&mp1, &mr1, mp1_pool, PLANNER_BUFFER_POOL_SIZE); // primary motion planner + planner_init(&mp2, &mr2, mp2_pool, SECONDARY_BUFFER_POOL_SIZE); // secondary motion planner + canonical_machine_init(&cm1); // primary canonical machine +// canonical_machine_init(&cm2); // secondary canonical machine } void application_init_startup(void) @@ -119,8 +119,8 @@ void application_init_startup(void) // start the application controller_init(); // should be first startup init (requires xio_init()) config_init(); // apply the config settings from persistence - canonical_machine_reset(&cm0); // +++++ -// canonical_machine_reset(&cm1); // +++++ + canonical_machine_reset(&cm1); +// canonical_machine_reset(&cm2); spindle_init(); // should be after PWM and canonical machine inits and config_init() spindle_reset(); temperature_init(); diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 83f6b033..da61dd42 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -67,15 +67,15 @@ // Allocate planner structures mpPlanner_t *mp; // currently active planner (global variable) -mpPlanner_t mp0; // primary planning context -mpPlanner_t mp1; // secondary planning context +mpPlanner_t mp1; // primary planning context +mpPlanner_t mp2; // secondary planning context mpPlannerRuntime_t *mr; // context for planner block runtime -mpPlannerRuntime_t mr0; // runtime context for primary planner -mpPlannerRuntime_t mr1; // runtime context for secondary planner +mpPlannerRuntime_t mr1; // primary planner runtime context +mpPlannerRuntime_t mr2; // secondary planner runtime context -mpBuf_t mp0_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers -mpBuf_t mp1_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers +mpBuf_t mp1_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +mpBuf_t mp2_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers #define JSON_COMMAND_BUFFER_SIZE 3 @@ -143,15 +143,15 @@ static stat_t _exec_json_wait(mpBuf_t *bf); /* * planner_init() * planner_reset() - * runtime_init() + * planner_test_assertions() - test assertions, PANIC if violation exists */ // initialize a planner queue -void _init_planner_queue(mpPlanner_t *mpl, mpBuf_t *pool, uint8_t size) +void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *pool, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; - mpPlannerQueue_t *q = &(mpl->q); + mpPlannerQueue_t *q = &(_mp->q); memset(q, 0, sizeof(mpPlannerQueue_t)); // clear values, pointers and status q->magic_start = MAGICNUM; @@ -161,7 +161,7 @@ void _init_planner_queue(mpPlanner_t *mpl, mpBuf_t *pool, uint8_t size) q->bf = pool; // link the buffer pool first q->w = pool; // init all buffer pointers q->r = pool; - q->queue_size = size-1; + q->queue_size = size; q->buffers_available = size; pv = &q->bf[size-1]; @@ -176,46 +176,42 @@ void _init_planner_queue(mpPlanner_t *mpl, mpBuf_t *pool, uint8_t size) q->bf[size-1].nx = pool; } -void planner_init(mpPlanner_t *mpl, mpBuf_t *pool, mpPlannerRuntime_t *mrl) +void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *_pool, uint8_t _queue_size) { - mp = &mp0; // set global pointer to the primary planner - mr = &mr0; // and primary runtime + mp = &mp1; // set global pointer to the primary planner + mr = &mr1; // and primary runtime // init planner master structure - memset(mpl, 0, sizeof(mpPlanner_t));// clear all values, pointers and status - mpl->magic_start = MAGICNUM; // set boundary condition assertions - mpl->magic_end = MAGICNUM; - mpl->mfo_factor = 1.00; + memset(_mp, 0, sizeof(mpPlanner_t));// clear all values, pointers and status + _mp->magic_start = MAGICNUM; // set boundary condition assertions + _mp->magic_end = MAGICNUM; + _mp->mfo_factor = 1.00; // init planner queues - mpl->q.bf = pool; // assign puffer pool to queue manager structure - _init_planner_queue(mpl, pool, PLANNER_BUFFER_POOL_SIZE); + _mp->q.bf = _pool; // assign puffer pool to queue manager structure + _init_planner_queue(_mp, _pool, _queue_size); // init runtime structs - mpl->mr = mrl; - memset(mrl, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status - mrl->bf[0].nx = &mrl->bf[1]; // Handle the two "stub blocks" in the runtime structure. - mrl->bf[1].nx = &mrl->bf[0]; - mrl->r = &mrl->bf[0]; - mrl->p = &mrl->bf[1]; - mpl->mr->magic_start = MAGICNUM; // assertions - mpl->mr->magic_end = MAGICNUM; + _mp->mr = _mr; + memset(_mr, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status + _mr->bf[0].nx = &_mr->bf[1]; // Handle the two "stub blocks" in the runtime structure. + _mr->bf[1].nx = &_mr->bf[0]; + _mr->r = &_mr->bf[0]; + _mr->p = &_mr->bf[1]; + _mp->mr->magic_start = MAGICNUM; // assertions + _mp->mr->magic_end = MAGICNUM; } -void planner_reset(mpPlanner_t *mpl) +void planner_reset(mpPlanner_t *_mp) { - planner_init(mpl, mpl->q.bf, mpl->mr); // reset parent planner and linked Q and MR + planner_init(_mp, _mp->mr, _mp->q.bf, _mp->q.queue_size); // reset parent planner and linked Q and MR } -/* - * planner_test_assertions() - test assertions, PANIC if violation exists - */ - -stat_t planner_test_assertions(mpPlanner_t *mpl) +stat_t planner_test_assertions(mpPlanner_t *_mp) { if ( - (BAD_MAGIC(mpl->magic_start)) || (BAD_MAGIC(mpl->magic_end)) || - (BAD_MAGIC(mpl->mr->magic_start)) || (BAD_MAGIC(mpl->mr->magic_end)) + (BAD_MAGIC(_mp->magic_start)) || (BAD_MAGIC(_mp->magic_end)) || + (BAD_MAGIC(_mp->mr->magic_start)) || (BAD_MAGIC(_mp->mr->magic_end)) ) { return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); } @@ -247,12 +243,12 @@ void mp_halt_runtime() * This function is designed to be called during a hold to reset the planner * This function should not generally be called; call cm_queue_flush() instead */ -void mp_flush_planner(mpPlanner_t *mpl) +void mp_flush_planner(mpPlanner_t *_mp) { cm_abort_arc(); -// mp_init_planner_buffers(mpl); //+++++ -// planner_init(mpl); //+++++ - planner_reset(mpl); +// mp_init_planner_buffers(_mp); //+++++ +// planner_init(_mp); //+++++ + planner_reset(_mp); mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to prevent subsequent motion } @@ -509,20 +505,20 @@ bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } */ -uint8_t mp_get_planner_buffers(mpPlanner_t *mpl) // which planner are you interested in? +uint8_t mp_get_planner_buffers(mpPlanner_t *_mp) // which planner are you interested in? { - return (mpl->q.buffers_available); + return (_mp->q.buffers_available); } -bool mp_planner_is_full(mpPlanner_t *mpl) // which planner are you interested in? +bool mp_planner_is_full(mpPlanner_t *_mp) // which planner are you interested in? { // We also need to ensure we have room for another JSON command - return ((mpl->q.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0)); + return ((_mp->q.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0)); } -bool mp_has_runnable_buffer(mpPlanner_t *mpl) // which planner are you interested in?) +bool mp_has_runnable_buffer(mpPlanner_t *_mp) // which planner are you interested in?) { - return (mpl->q.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true + return (_mp->q.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } bool mp_is_phat_city_time() diff --git a/g2core/planner.h b/g2core/planner.h index 03c54643..130a717f 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -416,7 +416,7 @@ typedef struct mpPlannerQueue { // control structure for queue magic_t magic_start; // magic number to test memory integrity mpBuf_t *r; // run buffer pointer mpBuf_t *w; // write buffer pointer - uint8_t queue_size; // total number of buffers, zero-based (e.g. 47 not 48) + uint8_t queue_size; // total number of buffers, one-based (e.g. 48 not 47) uint8_t buffers_available; // running count of available buffers in queue mpBuf_t *bf; // pointer to buffer pool (storage array) magic_t magic_end; @@ -528,28 +528,29 @@ typedef struct mpPlanner { // common variables for a planner contex // Reference global scope structures -extern mpPlanner_t *mp; // currently active planner (global variable) -extern mpPlanner_t mp0; // primary planning context -extern mpPlanner_t mp1; // secondary planning context -extern mpBuf_t mp0_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers -extern mpBuf_t mp1_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers +extern mpPlanner_t *mp; // currently active planner (global variable) +extern mpPlanner_t mp1; // primary planning context +extern mpPlanner_t mp2; // secondary planning context -extern mpPlannerRuntime_t *mr; // context for block runtime -extern mpPlannerRuntime_t mr0; // runtime context for primary planner -extern mpPlannerRuntime_t mr1; // runtime context for secondary planner +extern mpPlannerRuntime_t *mr; // context for block runtime +extern mpPlannerRuntime_t mr1; // primary planner runtime context +extern mpPlannerRuntime_t mr2; // secondary planner runtime context + +extern mpBuf_t mp1_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers +extern mpBuf_t mp2_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers /* * Global Scope Functions */ -//planner.cpp functions +//**** planner.cpp functions -void planner_init(mpPlanner_t *mpl, mpBuf_t *pool, mpPlannerRuntime_t *mrl); -void planner_reset(mpPlanner_t *mpl); -stat_t planner_test_assertions(mpPlanner_t *mpl); +void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *_pool, uint8_t _queue_size); +void planner_reset(mpPlanner_t *_mp); +stat_t planner_test_assertions(mpPlanner_t *_mp); void mp_halt_runtime(void); -void mp_flush_planner(mpPlanner_t *mpl); +void mp_flush_planner(mpPlanner_t *_mp); void mp_set_planner_position(uint8_t axis, const float position); void mp_set_runtime_position(uint8_t axis, const float position); void mp_set_steps_to_runtime_position(void); @@ -565,10 +566,10 @@ void mp_end_dwell(void); void mp_request_out_of_band_dwell(float seconds); stat_t mp_exec_out_of_band_dwell(void); -// planner functions and helpers -uint8_t mp_get_planner_buffers(mpPlanner_t *mpl); -bool mp_planner_is_full(mpPlanner_t *mpl); -bool mp_has_runnable_buffer(mpPlanner_t *mpl); +//**** planner functions and helpers +uint8_t mp_get_planner_buffers(mpPlanner_t *_mp); +bool mp_planner_is_full(mpPlanner_t *_mp); +bool mp_has_runnable_buffer(mpPlanner_t *_mp); bool mp_is_phat_city_time(void); stat_t mp_planner_callback(); @@ -577,7 +578,7 @@ void mp_start_feed_override(const float ramp_time, const float override); void mp_end_feed_override(const float ramp_time); void mp_planner_time_accounting(void); -// planner buffer primitives +//**** planner buffer primitives //void mp_init_planner_buffers(void); //mpBuf_t * mp_get_w(int8_t q); //mpBuf_t * mp_get_r(int8_t q); @@ -594,7 +595,7 @@ void mp_commit_write_buffer(const blockType block_type); mpBuf_t * mp_get_run_buffer(void); bool mp_free_run_buffer(void); -// plan_line.c functions +//**** plan_line.c functions void mp_zero_segment_velocity(void); // getters and setters... float mp_get_runtime_velocity(void); float mp_get_runtime_absolute_position(uint8_t axis); @@ -607,7 +608,7 @@ stat_t mp_aline(GCodeState_t *gm_in); // line planning... void mp_plan_block_list(void); void mp_plan_block_forward(mpBuf_t *bf); -// plan_zoid.c functions +//**** plan_zoid.c functions void mp_calculate_ramps(mpBlockRuntimeBuf_t *block, mpBuf_t *bf, const float entry_velocity); float mp_get_target_length(const float v_0, const float v_1, const mpBuf_t *bf); float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t *bf); // acceleration ONLY @@ -619,7 +620,7 @@ float mp_calc_a(const float t, const float v_0, const float v_1, const float T); float mp_calc_j(const float t, const float v_0, const float v_1, const float T); // compute jerk over curve accelerating from v_0 to v_1, at position t=[0,1], total time T //float mp_calc_l(const float t, const float v_0, const float v_1, const float T); // compute length over curve accelerating from v_0 to v_1, at position t=[0,1], total time T -// plan_exec.c functions +//**** plan_exec.c functions stat_t mp_forward_plan(void); stat_t mp_exec_move(void); stat_t mp_exec_aline(mpBuf_t *bf); diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index f3a69482..31d99aa7 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -2,8 +2,8 @@ * stepper.cpp - stepper motor controls * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -80,7 +80,7 @@ load_timer_type load_timer; // triggers load of next stepper segment exec_timer_type exec_timer; // triggers calculation of next+1 stepper segment fwd_plan_timer_type fwd_plan_timer; // triggers planning of next block -// SystickEvent for handling dweels (must be registered before it is active) +// SystickEvent for handling dwells (must be registered before it is active) Motate::SysTickEvent dwell_systick_event {[&] { if (--st_run.dwell_ticks_downcount == 0) { SysTickTimer.unregisterEvent(&dwell_systick_event); @@ -800,11 +800,10 @@ void st_request_out_of_band_dwell(float microseconds) */ static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps) { - if (motor >= MOTORS) {return;} + if (motor >= MOTORS) { return; } Motors[motor]->setMicrosteps(microsteps); - } - +} /*********************************************************************************** * CONFIGURATION AND INTERFACE FUNCTIONS diff --git a/g2core/stepper.h b/g2core/stepper.h index 26204c61..35f1770c 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -2,8 +2,8 @@ * stepper.h - stepper motor interface * This file is part of g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the From cb0ab6c787b6f69b146a46adbefa7de33a080932 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 10 Jan 2017 12:36:33 -0500 Subject: [PATCH 057/283] Checkpoint. Running 2 planners. Passes (most) regressions; separated Gcode inits from CM inits; added CM dependency injection to arc commands --- g2core/canonical_machine.cpp | 190 +++++++++++++++++------------------ g2core/canonical_machine.h | 10 +- g2core/controller.cpp | 6 +- g2core/gcode.h | 1 + g2core/gcode_parser.cpp | 14 ++- g2core/main.cpp | 11 +- g2core/plan_arc.cpp | 32 +++--- g2core/plan_arc.h | 46 +-------- g2core/planner.cpp | 71 +++++-------- g2core/planner.h | 18 ++-- 10 files changed, 174 insertions(+), 225 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ecfa0264..8c5e050f 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -135,6 +135,100 @@ static int8_t _axis(const index_t index); **** CODE ************************************************************************* ***********************************************************************************/ +/* + * canonical_machine_init() - initialize cm struct + * canonical_machine_reset() - apply startup settings or reset to startup + * canonical_machine_reset_rotation() + */ + +void canonical_machine_init(cmMachine_t *_cm) +{ + // Note cm* was assignd in main() + // If you can assume all memory has been zeroed by a hard reset you don't need this code: + memset(_cm, 0, sizeof(cmMachine_t)); // do not reset canonicalMachine once it's been initialized + memset(&_cm->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status + + canonical_machine_init_assertions(_cm); // establish assertions + ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer + cm_arc_init(_cm); // Note: spindle and coolant inits are independent +} + +// Note: run canonical_machine_init and profile initializations beforehand +void canonical_machine_reset(cmMachine_t *_cm) +{ + // reset canonical machine assertions + canonical_machine_init_assertions(_cm); + + // set canonical machine gcode defaults + cm_set_units_mode(gc.default_units_mode); + cm_set_coord_system(gc.default_coord_system); // NB: queues a block to the planner with the coordinates + cm_select_plane(gc.default_select_plane); + cm_set_path_control(MODEL, gc.default_path_control); + cm_set_distance_mode(gc.default_distance_mode); + cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE); // always the default + cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default + cm_reset_overrides(); // set overrides to initial conditions + + // NOTE: Should unhome axes here + + // reset request flags + _cm->queue_flush_state = FLUSH_OFF; + _cm->end_hold_requested = false; + _cm->limit_requested = 0; // resets switch closures that occurred during initialization + _cm->safety_interlock_disengaged = 0; // ditto + _cm->safety_interlock_reengaged = 0; // ditto + _cm->shutdown_requested = 0; // ditto + + // set initial state and signal that the machine is ready for action + _cm->cycle_state = CYCLE_OFF; + _cm->motion_state = MOTION_STOP; + _cm->hold_state = FEEDHOLD_OFF; + _cm->esc_boot_timer = SysTickTimer_getValue(); + _cm->gmx.block_delete_switch = true; + _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode + _cm->machine_state = MACHINE_READY; + + canonical_machine_reset_rotation(_cm); + memset(&_cm->probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); + memset(&_cm->probe_results, 0, sizeof(float)*PROBES_STORED*AXES); +} + +void canonical_machine_reset_rotation(cmMachine_t *_cm) { + + // We must make it an identity matrix for no rotation + memset(&_cm->rotation_matrix, 0, sizeof(float)*3*3); + _cm->rotation_matrix[0][0] = 1.0; + _cm->rotation_matrix[1][1] = 1.0; + _cm->rotation_matrix[2][2] = 1.0; + _cm->rotation_z_offset = 0.0; +} + +/* + * canonical_machine_init_assertions() + * canonical_machine_test_assertions() - test assertions, return error code if violation exists + */ + +void canonical_machine_init_assertions(cmMachine_t *_cm) +{ + _cm->magic_start = MAGICNUM; + _cm->magic_end = MAGICNUM; + _cm->gmx.magic_start = MAGICNUM; + _cm->gmx.magic_end = MAGICNUM; + _cm->arc.magic_start = MAGICNUM; + _cm->arc.magic_end = MAGICNUM; +} + +stat_t canonical_machine_test_assertions(cmMachine_t *_cm) +{ + if ((BAD_MAGIC(_cm->magic_start)) || (BAD_MAGIC(_cm->magic_end)) || + (BAD_MAGIC(_cm->gmx.magic_start)) || (BAD_MAGIC(_cm->gmx.magic_end)) || + (BAD_MAGIC(_cm->arc.magic_start)) || (BAD_MAGIC(_cm->arc.magic_end))) { + return(cm_panic(STAT_CANONICAL_MACHINE_ASSERTION_FAILURE, "canonical_machine_test_assertions()")); + } + return (STAT_OK); +} + + /************************************* * Internal getters and setters * * Canonical Machine State functions * @@ -713,103 +807,7 @@ stat_t cm_test_soft_limits(const float target[]) * found in NIST RS274 NGCv3 ************************************************************************/ -/****************************************** - * Initialization and Termination (4.3.2) * - ******************************************/ -/* - * canonical_machine_init() - initialize cm struct - * canonical_machine_reset() - apply startup settings or reset to startup - * run profile initialization beforehand - */ -void canonical_machine_init(cmMachine_t *m) -{ - // Note cm* was assignd in main() - // If you can assume all memory has been zeroed by a hard reset you don't need this code: - memset(m, 0, sizeof(cmMachine_t)); // do not reset canonicalMachine once it's been initialized -// memset(&m->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status - -// memset(&gc.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs -// memset(&gc.gf, 0, sizeof(GCodeFlags_t)); - - canonical_machine_init_assertions(m); // establish assertions - ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer - cm_arc_init(); // Note: spindle and coolant inits are independent -} - -void canonical_machine_reset(cmMachine_t *m) -{ - // reset canonical machine assertions - canonical_machine_init_assertions(m); - - // set gcode defaults - cm_set_units_mode(gc.default_units_mode); - cm_set_coord_system(gc.default_coord_system); // NB: queues a block to the planner with the coordinates - cm_select_plane(gc.default_select_plane); - cm_set_path_control(MODEL, gc.default_path_control); - cm_set_distance_mode(gc.default_distance_mode); - cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE); // always the default - cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default - cm_reset_overrides(); // set overrides to initial conditions - - // NOTE: Should unhome axes here - - // reset request flags - m->queue_flush_state = FLUSH_OFF; - m->end_hold_requested = false; - m->limit_requested = 0; // resets switch closures that occurred during initialization - m->safety_interlock_disengaged = 0; // ditto - m->safety_interlock_reengaged = 0; // ditto - m->shutdown_requested = 0; // ditto - - // set initial state and signal that the machine is ready for action - m->cycle_state = CYCLE_OFF; - m->motion_state = MOTION_STOP; - m->hold_state = FEEDHOLD_OFF; - m->esc_boot_timer = SysTickTimer_getValue(); - m->gmx.block_delete_switch = true; - m->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode - m->machine_state = MACHINE_READY; - - canonical_machine_reset_rotation(m); - memset(&m->probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); - memset(&m->probe_results, 0, sizeof(float)*PROBES_STORED*AXES); -} - -void canonical_machine_reset_rotation(cmMachine_t *m) { - memset(&cm->rotation_matrix, 0, sizeof(float)*3*3); - - // We must make it an identity matrix for no rotation - m->rotation_matrix[0][0] = 1.0; - m->rotation_matrix[1][1] = 1.0; - m->rotation_matrix[2][2] = 1.0; - m->rotation_z_offset = 0.0; -} - -/* - * canonical_machine_init_assertions() - * canonical_machine_test_assertions() - test assertions, return error code if violation exists - */ - -void canonical_machine_init_assertions(cmMachine_t *m) -{ - m->magic_start = MAGICNUM; - m->magic_end = MAGICNUM; - m->gmx.magic_start = MAGICNUM; - m->gmx.magic_end = MAGICNUM; - m->arc.magic_start = MAGICNUM; - m->arc.magic_end = MAGICNUM; -} - -stat_t canonical_machine_test_assertions(cmMachine_t *m) -{ - if ((BAD_MAGIC(m->magic_start)) || (BAD_MAGIC(m->magic_end)) || - (BAD_MAGIC(m->gmx.magic_start)) || (BAD_MAGIC(m->gmx.magic_end)) || - (BAD_MAGIC(m->arc.magic_start)) || (BAD_MAGIC(m->arc.magic_end))) { - return(cm_panic(STAT_CANONICAL_MACHINE_ASSERTION_FAILURE, "canonical_machine_test_assertions()")); - } - return (STAT_OK); -} /************************** * Alarms * diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 24c1da8d..25d9da0c 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -340,11 +340,11 @@ stat_t cm_test_soft_limits(const float target[]); /*--- Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc] ---*/ // Initialization and termination (4.3.2) -void canonical_machine_init(cmMachine_t *machine); -void canonical_machine_reset_rotation(cmMachine_t *machine); // NOT in NIST -void canonical_machine_reset(cmMachine_t *machine); -void canonical_machine_init_assertions(cmMachine_t *machine); -stat_t canonical_machine_test_assertions(cmMachine_t *machine); +void canonical_machine_init(cmMachine_t *_cm); +void canonical_machine_reset_rotation(cmMachine_t *_cm); // NOT in NIST +void canonical_machine_reset(cmMachine_t *_cm); +void canonical_machine_init_assertions(cmMachine_t *_cm); +stat_t canonical_machine_test_assertions(cmMachine_t *_cm); // Alarms and state management stat_t cm_alrm(nvObj_t *nv); // trigger alarm from command input diff --git a/g2core/controller.cpp b/g2core/controller.cpp index cdae6602..553f2878 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -2,8 +2,8 @@ * controller.cpp - g2core controller and top level parser * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -161,7 +161,7 @@ static void _controller_HSM() DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(mp_planner_callback()); // motion planner - DISPATCH(cm_arc_callback()); // arc generation runs as a cycle above lines + DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation diff --git a/g2core/gcode.h b/g2core/gcode.h index 94917883..8e24f1e0 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -386,6 +386,7 @@ extern GCodeSingleton_t gc; // gcode structs /* * Global Scope Functions */ +void gcode_parser_init(void); stat_t gcode_parser(char* block); stat_t gc_get_gc(nvObj_t* nv); stat_t gc_run_gc(nvObj_t* nv); diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index c26337ec..f87c7594 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -2,8 +2,8 @@ * gcode_parser.cpp - rs274/ngc Gcode parser * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2016 Rob Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -41,6 +41,16 @@ static stat_t _execute_gcode_block(char *active_comment); // Execute t #define SET_NON_MODAL(parm,val) ({gc.gn.parm=val; gc.gf.parm=true; break;}) #define EXEC_FUNC(f,v) if(gc.gf.v) { status=f(gc.gn.v);} +/* + * gcode_parser_init() + */ + +void gcode_parser_init() +{ + memset(&gc.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs + memset(&gc.gf, 0, sizeof(GCodeFlags_t)); +} + /* * gcode_parser() - parse a block (line) of gcode * diff --git a/g2core/main.cpp b/g2core/main.cpp index f48c9df7..a00cccd0 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -108,10 +108,11 @@ void application_init_machine(void) encoder_init(); // virtual encoders gpio_init(); // inputs and outputs pwm_init(); // pulse width modulation drivers - planner_init(&mp1, &mr1, mp1_pool, PLANNER_BUFFER_POOL_SIZE); // primary motion planner - planner_init(&mp2, &mr2, mp2_pool, SECONDARY_BUFFER_POOL_SIZE); // secondary motion planner + + planner_init(&mp1, &mr1, mp1_queue, PLANNER_QUEUE_SIZE); + planner_init(&mp2, &mr2, mp2_queue, SECONDARY_QUEUE_SIZE); canonical_machine_init(&cm1); // primary canonical machine -// canonical_machine_init(&cm2); // secondary canonical machine + canonical_machine_init(&cm2); // secondary canonical machine } void application_init_startup(void) @@ -119,8 +120,8 @@ void application_init_startup(void) // start the application controller_init(); // should be first startup init (requires xio_init()) config_init(); // apply the config settings from persistence - canonical_machine_reset(&cm1); -// canonical_machine_reset(&cm2); + canonical_machine_reset(&cm1); // initialize both CMs but only reset the primary + gcode_parser_init(); // baseline Gcode parser spindle_init(); // should be after PWM and canonical machine inits and config_init() spindle_reset(); temperature_init(); diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 944e3925..99403d63 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -2,7 +2,7 @@ * plan_arc.c - arc planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -47,10 +47,10 @@ static stat_t _test_arc_soft_limits(void); /* * cm_arc_init() - initialize arc structures */ -void cm_arc_init() +void cm_arc_init(cmMachine_t *_cm) { - cm->arc.magic_start = MAGICNUM; - cm->arc.magic_end = MAGICNUM; + _cm->arc.magic_start = MAGICNUM; + _cm->arc.magic_end = MAGICNUM; } /* @@ -59,9 +59,9 @@ void cm_arc_init() * OK to call if no arc is running */ -void cm_abort_arc() +void cm_abort_arc(cmMachine_t *_cm) { - cm->arc.run_state = BLOCK_INACTIVE; + _cm->arc.run_state = BLOCK_INACTIVE; } /* @@ -73,26 +73,26 @@ void cm_abort_arc() * Parts of this routine were informed by the grbl project. */ -stat_t cm_arc_callback() +stat_t cm_arc_callback(cmMachine_t *_cm) { - if (cm->arc.run_state == BLOCK_INACTIVE) { + if (_cm->arc.run_state == BLOCK_INACTIVE) { return (STAT_NOOP); } if (mp_planner_is_full(mp)) { //+++++ return (STAT_EAGAIN); } - cm->arc.theta += cm->arc.segment_theta; - cm->arc.gm.target[cm->arc.plane_axis_0] = cm->arc.center_0 + sin(cm->arc.theta) * cm->arc.radius; - cm->arc.gm.target[cm->arc.plane_axis_1] = cm->arc.center_1 + cos(cm->arc.theta) * cm->arc.radius; - cm->arc.gm.target[cm->arc.linear_axis] += cm->arc.segment_linear_travel; + _cm->arc.theta += _cm->arc.segment_theta; + _cm->arc.gm.target[_cm->arc.plane_axis_0] = _cm->arc.center_0 + sin(_cm->arc.theta) * _cm->arc.radius; + _cm->arc.gm.target[_cm->arc.plane_axis_1] = _cm->arc.center_1 + cos(_cm->arc.theta) * _cm->arc.radius; + _cm->arc.gm.target[_cm->arc.linear_axis] += _cm->arc.segment_linear_travel; - mp_aline(&(cm->arc.gm)); // run the line - copy_vector(cm->arc.position, cm->arc.gm.target); // update arc current position + mp_aline(&(_cm->arc.gm)); // run the line + copy_vector(_cm->arc.position, _cm->arc.gm.target); // update arc current position - if (--(cm->arc.segment_count) > 0) { + if (--(_cm->arc.segment_count) > 0) { return (STAT_EAGAIN); } - cm->arc.run_state = BLOCK_INACTIVE; + _cm->arc.run_state = BLOCK_INACTIVE; return (STAT_OK); } diff --git a/g2core/plan_arc.h b/g2core/plan_arc.h index 5e2f0dc8..641fb86d 100644 --- a/g2core/plan_arc.h +++ b/g2core/plan_arc.h @@ -2,7 +2,7 @@ * plan_arc.h - arc planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -31,49 +31,11 @@ #define ARC_RADIUS_TOLERANCE ((float)0.001) // 0.1% radius variance test #define CHORDAL_TOLERANCE_MIN (0.001) // values below this are not accepted -/* -typedef struct arArcSingleton { // persistent planner and runtime variables - magic_t magic_start; - uint8_t run_state; // runtime state machine sequence - float position[AXES]; // accumulating runtime position - float offset[3]; // arc IJK offsets - - float length; // length of line or helix in mm - float radius; // Raw R value, or computed via offsets - float theta; // starting angle of arc - float angular_travel; // travel along the arc in radians - float planar_travel; // travel in arc plane in mm - float linear_travel; // travel along linear axis of arc in mm - bool full_circle; // True if full circle arcs specified - float rotations; // number of full rotations to add (P value + sign) - - cmAxes plane_axis_0; // arc plane axis 0 - e.g. X for G17 - cmAxes plane_axis_1; // arc plane axis 1 - e.g. Y for G17 - cmAxes linear_axis; // linear axis (normal to plane) - - float segments; // number of segments in arc or blend - int32_t segment_count; // count of running segments - float segment_theta; // angular motion per segment - float segment_linear_travel; // linear motion per segment - float center_0; // center of circle at plane axis 0 (e.g. X for G17) - float center_1; // center of circle at plane axis 1 (e.g. Y for G17) - - GCodeState_t gm; // Gcode state struct is passed for each arc segment. - // Usage: - // uint32_t linenum; // line number of the arc feed move - same for each segment - // float target[AXES]; // arc segment target -// float work_offset[AXES]; // offset from machine coord system for reporting (same for each segment) -// float block_time; // segment_time: constant time per aline segment - - magic_t magic_end; -} arc_t; -extern arc_t arc; -*/ /* arc function prototypes */ -void cm_arc_init(void); -void cm_abort_arc(void); -stat_t cm_arc_callback(void); +void cm_arc_init(cmMachine_t *_cm); +void cm_abort_arc(cmMachine_t *_cm); +stat_t cm_arc_callback(cmMachine_t *_cm); #endif // End of include guard: PLAN_ARC_H_ONCE diff --git a/g2core/planner.cpp b/g2core/planner.cpp index da61dd42..183c61be 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -74,8 +74,8 @@ mpPlannerRuntime_t *mr; // context for planner block runtime mpPlannerRuntime_t mr1; // primary planner runtime context mpPlannerRuntime_t mr2; // secondary planner runtime context -mpBuf_t mp1_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers -mpBuf_t mp2_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers +mpBuf_t mp1_queue[PLANNER_QUEUE_SIZE]; // storage allocation for primary planner queue buffers +mpBuf_t mp2_queue[SECONDARY_QUEUE_SIZE]; // storage allocation for secondary planner queue buffers #define JSON_COMMAND_BUFFER_SIZE 3 @@ -147,7 +147,7 @@ static stat_t _exec_json_wait(mpBuf_t *bf); */ // initialize a planner queue -void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *pool, uint8_t size) +void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *queue, uint8_t size) { mpBuf_t *pv, *nx; uint8_t i, nx_i; @@ -157,10 +157,10 @@ void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *pool, uint8_t size) q->magic_start = MAGICNUM; q->magic_end = MAGICNUM; - memset(pool, 0, sizeof(mpBuf_t)*size); // clear all buffers in pool - q->bf = pool; // link the buffer pool first - q->w = pool; // init all buffer pointers - q->r = pool; + memset(queue, 0, sizeof(mpBuf_t)*size); // clear all buffers in queue + q->bf = queue; // link the buffer pool first + q->w = queue; // init all buffer pointers + q->r = queue; q->queue_size = size; q->buffers_available = size; @@ -173,10 +173,10 @@ void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *pool, uint8_t size) q->bf[i].pv = pv; pv = &q->bf[i]; } - q->bf[size-1].nx = pool; + q->bf[size-1].nx = queue; } -void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *_pool, uint8_t _queue_size) +void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uint8_t queue_size) { mp = &mp1; // set global pointer to the primary planner mr = &mr1; // and primary runtime @@ -188,8 +188,8 @@ void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *_pool, uin _mp->mfo_factor = 1.00; // init planner queues - _mp->q.bf = _pool; // assign puffer pool to queue manager structure - _init_planner_queue(_mp, _pool, _queue_size); + _mp->q.bf = queue; // assign puffer pool to queue manager structure + _init_planner_queue(_mp, queue, queue_size); // init runtime structs _mp->mr = _mr; @@ -207,22 +207,19 @@ void planner_reset(mpPlanner_t *_mp) planner_init(_mp, _mp->mr, _mp->q.bf, _mp->q.queue_size); // reset parent planner and linked Q and MR } -stat_t planner_test_assertions(mpPlanner_t *_mp) +stat_t planner_test_assertions(const mpPlanner_t *_mp) { if ( (BAD_MAGIC(_mp->magic_start)) || (BAD_MAGIC(_mp->magic_end)) || (BAD_MAGIC(_mp->mr->magic_start)) || (BAD_MAGIC(_mp->mr->magic_end)) ) { - return(cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); + return (cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); + } + for (uint8_t i=0; i < _mp->q.queue_size; i++) { + if ((_mp->q.bf[i].nx == nullptr) || (_mp->q.bf[i].pv == nullptr)) { + return (cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner buffer is corrupted")); + } } -// for (uint8_t i=0; i < PLANNER_BUFFER_POOL_SIZE; i++) { -// if (mb.bf[i].nx == nullptr) { -// _debug_trap("buffer has nullptr for nx"); -// } -// if (mb.bf[i].pv == nullptr) { -// _debug_trap("buffer has nullptr for pv"); -// } -// } return (STAT_OK); } @@ -245,9 +242,7 @@ void mp_halt_runtime() */ void mp_flush_planner(mpPlanner_t *_mp) { - cm_abort_arc(); -// mp_init_planner_buffers(_mp); //+++++ -// planner_init(_mp); //+++++ + cm_abort_arc(cm); planner_reset(_mp); mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to prevent subsequent motion } @@ -485,38 +480,19 @@ stat_t mp_exec_out_of_band_dwell(void) * mp_has_runnable_buffer() - true if next buffer is runnable, indicating motion has not stopped. * mp_is_it_phat_city_time() - test if there is time for non-essential processes */ -/* -uint8_t mp_get_planner_buffers(int8_t q) // which queue are you interested in? -{ - if (q == ACTIVE_Q) { q = mb.active_q; }; - return (mb.q[q].buffers_available); -} -bool mp_planner_is_full(int8_t q) // which queue are you interested in? -{ - if (q == ACTIVE_Q) { q = mb.active_q; }; - return ((mb.q[q].buffers_available < PLANNER_BUFFER_HEADROOM) - || (jc.available == 0)); // We also need to ensure we have room for another JSON command -} - -bool mp_has_runnable_buffer(int8_t q) // which queue are you interested in?) -{ - if (q == ACTIVE_Q) { q = mb.active_q; }; - return (mb.q[q].r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true -} -*/ -uint8_t mp_get_planner_buffers(mpPlanner_t *_mp) // which planner are you interested in? +uint8_t mp_get_planner_buffers(const mpPlanner_t *_mp) // which planner are you interested in? { return (_mp->q.buffers_available); } -bool mp_planner_is_full(mpPlanner_t *_mp) // which planner are you interested in? +bool mp_planner_is_full(const mpPlanner_t *_mp) // which planner are you interested in? { // We also need to ensure we have room for another JSON command return ((_mp->q.buffers_available < PLANNER_BUFFER_HEADROOM) || (jc.available == 0)); } -bool mp_has_runnable_buffer(mpPlanner_t *_mp) // which planner are you interested in?) +bool mp_has_runnable_buffer(const mpPlanner_t *_mp) // which planner are you interested in?) { return (_mp->q.r->buffer_state); // anything other than MP_BUFFER_EMPTY returns true } @@ -566,7 +542,8 @@ bool mp_is_phat_city_time() stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state - if ((mp_get_planner_buffers(mp) == PLANNER_BUFFER_POOL_SIZE) && //+++++ // detect and set IDLE state +// if ((mp_get_planner_buffers(mp) == PLANNER_BUFFER_POOL_SIZE) && //+++++ // detect and set IDLE state + if ((mp_get_planner_buffers(mp) == mp->q.queue_size) && //+++++ // detect and set IDLE state (cm->motion_state == MOTION_STOP) && (cm->hold_state == FEEDHOLD_OFF)) { mp->planner_state = PLANNER_IDLE; diff --git a/g2core/planner.h b/g2core/planner.h index 130a717f..9044aeaa 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -250,8 +250,8 @@ typedef enum { */ /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ -#define PLANNER_BUFFER_POOL_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 -#define SECONDARY_BUFFER_POOL_SIZE ((uint8_t)12) // Secondary planner queue for feedhold operations +#define PLANNER_QUEUE_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 +#define SECONDARY_QUEUE_SIZE ((uint8_t)12) // Secondary planner queue for feedhold operations #define PLANNER_BUFFER_HEADROOM ((uint8_t)4) // Buffers to reserve in planner before processing new input line #define JERK_MULTIPLIER ((float)1000000) // DO NOT CHANGE - must always be 1 million @@ -536,8 +536,8 @@ extern mpPlannerRuntime_t *mr; // context for block runtime extern mpPlannerRuntime_t mr1; // primary planner runtime context extern mpPlannerRuntime_t mr2; // secondary planner runtime context -extern mpBuf_t mp1_pool[PLANNER_BUFFER_POOL_SIZE]; // storage allocation for primary planner queue buffers -extern mpBuf_t mp2_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for secondary planner queue buffers +extern mpBuf_t mp1_queue[PLANNER_QUEUE_SIZE]; // storage allocation for primary planner queue buffers +extern mpBuf_t mp2_queue[SECONDARY_QUEUE_SIZE]; // storage allocation for secondary planner queue buffers /* * Global Scope Functions @@ -545,9 +545,9 @@ extern mpBuf_t mp2_pool[SECONDARY_BUFFER_POOL_SIZE]; // storage allocation for s //**** planner.cpp functions -void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *_pool, uint8_t _queue_size); +void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uint8_t queue_size); void planner_reset(mpPlanner_t *_mp); -stat_t planner_test_assertions(mpPlanner_t *_mp); +stat_t planner_test_assertions(const mpPlanner_t *_mp); void mp_halt_runtime(void); void mp_flush_planner(mpPlanner_t *_mp); @@ -567,9 +567,9 @@ void mp_request_out_of_band_dwell(float seconds); stat_t mp_exec_out_of_band_dwell(void); //**** planner functions and helpers -uint8_t mp_get_planner_buffers(mpPlanner_t *_mp); -bool mp_planner_is_full(mpPlanner_t *_mp); -bool mp_has_runnable_buffer(mpPlanner_t *_mp); +uint8_t mp_get_planner_buffers(const mpPlanner_t *_mp); +bool mp_planner_is_full(const mpPlanner_t *_mp); +bool mp_has_runnable_buffer(const mpPlanner_t *_mp); bool mp_is_phat_city_time(void); stat_t mp_planner_callback(); From 7c1ef0f1972a1050269576a52140b52e464e7b01 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 10 Jan 2017 13:06:03 -0500 Subject: [PATCH 058/283] Prep to implement switch context --- g2core/canonical_machine.cpp | 24 ++++++++------- g2core/canonical_machine.h | 57 ++++++++++++++++++------------------ g2core/controller.cpp | 15 +++++----- g2core/main.cpp | 4 +-- 4 files changed, 51 insertions(+), 49 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8c5e050f..206e37a4 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -39,7 +39,7 @@ * * There are 3 temporal contexts for system state: * - The gcode model in the canonical machine (the MODEL context, held in gm) - * - The gcode model used by the planner (PLANNER context, held in bf's and mm) + * - The gcode model used by the planner (PLANNER context, held in bf's and mp) * - The gcode model used during motion for reporting (RUNTIME context, held in mr) * * It's a bit more complicated than this. The 'gm' struct contains the core Gcode model @@ -141,7 +141,7 @@ static int8_t _axis(const index_t index); * canonical_machine_reset_rotation() */ -void canonical_machine_init(cmMachine_t *_cm) +void canonical_machine_init(cmMachine_t *_cm, void *_mp) { // Note cm* was assignd in main() // If you can assume all memory has been zeroed by a hard reset you don't need this code: @@ -149,11 +149,12 @@ void canonical_machine_init(cmMachine_t *_cm) memset(&_cm->gm, 0, sizeof(GCodeState_t)); // clear all values, pointers and status canonical_machine_init_assertions(_cm); // establish assertions + cm_arc_init(_cm); // setup arcs. Note: spindle and coolant inits are independent + _cm->mp = _mp; // point to associated planner ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer - cm_arc_init(_cm); // Note: spindle and coolant inits are independent } -// Note: run canonical_machine_init and profile initializations beforehand +// *** Note: Run canonical_machine_init and profile initializations beforehand *** void canonical_machine_reset(cmMachine_t *_cm) { // reset canonical machine assertions @@ -200,6 +201,9 @@ void canonical_machine_reset_rotation(cmMachine_t *_cm) { _cm->rotation_matrix[0][0] = 1.0; _cm->rotation_matrix[1][1] = 1.0; _cm->rotation_matrix[2][2] = 1.0; + + // Separately handle a z-offset so that the new plane maintains a consistent + // distance from the old one. We only need z, since we are rotating to the z axis. _cm->rotation_z_offset = 0.0; } @@ -582,7 +586,7 @@ stat_t cm_set_tram(nvObj_t *nv) // if passed false/0, we will clear the rotation matrix if (!do_set) { - canonical_machine_reset_rotation(cm); //++++++ cleanup on aisle 5 + canonical_machine_reset_rotation(cm); //++++++ return (STAT_OK); } @@ -906,7 +910,7 @@ void cm_halt_all(void) void cm_halt_motion(void) { mp_halt_runtime(); // stop the runtime. Do this immediately. (Reset is in cm_clear) - canonical_machine_reset(cm); //++++++ // reset Gcode model + canonical_machine_reset(cm); // halt the currently active machine cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone cm->motion_state = MOTION_STOP; cm->hold_state = FEEDHOLD_OFF; @@ -1354,7 +1358,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_finalize_move(); - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //+++++ + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //applies to currently active machine cm_cycle_end(); return (STAT_OK); } @@ -1374,7 +1378,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm const bool flags[]) // all false if no intermediate move { // Go through intermediate point if one is provided - while (mp_planner_is_full(mp)); //+++++ // Make sure you have available buffers + while (mp_planner_is_full(mp)); // Make sure you have available buffers ritorno(cm_straight_traverse(intermediate_target, flags)); // w/no action if no axis flags // If G20 adjust stored position (always in mm) to inches so traverse will be correct @@ -1387,7 +1391,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm } // Run the stored position move - while (mp_planner_is_full(mp)); //+++++ // Make sure you have available buffers + while (mp_planner_is_full(mp)); // Make sure you have available buffers uint8_t saved_distance_mode = cm_get_distance_mode(MODEL); cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); // Position was stored in absolute coords @@ -1512,7 +1516,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) cm_finalize_move(); // <-- ONLY safe because we don't care about status... - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //+++++ + if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { cm_cycle_end(); return (STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 25d9da0c..0338d18d 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -176,36 +176,36 @@ typedef struct cmAxis { float zero_backoff; // backoff from switches for machine zero } cfgAxis_t; -typedef struct arArcSingleton { // persistent planner and runtime variables +typedef struct cmArc { // planner and runtime variables for arc generation magic_t magic_start; - uint8_t run_state; // runtime state machine sequence + uint8_t run_state; // runtime state machine sequence - float position[AXES]; // accumulating runtime position - float offset[3]; // arc IJK offsets + float position[AXES]; // accumulating runtime position + float offset[3]; // arc IJK offsets - float length; // length of line or helix in mm - float radius; // Raw R value, or computed via offsets - float theta; // starting angle of arc - float angular_travel; // travel along the arc in radians - float planar_travel; // travel in arc plane in mm - float linear_travel; // travel along linear axis of arc in mm - bool full_circle; // True if full circle arcs specified - float rotations; // number of full rotations to add (P value + sign) + float length; // length of line or helix in mm + float radius; // Raw R value, or computed via offsets + float theta; // starting angle of arc + float angular_travel; // travel along the arc in radians + float planar_travel; // travel in arc plane in mm + float linear_travel; // travel along linear axis of arc in mm + bool full_circle; // True if full circle arcs specified + float rotations; // number of full rotations to add (P value + sign) - cmAxes plane_axis_0; // arc plane axis 0 - e.g. X for G17 - cmAxes plane_axis_1; // arc plane axis 1 - e.g. Y for G17 - cmAxes linear_axis; // linear axis (normal to plane) + cmAxes plane_axis_0; // arc plane axis 0 - e.g. X for G17 + cmAxes plane_axis_1; // arc plane axis 1 - e.g. Y for G17 + cmAxes linear_axis; // linear axis (normal to plane) - float segments; // number of segments in arc or blend - int32_t segment_count; // count of running segments - float segment_theta; // angular motion per segment - float segment_linear_travel; // linear motion per segment - float center_0; // center of circle at plane axis 0 (e.g. X for G17) - float center_1; // center of circle at plane axis 1 (e.g. Y for G17) + float segments; // number of segments in arc or blend + int32_t segment_count; // count of running segments + float segment_theta; // angular motion per segment + float segment_linear_travel; // linear motion per segment + float center_0; // center of circle at plane axis 0 (e.g. X for G17) + float center_1; // center of circle at plane axis 1 (e.g. Y for G17) - GCodeState_t gm; // Gcode state struct is passed for each arc segment. + GCodeState_t gm; // Gcode state struct is passed for each arc segment. magic_t magic_end; -} arc_t; +} cmArc_t; typedef struct cmMachine { // struct to manage canonical machine globals and state magic_t magic_start; // magic number to test memory integrity @@ -230,6 +230,8 @@ typedef struct cmMachine { // struct to manage canonical machin // Global state variables and requestors + void *mp; // linked mpPlanner_t - use a void pointer to avoid circular header files + cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleState cycle_state; // cycs cmMotionState motion_state; // momo @@ -256,14 +258,11 @@ typedef struct cmMachine { // struct to manage canonical machin float probe_results[PROBES_STORED][AXES]; // probing results float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore rotary axes. - float rotation_z_offset; // separately handle a z-offset, so that the new plane - // maintains a consistent distance from the old one. - // We only need z, since we are rotating to the z axis. - + float rotation_z_offset; // separately handle a z-offset to maintain consistent distance to bed float jogging_dest; // jogging destination as a relative move from current position /**** Model state structures ****/ - arc_t arc; // arc parameters + cmArc_t arc; // arc parameters GCodeState_t *am; // active Gcode model is maintained by state management GCodeState_t gm; // core gcode model state GCodeStateX_t gmx; // extended gcode model state @@ -340,7 +339,7 @@ stat_t cm_test_soft_limits(const float target[]); /*--- Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc] ---*/ // Initialization and termination (4.3.2) -void canonical_machine_init(cmMachine_t *_cm); +void canonical_machine_init(cmMachine_t *_cm, void *_mp); void canonical_machine_reset_rotation(cmMachine_t *_cm); // NOT in NIST void canonical_machine_reset(cmMachine_t *_cm); void canonical_machine_init_assertions(cmMachine_t *_cm); diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 553f2878..77314281 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -410,12 +410,11 @@ static stat_t _shutdown_handler(void) static stat_t _limit_switch_handler(void) { auto machine_state = cm_get_machine_state(); - if ((machine_state != MACHINE_ALARM) && (machine_state != MACHINE_PANIC) && (machine_state != MACHINE_SHUTDOWN)) { + if ((machine_state != MACHINE_ALARM) && + (machine_state != MACHINE_PANIC) && + (machine_state != MACHINE_SHUTDOWN)) { safe_pin.toggle(); } - -// safe_pin = 1; - if ((cm->limit_enable == true) && (cm->limit_requested != 0)) { char msg[10]; sprintf(msg, "input %d", (int)cm->limit_requested); @@ -475,10 +474,10 @@ stat_t _test_system_assertions() // these functions will panic if an assertion fails _test_assertions(); // controller assertions (local) config_test_assertions(); - canonical_machine_test_assertions(&cm1); // +++++ cleanup later -// canonical_machine_test_assertions(&cm2); // +++++ cleanup later - planner_test_assertions(&mp1); // +++++ cleanup later -// planner_test_assertions(&mp2); // +++++ cleanup later + canonical_machine_test_assertions(&cm1); + canonical_machine_test_assertions(&cm2); + planner_test_assertions(&mp1); + planner_test_assertions(&mp2); stepper_test_assertions(); encoder_test_assertions(); xio_test_assertions(); diff --git a/g2core/main.cpp b/g2core/main.cpp index a00cccd0..0184e671 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -111,8 +111,8 @@ void application_init_machine(void) planner_init(&mp1, &mr1, mp1_queue, PLANNER_QUEUE_SIZE); planner_init(&mp2, &mr2, mp2_queue, SECONDARY_QUEUE_SIZE); - canonical_machine_init(&cm1); // primary canonical machine - canonical_machine_init(&cm2); // secondary canonical machine + canonical_machine_init(&cm1, &mp1); // primary canonical machine + canonical_machine_init(&cm2, &mp2); // secondary canonical machine } void application_init_startup(void) From 15241fabb53adba9354d1843b9fef4f2c9c0460d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 11 Jan 2017 09:06:26 -0500 Subject: [PATCH 059/283] Checkpoint. Testing switch to secondary planner --- g2core/canonical_machine.cpp | 88 +++++++++++++++++----------- g2core/canonical_machine.h | 8 +-- g2core/gcode.h | 10 ++-- g2core/gcode_parser.cpp | 2 +- g2core/main.cpp | 4 ++ g2core/plan_exec.cpp | 6 +- g2core/plan_line.cpp | 9 ++- g2core/planner.cpp | 8 +-- g2core/planner.h | 16 +---- g2core/settings/settings_makeblock.h | 7 ++- 10 files changed, 85 insertions(+), 73 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 206e37a4..c1476938 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -171,14 +171,15 @@ void canonical_machine_reset(cmMachine_t *_cm) cm_reset_overrides(); // set overrides to initial conditions // NOTE: Should unhome axes here + _cm->homing_state = HOMING_NOT_HOMED; // reset request flags _cm->queue_flush_state = FLUSH_OFF; _cm->end_hold_requested = false; - _cm->limit_requested = 0; // resets switch closures that occurred during initialization - _cm->safety_interlock_disengaged = 0; // ditto - _cm->safety_interlock_reengaged = 0; // ditto - _cm->shutdown_requested = 0; // ditto + _cm->limit_requested = 0; // resets switch closures that occurred during initialization + _cm->safety_interlock_disengaged = 0; // ditto + _cm->safety_interlock_reengaged = 0; // ditto + _cm->shutdown_requested = 0; // ditto // set initial state and signal that the machine is ready for action _cm->cycle_state = CYCLE_OFF; @@ -232,6 +233,56 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) return (STAT_OK); } +/* + * cm_switch() - switch canonical machine to secondary machine + * cm_return() - return secondary canoncial machine to primary machine + * + * Doing a Switch is only safe when the machine has complete stopped during a feedhold + */ + +stat_t cm_switch(nvObj_t *nv) +{ + // Test for: + // - must be in the correct CM + // - must be fully stopped in a hold + if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { + return (STAT_COMMAND_NOT_ACCEPTED); + } + + // initialize the secondary context to agree with the primary + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // now make the changes so you can actually use it + cmMachine_t *_cm = &cm2; + _cm->motion_state = MOTION_STOP; + _cm->hold_state = FEEDHOLD_OFF; + _cm->hold_disabled = true; + + // setup the gm and gmx + _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + _cm->gm.feed_rate = 0; + memset(&(_cm->gm.target), 0 , sizeof(_cm->gm.target)); + memset(&(_cm->gm.target_comp), 0 , sizeof(_cm->gm.target_comp)); + copy_vector(_cm->gmx.position, mr->position); // get the current holding position + + // reassign the globals to the secondary planner (this must be last) + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + return (STAT_OK); +} + +stat_t cm_return(nvObj_t *nv) // if value == true return with offset corrections +{ + // reset the globals to the primary planner + cm = &cm1; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + return (STAT_OK); +} /************************************* * Internal getters and setters * @@ -363,33 +414,6 @@ void cm_set_model_linenum(const uint32_t linenum) nv_add_object((const char *)"n"); // then add the line number to the nv list } -/* - * cm_switch() - switch canonical machine to a different machine - * cm_return() - return canoncial machine to origincal machine - */ -stat_t cm_switch(nvObj_t *nv) -{ -/* - if (nv->value < PRIMARY_Q) { - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value < SECONDARY_Q) { - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - mb.return_q = mb.active_q; - mb.active_q = (uint8_t)nv->value; -*/ - return (STAT_OK); -} - -stat_t cm_return(nvObj_t *nv) // if value == true return with offset corrections -{ -/* - mb.active_q = mb.return_q; -*/ - return (STAT_OK); -} - /*********************************************************************************** * COORDINATE SYSTEMS AND OFFSETS * Functions to get, set and report coordinate systems and work offsets @@ -811,8 +835,6 @@ stat_t cm_test_soft_limits(const float target[]) * found in NIST RS274 NGCv3 ************************************************************************/ - - /************************** * Alarms * **************************/ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 0338d18d..c865c4f2 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -230,8 +230,6 @@ typedef struct cmMachine { // struct to manage canonical machin // Global state variables and requestors - void *mp; // linked mpPlanner_t - use a void pointer to avoid circular header files - cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleState cycle_state; // cycs cmMotionState motion_state; // momo @@ -244,9 +242,10 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot - bool g28_flag; // true = complete a G28 move - bool g30_flag; // true = complete a G30 move +// bool g28_flag; // true = complete a G28 move (transient state) +// bool g30_flag; // true = complete a G30 move bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them + bool hold_disabled; // set true when in secondary planner to disable feedhold requests bool end_hold_requested; // request restart after feedhold uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) @@ -262,6 +261,7 @@ typedef struct cmMachine { // struct to manage canonical machin float jogging_dest; // jogging destination as a relative move from current position /**** Model state structures ****/ + void *mp; // linked mpPlanner_t - use a void pointer to avoid circular header files cmArc_t arc; // arc parameters GCodeState_t *am; // active Gcode model is maintained by state management GCodeState_t gm; // core gcode model state diff --git a/g2core/gcode.h b/g2core/gcode.h index 8e24f1e0..ec311875 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -22,7 +22,7 @@ #include "hardware.h" -/* Gcode-specific definitions */ +/**** Gcode-specific definitions ****/ /* The difference between NextAction and MotionMode is that NextAction is * used by the current block, and may carry non-modal commands, whereas @@ -280,6 +280,8 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used } GCodeStateX_t; +// Structures used by Gcode parser + typedef struct GCodeInput { // Gcode model inputs - meaning depends on context uint8_t next_action; // handles G modal group 1 moves & non-modals @@ -366,7 +368,7 @@ typedef struct GCodeFlags { // Gcode model input flags bool arc_offset[3]; } GCodeFlags_t; -typedef struct GCodeSingleton { +typedef struct GCodeParser { // gcode power-on default settings - defaults are not the same as the gm state cmCoordSystem default_coord_system; // G10 active coordinate system default @@ -378,9 +380,9 @@ typedef struct GCodeSingleton { GCodeInput_t gn; // gcode input values - transient GCodeFlags_t gf; // gcode input flags - transient -} GCodeSingleton_t; +} GCodeParser_t; -extern GCodeSingleton_t gc; // gcode structs +extern GCodeParser_t gc; /* diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index f87c7594..6999721e 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -27,7 +27,7 @@ #include "util.h" #include "xio.h" // for char definitions -GCodeSingleton_t gc; // gcode structs +GCodeParser gc; // local helper functions and macros static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); diff --git a/g2core/main.cpp b/g2core/main.cpp index 0184e671..ccbe5c3d 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -117,6 +117,10 @@ void application_init_machine(void) void application_init_startup(void) { + cm = &cm1; // set global canonical machine pointer to primary machine + mp = &mp1; // set global pointer to the primary planner + mr = &mr1; // and primary runtime + // start the application controller_init(); // should be first startup init (requires xio_init()) config_init(); // apply the config settings from persistence diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index d7e8205a..c4ebc8b6 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1044,14 +1044,12 @@ static stat_t _exec_aline_segment() // see https://en.wikipedia.org/wiki/Kahan_summation_algorithm // for the summation compensation description for (uint8_t a=0; aunit[a] * segment_length) - mr->gm.target_comp[a]; float target = mr->position[a] + to_add; mr->gm.target_comp[a] = (target - mr->position[a]) - to_add; mr->gm.target[a] = target; -#else - mr->gm.target[a] = mr->position[a] + (mr->unit[a] * segment_length); -#endif + // the above replaces this line: + // mr->gm.target[a] = mr->position[a] + (mr->unit[a] * segment_length); } } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 8b38bc04..90067fef 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -2,8 +2,8 @@ * plan_line.c - acceleration managed line planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2016 Rob Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -699,11 +699,10 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa static void _calculate_junction_vmax(mpBuf_t* bf) { - // ++++ RG If we change cruise_vmax, we'll need to recompute junction_vmax, if we do this: + // If we change cruise_vmax, we'll need to recompute junction_vmax, if we do this: float velocity = min(bf->cruise_vmax, bf->nx->cruise_vmax); // start with our maximum possible velocity - // uint8_t jerk_axis = AXIS_X; - // cmAxes jerk_axis = AXIS_X; + // cmAxes jerk_axis = AXIS_X; // a diagnostic in case you want to find the limiting axis for (uint8_t axis = 0; axis < AXES; axis++) { if (bf->axis_flags[axis] || bf->nx->axis_flags[axis]) { // skip axes with no movement diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 183c61be..c775711d 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -178,9 +178,6 @@ void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *queue, uint8_t size) void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uint8_t queue_size) { - mp = &mp1; // set global pointer to the primary planner - mr = &mr1; // and primary runtime - // init planner master structure memset(_mp, 0, sizeof(mpPlanner_t));// clear all values, pointers and status _mp->magic_start = MAGICNUM; // set boundary condition assertions @@ -194,12 +191,13 @@ void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uin // init runtime structs _mp->mr = _mr; memset(_mr, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status + _mr->magic_start = MAGICNUM; // mr assertions + _mr->magic_end = MAGICNUM; + _mr->bf[0].nx = &_mr->bf[1]; // Handle the two "stub blocks" in the runtime structure. _mr->bf[1].nx = &_mr->bf[0]; _mr->r = &_mr->bf[0]; _mr->p = &_mr->bf[1]; - _mp->mr->magic_start = MAGICNUM; // assertions - _mp->mr->magic_end = MAGICNUM; } void planner_reset(mpPlanner_t *_mp) diff --git a/g2core/planner.h b/g2core/planner.h index 9044aeaa..1b951965 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -155,8 +155,7 @@ using Motate::Timeout; /* * Enums and other type definitions - * - * All the enums that equal zero must be zero. Don't change them + * All the enums that equal some starting value must be that value. Don't change them */ typedef void (*cm_exec_t)(float[], bool[]); // callback to canonical_machine execution function @@ -241,13 +240,6 @@ typedef enum { ZOID_EXIT_3a2 } zoidExitPoint; -/* +++++ REMOVE -typedef enum { - ACTIVE_Q = -1, // Must be -1 - PRIMARY_Q, // must line up with structure indexes - SECONDARY_Q -} queueType; -*/ /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_QUEUE_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 @@ -516,12 +508,8 @@ typedef struct mpPlanner { // common variables for a planner contex mpBuf_t *p; // planner buffer pointer mpBuf_t *c; // pointer to buffer immediately following critical region mpBuf_t *planning_return; // buffer to return to once back-planning is complete - - // planner queue manager - mpPlannerQueue_t q; // embed a planner buffer queue manager - - // planner runtime mpPlannerRuntime_t *mr; // bind to mr associated with this planner + mpPlannerQueue_t q; // embed a planner buffer queue manager magic_t magic_end; } mpPlanner_t; diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 79b591be..78609bc9 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -34,7 +34,8 @@ // Machine configuration settings -#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +//#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define JUNCTION_INTEGRATION_TIME 1.25 // cornering - between 0.10 and 2.00 (higher is faster) #define CHORDAL_TOLERANCE 0.1 // chordal tolerance for arcs (in mm) #define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on @@ -110,7 +111,7 @@ // *** axis settings ********************************************************************************** -#define JERK_MAX 5000 +#define JERK_MAX 20000 #define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values #define X_VELOCITY_MAX 40000 // xvm G0 max velocity in mm/min @@ -145,7 +146,7 @@ #define Z_FEEDRATE_MAX Z_VELOCITY_MAX #define Z_TRAVEL_MAX 0 #define Z_TRAVEL_MIN -95 -#define Z_JERK_MAX 500 +#define Z_JERK_MAX 1000 #define Z_JERK_HIGH_SPEED 1000 #define Z_HOMING_INPUT 6 #define Z_HOMING_DIRECTION 1 From dc8800b7bdc25122c911391e72c394db828753a2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 11 Jan 2017 10:00:50 -0500 Subject: [PATCH 060/283] Cleaned up Gcode startup default values - moved from Gcode parser to Canonical machine settings --- g2core/canonical_machine.cpp | 56 +++++++++++++-------- g2core/canonical_machine.h | 26 ++++++++-- g2core/config_app.cpp | 12 ++--- g2core/cycle_homing.cpp | 66 ++++++++++++------------- g2core/gcode.h | 15 +----- g2core/gcode_parser.cpp | 95 ++++++++++++++++++++---------------- g2core/spindle.cpp | 6 +-- 7 files changed, 155 insertions(+), 121 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index c1476938..e126a8b1 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -161,11 +161,11 @@ void canonical_machine_reset(cmMachine_t *_cm) canonical_machine_init_assertions(_cm); // set canonical machine gcode defaults - cm_set_units_mode(gc.default_units_mode); - cm_set_coord_system(gc.default_coord_system); // NB: queues a block to the planner with the coordinates - cm_select_plane(gc.default_select_plane); - cm_set_path_control(MODEL, gc.default_path_control); - cm_set_distance_mode(gc.default_distance_mode); + cm_set_units_mode(cm->default_units_mode); + cm_set_coord_system(cm->default_coord_system); // NB: queues a block to the planner with the coordinates + cm_select_plane(cm->default_select_plane); + cm_set_path_control(MODEL, cm->default_path_control); + cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE); // always the default cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default cm_reset_overrides(); // set overrides to initial conditions @@ -237,7 +237,9 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) * cm_switch() - switch canonical machine to secondary machine * cm_return() - return secondary canoncial machine to primary machine * - * Doing a Switch is only safe when the machine has complete stopped during a feedhold + * Doing a Switch is only safe when the machine has completely stopped during a feedhold + * Switch works to switch from the primary planer to the secondary planner + * Use Return to return to the primary planner */ stat_t cm_switch(nvObj_t *nv) @@ -246,6 +248,7 @@ stat_t cm_switch(nvObj_t *nv) // - must be in the correct CM // - must be fully stopped in a hold if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { + nv->valuetype = TYPE_NULL; return (STAT_COMMAND_NOT_ACCEPTED); } @@ -1102,7 +1105,7 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode) stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word, const float offset[], const bool flag[]) { - if (!gc.gf.L_word) { + if (!gp.gf.L_word) { return (STAT_L_WORD_IS_MISSING); } @@ -1166,15 +1169,15 @@ stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word, stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional) { uint8_t tool; - if (gc.gf.H_word) + if (gp.gf.H_word) { - if (gc.gn.H_word > TOOLS) { + if (gp.gn.H_word > TOOLS) { return (STAT_H_WORD_IS_INVALID); } - if (gc.gn.H_word == 0) { // interpret H0 as "current tool", just like no H at all. + if (gp.gn.H_word == 0) { // interpret H0 as "current tool", just like no H at all. tool = cm->gm.tool; } else { - tool = gc.gn.H_word; + tool = gp.gn.H_word; } } else { tool = cm->gm.tool; @@ -1699,17 +1702,17 @@ stat_t cm_mfo_enable(uint8_t enable) // M50 { bool new_enable = true; bool new_override = false; - if (gc.gf.parameter) { // if parameter is present in Gcode block - if (fp_ZERO(gc.gn.parameter)) { + if (gp.gf.parameter) { // if parameter is present in Gcode block + if (fp_ZERO(gp.gn.parameter)) { new_enable = false; // P0 disables override } else { - if (gc.gn.parameter < FEED_OVERRIDE_MIN) { + if (gp.gn.parameter < FEED_OVERRIDE_MIN) { return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (gc.gn.parameter > FEED_OVERRIDE_MAX) { + if (gp.gn.parameter > FEED_OVERRIDE_MAX) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - cm->gmx.mfo_factor = gc.gn.parameter; // it validates - store it. + cm->gmx.mfo_factor = gp.gn.parameter; // it validates - store it. new_override = true; } } @@ -1988,9 +1991,9 @@ static void _exec_program_finalize(float *value, bool *flag) if (((uint8_t)value[0]) == MACHINE_PROGRAM_END) { cm_suspend_origin_offsets(); // G92.2 - as per NIST // cm_reset_origin_offsets(); // G92.1 - alternative to above - cm_set_coord_system(gc.default_coord_system); // reset to default coordinate system - cm_select_plane(gc.default_select_plane); // reset to default arc plane - cm_set_distance_mode(gc.default_distance_mode); + cm_set_coord_system(cm->default_coord_system); // reset to default coordinate system + cm_select_plane(cm->default_select_plane); // reset to default arc plane + cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default cm_spindle_off_immediate(); // M5 cm_coolant_off_immediate(); // M9 @@ -2633,6 +2636,21 @@ stat_t cm_set_troe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.mto_enab stat_t cm_get_tro(nvObj_t *nv) { return(get_float(nv, cm->gmx.mto_factor)); } stat_t cm_set_tro(nvObj_t *nv) { return(set_float_range(nv, cm->gmx.mto_factor, TRAVERSE_OVERRIDE_MIN, TRAVERSE_OVERRIDE_MAX)); } +stat_t cm_get_gpl(nvObj_t *nv) { return(get_int(nv, cm->default_select_plane)); } +stat_t cm_set_gpl(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_select_plane, CANON_PLANE_XY, CANON_PLANE_YZ)); } + +stat_t cm_get_gun(nvObj_t *nv) { return(get_int(nv, cm->default_units_mode)); } +stat_t cm_set_gun(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_units_mode, INCHES, MILLIMETERS)); } + +stat_t cm_get_gco(nvObj_t *nv) { return(get_int(nv, cm->default_coord_system)); } +stat_t cm_set_gco(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_coord_system, G54, G59)); } + +stat_t cm_get_gpa(nvObj_t *nv) { return(get_int(nv, cm->default_path_control)); } +stat_t cm_set_gpa(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_path_control, PATH_EXACT_PATH, PATH_CONTINUOUS)); } + +stat_t cm_get_gdi(nvObj_t *nv) { return(get_int(nv, cm->default_distance_mode)); } +stat_t cm_set_gdi(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_distance_mode, ABSOLUTE_DISTANCE_MODE, INCREMENTAL_DISTANCE_MODE)); } + /* * Run Commands * diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index c865c4f2..ca93ff99 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -226,6 +226,13 @@ typedef struct cmMachine { // struct to manage canonical machin // Axis settings cfgAxis_t a[AXES]; + // gcode power-on default settings - defaults are not the same as the gm state + cmCoordSystem default_coord_system; // G10 active coordinate system default + cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default + cmUnitsMode default_units_mode; // G20,G21 reset default + cmPathControl default_path_control; // G61,G61.1,G64 reset default + cmDistanceMode default_distance_mode; // G90,G91 reset default + /**** Runtime variables (PRIVATE) ****/ // Global state variables and requestors @@ -562,14 +569,25 @@ stat_t cm_set_froe(nvObj_t *nv); // set feedrate override enable stat_t cm_get_fro(nvObj_t *nv); // get feedrate override factor stat_t cm_set_fro(nvObj_t *nv); // set feedrate override factor -stat_t cm_get_troe(nvObj_t *nv); // get traverse override enable -stat_t cm_set_troe(nvObj_t *nv); // set traverse override enable -stat_t cm_get_tro(nvObj_t *nv); // get traverse override factor -stat_t cm_set_tro(nvObj_t *nv); // set traverse override factor +stat_t cm_get_troe(nvObj_t *nv); // get traverse override enable +stat_t cm_set_troe(nvObj_t *nv); // set traverse override enable +stat_t cm_get_tro(nvObj_t *nv); // get traverse override factor +stat_t cm_set_tro(nvObj_t *nv); // set traverse override factor stat_t cm_set_tram(nvObj_t *nv); // attempt setting the rotation matrix stat_t cm_get_tram(nvObj_t *nv); // return if the rotation matrix is non-identity +stat_t cm_get_gpl(nvObj_t *nv); // get gcode default plane +stat_t cm_set_gpl(nvObj_t *nv); // set gcode default plane +stat_t cm_get_gun(nvObj_t *nv); // get gcode default units mode +stat_t cm_set_gun(nvObj_t *nv); // set gcode default units mode +stat_t cm_get_gco(nvObj_t *nv); // get gcode default coordinate system +stat_t cm_set_gco(nvObj_t *nv); // set gcode default coordinate system +stat_t cm_get_gpa(nvObj_t *nv); // get gcode default path control mode +stat_t cm_set_gpa(nvObj_t *nv); // set gcode default path control mode +stat_t cm_get_gdi(nvObj_t *nv); // get gcode default distance mode +stat_t cm_set_gdi(nvObj_t *nv); // set gcode default distance mode + /*--- text_mode support functions ---*/ #ifdef __TEXT_MODE diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index a8dd23c9..866c27a0 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -880,12 +880,12 @@ const cfgItem_t cfgArray[] = { // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco - { "sys","gpl", _fipn, 0, cm_print_gpl, get_ui8, set_012, (float *)&gc.default_select_plane, GCODE_DEFAULT_PLANE }, - { "sys","gun", _fipn, 0, cm_print_gun, get_ui8, set_01, (float *)&gc.default_units_mode, GCODE_DEFAULT_UNITS }, - { "sys","gco", _fipn, 0, cm_print_gco, get_ui8, set_ui8, (float *)&gc.default_coord_system, GCODE_DEFAULT_COORD_SYSTEM }, - { "sys","gpa", _fipn, 0, cm_print_gpa, get_ui8, set_012, (float *)&gc.default_path_control, GCODE_DEFAULT_PATH_CONTROL }, - { "sys","gdi", _fipn, 0, cm_print_gdi, get_ui8, set_01, (float *)&gc.default_distance_mode, GCODE_DEFAULT_DISTANCE_MODE }, - { "", "gc", _f0, 0, tx_print_nul, gc_get_gc,gc_run_gc,(float *)&cs.null, 0 }, // gcode block - must be last in this group + { "sys","gpl", _fipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, (float *)&cs.null, GCODE_DEFAULT_PLANE }, + { "sys","gun", _fipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, (float *)&cs.null, GCODE_DEFAULT_UNITS }, + { "sys","gco", _fipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, + { "sys","gpa", _fipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, + { "sys","gdi", _fipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, + { "", "gc", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index fbec4f6a..4767f099 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -2,8 +2,8 @@ * cycle_homing.cpp - homing cycle extension to canonical_machine * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -407,38 +407,38 @@ static stat_t _homing_finalize_exit(int8_t axis) // third part of return to hom static int8_t _get_next_axis(int8_t axis) { #if (HOMING_AXES <= 4) if (axis == -1) { // inelegant brute force solution - if (gc.gf.target[AXIS_Z]) { + if (gp.gf.target[AXIS_Z]) { return (AXIS_Z); } - if (gc.gf.target[AXIS_X]) { + if (gp.gf.target[AXIS_X]) { return (AXIS_X); } - if (gc.gf.target[AXIS_Y]) { + if (gp.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } return (-2); // error } else if (axis == AXIS_Z) { - if (gc.gf.target[AXIS_X]) { + if (gp.gf.target[AXIS_X]) { return (AXIS_X); } - if (gc.gf.target[AXIS_Y]) { + if (gp.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_X) { - if (gc.gf.target[AXIS_Y]) { + if (gp.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_Y) { - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } } @@ -446,73 +446,73 @@ static int8_t _get_next_axis(int8_t axis) { #else if (axis == -1) { - if (gc.gf.target[AXIS_Z]) { + if (gp.gf.target[AXIS_Z]) { return (AXIS_Z); } - if (gc.gf.target[AXIS_X]) { + if (gp.gf.target[AXIS_X]) { return (AXIS_X); } - if (gc.gf.target[AXIS_Y]) { + if (gp.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } - if (gc.gf.target[AXIS_B]) { + if (gp.gf.target[AXIS_B]) { return (AXIS_B); } - if (gc.gf.target[AXIS_C]) { + if (gp.gf.target[AXIS_C]) { return (AXIS_C); } return (-2); // error } else if (axis == AXIS_Z) { - if (gc.gf.target[AXIS_X]) { + if (gp.gf.target[AXIS_X]) { return (AXIS_X); } - if (gc.gf.target[AXIS_Y]) { + if (gp.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } - if (gc.gf.target[AXIS_B]) { + if (gp.gf.target[AXIS_B]) { return (AXIS_B); } - if (gc.gf.target[AXIS_C]) { + if (gp.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_X) { - if (gc.gf.target[AXIS_Y]) { + if (gp.gf.target[AXIS_Y]) { return (AXIS_Y); } - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } - if (gc.gf.target[AXIS_B]) { + if (gp.gf.target[AXIS_B]) { return (AXIS_B); } - if (gc.gf.target[AXIS_C]) { + if (gp.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_Y) { - if (gc.gf.target[AXIS_A]) { + if (gp.gf.target[AXIS_A]) { return (AXIS_A); } - if (gc.gf.target[AXIS_B]) { + if (gp.gf.target[AXIS_B]) { return (AXIS_B); } - if (gc.gf.target[AXIS_C]) { + if (gp.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_A) { - if (gc.gf.target[AXIS_B]) { + if (gp.gf.target[AXIS_B]) { return (AXIS_B); } - if (gc.gf.target[AXIS_C]) { + if (gp.gf.target[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_B) { - if (gc.gf.target[AXIS_C]) { + if (gp.gf.target[AXIS_C]) { return (AXIS_C); } } diff --git a/g2core/gcode.h b/g2core/gcode.h index ec311875..07d14167 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -198,7 +198,7 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) * some state elements are necessarily restored from gm. * * - gf is used by the gcode parser interpreter to hold flags for any data - * that has changed in gn during the parse. gc.gf.target[] values are also used + * that has changed in gn during the parse. gp.gf.target[] values are also used * by the canonical machine during set_target(). * * - cfg (config struct in config.h) is also used heavily and contains some @@ -279,7 +279,6 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used uint16_t magic_end; } GCodeStateX_t; - // Structures used by Gcode parser typedef struct GCodeInput { // Gcode model inputs - meaning depends on context @@ -369,21 +368,11 @@ typedef struct GCodeFlags { // Gcode model input flags } GCodeFlags_t; typedef struct GCodeParser { - - // gcode power-on default settings - defaults are not the same as the gm state - cmCoordSystem default_coord_system; // G10 active coordinate system default - cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default - cmUnitsMode default_units_mode; // G20,G21 reset default - cmPathControl default_path_control; // G61,G61.1,G64 reset default - cmDistanceMode default_distance_mode; // G90,G91 reset default - GCodeInput_t gn; // gcode input values - transient GCodeFlags_t gf; // gcode input flags - transient - } GCodeParser_t; -extern GCodeParser_t gc; - +extern GCodeParser_t gp; /* * Global Scope Functions diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 6999721e..787d6882 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -27,7 +27,16 @@ #include "util.h" #include "xio.h" // for char definitions -GCodeParser gc; +GCodeParser gp; + +/* TODO + A series of leakages of the gp.gn and gp.gf structs that should be parameterized in the function arguments: + - cm_set_g10_data() + - cm_set_tl_offset() + - cm_mfo_enable() + - cycle_homing / _get_next_axis() + - others? + */ // local helper functions and macros static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); @@ -37,9 +46,9 @@ static stat_t _validate_gcode_block(char *active_comment); static stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs static stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block -#define SET_MODAL(m,parm,val) ({gc.gn.parm=val; gc.gf.parm=true; gc.gf.modals[m]=true; break;}) -#define SET_NON_MODAL(parm,val) ({gc.gn.parm=val; gc.gf.parm=true; break;}) -#define EXEC_FUNC(f,v) if(gc.gf.v) { status=f(gc.gn.v);} +#define SET_MODAL(m,parm,val) ({gp.gn.parm=val; gp.gf.parm=true; gp.gf.modals[m]=true; break;}) +#define SET_NON_MODAL(parm,val) ({gp.gn.parm=val; gp.gf.parm=true; break;}) +#define EXEC_FUNC(f,v) if(gp.gf.v) { status=f(gp.gn.v);} /* * gcode_parser_init() @@ -47,8 +56,8 @@ static stat_t _execute_gcode_block(char *active_comment); // Execute t void gcode_parser_init() { - memset(&gc.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs - memset(&gc.gf, 0, sizeof(GCodeFlags_t)); + memset(&gp.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs + memset(&gp.gf, 0, sizeof(GCodeFlags_t)); } /* @@ -399,12 +408,12 @@ static stat_t _validate_gcode_block(char *active_comment) // uses axis words appears on the line, the activity of the group 1 G-code is suspended // for that line. The axis word-using G-codes from group 0 are G10, G28, G30, and G92" -// if ((gc.gn.modals[MODAL_GROUP_G0] == true) && (gc.gn.modals[MODAL_GROUP_G1] == true)) { +// if ((gp.gn.modals[MODAL_GROUP_G0] == true) && (gp.gn.modals[MODAL_GROUP_G1] == true)) { // return (STAT_MODAL_GROUP_VIOLATION); // } // look for commands that require an axis word to be present -// if ((gc.gn.modals[MODAL_GROUP_G0] == true) || (gc.gn.modals[MODAL_GROUP_G1] == true)) { +// if ((gp.gn.modals[MODAL_GROUP_G0] == true) || (gp.gn.modals[MODAL_GROUP_G1] == true)) { // if (_axis_changed() == false) // return (STAT_GCODE_AXIS_IS_MISSING); // } @@ -427,16 +436,16 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) stat_t status = STAT_OK; // set initial state for new move - memset(&gc.gn, 0, sizeof(GCodeInput_t)); // clear all next-state values - memset(&gc.gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags - gc.gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block + memset(&gp.gn, 0, sizeof(GCodeInput_t)); // clear all next-state values + memset(&gp.gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags + gp.gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block // Causes a later exception if // (1) INVERSE_TIME_MODE is active and a feed rate is not provided or // (2) INVERSE_TIME_MODE is changed to UNITS_PER_MINUTE and a new feed rate is missing if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate req'd when in INV_TIME_MODE - gc.gn.feed_rate = 0; - gc.gf.feed_rate = true; + gp.gn.feed_rate = 0; + gp.gf.feed_rate = true; } // extract commands and parameters @@ -640,7 +649,7 @@ static stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; - cm_set_model_linenum(gc.gn.linenum); + cm_set_model_linenum(gp.gn.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, feed_rate); // F EXEC_FUNC(cm_set_spindle_speed, spindle_speed); // S @@ -662,20 +671,20 @@ static stat_t _execute_gcode_block(char *active_comment) // EXEC_FUNC(cm_mfo_enable, feed_rate_override_factor); // EXEC_FUNC(cm_sso_enable, sso_enable); - if (gc.gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell - ritorno(cm_dwell(gc.gn.parameter)); // return if error, otherwise complete the block + if (gp.gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell + ritorno(cm_dwell(gp.gn.parameter)); // return if error, otherwise complete the block } EXEC_FUNC(cm_select_plane, select_plane); // G17, G18, G19 EXEC_FUNC(cm_set_units_mode, units_mode); // G20, G21 //--> cutter radius compensation goes here - switch (gc.gn.next_action) { // Tool length offsets + switch (gp.gn.next_action) { // Tool length offsets case NEXT_ACTION_SET_TL_OFFSET: { // G43 - ritorno(cm_set_tl_offset(gc.gn.H_word, false)); + ritorno(cm_set_tl_offset(gp.gn.H_word, false)); break; } case NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET: { // G43.2 - ritorno(cm_set_tl_offset(gc.gn.H_word, true)); + ritorno(cm_set_tl_offset(gp.gn.H_word, true)); break; } case NEXT_ACTION_CANCEL_TL_OFFSET: { // G49 @@ -686,29 +695,29 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_set_coord_system, coord_system); // G54, G55, G56, G57, G58, G59 // EXEC_FUNC(cm_set_path_control, path_control); // G61, G61.1, G64 - if(gc.gf.path_control) { status = cm_set_path_control(MODEL, gc.gn.path_control); } + if(gp.gf.path_control) { status = cm_set_path_control(MODEL, gp.gn.path_control); } EXEC_FUNC(cm_set_distance_mode, distance_mode); // G90, G91 EXEC_FUNC(cm_set_arc_distance_mode, arc_distance_mode); // G90.1, G91.1 //--> set retract mode goes here - switch (gc.gn.next_action) { + switch (gp.gn.next_action) { case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gc.gn.target, gc.gf.target); break;} // G28 + case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gp.gn.target, gp.gf.target); break;} // G28 case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gc.gn.target, gc.gf.target); break;} // G30 + case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gp.gn.target, gp.gf.target); break;} // G30 case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gc.gn.target, gc.gf.target); break;}// G28.3 + case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gp.gn.target, gp.gf.target); break;}// G28.3 case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(); break;} // G28.4 - case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gc.gn.target, gc.gf.target, true, true); break;} // G38.2 - case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gc.gn.target, gc.gf.target, false, true); break;} // G38.3 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gc.gn.target, gc.gf.target, true, false); break;} // G38.4 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gc.gn.target, gc.gf.target, false, false); break;} // G38.5 + case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gp.gn.target, gp.gf.target, true, true); break;} // G38.2 + case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gp.gn.target, gp.gf.target, false, true); break;} // G38.3 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gp.gn.target, gp.gf.target, true, false); break;} // G38.4 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gp.gn.target, gp.gf.target, false, false); break;} // G38.5 - case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gc.gn.parameter, gc.gn.L_word, gc.gn.target, gc.gf.target); break;} - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gc.gn.target, gc.gf.target); break;}// G92 + case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gp.gn.parameter, gp.gn.L_word, gp.gn.target, gp.gf.target); break;} + case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gp.gn.target, gp.gf.target); break;}// G92 case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 @@ -718,18 +727,18 @@ static stat_t _execute_gcode_block(char *active_comment) // case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 case NEXT_ACTION_DEFAULT: { - cm_set_absolute_override(MODEL, gc.gn.absolute_override); // apply absolute override - switch (gc.gn.motion_mode) { - case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gc.gn.motion_mode; break;} // G80 - case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gc.gn.target, gc.gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gc.gn.target, gc.gf.target); break;} // G1 + cm_set_absolute_override(MODEL, gp.gn.absolute_override); // apply absolute override + switch (gp.gn.motion_mode) { + case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gp.gn.motion_mode; break;} // G80 + case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gp.gn.target, gp.gf.target); break;} // G0 + case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gp.gn.target, gp.gf.target); break;} // G1 case MOTION_MODE_CW_ARC: // G2 - case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gc.gn.target, gc.gf.target, // G3 - gc.gn.arc_offset, gc.gf.arc_offset, - gc.gn.arc_radius, gc.gf.arc_radius, - gc.gn.parameter, gc.gf.parameter, - gc.gf.modals[MODAL_GROUP_G1], - gc.gn.motion_mode); + case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gp.gn.target, gp.gf.target, // G3 + gp.gn.arc_offset, gp.gf.arc_offset, + gp.gn.arc_radius, gp.gf.arc_radius, + gp.gn.parameter, gp.gf.parameter, + gp.gf.modals[MODAL_GROUP_G1], + gp.gn.motion_mode); break; } default: break; @@ -739,8 +748,8 @@ static stat_t _execute_gcode_block(char *active_comment) } // do the program stops and ends : M0, M1, M2, M30, M60 - if (gc.gf.program_flow == true) { - if (gc.gn.program_flow == PROGRAM_STOP) { + if (gp.gf.program_flow == true) { + if (gp.gn.program_flow == PROGRAM_STOP) { cm_program_stop(); } else { cm_program_end(); diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 076f728f..b90492b4 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -2,7 +2,7 @@ * spindle.cpp - canonical machine spindle driver * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -228,7 +228,7 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) /* stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 { - if (fp_TRUE(gc.gf.parameter) && fp_ZERO(gc.gn.parameter)) { + if (fp_TRUE(gp.gf.parameter) && fp_ZERO(gp.gn.parameter)) { spindle.override_enable = false; } else { spindle.override_enable = true; @@ -239,7 +239,7 @@ stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 stat_t cm_spindle_override_factor(uint8_t flag) // M50.1 { spindle.override_enable = flag; - spindle.override_factor = gc.gn.parameter; + spindle.override_factor = gp.gn.parameter; // change spindle speed return (STAT_OK); } From 9b6ae6c5539a8263bf10907e199b4460b1dba4e8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 11 Jan 2017 11:12:18 -0500 Subject: [PATCH 061/283] Switch is working enough to take commands --- g2core/canonical_machine.cpp | 68 +++++++++++------------------------- g2core/canonical_machine.h | 3 +- g2core/plan_line.cpp | 12 +++---- g2core/planner.cpp | 5 +-- 4 files changed, 29 insertions(+), 59 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index e126a8b1..2371c672 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -151,7 +151,7 @@ void canonical_machine_init(cmMachine_t *_cm, void *_mp) canonical_machine_init_assertions(_cm); // establish assertions cm_arc_init(_cm); // setup arcs. Note: spindle and coolant inits are independent _cm->mp = _mp; // point to associated planner - ACTIVE_MODEL = MODEL; // setup initial Gcode model pointer + _cm->am = MODEL; // setup initial Gcode model pointer } // *** Note: Run canonical_machine_init and profile initializations beforehand *** @@ -244,37 +244,39 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) stat_t cm_switch(nvObj_t *nv) { - // Test for: - // - must be in the correct CM - // - must be fully stopped in a hold + // Must be in the correct CM and must be fully stopped in a hold if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { nv->valuetype = TYPE_NULL; return (STAT_COMMAND_NOT_ACCEPTED); } - // initialize the secondary context to agree with the primary + // copy the primary canonical machine to the secondary, + // fix the planner pointer, and reset the secondary planner memcpy(&cm2, &cm1, sizeof(cmMachine_t)); cm2.mp = &mp2; planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - // now make the changes so you can actually use it + // set parameters in cm, gm and gmx so you can actually use it cmMachine_t *_cm = &cm2; - _cm->motion_state = MOTION_STOP; _cm->hold_state = FEEDHOLD_OFF; _cm->hold_disabled = true; - - // setup the gm and gmx _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; _cm->gm.feed_rate = 0; - memset(&(_cm->gm.target), 0 , sizeof(_cm->gm.target)); - memset(&(_cm->gm.target_comp), 0 , sizeof(_cm->gm.target_comp)); - copy_vector(_cm->gmx.position, mr->position); // get the current holding position + + // clear the target and set the positions to the current hold position + memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); + memset(&(_cm->gm.target_comp), 0, sizeof(_cm->gm.target_comp)); + copy_vector(_cm->gmx.position, mr->position); + copy_vector(mp2.position, mr->position); - // reassign the globals to the secondary planner (this must be last) + // reassign the globals to the secondary planner (this must be next-to-last) cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer mr = mp->mr; + + // finally, set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 + cm_set_motion_state(MOTION_STOP); return (STAT_OK); } @@ -377,7 +379,6 @@ cmCombinedState cm_get_combined_state() /* These getters and setters will work on any gm model with inputs: * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ @@ -465,12 +466,8 @@ float cm_get_active_coord_offset(const uint8_t axis) } /* - * cm_get_work_offset() - return a coord offset from the gcode_state - * - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to - * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm->am // active model pointer is maintained by state management + * cm_get_work_offset() - return a coord offset from the active Gcode dynamic model + * cm_set_work_offsets() - capture coord offsets from the model into absolute values in the active Gcode dynamic model */ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) @@ -478,15 +475,6 @@ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) return (gcode_state->work_offset[axis]); } -/* - * cm_set_work_offsets() - capture coord offsets from the model into absolute values in the gcode_state - * - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to - * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm->am // active model pointer is maintained by state management - */ - void cm_set_work_offsets(GCodeState_t *gcode_state) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { @@ -495,14 +483,9 @@ void cm_set_work_offsets(GCodeState_t *gcode_state) } /* - * cm_get_absolute_position() - get position of axis in absolute coordinates + * cm_get_absolute_position() - get position of axis in absolute coordinates from the active Gcode dynamic model * - * This function accepts as input: - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct - * - * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) - * NOTE: Machine position is always returned in mm mode. No units conversion is performed + * ... machine position is always returned in mm mode. No units conversion is performed */ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t axis) @@ -514,18 +497,9 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax } /* - * cm_get_work_position() - return work position in external form + * cm_get_work_position() - return work position in external form from the active Gcode dynamic model * * ... that means in prevailing units (mm/inch) and with all offsets applied - * - * NOTE: This function only works after the gcode_state struct as had the work_offsets setup by - * calling cm_get_model_coord_offset_vector() first. - * - * This function accepts as input: - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct - * - * NOTE: Only MODEL and RUNTIME are supported (no PLANNER or bf's) */ float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index ca93ff99..b6e1fea7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -39,9 +39,8 @@ /* Defines, Macros, and Assorted Parameters */ #define MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model -#define PLANNER (GCodeState_t *)&bf->gm // relative to buffer *bf is currently pointing to #define RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct -#define ACTIVE_MODEL cm->am // active model pointer is maintained by state management +#define ACTIVE_MODEL cm->am // active model pointer is maintained by cm_set_motion_state() #define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 90067fef..67f16b90 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -180,7 +180,7 @@ stat_t mp_aline(GCodeState_t* gm_in) gm_in->target[2] * cm->rotation_matrix[2][2] + cm->rotation_z_offset; - // copy rotation axes ABC + // copy rotation axes for ABC (no changes) target_rotated[3] = gm_in->target[3]; target_rotated[4] = gm_in->target[4]; target_rotated[5] = gm_in->target[5]; @@ -204,13 +204,13 @@ stat_t mp_aline(GCodeState_t* gm_in) // get a cleared buffer and copy in the Gcode model state mpBuf_t* bf = mp_get_write_buffer(); + if (bf == NULL) { // never supposed to fail -// if ((bf = mp_get_write_buffer()) == NULL) { // never supposed to fail return (cm_panic(STAT_FAILED_GET_PLANNER_BUFFER, "aline()")); } memcpy(&bf->gm, gm_in, sizeof(GCodeState_t)); // Since bf->gm.target is being used all over the place, we'll make it the rotated target - copy_vector(bf->gm.target, target_rotated); // copy the rotated taget in place + copy_vector(bf->gm.target, target_rotated); // copy the rotated target in place // setup the buffer bf->bf_func = mp_exec_aline; // register the callback to the exec function @@ -225,7 +225,7 @@ stat_t mp_aline(GCodeState_t* gm_in) _set_bf_diagnostics(bf); //+++++DIAGNOSTIC // Note: these next lines must remain in exact order. Position must update before committing the buffer. - copy_vector(mp->position, bf->gm.target); // set the planner position + copy_vector(mp->position, bf->gm.target); // set the planner position mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) return (STAT_OK); } @@ -304,8 +304,8 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) if (bf->nx->plannable) { // read in new buffers until EMPTY return (bf->nx); } - mp->planning_return = bf->nx; // where to return after planning is complete - mp->planner_state = PLANNER_BACK_PLANNING; // start backplanning + mp->planning_return = bf->nx; // where to return after planning is complete + mp->planner_state = PLANNER_BACK_PLANNING; // start backplanning } // Backward Planning Pass diff --git a/g2core/planner.cpp b/g2core/planner.cpp index c775711d..3054d9af 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -747,15 +747,12 @@ mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); } mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } */ -//mpBuf_t * mp_get_w(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].w : mb.q[q].w); } -//mpBuf_t * mp_get_r(int8_t q) { return ((q == ACTIVE_Q) ? mb.q[mb.active_q].r : mb.q[q].r); } - mpBuf_t * mp_get_w() { return (mp->q.w); } //++++ should this be a DI function? mpBuf_t * mp_get_r() { return (mp->q.r); } //+++++ ditto mpBuf_t * mp_get_write_buffer() // get & clear a buffer { -// mpQueue_t *q = &mb.q[mb.active_q]; + mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state == MP_BUFFER_EMPTY) { From d98a74fa6296b5b9a443548a32a39b4e60f3e34b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 11 Jan 2017 17:29:54 -0500 Subject: [PATCH 062/283] Executes manual pullup and return --- g2core/canonical_machine.cpp | 92 +++++++++++++++++++++++++++++++----- g2core/canonical_machine.h | 15 ++++-- g2core/controller.cpp | 1 + g2core/cycle_homing.cpp | 6 +-- g2core/cycle_probing.cpp | 9 ++-- g2core/g2core.cppproj | 4 +- g2core/main.cpp | 10 +--- g2core/plan_arc.cpp | 6 --- g2core/planner.cpp | 3 -- 9 files changed, 103 insertions(+), 43 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 2371c672..e7225677 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -37,9 +37,9 @@ * * Useful reference for doing C callbacks http://www.newty.de/fpt/fpt.html * - * There are 3 temporal contexts for system state: - * - The gcode model in the canonical machine (the MODEL context, held in gm) - * - The gcode model used by the planner (PLANNER context, held in bf's and mp) + * There are 3 layered contexts for dynamic system state ("gcode model"): + * - The gcode model in the canonical machine (the MODEL context, held in cm->gm) + * - The gcode model used by the planner (PLANNER context, held in mp & its buffers) * - The gcode model used during motion for reporting (RUNTIME context, held in mr) * * It's a bit more complicated than this. The 'gm' struct contains the core Gcode model @@ -110,9 +110,10 @@ #include "xio.h" // for serial queue flush /*********************************************************************************** - **** STRUCTURE ALLOCATIONS ******************************************************** + **** CM GLOBALS & STRUCTURE ALLOCATIONS ******************************************* ***********************************************************************************/ +cmMachineSelect cm_select; cmMachine_t *cm; // pointer to active canonical machine cmMachine_t cm1; // canonical machine primary machine cmMachine_t cm2; // canonical machine secondary machine @@ -136,11 +137,24 @@ static int8_t _axis(const index_t index); ***********************************************************************************/ /* + * canonical_machine_inits() - combined cm inits * canonical_machine_init() - initialize cm struct * canonical_machine_reset() - apply startup settings or reset to startup * canonical_machine_reset_rotation() */ +void canonical_machine_inits() +{ + planner_init(&mp1, &mr1, mp1_queue, PLANNER_QUEUE_SIZE); + planner_init(&mp2, &mr2, mp2_queue, SECONDARY_QUEUE_SIZE); + canonical_machine_init(&cm1, &mp1); // primary canonical machine + canonical_machine_init(&cm2, &mp2); // secondary canonical machine + cm = &cm1; // set global canonical machine pointer to primary machine + mp = &mp1; // set global pointer to the primary planner + mr = &mr1; // and primary runtime + cm_select = CM_PRIMARY; +} + void canonical_machine_init(cmMachine_t *_cm, void *_mp) { // Note cm* was assignd in main() @@ -244,7 +258,7 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) stat_t cm_switch(nvObj_t *nv) { - // Must be in the correct CM and must be fully stopped in a hold + // Must be in the primary CM and fully stopped in a hold if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { nv->valuetype = TYPE_NULL; return (STAT_COMMAND_NOT_ACCEPTED); @@ -259,36 +273,81 @@ stat_t cm_switch(nvObj_t *nv) // set parameters in cm, gm and gmx so you can actually use it cmMachine_t *_cm = &cm2; _cm->hold_state = FEEDHOLD_OFF; - _cm->hold_disabled = true; _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; _cm->gm.feed_rate = 0; + // clear the target and set the positions to the current hold position memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); - memset(&(_cm->gm.target_comp), 0, sizeof(_cm->gm.target_comp)); +// memset(&(_cm->gm.target_comp), 0, sizeof(_cm->gm.target_comp)); + copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation copy_vector(_cm->gmx.position, mr->position); copy_vector(mp2.position, mr->position); + copy_vector(mr2.position, mr->position); - // reassign the globals to the secondary planner (this must be next-to-last) + // reassign the globals to the secondary CM (this must be next-to-last) cm = &cm2; mp = (mpPlanner_t *)cm->mp; // mp is a void pointer mr = mp->mr; + cm_select = CM_SECONDARY; // finally, set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 + cm_set_g30_position(); cm_set_motion_state(MOTION_STOP); return (STAT_OK); } -stat_t cm_return(nvObj_t *nv) // if value == true return with offset corrections +static void _return_move_callback(float* vect, bool* flag) { - // reset the globals to the primary planner - cm = &cm1; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; + cm2.waiting_for_motion_end = false; +} + +stat_t cm_return(nvObj_t *nv) // LATER: if value == true return with offset corrections +{ + // Must be in the secondary CM and fully stopped + if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { + nv->valuetype = TYPE_NULL; + return (STAT_COMMAND_NOT_ACCEPTED); + } + + // while still in secondary, perform the G30 move and queue a wait + float target[] = { 0,0,0,0,0,0 }; + bool flags[] = { 0,0,0,0,0,0 }; + cm_goto_g30_position(target, flags); // initiate a return move + cm->waiting_for_motion_end = true; // indicates running the final G30 move in the secondary + mp_queue_command(_return_move_callback, nullptr, nullptr); + cm_select = CM_SECONDARY_RETURN; return (STAT_OK); } +stat_t cm_return_callback() +{ + if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner + return (STAT_NOOP); + } + if (cm->waiting_for_motion_end) { // sync to planner move ends (using callback) + return (STAT_EAGAIN); + } + + // return to primary CM + cm = &cm1; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + cm_select = CM_PRIMARY; + cm_set_motion_state(MOTION_STOP); // sets active model to primary + + cm_end_hold(); + return (STAT_OK); +} + +/* +stat_t cm_return_from_hold_callback() +{ + +} +*/ + /************************************* * Internal getters and setters * * Canonical Machine State functions * @@ -1828,6 +1887,13 @@ stat_t cm_feedhold_sequencing_callback() cm_end_hold(); } } +/* + if (cm->return_hold_requested) { + if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing + cm_end_hold(); + } + } +*/ return (STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index b6e1fea7..ce0e9ec2 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -145,6 +145,13 @@ typedef enum { // queue flush state machine FLUSH_REQUESTED, // flush has been requested but not started yet } cmQueueFlushState; +typedef enum { + CM_NOT_INIT = 0, // planners need initialization + CM_PRIMARY, // in primary machine/planner + CM_SECONDARY, // in secondary machine/planner + CM_SECONDARY_RETURN // in return move from secondary planner +} cmMachineSelect; + /***************************************************************************** * CANONICAL MACHINE STRUCTURES */ @@ -248,11 +255,9 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot -// bool g28_flag; // true = complete a G28 move (transient state) -// bool g30_flag; // true = complete a G30 move - bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them - bool hold_disabled; // set true when in secondary planner to disable feedhold requests + bool waiting_for_motion_end; // set true during a return-to-primary planner operation (G30 is completing) bool end_hold_requested; // request restart after feedhold + bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) @@ -345,6 +350,7 @@ stat_t cm_test_soft_limits(const float target[]); /*--- Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc] ---*/ // Initialization and termination (4.3.2) +void canonical_machine_inits(void); void canonical_machine_init(cmMachine_t *_cm, void *_mp); void canonical_machine_reset_rotation(cmMachine_t *_cm); // NOT in NIST void canonical_machine_reset(cmMachine_t *_cm); @@ -430,6 +436,7 @@ void cm_request_end_hold(void); void cm_request_queue_flush(void); void cm_request_end_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests +stat_t cm_return_callback(void); // return from secondary planner bool cm_has_hold(void); void cm_start_hold(void); diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 77314281..897b3976 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -161,6 +161,7 @@ static void _controller_HSM() DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(mp_planner_callback()); // motion planner + DISPATCH(cm_return_callback()); // return from secondary planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index 4767f099..c9858f79 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -180,7 +180,7 @@ stat_t cm_homing_cycle_start(void) { stat_t cm_homing_cycle_start_no_set(void) { cm_homing_cycle_start(); - hm.set_coordinates = false; // set flag to not update position variables at the end of the cycle + hm.set_coordinates = false; // set flag to not update position variables at the end of the cycle return (STAT_OK); } @@ -188,10 +188,10 @@ stat_t cm_homing_cycle_callback(void) { if (cm->cycle_state != CYCLE_HOMING) { // exit if not in a homing cycle return (STAT_NOOP); } - if (hm.waiting_for_motion_end) { // sync to planner move ends (using callback) + if (hm.waiting_for_motion_end) { // sync to planner move ends (using callback) return (STAT_EAGAIN); } - return (hm.func(hm.axis)); // execute the current homing move + return (hm.func(hm.axis)); // execute the current homing move } /* diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 45391149..e44d65ef 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -142,7 +142,7 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, b return (STAT_AXIS_IS_MISSING); } - pb.failure_is_fatal = failure_is_fatal; + pb.failure_is_fatal = failure_is_fatal; pb.moving_toward_switch = moving_toward_switch; copy_vector(pb.target, target); // set probe move endpoint @@ -158,7 +158,7 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, b clear_vector(cm->probe_results[0]); // clear the old probe position // NOTE: relying on probe_result will not detect a probe to 0,0,0. - cm->probe_state[0] = PROBE_WAITING; // wait until planner queue empties before completing initialization + cm->probe_state[0] = PROBE_WAITING; // wait until planner queue empties before completing initialization pb.waiting_for_motion_end = true; // queue a function to let us know when we can start probing @@ -332,7 +332,10 @@ static stat_t _probe_axis_move(const float target[], bool exact_position) { return (STAT_EAGAIN); } -static void _probe_axis_move_callback(float* vect, bool* flag) { pb.waiting_for_motion_end = false; } +static void _probe_axis_move_callback(float* vect, bool* flag) +{ + pb.waiting_for_motion_end = false; +} /* * _probing_finish() - report probe results and clean up diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index c8cc86a8..d57acc1f 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/main.cpp b/g2core/main.cpp index ccbe5c3d..4ae783f9 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -108,19 +108,11 @@ void application_init_machine(void) encoder_init(); // virtual encoders gpio_init(); // inputs and outputs pwm_init(); // pulse width modulation drivers - - planner_init(&mp1, &mr1, mp1_queue, PLANNER_QUEUE_SIZE); - planner_init(&mp2, &mr2, mp2_queue, SECONDARY_QUEUE_SIZE); - canonical_machine_init(&cm1, &mp1); // primary canonical machine - canonical_machine_init(&cm2, &mp2); // secondary canonical machine + canonical_machine_inits(); // combined inits for CMs and planner } void application_init_startup(void) { - cm = &cm1; // set global canonical machine pointer to primary machine - mp = &mp1; // set global pointer to the primary planner - mr = &mr1; // and primary runtime - // start the application controller_init(); // should be first startup init (requires xio_init()) config_init(); // apply the config settings from persistence diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 99403d63..49389f29 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -24,10 +24,6 @@ #include "planner.h" #include "util.h" -// Allocate arc planner singleton structure - -//arc_t arc; - // Local functions static stat_t _compute_arc(const bool radius_f); @@ -69,8 +65,6 @@ void cm_abort_arc(cmMachine_t *_cm) * * cm_arc_cycle_callback() is called from the controller main loop. Each time it's called * it queues as many arc segments (lines) as it can before it blocks, then returns. - * - * Parts of this routine were informed by the grbl project. */ stat_t cm_arc_callback(cmMachine_t *_cm) diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 3054d9af..a26208ad 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -768,7 +768,6 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer void mp_unget_write_buffer() // mark buffer as empty and adjust free buffer count { -// mpQueue_t *q = &mb.q[mb.active_q]; mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state != MP_BUFFER_EMPTY) { // safety. Can't unget an empty buffer @@ -784,7 +783,6 @@ void mp_unget_write_buffer() // mark buffer as empty and adjust free buff void mp_commit_write_buffer(const blockType block_type) { -// mpQueue_t *q = &mb.q[mb.active_q]; mpPlannerQueue_t *q = &(mp->q); q->w->block_type = block_type; @@ -815,7 +813,6 @@ void mp_commit_write_buffer(const blockType block_type) // (2) is the buffer in error - i.e. not yet ready for running? mpBuf_t * mp_get_run_buffer() { -// mpBuf_t *r = mb.q[mb.active_q].r; mpBuf_t *r = mp->q.r; if (r->buffer_state == MP_BUFFER_EMPTY) { From ca546db67d92cb65694cd602a01399adb854db01 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 12 Jan 2017 08:52:12 -0500 Subject: [PATCH 063/283] Intermediate checkpoint for isolating Gcode parser --- g2core/canonical_machine.cpp | 79 +++++++++++++----- g2core/canonical_machine.h | 23 +++--- g2core/cycle_homing.cpp | 75 +++++++++-------- g2core/g2core.cppproj | 4 +- g2core/gcode.h | 14 ++-- g2core/gcode_parser.cpp | 153 ++++++++++++++++++++++++++++------- g2core/planner.cpp | 10 +++ g2core/planner.h | 2 + g2core/spindle.cpp | 53 +++++++++--- g2core/spindle.h | 8 +- 10 files changed, 310 insertions(+), 111 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index e7225677..f66bcd87 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1135,10 +1135,12 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode) * cm_set_work_offsets() immediately afterwards. */ -stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word, +stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, + const uint8_t L_word, const bool L_flag, const float offset[], const bool flag[]) { - if (!gp.gf.L_word) { +// if (!gp.gf.L_word) { + if (!L_flag) { return (STAT_L_WORD_IS_MISSING); } @@ -1199,11 +1201,11 @@ stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word, * cm_set_coord_system() - G54-G59 * _exec_offset() - callback from planner */ -stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional) +stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool apply_additional) { uint8_t tool; - if (gp.gf.H_word) - { +/* + if (gp.gf.H_word) { if (gp.gn.H_word > TOOLS) { return (STAT_H_WORD_IS_INVALID); } @@ -1212,6 +1214,16 @@ stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional) } else { tool = gp.gn.H_word; } +*/ + if (H_flag) { + if (H_word > TOOLS) { + return (STAT_H_WORD_IS_INVALID); + } + if (H_word == 0) { // interpret H0 as "current tool", just like no H at all. + tool = cm->gm.tool; + } else { + tool = H_word; + } } else { tool = cm->gm.tool; } @@ -1692,7 +1704,7 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 } /* - * cm_feed_rate_override_enable() - M50 + * cm_mfo_control() - M50 manual feed rate override comtrol * * M50 enables manual feedrate override and the optional P override parameter. * P is expressed as M% to N% of programmed feedrate, typically a value from 0.05 to 2.000. @@ -1731,39 +1743,64 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 * ENABLE ENABLE M50 Pn ENABLE start ramp w/new P value; store P value * (Note: new ramp will supercede any existing ramp) */ -stat_t cm_mfo_enable(uint8_t enable) // M50 + +stat_t cm_mfo_control(const float P_word, const bool P_flag) // M50 { bool new_enable = true; bool new_override = false; - if (gp.gf.parameter) { // if parameter is present in Gcode block - if (fp_ZERO(gp.gn.parameter)) { - new_enable = false; // P0 disables override + if (P_flag) { // if parameter is present in Gcode block + if (fp_ZERO(P_word)) { + new_enable = false; // P0 disables override } else { - if (gp.gn.parameter < FEED_OVERRIDE_MIN) { + if (P_word < FEED_OVERRIDE_MIN) { return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (gp.gn.parameter > FEED_OVERRIDE_MAX) { + if (P_word > FEED_OVERRIDE_MAX) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - cm->gmx.mfo_factor = gp.gn.parameter; // it validates - store it. + cm->gmx.mfo_factor = P_word; // P word is valid, store it. new_override = true; } } - if (cm->gmx.m48_enable) { // if master enable is ON + if (cm->gmx.m48_enable) { // if master enable is ON if (new_enable && (new_override || !cm->gmx.mfo_enable)) { // 3 cases to start a ramp mp_start_feed_override(FEED_OVERRIDE_RAMP_TIME, cm->gmx.mfo_factor); } else if (cm->gmx.mfo_enable && !new_enable) { // case to turn off the ramp mp_end_feed_override(FEED_OVERRIDE_RAMP_TIME); } } - cm->gmx.mfo_enable = new_enable; // always update the enable state + cm->gmx.mfo_enable = new_enable; // always update the enable state return (STAT_OK); } -// if ((new_enable && new_override) || (new_enable && !cm->gmx.mfo_enable)) { -// if (!(cm->gmx.mfo_enable && new_override)) { - - +stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 +{ + bool new_enable = true; + bool new_override = false; + if (P_flag) { // if parameter is present in Gcode block + if (fp_ZERO(P_word)) { + new_enable = false; // P0 disables override + } else { + if (P_word < TRAVERSE_OVERRIDE_MIN) { + return (STAT_INPUT_LESS_THAN_MIN_VALUE); + } + if (P_word > TRAVERSE_OVERRIDE_MAX) { + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + cm->gmx.mto_factor = P_word; // P word is valid, store it. + new_override = true; + } + } + if (cm->gmx.m48_enable) { // if master enable is ON + if (new_enable && (new_override || !cm->gmx.mfo_enable)) { // 3 cases to start a ramp + mp_start_traverse_override(FEED_OVERRIDE_RAMP_TIME, cm->gmx.mto_factor); + } else if (cm->gmx.mto_enable && !new_enable) { // case to turn off the ramp + mp_end_traverse_override(FEED_OVERRIDE_RAMP_TIME); + } + } + cm->gmx.mto_enable = new_enable; // always update the enable state + return (STAT_OK); +} /************************************************ * Feedhold and Related Functions (no NIST ref) * ************************************************/ @@ -2707,7 +2744,9 @@ stat_t cm_run_qf(nvObj_t *nv) stat_t cm_run_home(nvObj_t *nv) { if (fp_TRUE(nv->value)) { - cm_homing_cycle_start(); + float axes[] = { 1,1,1,1,1,1 }; + bool flags[] = { 1,1,1,1,1,1 }; + cm_homing_cycle_start(axes, flags); } return (STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index ce0e9ec2..7d58e830 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -376,9 +376,12 @@ stat_t cm_select_plane(const uint8_t plane); // G stat_t cm_set_units_mode(const uint8_t mode); // G20, G21 stat_t cm_set_distance_mode(const uint8_t mode); // G90, G91 stat_t cm_set_arc_distance_mode(const uint8_t mode); // G90.1, G91.1 -stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional); // G43, G43.2 +//stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional); // G43, G43.2 +stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, // G43, G43.2 + const bool apply_additional); stat_t cm_cancel_tl_offset(void); // G49 -stat_t cm_set_g10_data(const uint8_t P_word, const uint8_t L_word, // G10 +stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, // G10 + const uint8_t L_word, const bool L_flag, const float offset[], const bool flag[]); void cm_set_position(const uint8_t axis, const float position); // set absolute position - single axis @@ -418,17 +421,19 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // G // see spindle.h for spindle functions - which would go right here // Tool Functions (4.3.8) -stat_t cm_select_tool(const uint8_t tool); // T parameter -stat_t cm_change_tool(const uint8_t tool); // M6 +stat_t cm_select_tool(const uint8_t tool); // T parameter +stat_t cm_change_tool(const uint8_t tool); // M6 // Miscellaneous Functions (4.3.9) // see coolant.h for coolant functions - which would go right here -void cm_message(const char *message); // msg to console (e.g. Gcode comments) +void cm_message(const char *message); // msg to console (e.g. Gcode comments) void cm_reset_overrides(void); -stat_t cm_m48_enable(uint8_t enable); // M48, M49 -stat_t cm_mfo_enable(uint8_t enable); // M50 +stat_t cm_m48_enable(uint8_t enable); // M48, M49 +stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50 +stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1 +// See spindle.cpp for cm_sso_control() // M51 // Program Functions (4.3.10) void cm_request_feedhold(void); @@ -458,8 +463,8 @@ stat_t cm_json_wait(char *json_string); // M102 /*--- Cycles ---*/ // Homing cycles -stat_t cm_homing_cycle_start(void); // G28.2 -stat_t cm_homing_cycle_start_no_set(void); // G28.4 +stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2 +stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]); // G28.4 stat_t cm_homing_cycle_callback(void); // G28.2/.4 main loop callback // Probe cycles diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index c9858f79..adb1b4ba 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -59,6 +59,9 @@ struct hmHomingSingleton { // persistent homing runtime variables float max_clear_backoff; // maximum distance of switch clearing backoffs before erring out float setpoint; // ultimate setpoint, usually zero, but not always +// float axes[AXES]; // local storage for axis words and associated flags + bool axis_flags[AXES]; + // state saved from gcode model cmUnitsMode saved_units_mode; // G20,G21 global setting cmCoordSystem saved_coord_system; // G54 - G59 setting @@ -152,7 +155,7 @@ static stat_t _set_homing_func(stat_t (*func)(int8_t axis)) { * to cm_get_runtime_busy() is about. */ -stat_t cm_homing_cycle_start(void) { +stat_t cm_homing_cycle_start(const float axes[], const bool flags[]) { // save relevant non-axis parameters from Gcode model hm.saved_units_mode = (cmUnitsMode)cm_get_units_mode(ACTIVE_MODEL); hm.saved_coord_system = (cmCoordSystem)cm_get_coord_system(ACTIVE_MODEL); @@ -160,6 +163,9 @@ stat_t cm_homing_cycle_start(void) { hm.saved_feed_rate_mode = (cmFeedRateMode)cm_get_feed_rate_mode(ACTIVE_MODEL); hm.saved_feed_rate = cm_get_feed_rate(ACTIVE_MODEL); +// copy_vector(hm.axes, axes); + copy_vector(hm.axis_flags, flags); + // set working values cm_set_units_mode(MILLIMETERS); cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); @@ -178,8 +184,8 @@ stat_t cm_homing_cycle_start(void) { return (STAT_OK); } -stat_t cm_homing_cycle_start_no_set(void) { - cm_homing_cycle_start(); +stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]) { + cm_homing_cycle_start(axes, flags); hm.set_coordinates = false; // set flag to not update position variables at the end of the cycle return (STAT_OK); } @@ -207,6 +213,7 @@ stat_t cm_homing_cycle_callback(void) { */ static stat_t _homing_axis_start(int8_t axis) { + // get the first or next axis if ((axis = _get_next_axis(axis)) < 0) { // axes are done or error if (axis == -1) { // -1 is done @@ -407,38 +414,38 @@ static stat_t _homing_finalize_exit(int8_t axis) // third part of return to hom static int8_t _get_next_axis(int8_t axis) { #if (HOMING_AXES <= 4) if (axis == -1) { // inelegant brute force solution - if (gp.gf.target[AXIS_Z]) { + if (hm.axis_flags[AXIS_Z]) { return (AXIS_Z); } - if (gp.gf.target[AXIS_X]) { + if (hm.axis_flags[AXIS_X]) { return (AXIS_X); } - if (gp.gf.target[AXIS_Y]) { + if (hm.axis_flags[AXIS_Y]) { return (AXIS_Y); } - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } return (-2); // error } else if (axis == AXIS_Z) { - if (gp.gf.target[AXIS_X]) { + if (hm.axis_flags[AXIS_X]) { return (AXIS_X); } - if (gp.gf.target[AXIS_Y]) { + if (hm.axis_flags[AXIS_Y]) { return (AXIS_Y); } - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_X) { - if (gp.gf.target[AXIS_Y]) { + if (hm.axis_flags[AXIS_Y]) { return (AXIS_Y); } - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } } else if (axis == AXIS_Y) { - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } } @@ -446,73 +453,73 @@ static int8_t _get_next_axis(int8_t axis) { #else if (axis == -1) { - if (gp.gf.target[AXIS_Z]) { + if (hm.axis_flags[AXIS_Z]) { return (AXIS_Z); } - if (gp.gf.target[AXIS_X]) { + if (hm.axis_flags[AXIS_X]) { return (AXIS_X); } - if (gp.gf.target[AXIS_Y]) { + if (hm.axis_flags[AXIS_Y]) { return (AXIS_Y); } - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } - if (gp.gf.target[AXIS_B]) { + if (hm.axis_flags[AXIS_B]) { return (AXIS_B); } - if (gp.gf.target[AXIS_C]) { + if (hm.axis_flags[AXIS_C]) { return (AXIS_C); } return (-2); // error } else if (axis == AXIS_Z) { - if (gp.gf.target[AXIS_X]) { + if (hm.axis_flags[AXIS_X]) { return (AXIS_X); } - if (gp.gf.target[AXIS_Y]) { + if (hm.axis_flags[AXIS_Y]) { return (AXIS_Y); } - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } - if (gp.gf.target[AXIS_B]) { + if (hm.axis_flags[AXIS_B]) { return (AXIS_B); } - if (gp.gf.target[AXIS_C]) { + if (hm.axis_flags[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_X) { - if (gp.gf.target[AXIS_Y]) { + if (hm.axis_flags[AXIS_Y]) { return (AXIS_Y); } - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } - if (gp.gf.target[AXIS_B]) { + if (hm.axis_flags[AXIS_B]) { return (AXIS_B); } - if (gp.gf.target[AXIS_C]) { + if (hm.axis_flags[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_Y) { - if (gp.gf.target[AXIS_A]) { + if (hm.axis_flags[AXIS_A]) { return (AXIS_A); } - if (gp.gf.target[AXIS_B]) { + if (hm.axis_flags[AXIS_B]) { return (AXIS_B); } - if (gp.gf.target[AXIS_C]) { + if (hm.axis_flags[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_A) { - if (gp.gf.target[AXIS_B]) { + if (hm.axis_flags[AXIS_B]) { return (AXIS_B); } - if (gp.gf.target[AXIS_C]) { + if (hm.axis_flags[AXIS_C]) { return (AXIS_C); } } else if (axis == AXIS_B) { - if (gp.gf.target[AXIS_C]) { + if (hm.axis_flags[AXIS_C]) { return (AXIS_C); } } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index d57acc1f..c8cc86a8 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/gcode.h b/g2core/gcode.h index 07d14167..52790525 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -279,6 +279,7 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used uint16_t magic_end; } GCodeStateX_t; +/* // Structures used by Gcode parser typedef struct GCodeInput { // Gcode model inputs - meaning depends on context @@ -301,9 +302,9 @@ typedef struct GCodeInput { // Gcode model inputs - meaning depends float arc_offset[3]; // IJK - used by arc commands bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_enable; // M50 feedrate override enable - bool mto_enable; // Mxx traverse override enable - bool sso_enable; // M51 spindle speed override enable + bool mfo_control; // M50 feedrate override control + bool mto_control; // M50.1 traverse override control + bool sso_control; // M51 spindle speed override control uint8_t select_plane; // G17,G18,G19 - values to set plane to uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) @@ -339,9 +340,9 @@ typedef struct GCodeFlags { // Gcode model input flags bool feed_rate_mode; bool m48_enable; - bool mfo_enable; - bool mto_enable; - bool sso_enable; + bool mfo_control; + bool mto_control; + bool sso_control; bool select_plane; bool units_mode; @@ -373,6 +374,7 @@ typedef struct GCodeParser { } GCodeParser_t; extern GCodeParser_t gp; +*/ /* * Global Scope Functions diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 787d6882..fea72a69 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -27,16 +27,101 @@ #include "util.h" #include "xio.h" // for char definitions -GCodeParser gp; +// Structures used by Gcode parser -/* TODO - A series of leakages of the gp.gn and gp.gf structs that should be parameterized in the function arguments: - - cm_set_g10_data() - - cm_set_tl_offset() - - cm_mfo_enable() - - cycle_homing / _get_next_axis() - - others? - */ +typedef struct GCodeInput { // Gcode model inputs - meaning depends on context + + uint8_t next_action; // handles G modal group 1 moves & non-modals + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 + // G83, G84, G85, G86, G87, G88, G89 + + uint8_t program_flow; // used only by the gcode_parser + uint32_t linenum; // N word + float target[AXES]; // XYZABC where the move should go + + uint8_t H_word; // H word - used by G43s + uint8_t L_word; // L word - used by G10s + + float feed_rate; // F - normalized to millimeters/minute + uint8_t feed_rate_mode; // See cmFeedRateMode for settings + float parameter; // P - parameter used for dwell time in seconds, G10 coord select... + float arc_radius; // R - radius value in arc radius mode + float arc_offset[3]; // IJK - used by arc commands + + bool m48_enable; // M48/M49 input (enables for feed and spindle) + bool mfo_control; // M50 feedrate override control + bool mto_control; // M50.1 traverse override control + bool sso_control; // M51 spindle speed override control + + uint8_t select_plane; // G17,G18,G19 - values to set plane to + uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) + uint8_t coord_system; // G54-G59 - select coordinate system 1-9 + uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS + uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement + uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets + uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode + uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) + uint8_t tool; // Tool after T and M6 (tool_select and tool_change) + uint8_t tool_select; // T value - T sets this value + uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" + uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) + uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) + + uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) + float spindle_speed; // in RPM + float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there + uint8_t spindle_override_enable; // TRUE = override enabled +} GCodeInput_t; + +typedef struct GCodeFlags { // Gcode model input flags + bool next_action; + bool motion_mode; + bool modals[MODAL_GROUP_COUNT]; + bool program_flow; + bool linenum; + bool target[AXES]; + + bool H_word; + bool L_word; + bool feed_rate; + bool feed_rate_mode; + + bool m48_enable; + bool mfo_control; + bool mto_control; + bool sso_control; + + bool select_plane; + bool units_mode; + bool coord_system; + bool path_control; + bool distance_mode; + bool arc_distance_mode; + bool origin_offset_mode; + bool absolute_override; + bool tool; + bool tool_select; + bool tool_change; + bool mist_coolant; + bool flood_coolant; + + bool spindle_control; + bool spindle_speed; + bool spindle_override_factor; + bool spindle_override_enable; + + bool parameter; + bool arc_radius; + bool arc_offset[3]; +} GCodeFlags_t; + +typedef struct GCodeParser { + GCodeInput_t gn; // gcode input values - transient + GCodeFlags_t gf; // gcode input flags - transient +} GCodeParser_t; + +//extern GCodeParser_t gp; +GCodeParser gp; // local helper functions and macros static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); @@ -568,8 +653,15 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 9: SET_MODAL (MODAL_GROUP_M8, flood_coolant, false); case 48: SET_MODAL (MODAL_GROUP_M9, m48_enable, true); case 49: SET_MODAL (MODAL_GROUP_M9, m48_enable, false); - case 50: SET_MODAL (MODAL_GROUP_M9, mfo_enable, true); - case 51: SET_MODAL (MODAL_GROUP_M9, sso_enable, true); + case 50: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); + switch (_point(value)) { + case 0: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); + case 1: SET_MODAL (MODAL_GROUP_M9, mto_control, true); + default: status = STAT_GCODE_COMMAND_UNSUPPORTED; + } + break; +// case 50: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); + case 51: SET_MODAL (MODAL_GROUP_M9, sso_control, true); case 100: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC); case 101: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_WAIT); default: status = STAT_MCODE_COMMAND_UNSUPPORTED; @@ -653,24 +745,25 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, feed_rate); // F EXEC_FUNC(cm_set_spindle_speed, spindle_speed); // S -// EXEC_FUNC(cm_spindle_override_factor, spindle_override_factor); + if (gp.gf.sso_control) { // spindle speed override + ritorno(cm_sso_control(gp.gn.parameter, gp.gf.parameter)); + } + EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written EXEC_FUNC(cm_change_tool, tool_change); // M6 EXEC_FUNC(cm_spindle_control, spindle_control); // spindle CW, CCW, OFF -/* - EXEC_FUNC(cm_feed_rate_override_enable, feed_rate_override_enable); - EXEC_FUNC(cm_traverse_override_enable, traverse_override_enable); - EXEC_FUNC(cm_spindle_override_enable, spindle_override_enable); - EXEC_FUNC(cm_override_enables, override_enables); -*/ EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF EXEC_FUNC(cm_m48_enable, m48_enable); - EXEC_FUNC(cm_mfo_enable, mfo_enable); -// EXEC_FUNC(cm_mfo_enable, feed_rate_override_factor); -// EXEC_FUNC(cm_sso_enable, sso_enable); + if (gp.gf.mfo_control) { // manual feedrate override + ritorno(cm_mfo_control(gp.gn.parameter, gp.gf.parameter)); + } + if (gp.gf.mto_control) { // manual traverse override + ritorno(cm_mto_control(gp.gn.parameter, gp.gf.parameter)); + } + if (gp.gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell ritorno(cm_dwell(gp.gn.parameter)); // return if error, otherwise complete the block } @@ -680,11 +773,11 @@ static stat_t _execute_gcode_block(char *active_comment) switch (gp.gn.next_action) { // Tool length offsets case NEXT_ACTION_SET_TL_OFFSET: { // G43 - ritorno(cm_set_tl_offset(gp.gn.H_word, false)); + ritorno(cm_set_tl_offset(gp.gn.H_word, gp.gf.H_word, false)); break; } case NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET: { // G43.2 - ritorno(cm_set_tl_offset(gp.gn.H_word, true)); + ritorno(cm_set_tl_offset(gp.gn.H_word, gp.gf.H_word, true)); break; } case NEXT_ACTION_CANCEL_TL_OFFSET: { // G49 @@ -694,8 +787,9 @@ static stat_t _execute_gcode_block(char *active_comment) } EXEC_FUNC(cm_set_coord_system, coord_system); // G54, G55, G56, G57, G58, G59 -// EXEC_FUNC(cm_set_path_control, path_control); // G61, G61.1, G64 - if(gp.gf.path_control) { status = cm_set_path_control(MODEL, gp.gn.path_control); } + if (gp.gf.path_control) { // G61, G61.1, G64 + status = cm_set_path_control(MODEL, gp.gn.path_control); + } EXEC_FUNC(cm_set_distance_mode, distance_mode); // G90, G91 EXEC_FUNC(cm_set_arc_distance_mode, arc_distance_mode); // G90.1, G91.1 @@ -707,16 +801,19 @@ static stat_t _execute_gcode_block(char *active_comment) case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gp.gn.target, gp.gf.target); break;} // G30 - case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(); break;} // G28.2 + case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gp.gn.target, gp.gf.target); break;} // G28.2 case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gp.gn.target, gp.gf.target); break;}// G28.3 - case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(); break;} // G28.4 + case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(gp.gn.target, gp.gf.target); break;} // G28.4 case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gp.gn.target, gp.gf.target, true, true); break;} // G38.2 case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gp.gn.target, gp.gf.target, false, true); break;} // G38.3 case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gp.gn.target, gp.gf.target, true, false); break;} // G38.4 case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gp.gn.target, gp.gf.target, false, false); break;} // G38.5 - case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gp.gn.parameter, gp.gn.L_word, gp.gn.target, gp.gf.target); break;} + case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gp.gn.parameter, gp.gf.parameter, + gp.gn.L_word, gp.gf.L_word, + gp.gn.target, gp.gf.target); break;} + case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gp.gn.target, gp.gf.target); break;}// G92 case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 diff --git a/g2core/planner.cpp b/g2core/planner.cpp index a26208ad..2b69f14b 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -637,6 +637,16 @@ void mp_end_feed_override(const float ramp_time) mp_start_feed_override (FEED_OVERRIDE_RAMP_TIME, 1.00); } +void mp_start_traverse_override(const float ramp_time, const float override_factor) +{ + return; +} + +void mp_end_traverse_override(const float ramp_time) +{ + return; +} + /* * mp_planner_time_accounting() - gather time in planner */ diff --git a/g2core/planner.h b/g2core/planner.h index 1b951965..a985c2e8 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -564,6 +564,8 @@ stat_t mp_planner_callback(); void mp_replan_queue(mpBuf_t *bf); void mp_start_feed_override(const float ramp_time, const float override); void mp_end_feed_override(const float ramp_time); +void mp_start_traverse_override(const float ramp_time, const float override); +void mp_end_traverse_override(const float ramp_time); void mp_planner_time_accounting(void); //**** planner buffer primitives diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index b90492b4..a60e7dd9 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -222,28 +222,63 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) /* - * cm_spindle_override_enable() - * cm_spindle_override_factor() + * cm_spindle_override_control() + * cm_start_spindle_override() + * cm_end_spindle_override() */ -/* -stat_t cm_spindle_override_enable(uint8_t flag) // M51.1 + +void cm_start_spindle_override(const float ramp_time, const float override_factor) { + return; +} + +void cm_end_spindle_override(const float ramp_time) +{ + return; +} + +stat_t cm_sso_control(const float P_word, const bool P_flag) // M51 +{ +/* if (fp_TRUE(gp.gf.parameter) && fp_ZERO(gp.gn.parameter)) { spindle.override_enable = false; } else { spindle.override_enable = true; } return (STAT_OK); -} -stat_t cm_spindle_override_factor(uint8_t flag) // M50.1 -{ - spindle.override_enable = flag; + spindle.override_enable = ; spindle.override_factor = gp.gn.parameter; // change spindle speed return (STAT_OK); +*/ + bool new_enable = true; + bool new_override = false; + if (P_flag) { // if parameter is present in Gcode block + if (fp_ZERO(P_word)) { + new_enable = false; // P0 disables override + } else { + if (P_word < SPINDLE_OVERRIDE_MIN) { + return (STAT_INPUT_LESS_THAN_MIN_VALUE); + } + if (P_word > SPINDLE_OVERRIDE_MAX) { + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + spindle.sso_factor = P_word; // P word is valid, store it. + new_override = true; + } + } + if (cm->gmx.m48_enable) { // if master enable is ON + if (new_enable && (new_override || !spindle.sso_enable)) { // 3 cases to start a ramp + cm_start_spindle_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.sso_factor); + } else if (spindle.sso_enable && !new_enable) { // case to turn off the ramp + cm_end_spindle_override(SPINDLE_OVERRIDE_RAMP_TIME); + } + } + spindle.sso_enable = new_enable; // always update the enable state + return (STAT_OK); } -*/ + /**************************** * END OF SPINDLE FUNCTIONS * ****************************/ diff --git a/g2core/spindle.h b/g2core/spindle.h index 33820ce8..5ed3e877 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -2,7 +2,7 @@ * spindle.h - spindle driver * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -62,6 +62,7 @@ typedef enum { #define SPINDLE_OVERRIDE_FACTOR 1.00 #define SPINDLE_OVERRIDE_MIN 0.05 // 5% #define SPINDLE_OVERRIDE_MAX 2.00 // 200% +#define SPINDLE_OVERRIDE_RAMP_TIME 1 // change sped in seconds /* * Spindle control structure @@ -99,8 +100,9 @@ void cm_spindle_off_immediate(void); void cm_spindle_optional_pause(bool option); // stop spindle based on system options selected void cm_spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state -// stat_t cm_spindle_override_enable(uint8_t flag); // M51 -// stat_t cm_spindle_override_factor(uint8_t flag); // M51.1 +stat_t cm_sso_control(const float P_word, const bool P_flag); // M51 +void cm_start_spindle_override(const float ramp_time, const float override_factor); +void cm_end_spindle_override(const float ramp_time); stat_t cm_set_dir(nvObj_t* nv); stat_t cm_set_sso(nvObj_t* nv); From f26522aae27eabab6892343e4eb7158dbfcac2bd Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 12 Jan 2017 09:50:01 -0500 Subject: [PATCH 064/283] Isolated Gcode parser and cleaned it up a bit --- g2core/canonical_machine.cpp | 13 -- g2core/gcode.h | 2 +- g2core/gcode_parser.cpp | 262 +++++++++++++++++------------------ g2core/spindle.cpp | 13 -- 4 files changed, 127 insertions(+), 163 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f66bcd87..b805d3e4 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1139,7 +1139,6 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, const uint8_t L_word, const bool L_flag, const float offset[], const bool flag[]) { -// if (!gp.gf.L_word) { if (!L_flag) { return (STAT_L_WORD_IS_MISSING); } @@ -1204,17 +1203,6 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool apply_additional) { uint8_t tool; -/* - if (gp.gf.H_word) { - if (gp.gn.H_word > TOOLS) { - return (STAT_H_WORD_IS_INVALID); - } - if (gp.gn.H_word == 0) { // interpret H0 as "current tool", just like no H at all. - tool = cm->gm.tool; - } else { - tool = gp.gn.H_word; - } -*/ if (H_flag) { if (H_word > TOOLS) { return (STAT_H_WORD_IS_INVALID); @@ -1550,7 +1538,6 @@ stat_t cm_set_path_control(GCodeState_t *gcode_state, const uint8_t mode) * cm_arc_feed() - SEE plan_arc.cpp */ - /* * cm_dwell() - G4, P parameter (seconds) */ diff --git a/g2core/gcode.h b/g2core/gcode.h index 52790525..39b5a28c 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -198,7 +198,7 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) * some state elements are necessarily restored from gm. * * - gf is used by the gcode parser interpreter to hold flags for any data - * that has changed in gn during the parse. gp.gf.target[] values are also used + * that has changed in gn during the parse. gf.target[] values are also used * by the canonical machine during set_target(). * * - cfg (config struct in config.h) is also used heavily and contains some diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index fea72a69..656068e0 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -29,68 +29,63 @@ // Structures used by Gcode parser -typedef struct GCodeInput { // Gcode model inputs - meaning depends on context +typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context + + uint8_t next_action; // handles G modal group 1 moves & non-modals + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89 + uint8_t program_flow; // used only by the gcode_parser + uint32_t linenum; // N word - uint8_t next_action; // handles G modal group 1 moves & non-modals - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 - // G83, G84, G85, G86, G87, G88, G89 + float target[AXES]; // XYZABC where the move should go + float arc_offset[3]; // IJK - used by arc commands + float arc_radius; // R - radius value in arc radius mode - uint8_t program_flow; // used only by the gcode_parser - uint32_t linenum; // N word - float target[AXES]; // XYZABC where the move should go + float F_word; // F - normalized to millimeters/minute + uint8_t H_word; // H word - used by G43s + uint8_t L_word; // L word - used by G10s + float P_word; // P - parameter used for dwell time in seconds, G10 coord select... + float S_word; // S word - in RPM - uint8_t H_word; // H word - used by G43s - uint8_t L_word; // L word - used by G10s + uint8_t feed_rate_mode; // See cmFeedRateMode for settings + uint8_t select_plane; // G17,G18,G19 - values to set plane to + uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) + uint8_t coord_system; // G54-G59 - select coordinate system 1-9 + uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS + uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement + uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets + uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode + uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) + uint8_t tool; // Tool after T and M6 (tool_select and tool_change) + uint8_t tool_select; // T value - T sets this value + uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" + uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) + uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) + uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - float feed_rate; // F - normalized to millimeters/minute - uint8_t feed_rate_mode; // See cmFeedRateMode for settings - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... - float arc_radius; // R - radius value in arc radius mode - float arc_offset[3]; // IJK - used by arc commands + bool m48_enable; // M48/M49 input (enables for feed and spindle) + bool mfo_control; // M50 feedrate override control + bool mto_control; // M50.1 traverse override control + bool sso_control; // M51 spindle speed override control +} GCodeValue_t; - bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_control; // M50 feedrate override control - bool mto_control; // M50.1 traverse override control - bool sso_control; // M51 spindle speed override control +typedef struct GCodeFlags { // Gcode input flags - uint8_t select_plane; // G17,G18,G19 - values to set plane to - uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - uint8_t coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement - uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode - uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) - uint8_t tool; // Tool after T and M6 (tool_select and tool_change) - uint8_t tool_select; // T value - T sets this value - uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" - uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) - uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) - - uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - float spindle_speed; // in RPM - float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there - uint8_t spindle_override_enable; // TRUE = override enabled -} GCodeInput_t; - -typedef struct GCodeFlags { // Gcode model input flags bool next_action; bool motion_mode; - bool modals[MODAL_GROUP_COUNT]; bool program_flow; bool linenum; - bool target[AXES]; + bool target[AXES]; + bool arc_offset[3]; + bool arc_radius; + + bool F_word; bool H_word; bool L_word; - bool feed_rate; + bool P_word; + bool S_word; + bool feed_rate_mode; - - bool m48_enable; - bool mfo_control; - bool mto_control; - bool sso_control; - bool select_plane; bool units_mode; bool coord_system; @@ -104,24 +99,21 @@ typedef struct GCodeFlags { // Gcode model input flags bool tool_change; bool mist_coolant; bool flood_coolant; - bool spindle_control; - bool spindle_speed; - bool spindle_override_factor; - bool spindle_override_enable; - bool parameter; - bool arc_radius; - bool arc_offset[3]; -} GCodeFlags_t; - + bool m48_enable; + bool mfo_control; + bool mto_control; + bool sso_control; +} GCodeFlag_t; + typedef struct GCodeParser { - GCodeInput_t gn; // gcode input values - transient - GCodeFlags_t gf; // gcode input flags - transient + bool modals[MODAL_GROUP_COUNT]; } GCodeParser_t; -//extern GCodeParser_t gp; -GCodeParser gp; +GCodeParser_t gp; // main parser struct +GCodeValue_t gv; // gcode input values +GCodeFlag_t gf; // gcode input flags // local helper functions and macros static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); @@ -131,9 +123,9 @@ static stat_t _validate_gcode_block(char *active_comment); static stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs static stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block -#define SET_MODAL(m,parm,val) ({gp.gn.parm=val; gp.gf.parm=true; gp.gf.modals[m]=true; break;}) -#define SET_NON_MODAL(parm,val) ({gp.gn.parm=val; gp.gf.parm=true; break;}) -#define EXEC_FUNC(f,v) if(gp.gf.v) { status=f(gp.gn.v);} +#define SET_MODAL(m,parm,val) ({gv.parm=val; gf.parm=true; gp.modals[m]=true; break;}) +#define SET_NON_MODAL(parm,val) ({gv.parm=val; gf.parm=true; break;}) +#define EXEC_FUNC(f,v) if(gf.v) { status=f(gv.v);} /* * gcode_parser_init() @@ -141,8 +133,8 @@ static stat_t _execute_gcode_block(char *active_comment); // Execute t void gcode_parser_init() { - memset(&gp.gn, 0, sizeof(GCodeInput_t)); // reset the Gcode inputs - memset(&gp.gf, 0, sizeof(GCodeFlags_t)); + memset(&gv, 0, sizeof(GCodeValue_t)); + memset(&gf, 0, sizeof(GCodeFlag_t)); } /* @@ -222,7 +214,7 @@ static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *bl char *gc_rd = str; // read pointer char *gc_wr = _normalize_scratch; // write pointer - char *ac_rd = str; // read pointer + char *ac_rd = str; // Active Comment read pointer char *ac_wr = _normalize_scratch; // Active Comment write pointer bool last_char_was_digit = false; // used for octal stripping @@ -317,7 +309,6 @@ static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *bl ac_wr++; // move the ac start position } } - gc_rd++; } @@ -420,7 +411,6 @@ static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *bl break; } } - ac_rd++; } } @@ -493,12 +483,12 @@ static stat_t _validate_gcode_block(char *active_comment) // uses axis words appears on the line, the activity of the group 1 G-code is suspended // for that line. The axis word-using G-codes from group 0 are G10, G28, G30, and G92" -// if ((gp.gn.modals[MODAL_GROUP_G0] == true) && (gp.gn.modals[MODAL_GROUP_G1] == true)) { +// if ((gp.modals[MODAL_GROUP_G0] == true) && (gp.modals[MODAL_GROUP_G1] == true)) { // return (STAT_MODAL_GROUP_VIOLATION); // } // look for commands that require an axis word to be present -// if ((gp.gn.modals[MODAL_GROUP_G0] == true) || (gp.gn.modals[MODAL_GROUP_G1] == true)) { +// if ((gp.modals[MODAL_GROUP_G0] == true) || (gp.modals[MODAL_GROUP_G1] == true)) { // if (_axis_changed() == false) // return (STAT_GCODE_AXIS_IS_MISSING); // } @@ -515,22 +505,22 @@ static stat_t _validate_gcode_block(char *active_comment) static stat_t _parse_gcode_block(char *buf, char *active_comment) { - char *pstr = (char *)buf; // persistent pointer into gcode block for parsing words - char letter; // parsed letter, eg.g. G or X or Y - float value = 0; // value parsed from letter (e.g. 2 for G2) + char *pstr = (char *)buf; // persistent pointer into gcode block for parsing words + char letter; // parsed letter, eg.g. G or X or Y + float value = 0; // value parsed from letter (e.g. 2 for G2) stat_t status = STAT_OK; // set initial state for new move - memset(&gp.gn, 0, sizeof(GCodeInput_t)); // clear all next-state values - memset(&gp.gf, 0, sizeof(GCodeFlags_t)); // clear all next-state flags - gp.gn.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block + memset(&gv, 0, sizeof(GCodeValue_t)); // clear all next-state values + memset(&gf, 0, sizeof(GCodeFlag_t)); // clear all next-state flags + gv.motion_mode = cm_get_motion_mode(MODEL); // get motion mode from previous block // Causes a later exception if // (1) INVERSE_TIME_MODE is active and a feed rate is not provided or // (2) INVERSE_TIME_MODE is changed to UNITS_PER_MINUTE and a new feed rate is missing if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate req'd when in INV_TIME_MODE - gp.gn.feed_rate = 0; - gp.gf.feed_rate = true; + gv.F_word = 0; + gf.F_word = true; } // extract commands and parameters @@ -659,8 +649,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 1: SET_MODAL (MODAL_GROUP_M9, mto_control, true); default: status = STAT_GCODE_COMMAND_UNSUPPORTED; } - break; -// case 50: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); + break; case 51: SET_MODAL (MODAL_GROUP_M9, sso_control, true); case 100: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC); case 101: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_WAIT); @@ -669,9 +658,9 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) break; case 'T': SET_NON_MODAL (tool_select, (uint8_t)trunc(value)); - case 'F': SET_NON_MODAL (feed_rate, value); - case 'P': SET_NON_MODAL (parameter, value); // used for dwell time, G10 coord select - case 'S': SET_NON_MODAL (spindle_speed, value); + case 'F': SET_NON_MODAL (F_word, value); + case 'P': SET_NON_MODAL (P_word, value); // used for dwell time, G10 coord select + case 'S': SET_NON_MODAL (S_word, value); case 'X': SET_NON_MODAL (target[AXIS_X], value); case 'Y': SET_NON_MODAL (target[AXIS_Y], value); case 'Z': SET_NON_MODAL (target[AXIS_Z], value); @@ -741,12 +730,12 @@ static stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; - cm_set_model_linenum(gp.gn.linenum); + cm_set_model_linenum(gv.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 - EXEC_FUNC(cm_set_feed_rate, feed_rate); // F - EXEC_FUNC(cm_set_spindle_speed, spindle_speed); // S - if (gp.gf.sso_control) { // spindle speed override - ritorno(cm_sso_control(gp.gn.parameter, gp.gf.parameter)); + EXEC_FUNC(cm_set_feed_rate, F_word); // F + EXEC_FUNC(cm_set_spindle_speed, S_word); // S + if (gf.sso_control) { // spindle speed override + ritorno(cm_sso_control(gv.P_word, gf.P_word)); } EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written @@ -757,27 +746,27 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF EXEC_FUNC(cm_m48_enable, m48_enable); - if (gp.gf.mfo_control) { // manual feedrate override - ritorno(cm_mfo_control(gp.gn.parameter, gp.gf.parameter)); + if (gf.mfo_control) { // manual feedrate override + ritorno(cm_mfo_control(gv.P_word, gf.P_word)); } - if (gp.gf.mto_control) { // manual traverse override - ritorno(cm_mto_control(gp.gn.parameter, gp.gf.parameter)); + if (gf.mto_control) { // manual traverse override + ritorno(cm_mto_control(gv.P_word, gf.P_word)); } - if (gp.gn.next_action == NEXT_ACTION_DWELL) { // G4 - dwell - ritorno(cm_dwell(gp.gn.parameter)); // return if error, otherwise complete the block + if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell + ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block } EXEC_FUNC(cm_select_plane, select_plane); // G17, G18, G19 EXEC_FUNC(cm_set_units_mode, units_mode); // G20, G21 //--> cutter radius compensation goes here - switch (gp.gn.next_action) { // Tool length offsets + switch (gv.next_action) { // Tool length offsets case NEXT_ACTION_SET_TL_OFFSET: { // G43 - ritorno(cm_set_tl_offset(gp.gn.H_word, gp.gf.H_word, false)); + ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, false)); break; } case NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET: { // G43.2 - ritorno(cm_set_tl_offset(gp.gn.H_word, gp.gf.H_word, true)); + ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, true)); break; } case NEXT_ACTION_CANCEL_TL_OFFSET: { // G49 @@ -787,55 +776,56 @@ static stat_t _execute_gcode_block(char *active_comment) } EXEC_FUNC(cm_set_coord_system, coord_system); // G54, G55, G56, G57, G58, G59 - if (gp.gf.path_control) { // G61, G61.1, G64 - status = cm_set_path_control(MODEL, gp.gn.path_control); + + if (gf.path_control) { // G61, G61.1, G64 + status = cm_set_path_control(MODEL, gv.path_control); } EXEC_FUNC(cm_set_distance_mode, distance_mode); // G90, G91 EXEC_FUNC(cm_set_arc_distance_mode, arc_distance_mode); // G90.1, G91.1 //--> set retract mode goes here - switch (gp.gn.next_action) { - case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gp.gn.target, gp.gf.target); break;} // G28 - case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gp.gn.target, gp.gf.target); break;} // G30 + switch (gv.next_action) { + case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 + case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 + case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 + case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gv.target, gf.target); break;} // G30 - case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gp.gn.target, gp.gf.target); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gp.gn.target, gp.gf.target); break;}// G28.3 - case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(gp.gn.target, gp.gf.target); break;} // G28.4 + case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gv.target, gf.target); break;} // G28.2 + case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gv.target, gf.target); break;} // G28.3 + case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(gv.target, gf.target); break;} // G28.4 - case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gp.gn.target, gp.gf.target, true, true); break;} // G38.2 - case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gp.gn.target, gp.gf.target, false, true); break;} // G38.3 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gp.gn.target, gp.gf.target, true, false); break;} // G38.4 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gp.gn.target, gp.gf.target, false, false); break;} // G38.5 + case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gv.target, gf.target, true, true); break;} // G38.2 + case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gv.target, gf.target, false, true); break;} // G38.3 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gv.target, gf.target, true, false); break;} // G38.4 + case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gv.target, gf.target, false, false); break;}// G38.5 - case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gp.gn.parameter, gp.gf.parameter, - gp.gn.L_word, gp.gf.L_word, - gp.gn.target, gp.gf.target); break;} + case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gv.P_word, gf.P_word, + gv.L_word, gf.L_word, + gv.target, gf.target); break;} - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gp.gn.target, gp.gf.target); break;}// G92 - case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 - case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 - case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 + case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gv.target, gf.target); break;}// G92 + case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 + case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 + case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 - case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 - case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 -// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 + case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 + case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 +// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 case NEXT_ACTION_DEFAULT: { - cm_set_absolute_override(MODEL, gp.gn.absolute_override); // apply absolute override - switch (gp.gn.motion_mode) { - case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gp.gn.motion_mode; break;} // G80 - case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gp.gn.target, gp.gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gp.gn.target, gp.gf.target); break;} // G1 - case MOTION_MODE_CW_ARC: // G2 - case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gp.gn.target, gp.gf.target, // G3 - gp.gn.arc_offset, gp.gf.arc_offset, - gp.gn.arc_radius, gp.gf.arc_radius, - gp.gn.parameter, gp.gf.parameter, - gp.gf.modals[MODAL_GROUP_G1], - gp.gn.motion_mode); + cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override + switch (gv.motion_mode) { + case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gv.motion_mode; break;} // G80 + case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gv.target, gf.target); break;} // G0 + case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target); break;} // G1 + case MOTION_MODE_CW_ARC: // G2 + case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gv.target, gf.target, // G3 + gv.arc_offset, gf.arc_offset, + gv.arc_radius, gf.arc_radius, + gv.P_word, gf.P_word, + gp.modals[MODAL_GROUP_G1], + gv.motion_mode); break; } default: break; @@ -845,8 +835,8 @@ static stat_t _execute_gcode_block(char *active_comment) } // do the program stops and ends : M0, M1, M2, M30, M60 - if (gp.gf.program_flow == true) { - if (gp.gn.program_flow == PROGRAM_STOP) { + if (gf.program_flow == true) { + if (gv.program_flow == PROGRAM_STOP) { cm_program_stop(); } else { cm_program_end(); diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index a60e7dd9..de3ebb8d 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -239,19 +239,6 @@ void cm_end_spindle_override(const float ramp_time) stat_t cm_sso_control(const float P_word, const bool P_flag) // M51 { -/* - if (fp_TRUE(gp.gf.parameter) && fp_ZERO(gp.gn.parameter)) { - spindle.override_enable = false; - } else { - spindle.override_enable = true; - } - return (STAT_OK); - - spindle.override_enable = ; - spindle.override_factor = gp.gn.parameter; -// change spindle speed - return (STAT_OK); -*/ bool new_enable = true; bool new_override = false; if (P_flag) { // if parameter is present in Gcode block From 10794b1b0e6f256f52cb2adfa5af9ebe73451c02 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 12 Jan 2017 11:55:55 -0500 Subject: [PATCH 065/283] checkpoint --- g2core/canonical_machine.cpp | 1 + g2core/config_app.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index b805d3e4..7ecec89f 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1200,6 +1200,7 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, * cm_set_coord_system() - G54-G59 * _exec_offset() - callback from planner */ + stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool apply_additional) { uint8_t tool; diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 866c27a0..c072205b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -845,10 +845,11 @@ const cfgItem_t cfgArray[] = { { "sys","fro", _fipn,3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, { "sys","troe",_fipn,0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, { "sys","tro", _fipn,3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, +// { "sys","zl", _fipn,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT}, { "sys","mt", _fipn,2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors -// { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable +// { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable // Spindle functions { "sys","spep",_fipn,0, cm_print_spep,get_ui8, set_01, (float *)&spindle.enable_polarity, SPINDLE_ENABLE_POLARITY }, From 9a84732d70ad935e0e801855aae2e1aa3cc1f0a1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 12 Jan 2017 14:08:02 -0500 Subject: [PATCH 066/283] Added Zlift parameter; uncommented m48 enable --- g2core/canonical_machine.cpp | 14 +++++++++++--- g2core/canonical_machine.h | 20 ++++++++++++++------ g2core/config_app.cpp | 28 ++++++++++++++-------------- g2core/g2core.cppproj | 12 +++++------- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 7ecec89f..4c7801e2 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2682,6 +2682,9 @@ stat_t cm_set_jt(nvObj_t *nv) stat_t cm_get_ct(nvObj_t *nv) { return(get_float(nv, cm->chordal_tolerance)); } stat_t cm_set_ct(nvObj_t *nv) { return(set_float_range(nv, cm->chordal_tolerance, CHORDAL_TOLERANCE_MIN, 10000000)); } +stat_t cm_get_zl(nvObj_t *nv) { return(get_float(nv, cm->feedhold_z_lift)); } +stat_t cm_set_zl(nvObj_t *nv) { return(set_float(nv, cm->feedhold_z_lift)); } + stat_t cm_get_sl(nvObj_t *nv) { return(get_int(nv, cm->soft_limit_enable)); } stat_t cm_set_sl(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->soft_limit_enable, 0, 1)); } @@ -2691,6 +2694,9 @@ stat_t cm_set_lim(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->limit_enable, stat_t cm_get_saf(nvObj_t *nv) { return(get_int(nv, cm->safety_interlock_enable)); } stat_t cm_set_saf(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->safety_interlock_enable, 0, 1)); } +stat_t cm_get_m48(nvObj_t *nv) { return(get_int(nv, cm->gmx.m48_enable)); } +stat_t cm_set_m48(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.m48_enable, 0, 1)); } + stat_t cm_get_froe(nvObj_t *nv) { return(get_int(nv, cm->gmx.mfo_enable)); } stat_t cm_set_froe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.mfo_enable, 0, 1)); } stat_t cm_get_fro(nvObj_t *nv) { return(get_float(nv, cm->gmx.mfo_factor)); } @@ -2853,26 +2859,28 @@ void cm_print_gdi(nvObj_t *nv) { text_print(nv, fmt_gdi);} // TYPE_INT /* system parameter print functions */ -static const char fmt_jt[] = "[jt] junction integrgation time%6.2f\n"; +static const char fmt_jt[] = "[jt] junction integration time%7.2f\n"; static const char fmt_ct[] = "[ct] chordal tolerance%17.4f%s\n"; +static const char fmt_zl[] = "[zl] Z lift on feedhold%16.3f%s\n"; static const char fmt_sl[] = "[sl] soft limit enable%12d [0=disable,1=enable]\n"; static const char fmt_lim[] ="[lim] limit switch enable%10d [0=disable,1=enable]\n"; static const char fmt_saf[] ="[saf] safety interlock enable%6d [0=disable,1=enable]\n"; void cm_print_jt(nvObj_t *nv) { text_print(nv, fmt_jt);} // TYPE FLOAT void cm_print_ct(nvObj_t *nv) { text_print_flt_units(nv, fmt_ct, GET_UNITS(ACTIVE_MODEL));} +void cm_print_zl(nvObj_t *nv) { text_print_flt_units(nv, fmt_zl, GET_UNITS(ACTIVE_MODEL));} void cm_print_sl(nvObj_t *nv) { text_print(nv, fmt_sl);} // TYPE_INT void cm_print_lim(nvObj_t *nv){ text_print(nv, fmt_lim);} // TYPE_INT void cm_print_saf(nvObj_t *nv){ text_print(nv, fmt_saf);} // TYPE_INT -//static const char fmt_m48e[] = "[m48e] overrides enabled%11d [0=disable,1=enable]\n"; +static const char fmt_m48[] = "[m48] overrides enabled%12d [0=disable,1=enable]\n"; static const char fmt_froe[] = "[froe] feed override enable%8d [0=disable,1=enable]\n"; static const char fmt_fro[] = "[fro] feedrate override%15.3f [0.05 < mfo < 2.00]\n"; static const char fmt_troe[] = "[troe] traverse over enable%8d [0=disable,1=enable]\n"; static const char fmt_tro[] = "[tro] traverse override%15.3f [0.05 < mto < 1.00]\n"; static const char fmt_tram[] = "[tram] is coordinate space rotated to be tram %s\n"; -//void cm_print_m48e(nvObj_t *nv) { text_print(nv, fmt_m48e);} // TYPE_INT +void cm_print_m48(nvObj_t *nv) { text_print(nv, fmt_m48);} // TYPE_INT void cm_print_froe(nvObj_t *nv) { text_print(nv, fmt_froe);} // TYPE INT void cm_print_fro(nvObj_t *nv) { text_print(nv, fmt_fro);} // TYPE FLOAT void cm_print_troe(nvObj_t *nv) { text_print(nv, fmt_troe);} // TYPE INT diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index d03ffcef..966fd893 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -221,6 +221,7 @@ typedef struct cmMachine { // struct to manage canonical machin // System group settings float junction_integration_time; // how aggressively will the machine corner? 1.6 or so is about the upper limit float chordal_tolerance; // arc chordal accuracy setting in mm + float feedhold_z_lift; // mm to move Z axis on feedhold, or 0 to disable bool soft_limit_enable; // true to enable soft limit testing on Gcode inputs bool limit_enable; // true to enable limit switches (disabled is same as override) bool safety_interlock_enable; // true to enable safety interlock system @@ -568,6 +569,8 @@ stat_t cm_get_jt(nvObj_t *nv); // get junction integration time constan stat_t cm_set_jt(nvObj_t *nv); // set junction integration time constant stat_t cm_get_ct(nvObj_t *nv); // get chordal tolerance stat_t cm_set_ct(nvObj_t *nv); // set chordal tolerance +stat_t cm_get_zl(nvObj_t *nv); // get feedhold Z lift +stat_t cm_set_zl(nvObj_t *nv); // set feedhold Z lift stat_t cm_get_sl(nvObj_t *nv); // get soft limit enable stat_t cm_set_sl(nvObj_t *nv); // set soft limit enable stat_t cm_get_lim(nvObj_t *nv); // get hard limit enable @@ -575,6 +578,8 @@ stat_t cm_set_lim(nvObj_t *nv); // set hard limit enable stat_t cm_get_saf(nvObj_t *nv); // get safety interlock enable stat_t cm_set_saf(nvObj_t *nv); // set safety interlock enable +stat_t cm_get_m48(nvObj_t *nv); // get M48 value (enable/disable overrides) +stat_t cm_set_m48(nvObj_t *nv); // set M48 value (enable/disable overrides) stat_t cm_get_froe(nvObj_t *nv); // get feedrate override enable stat_t cm_set_froe(nvObj_t *nv); // set feedrate override enable stat_t cm_get_fro(nvObj_t *nv); // get feedrate override factor @@ -637,11 +642,12 @@ stat_t cm_set_gdi(nvObj_t *nv); // set gcode default distance mode void cm_print_jt(nvObj_t *nv); // global CM settings void cm_print_ct(nvObj_t *nv); + void cm_print_zl(nvObj_t *nv); void cm_print_sl(nvObj_t *nv); void cm_print_lim(nvObj_t *nv); void cm_print_saf(nvObj_t *nv); -// void cm_print_m48e(nvObj_t *nv); + void cm_print_m48(nvObj_t *nv); void cm_print_froe(nvObj_t *nv); void cm_print_fro(nvObj_t *nv); void cm_print_troe(nvObj_t *nv); @@ -703,15 +709,17 @@ stat_t cm_set_gdi(nvObj_t *nv); // set gcode default distance mode #define cm_print_jt tx_print_stub // global CM settings #define cm_print_ct tx_print_stub + #define cm_print_zl tx_print_stub #define cm_print_sl tx_print_stub #define cm_print_lim tx_print_stub #define cm_print_saf tx_print_stub - #define cm_print_m48e tx_print_stub - #define cm_print_mfoe tx_print_stub - #define cm_print_mfo tx_print_stub - #define cm_print_mtoe tx_print_stub - #define cm_print_mto tx_print_stub + #define cm_print_m48 tx_print_stub + #define cm_print_froe tx_print_stub + #define cm_print_fro tx_print_stub + #define cm_print_troe tx_print_stub + #define cm_print_tro tx_print_stub + #define cm_print_tram tx_print_stub #define cm_print_am tx_print_stub // axis print functions #define cm_print_fr tx_print_stub diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index c072205b..dee95c51 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -836,20 +836,20 @@ const cfgItem_t cfgArray[] = { { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, - { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, - { "sys","lim", _fipn,0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, - { "sys","saf", _fipn,0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, - { "sys","froe",_fipn,0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, - { "sys","fro", _fipn,3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, - { "sys","troe",_fipn,0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","tro", _fipn,3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, -// { "sys","zl", _fipn,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT}, - { "sys","mt", _fipn,2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, - { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors - { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors -// { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm->gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable + { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, + { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, + { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT}, + { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, + { "sys","lim", _fipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, + { "sys","saf", _fipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, + { "sys","m48", _fipn, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 0 }, // M48/M49 feedrate & spindle override enable + { "sys","froe",_fipn, 0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, + { "sys","fro", _fipn, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, + { "sys","troe",_fipn, 0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","tro", _fipn, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, + { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors + { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors // Spindle functions { "sys","spep",_fipn,0, cm_print_spep,get_ui8, set_01, (float *)&spindle.enable_polarity, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 636eb732..8744fc15 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -5,7 +5,7 @@ 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAM3X8E + ATSAM3X8C none Executable CPP @@ -21,10 +21,8 @@ exception_table 1 3.5.0 - - - - + SWD + com.atmel.avrdbg.tool.atmelice com.atmel.avrdbg.tool.samice J-Link @@ -70,7 +68,7 @@ - 10000000 + 2000000 SWD @@ -104,7 +102,7 @@ true J41800030015 0x284E0A60 - 10000000 + 2000000 From 224efe28fcf07192fd364cac1722eb51c79a9f9b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 12 Jan 2017 16:25:50 -0500 Subject: [PATCH 067/283] First cut at Z lift in a cycle. Still initiated by {switch:t} --- g2core/canonical_machine.cpp | 230 +++++++++++++++++++---------------- g2core/canonical_machine.h | 10 +- g2core/cycle_probing.cpp | 2 +- 3 files changed, 129 insertions(+), 113 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 4c7801e2..50259821 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -247,107 +247,6 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) return (STAT_OK); } -/* - * cm_switch() - switch canonical machine to secondary machine - * cm_return() - return secondary canoncial machine to primary machine - * - * Doing a Switch is only safe when the machine has completely stopped during a feedhold - * Switch works to switch from the primary planer to the secondary planner - * Use Return to return to the primary planner - */ - -stat_t cm_switch(nvObj_t *nv) -{ - // Must be in the primary CM and fully stopped in a hold - if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { - nv->valuetype = TYPE_NULL; - return (STAT_COMMAND_NOT_ACCEPTED); - } - - // copy the primary canonical machine to the secondary, - // fix the planner pointer, and reset the secondary planner - memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // set parameters in cm, gm and gmx so you can actually use it - cmMachine_t *_cm = &cm2; - _cm->hold_state = FEEDHOLD_OFF; - _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - _cm->gm.feed_rate = 0; - - - // clear the target and set the positions to the current hold position - memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); -// memset(&(_cm->gm.target_comp), 0, sizeof(_cm->gm.target_comp)); - copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation - copy_vector(_cm->gmx.position, mr->position); - copy_vector(mp2.position, mr->position); - copy_vector(mr2.position, mr->position); - - // reassign the globals to the secondary CM (this must be next-to-last) - cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // mp is a void pointer - mr = mp->mr; - cm_select = CM_SECONDARY; - - // finally, set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 - cm_set_g30_position(); - cm_set_motion_state(MOTION_STOP); - return (STAT_OK); -} - -static void _return_move_callback(float* vect, bool* flag) -{ - cm2.waiting_for_motion_end = false; -} - -stat_t cm_return(nvObj_t *nv) // LATER: if value == true return with offset corrections -{ - // Must be in the secondary CM and fully stopped - if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { - nv->valuetype = TYPE_NULL; - return (STAT_COMMAND_NOT_ACCEPTED); - } - - // while still in secondary, perform the G30 move and queue a wait - float target[] = { 0,0,0,0,0,0 }; - bool flags[] = { 0,0,0,0,0,0 }; - cm_goto_g30_position(target, flags); // initiate a return move - cm->waiting_for_motion_end = true; // indicates running the final G30 move in the secondary - mp_queue_command(_return_move_callback, nullptr, nullptr); - cm_select = CM_SECONDARY_RETURN; - return (STAT_OK); -} - -stat_t cm_return_callback() -{ - if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner - return (STAT_NOOP); - } - if (cm->waiting_for_motion_end) { // sync to planner move ends (using callback) - return (STAT_EAGAIN); - } - - // return to primary CM - cm = &cm1; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; - cm_select = CM_PRIMARY; - cm_set_motion_state(MOTION_STOP); // sets active model to primary - - cm_end_hold(); - return (STAT_OK); -} - -/* -stat_t cm_return_from_hold_callback() -{ - -} -*/ - /************************************* * Internal getters and setters * * Canonical Machine State functions * @@ -1912,13 +1811,6 @@ stat_t cm_feedhold_sequencing_callback() cm_end_hold(); } } -/* - if (cm->return_hold_requested) { - if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing - cm_end_hold(); - } - } -*/ return (STAT_OK); } @@ -1984,6 +1876,128 @@ void cm_queue_flush() } } +/* + * cm_switch() - switch canonical machine to secondary machine + * cm_return() - return secondary canoncial machine to primary machine + * + * Doing a Switch is only safe when the machine has completely stopped during a feedhold + * Switch works to switch from the primary planer to the secondary planner + * Use Return to return to the primary planner + */ + +stat_t cm_switch(nvObj_t *nv) +{ + stat_t status = cm_switch_to_secondary(); + if (status != STAT_OK) { + nv->valuetype = TYPE_NULL; + } + return (status); +} + +stat_t cm_return(nvObj_t *nv) +{ + stat_t status = cm_return_to_primary(); + if (status != STAT_OK) { + nv->valuetype = TYPE_NULL; + } + return (status); +} + +stat_t cm_switch_to_secondary() +{ + // Must be in the primary CM and fully stopped in a hold + if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { + return (STAT_COMMAND_NOT_ACCEPTED); + } + + // copy the primary canonical machine to the secondary, + // fix the planner pointer, and reset the secondary planner + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // set parameters in cm, gm and gmx so you can actually use it + cmMachine_t *_cm = &cm2; + _cm->hold_state = FEEDHOLD_OFF; + _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + _cm->gm.feed_rate = 0; + + // clear the target and set the positions to the current hold position + memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); +// memset(&(_cm->gm.target_comp), 0, sizeof(_cm->gm.target_comp)); // to zero out compensation terms + copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation + copy_vector(_cm->gmx.position, mr->position); + copy_vector(mp2.position, mr->position); + copy_vector(mr2.position, mr->position); + + // reassign the globals to the secondary CM + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer + mr = mp->mr; + cm_select = CM_SECONDARY; + + // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 + cm_set_g30_position(); + cm_set_motion_state(MOTION_STOP); + + // perform Z lift + if (fp_ZERO(cm->feedhold_z_lift)) { // skip this if the lift is zero + return (STAT_OK); + } + float stored_distance_mode = cm_get_distance_mode(MODEL); + cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); + bool flags[AXES] = { 0,0,1,0,0,0 }; + float target[AXES] = { 0,0, cm->feedhold_z_lift, 0,0,0 }; + cm_straight_traverse(target, flags); + cm_set_distance_mode(stored_distance_mode); + + return (STAT_OK); +} + +// Callback to run at when the G30 return move is finished +static void _return_move_callback(float* vect, bool* flag) +{ + cm2.waiting_for_motion_end = false; +} + +stat_t cm_return_to_primary() // LATER: if value == true return with offset corrections +{ + // Must be in the secondary CM and fully stopped + if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { + return (STAT_COMMAND_NOT_ACCEPTED); + } + + // while still in secondary, perform the G30 move and queue a wait + float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z + bool flags[] = { 0,0,0,0,0,0 }; + cm_goto_g30_position(target, flags); // initiate a return move + cm->waiting_for_motion_end = true; // indicates running the final G30 move in the secondary + mp_queue_command(_return_move_callback, nullptr, nullptr); + cm_select = CM_SECONDARY_RETURN; + return (STAT_OK); +} + +stat_t cm_return_callback() +{ + if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner + return (STAT_NOOP); + } + if (cm->waiting_for_motion_end) { // sync to planner move ends (using callback) + return (STAT_EAGAIN); + } + + // return to primary CM + cm = &cm1; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + cm_select = CM_PRIMARY; + cm_set_motion_state(MOTION_STOP); // sets active model to primary + + cm_end_hold(); + return (STAT_OK); +} + /****************************** * Program Functions (4.3.10) * ******************************/ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 966fd893..6827099a 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -310,9 +310,6 @@ cmHomingState cm_get_homing_state(void); cmProbeState cm_get_probe_state(void); uint8_t cm_get_jogging_state(void); -stat_t cm_switch(nvObj_t *nv); -stat_t cm_return(nvObj_t *nv); - void cm_set_motion_state(const cmMotionState motion_state); uint32_t cm_get_linenum(const GCodeState_t *gcode_state); @@ -377,7 +374,6 @@ stat_t cm_select_plane(const uint8_t plane); // G stat_t cm_set_units_mode(const uint8_t mode); // G20, G21 stat_t cm_set_distance_mode(const uint8_t mode); // G90, G91 stat_t cm_set_arc_distance_mode(const uint8_t mode); // G90.1, G91.1 -//stat_t cm_set_tl_offset(const uint8_t H_word, bool apply_additional); // G43, G43.2 stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, // G43, G43.2 const bool apply_additional); stat_t cm_cancel_tl_offset(void); // G49 @@ -444,6 +440,7 @@ void cm_request_end_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests stat_t cm_return_callback(void); // return from secondary planner +// Feedhold and related functions bool cm_has_hold(void); void cm_start_hold(void); void cm_end_hold(void); @@ -451,6 +448,11 @@ void cm_end_hold(void); void cm_queue_flush(void); // flush serial and planner queues with coordinate resets void cm_end_queue_flush(void); +stat_t cm_switch(nvObj_t *nv); +stat_t cm_switch_to_secondary(void); +stat_t cm_return(nvObj_t *nv); +stat_t cm_return_to_primary(void); + void cm_cycle_start(void); // (no Gcode) void cm_cycle_end(void); // (no Gcode) void cm_canned_cycle_end(void); // end of canned cycle diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index e44d65ef..425b77a2 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -2,7 +2,7 @@ * cycle_probing.c - probing cycle extension to canonical_machine.c * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S Hart, Jr., Sarah Tappon, Tom Cauchois, Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S Hart, Jr., Sarah Tappon, Tom Cauchois, Robert Giseburt * With contributions from Other Machine Company. * * This file ("the software") is free software: you can redistribute it and/or modify From 31406f5a00934e2aaf205c229c8049bfc3a45d40 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 06:19:37 -0500 Subject: [PATCH 068/283] checkpoint - working on hold cycles --- g2core/canonical_machine.cpp | 83 +++++++++++++++++++++++------------- g2core/canonical_machine.h | 6 ++- g2core/controller.cpp | 2 +- g2core/g2core.cppproj | 8 ++-- g2core/plan_exec.cpp | 7 +-- 5 files changed, 67 insertions(+), 39 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 50259821..47b3bafc 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1723,10 +1723,10 @@ stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 * then motion will stop in the current block. Otherwise the deceleration phase * will extend across as many blocks necessary until one will stop. * - * - Once deceleration is complete hold state transitions to FEEDHOLD_HOLD and the - * distance remaining in the bf last block is replanned up from zero velocity. - * The move in the bf block is NOT released (unlike normal operation), as it - * will be used again to restart from hold. + * - Once deceleration is complete hold state transitions to FEEDHOLD_FINALIZING and + * the distance remaining in the bf last block is replanned up from zero velocity. + * The move in the bf block is NOT released (unlike normal operation), as it will + * be used again to restart from hold. * * - When cm_end_hold() is called it releases the hold, restarts the move and restarts * the spindle if the spindle is active. @@ -1803,11 +1803,15 @@ stat_t cm_feedhold_sequencing_callback() if (cm->hold_state == FEEDHOLD_REQUESTED) { cm_start_hold(); // feed won't run unless the machine is moving } + if (cm->hold_state == FEEDHOLD_FINALIZING) { + cm->hold_state = FEEDHOLD_HOLD; + cm_switch_to_hold(); // perform Z lift, spindle & coolant operations + } if (cm->queue_flush_state == FLUSH_REQUESTED) { cm_queue_flush(); // queue flush won't run until runtime is idle } if (cm->end_hold_requested) { - if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing + if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing cm_end_hold(); } } @@ -1839,7 +1843,8 @@ void cm_end_hold() { if (cm->hold_state == FEEDHOLD_HOLD) { cm->end_hold_requested = false; - mp_exit_hold_state(); + cm_return_from_hold(); +// mp_exit_hold_state(); // State machine cases: if (cm->machine_state == MACHINE_ALARM) { @@ -1877,8 +1882,8 @@ void cm_queue_flush() } /* - * cm_switch() - switch canonical machine to secondary machine - * cm_return() - return secondary canoncial machine to primary machine + * cm_switch_to_hold() - switch canonical machine to secondary machine + * cm_return_from_hold() - return secondary canoncial machine to primary machine * * Doing a Switch is only safe when the machine has completely stopped during a feedhold * Switch works to switch from the primary planer to the secondary planner @@ -1887,7 +1892,7 @@ void cm_queue_flush() stat_t cm_switch(nvObj_t *nv) { - stat_t status = cm_switch_to_secondary(); + stat_t status = cm_switch_to_hold(); if (status != STAT_OK) { nv->valuetype = TYPE_NULL; } @@ -1896,14 +1901,15 @@ stat_t cm_switch(nvObj_t *nv) stat_t cm_return(nvObj_t *nv) { - stat_t status = cm_return_to_primary(); + stat_t status = cm_return_from_hold(); + cm_end_hold(); if (status != STAT_OK) { nv->valuetype = TYPE_NULL; } return (status); } -stat_t cm_switch_to_secondary() +stat_t cm_switch_to_hold() { // Must be in the primary CM and fully stopped in a hold if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { @@ -1925,7 +1931,6 @@ stat_t cm_switch_to_secondary() // clear the target and set the positions to the current hold position memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); -// memset(&(_cm->gm.target_comp), 0, sizeof(_cm->gm.target_comp)); // to zero out compensation terms copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation copy_vector(_cm->gmx.position, mr->position); copy_vector(mp2.position, mr->position); @@ -1941,17 +1946,20 @@ stat_t cm_switch_to_secondary() cm_set_g30_position(); cm_set_motion_state(MOTION_STOP); - // perform Z lift - if (fp_ZERO(cm->feedhold_z_lift)) { // skip this if the lift is zero - return (STAT_OK); + // optional Z lift + if (fp_NOT_ZERO(cm->feedhold_z_lift)) { + float stored_distance_mode = cm_get_distance_mode(MODEL); + cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); + bool flags[] = { 0,0,1,0,0,0 }; + float target[] = { 0,0, cm->feedhold_z_lift, 0,0,0 }; + cm_straight_traverse(target, flags); + cm_set_distance_mode(stored_distance_mode); + } + + // optional spindle stop + if (spindle.pause_on_hold) { + } - float stored_distance_mode = cm_get_distance_mode(MODEL); - cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); - bool flags[AXES] = { 0,0,1,0,0,0 }; - float target[AXES] = { 0,0, cm->feedhold_z_lift, 0,0,0 }; - cm_straight_traverse(target, flags); - cm_set_distance_mode(stored_distance_mode); - return (STAT_OK); } @@ -1961,14 +1969,20 @@ static void _return_move_callback(float* vect, bool* flag) cm2.waiting_for_motion_end = false; } -stat_t cm_return_to_primary() // LATER: if value == true return with offset corrections +stat_t cm_return_from_hold() // LATER: if value == true return with offset corrections { // Must be in the secondary CM and fully stopped if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { return (STAT_COMMAND_NOT_ACCEPTED); } + + // *** while still in secondary machine: + + // restart spindle (with optional dwell) - // while still in secondary, perform the G30 move and queue a wait + // restart coolant + + // perform the G30 move and queue a wait float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move @@ -1976,25 +1990,36 @@ stat_t cm_return_to_primary() // LATER: if value == true return with offset mp_queue_command(_return_move_callback, nullptr, nullptr); cm_select = CM_SECONDARY_RETURN; return (STAT_OK); + + // return_to_primary completes in cm_return_callback() after the wait } -stat_t cm_return_callback() +stat_t cm_return_from_hold_callback() { if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner return (STAT_NOOP); } - if (cm->waiting_for_motion_end) { // sync to planner move ends (using callback) + if (cm->waiting_for_motion_end) { // sync to planner move ends (via _return_move_callback) return (STAT_EAGAIN); } - // return to primary CM + // return to primary machine cm = &cm1; mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; cm_select = CM_PRIMARY; - cm_set_motion_state(MOTION_STOP); // sets active model to primary - cm_end_hold(); +// cm_set_motion_state(MOTION_STOP); // sets active model to primary + +// mp_exit_hold_state(); + + cm->hold_state = FEEDHOLD_OFF; + if (mp_has_runnable_buffer(mp)) { //+++++ + cm_set_motion_state(MOTION_RUN); + sr_request_status_report(SR_REQUEST_IMMEDIATE); + } else { + cm_set_motion_state(MOTION_STOP); + } return (STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 6827099a..19428ce0 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -114,6 +114,7 @@ typedef enum { // feedhold state machine FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero FEEDHOLD_DECEL_END, // end the deceleration FEEDHOLD_PENDING, // waiting to finalize the deceleration once motion stops + FEEDHOLD_FINALIZING, // switch to secondary planner and perform feedhold actions FEEDHOLD_HOLD // holding } cmFeedholdState; @@ -449,9 +450,10 @@ void cm_queue_flush(void); // flush serial void cm_end_queue_flush(void); stat_t cm_switch(nvObj_t *nv); -stat_t cm_switch_to_secondary(void); stat_t cm_return(nvObj_t *nv); -stat_t cm_return_to_primary(void); +stat_t cm_switch_to_hold(void); +stat_t cm_return_from_hold(void); +stat_t cm_return_from_hold_callback(void); void cm_cycle_start(void); // (no Gcode) void cm_cycle_end(void); // (no Gcode) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 897b3976..b1dc3abc 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -161,8 +161,8 @@ static void _controller_HSM() DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(mp_planner_callback()); // motion planner - DISPATCH(cm_return_callback()); // return from secondary planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines + DISPATCH(cm_return_from_hold_callback()); // return from secondary planner DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 8744fc15..d57acc1f 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 2000000 + 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index c4ebc8b6..589762c1 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -529,7 +529,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->motion_state == MOTION_HOLD) { // Case (7) - all motion has ceased - if (cm->hold_state == FEEDHOLD_HOLD) { + if (cm->hold_state >= FEEDHOLD_FINALIZING) { // FINALIZING or FEEDHOLD_HOLD return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } @@ -540,7 +540,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // when homing, we don't need to stay in HOLD cm->hold_state = FEEDHOLD_OFF; } else { - cm->hold_state = FEEDHOLD_HOLD; + cm->hold_state = FEEDHOLD_FINALIZING; } mp_zero_segment_velocity(); // for reporting purposes sr_request_status_report(SR_REQUEST_IMMEDIATE); // was SR_REQUEST_TIMED @@ -690,7 +690,7 @@ stat_t mp_plan_feedhold_move() * Return from feedhold by calling cm_request_end_hold() or cm_end_hold directly. * See canonical_macine.c for a more detailed explanation of feedhold operation. */ - +/* void mp_exit_hold_state() { cm->hold_state = FEEDHOLD_OFF; @@ -701,6 +701,7 @@ void mp_exit_hold_state() cm_set_motion_state(MOTION_STOP); } } +*/ /* * Forward difference math explained: From 7a0ea7d28a7a2a1cbee924d5e7723fe78259a9e4 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 08:36:16 -0500 Subject: [PATCH 069/283] Z lift operates from standard feedhold context, ! and ~ --- g2core/canonical_machine.cpp | 163 +++++++++++++++++++---------------- g2core/controller.h | 3 + g2core/error.h | 4 +- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 141 +++++++++++------------------- 5 files changed, 146 insertions(+), 169 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 47b3bafc..e3f74621 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -113,11 +113,11 @@ **** CM GLOBALS & STRUCTURE ALLOCATIONS ******************************************* ***********************************************************************************/ -cmMachineSelect cm_select; -cmMachine_t *cm; // pointer to active canonical machine -cmMachine_t cm1; // canonical machine primary machine -cmMachine_t cm2; // canonical machine secondary machine -cmToolTable_t tt; // global tool table +cmMachineSelect cm_select; // CM_PRIMARY, CM_SECONDARY, CM_SECONDARY_RETURN +cmMachine_t *cm; // pointer to active canonical machine +cmMachine_t cm1; // canonical machine primary machine +cmMachine_t cm2; // canonical machine secondary machine +cmToolTable_t tt; // global tool table /*********************************************************************************** **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** @@ -1766,52 +1766,81 @@ stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 * to ensure that it either arrives on the data channel or that the data channel is * empty before writing it to the control channel. */ +/* With the addition of the secondary CM, feedhold state management gets tricky. + What you see below is a temporary solution until we decide the general solution. + + The general solution causes a feedhold from the primary context to switch + into the secondary context to perform feedhold actions. When in the secondary + context an additional feedhold will perform the usual STOP operation, but + will remain in the secondary context, and therefore not perform any feedhold + actions (lifts, spindle, etc.). This is needed to support homing and probing + operations from within the secondary context. + + Oddities of the general solution: + - Should we allow a feedhold to be peformed if the tool is not moving? + Right now we don't, but with the secondary context this might be useful + + What you see here is a Q&D to only allow feedholds from the primary context. + It has the following limitations: + - Feedhold requests are only honored form the primary context + - Queue flush requests are only honored form the primary context + - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart + */ + /* * cm_request_feedhold() - * cm_request_end_hold() - cycle restart + * cm_request_end_hold() * cm_request_queue_flush() + * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests */ -void cm_request_feedhold(void) { - // honor request if not already in a feedhold and you are moving - if ((cm->hold_state == FEEDHOLD_OFF) && (cm->motion_state != MOTION_STOP)) { - cm->hold_state = FEEDHOLD_REQUESTED; + +void cm_request_feedhold(void) +{ + // do not generate a feedhold request from the secondary context + if (cm_select != CM_PRIMARY) { + return; + } + // only generate request if not already in a feedhold and the machine is in motion + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + cm1.hold_state = FEEDHOLD_REQUESTED; } } -void cm_request_end_hold(void) +void cm_request_end_hold(void) // This is usually requested form the secondary context { - if (cm->hold_state != FEEDHOLD_OFF) { - cm->end_hold_requested = true; + if (cm1.hold_state != FEEDHOLD_OFF) { + cm1.end_hold_requested = true; } } void cm_request_queue_flush() { - if ((cm->hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm->queue_flush_state == FLUSH_OFF)) { // ...and only once - cm->queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + // do not generate a queue flush request from the secondary context + if (cm_select != CM_PRIMARY) { + return; + } + if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold + (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once + cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now } } -/* - * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests - */ stat_t cm_feedhold_sequencing_callback() { - if (cm->hold_state == FEEDHOLD_REQUESTED) { + if (cm1.hold_state == FEEDHOLD_REQUESTED) { cm_start_hold(); // feed won't run unless the machine is moving } - if (cm->hold_state == FEEDHOLD_FINALIZING) { - cm->hold_state = FEEDHOLD_HOLD; + if (cm1.hold_state == FEEDHOLD_FINALIZING) { + cm1.hold_state = FEEDHOLD_HOLD; cm_switch_to_hold(); // perform Z lift, spindle & coolant operations } - if (cm->queue_flush_state == FLUSH_REQUESTED) { + if (cm1.queue_flush_state == FLUSH_REQUESTED) { cm_queue_flush(); // queue flush won't run until runtime is idle } - if (cm->end_hold_requested) { - if (cm->queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing + if (cm1.end_hold_requested) { + if (cm1.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing cm_end_hold(); } } @@ -1822,18 +1851,17 @@ stat_t cm_feedhold_sequencing_callback() * cm_has_hold() - return true if a hold condition exists (or a pending hold request) * cm_start_hold() - start a feedhhold by signalling the exec * cm_end_hold() - end a feedhold by returning the system to normal operation - * cm_queue_flush() - Flush planner queue and correct model positions */ bool cm_has_hold() { - return (cm->hold_state != FEEDHOLD_OFF); + return (cm1.hold_state != FEEDHOLD_OFF); } void cm_start_hold() { if (mp_has_runnable_buffer(mp)) { //+++++ // meaning there's something running - cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected - cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected +// cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected +// cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected cm_set_motion_state(MOTION_HOLD); cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } @@ -1841,43 +1869,9 @@ void cm_start_hold() void cm_end_hold() { - if (cm->hold_state == FEEDHOLD_HOLD) { - cm->end_hold_requested = false; + if (cm1.hold_state == FEEDHOLD_HOLD) { + cm1.end_hold_requested = false; cm_return_from_hold(); -// mp_exit_hold_state(); - - // State machine cases: - if (cm->machine_state == MACHINE_ALARM) { - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); - - } else if (cm->motion_state == MOTION_STOP) { // && (! MACHINE_ALARM) - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); - cm_cycle_end(); - - } else { // (MOTION_RUN || MOTION_PLANNING) && (! MACHINE_ALARM) - cm_cycle_start(); - cm_spindle_resume(spindle.dwell_seconds); - cm_coolant_resume(); - st_request_exec_move(); - } - } -} - -void cm_queue_flush() -{ - if (mp_runtime_is_idle()) { // can't flush planner during movement - mp_flush_planner(mp); // +++++ Active planner. Potential cleanup - - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions - cm_set_position(axis, mp_get_runtime_absolute_position(axis)); - } - if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one - cm_end_hold(); - } - cm->queue_flush_state = FLUSH_OFF; - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } } @@ -1976,13 +1970,17 @@ stat_t cm_return_from_hold() // LATER: if value == true return with offset c return (STAT_COMMAND_NOT_ACCEPTED); } - // *** while still in secondary machine: - + // *** While still in secondary machine: +/* + if (cm->machine_state == MACHINE_ALARM) { + cm_spindle_off_immediate(); + cm_coolant_off_immediate(); +*/ // restart spindle (with optional dwell) // restart coolant - // perform the G30 move and queue a wait + // perform the G30 move and queue a wait float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move @@ -2009,20 +2007,39 @@ stat_t cm_return_from_hold_callback() mr = mp->mr; cm_select = CM_PRIMARY; -// cm_set_motion_state(MOTION_STOP); // sets active model to primary - -// mp_exit_hold_state(); - cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(mp)) { //+++++ + if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); sr_request_status_report(SR_REQUEST_IMMEDIATE); } else { cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); } return (STAT_OK); } +/* + * cm_queue_flush() - Flush planner queue and correct model positions + */ + +void cm_queue_flush() +{ + if (mp_runtime_is_idle()) { // can't flush planner during movement + mp_flush_planner(mp); // +++++ Active planner. Potential cleanup + + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions + cm_set_position(axis, mp_get_runtime_absolute_position(axis)); + } + if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one + cm_end_hold(); + } + cm->queue_flush_state = FLUSH_OFF; + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available + } +} + /****************************** * Program Functions (4.3.10) * ******************************/ diff --git a/g2core/controller.h b/g2core/controller.h index 6d290dc2..e17ca3a9 100644 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -72,6 +72,9 @@ typedef struct controllerSingleton { // main TG controller struct char out_buf[OUTPUT_BUFFER_LEN]; // output buffer char saved_buf[SAVED_BUFFER_LEN]; // save the input buffer + // Exceptions - some exceptions cannot be notified by an ER because they are in interrupts + bool exec_aline_assertion_failure; // record an exception deep inside mp_exec_aline() + magic_t magic_end; } controller_t; diff --git a/g2core/error.h b/g2core/error.h index 1a26756f..a6e346a5 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -164,10 +164,10 @@ char *get_status_message(stat_t status); #define STAT_ERROR_84 84 #define STAT_ERROR_85 85 #define STAT_ERROR_86 86 -#define STAT_ERROR_87 87 // Assertion failures - build down from 99 until they meet the system internal errors +#define STAT_EXEC_ALINE_ASSERTION_FAILURE 87 #define STAT_BUFFER_FREE_ASSERTION_FAILURE 88 #define STAT_STATE_MANAGEMENT_ASSERTION_FAILURE 89 #define STAT_CONFIG_ASSERTION_FAILURE 90 @@ -469,8 +469,8 @@ static const char stat_83[] = "83"; static const char stat_84[] = "84"; static const char stat_85[] = "85"; static const char stat_86[] = "86"; -static const char stat_87[] = "87"; +static const char stat_87[] = "mp_exec_aline() assertion failure"; static const char stat_88[] = "Buffer free assertion failure"; static const char stat_89[] = "State management assertion failure"; static const char stat_90[] = "Config assertion failure"; diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index d57acc1f..c8cc86a8 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 589762c1..13ab102b 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -315,33 +315,33 @@ stat_t mp_exec_move() /************************************************************************* * ---> Everything here fires from interrupts and must be interrupt safe * - * _exec_aline() - acceleration line main routine - * _exec_aline_head() - helper for acceleration section - * _exec_aline_body() - helper for cruise section - * _exec_aline_tail() - helper for deceleration section + * _exec_aline() - acceleration line main routine + * _exec_aline_head() - helper for acceleration section + * _exec_aline_body() - helper for cruise section + * _exec_aline_tail() - helper for deceleration section * _exec_aline_segment() - helper for running a segment * * Returns: * STAT_OK move is done * STAT_EAGAIN move is not finished - has more segments to run - * STAT_NOOP cause no operation from the steppers - do not load the move + * STAT_NOOP would cause no operation to the steppers - do not load the move * STAT_xxxxx fatal error. Ends the move and frees the bf buffer * * This routine is called from the (LO) interrupt level. The interrupt sequencing * relies on the behaviors of the routines being exactly correct. Each call to - * _exec_aline() must execute and prep *one and only one* segment. If the segment + * _exec_aline() must execute and prep **one and only one** segment. If the segment * is the not the last segment in the bf buffer the _aline() must return STAT_EAGAIN. * If it's the last segment it must return STAT_OK. If it encounters a fatal error * that would terminate the move it should return a valid error code. Failure to * obey this will introduce subtle and very difficult to diagnose bugs (trust us on this). * * Note 1: Returning STAT_OK ends the move and frees the bf buffer. - * Returning STAT_OK at this point does NOT advance position meaning any - * position error will be compensated by the next move. + * Returning STAT_OK at this point does NOT advance the position vector, + * meaning any position error will be compensated by the next move. * - * Note 2: Solves a potential race condition where the current move ends but the - * new move has not started because the previous move is still being run - * by the steppers. Planning can overwrite the new move. + * Note 2: BF/MR sequencing solves a potential race condition where the current move + * ends but the new move has not started because the previous move is still + * being run by the steppers. Planning can overwrite the new move. */ /* --- State transitions - hierarchical state machine --- * @@ -357,7 +357,7 @@ stat_t mp_exec_move() * _RUN2 - run the second part * * Important distinction to note: - * - mp_plan move() is called for every type of move + * - mp_plan move() is called for every type of move (bf block) * - mp_exec_move() is called for every type of move * - mp_exec_aline() is only called for alines */ @@ -407,17 +407,17 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Initialize all new blocks, regardless of normal or feedhold operation if (mr->block_state == BLOCK_INACTIVE) { - // too short lines have already been removed... - // so is the following code is no longer needed ++++ ash + // Zero length moves (and other too-short moves) should have already been removed... + // ...so the following code is no longer needed. // But let's still alert the condition should it ever occur if (fp_ZERO(bf->length)) { // ...looks for an actual zero here rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, "mp_exec_aline() zero length move"); } // Start a new move by setting up the runtime singleton (mr) - memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state - bf->block_state = BLOCK_ACTIVE; // note that this buffer is running - // note the planner doesn't look at block_state + memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state + bf->block_state = BLOCK_ACTIVE; // note that this buffer is running + // note the planner doesn't look at block_state mr->block_state = BLOCK_INITIAL_ACTION; mr->section = SECTION_HEAD; mr->section_state = SECTION_NEW; @@ -426,35 +426,35 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block - // Assumptions that are required for this to work: - // entry velocity <= cruise velocity && cruise velocity >= exit velocity + // Equalities that must be true for this to work: + // entry velocity <= cruise velocity && + // cruise velocity >= exit velocity + // // Even if the move is head or tail only, cruise velocity needs to be valid. // This is because a "head" is *always* entry->cruise, and a "tail" is *always* cruise->exit, - // even if there are not other sections int he move. (This is a significant time savings.) + // even if there are not other sections in the move. (This is a significant time savings.) // Here we will check to make sure that the sections are longer than MIN_SEGMENT_TIME if ((!fp_ZERO(mr->r->head_length)) && (mr->r->head_time < MIN_SEGMENT_TIME)) { - // head_time !== body_time - // We have to compute the new body time addition. - mr->r->body_length += mr->r->head_length; - mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; - - mr->r->head_length = 0; - mr->r->head_time = 0; + // head_time !== body_time + // We have to compute the new body time addition. + mr->r->body_length += mr->r->head_length; + mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; + mr->r->head_length = 0; + mr->r->head_time = 0; } if ((!fp_ZERO(mr->r->tail_length)) && (mr->r->tail_time < MIN_SEGMENT_TIME)) { // tail_time !== body_time // We have to compute the new body time addition. mr->r->body_length += mr->r->tail_length; mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; - mr->r->tail_length = 0; mr->r->tail_time = 0; } // At this point, we've already possibly merged head and/or tail into the body. - // If the body is too "short" (brief) still, we *might* be able to add it to a head or tail. + // If the body is still too "short" (brief) we *might* be able to add it to a head or tail. // If there's still a head or a tail, we will add the body to whichever there is, maybe both. // We saved it for last since it's the most expensive. if ((!fp_ZERO(mr->r->body_length)) && (mr->r->body_time < MIN_SEGMENT_TIME)) { @@ -466,10 +466,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) float body_split = mr->r->body_length/2.0; mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->head_length += body_split; mr->r->tail_length += body_split; - mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } else { @@ -477,7 +475,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->tail_length += mr->r->body_length; mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } } @@ -486,13 +483,13 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->head_length += mr->r->body_length; mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); } else { // Uh oh! We have a move that's all body, and is still too short!! - // ++++ RG For now, we'll consider this impossible. - while (1); + // while (1); // ++++ RG For now, we'll consider this impossible. + cs.exec_aline_assertion_failure = true; + return (STAT_EXEC_ALINE_ASSERTION_FAILURE); } } @@ -523,27 +520,27 @@ stat_t mp_exec_aline(mpBuf_t *bf) // (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) // (5) - We have decelerated a block to zero velocity // (6) - We have finished all the runtime work now we have to wait for the steppers to stop - // (7) - The steppers have stopped. No motion should occur + // (7) - The steppers have stopped. No motion should occur. ALlows hold finalization to commence // (8) - We are removing the hold state and there is queued motion (handled outside this routine) // (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) if (cm->motion_state == MOTION_HOLD) { // Case (7) - all motion has ceased - if (cm->hold_state >= FEEDHOLD_FINALIZING) { // FINALIZING or FEEDHOLD_HOLD - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + if (cm->hold_state >= FEEDHOLD_FINALIZING) { // FEEDHOLD_FINALIZING or FEEDHOLD_HOLD + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } // Case (6) - wait for the steppers to stop if (cm->hold_state == FEEDHOLD_PENDING) { if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - // when homing, we don't need to stay in HOLD + // when homing or probing we don't want to stay in HOLD or execute finalizations cm->hold_state = FEEDHOLD_OFF; } else { cm->hold_state = FEEDHOLD_FINALIZING; } mp_zero_segment_velocity(); // for reporting purposes - sr_request_status_report(SR_REQUEST_IMMEDIATE); // was SR_REQUEST_TIMED + sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } return (STAT_OK); // hold here. No more movement @@ -552,28 +549,24 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (5) - decelerated to zero // Update the run buffer then force a replan of the whole planner queue if (cm->hold_state == FEEDHOLD_DECEL_END) { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr->target, mr->position);// reset length - //bf->entry_vmax = 0; // set bp+0 as hold point - + //bf->entry_vmax = 0; // set bp+0 as hold point cm->hold_state = FEEDHOLD_PENDING; // No point bothering with the rest of this move if homing or probing if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { mp_free_run_buffer(); } - mp_replan_queue(mp_get_r()); // make it replan all the blocks -// mp_replan_queue(mb.r); // make it replan all the blocks - return (STAT_OK); } // Cases (1a, 1b), Case (2), Case (4) // Build a tail-only move from here. Decelerate as fast as possible in the space we have. if ((cm->hold_state == FEEDHOLD_SYNC) || - ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { + ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { // Case (3a) - already decelerating, continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are @@ -587,13 +580,10 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Small exception, if we *just started* the head, then we're not actually accelerating yet. } else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { mr->entry_velocity = mr->segment_velocity; - mr->section = SECTION_TAIL; mr->section_state = SECTION_NEW; - mr->r->head_length = 0; mr->r->body_length = 0; - float available_length = get_axis_vector_length(mr->target, mr->position); mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length @@ -615,7 +605,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) } } } - + // End Feedhold Processing + mr->block_state = BLOCK_ACTIVE; // NB: from this point on the contents of the bf buffer do not affect execution @@ -649,19 +640,18 @@ stat_t mp_exec_aline(mpBuf_t *bf) // There is no fourth thing. Nobody expects the Spanish Inquisition if (status == STAT_EAGAIN) { - sr_request_status_report(SR_REQUEST_TIMED); // continue reporting mr buffer - // Note that tha'll happen in a lower interrupt level. + sr_request_status_report(SR_REQUEST_TIMED); // continue reporting mr buffer + // Note that that'll happen in a lower interrupt level. } else { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer (reset) mr->section_state = SECTION_OFF; - mp->run_time_remaining = 0.0; // it's done, so time goes to zero - - mr->entry_velocity = mr->r->exit_velocity; // feed the old exit into the entry. + mp->run_time_remaining = 0.0; // it's done, so time goes to zero + mr->entry_velocity = mr->r->exit_velocity; // feed the old exit into the entry. if (bf->block_state == BLOCK_ACTIVE) { - if (mp_free_run_buffer()) { // returns true of the buffer is empty + if (mp_free_run_buffer()) { // returns true of the buffer is empty if (cm->hold_state == FEEDHOLD_OFF) { - cm_cycle_end(); // free buffer & end cycle if planner is empty + cm_cycle_end(); // free buffer & end cycle if planner is empty } } else { st_request_forward_plan(); @@ -671,38 +661,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) return (status); } - -/* - * mp_plan_feedhold_move() - plan Z lift moves for feedhold - */ - -stat_t mp_plan_feedhold_move() -{ - - return (STAT_OK); -} - -/* - * mp_exit_hold_state() - end a feedhold - * - * Feedhold is executed as cm->hold_state transitions executed inside _exec_aline() - * Invoke a feedhold by calling cm_request_hold() or cm_start_hold() directly - * Return from feedhold by calling cm_request_end_hold() or cm_end_hold directly. - * See canonical_macine.c for a more detailed explanation of feedhold operation. - */ -/* -void mp_exit_hold_state() -{ - cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(mp)) { //+++++ - cm_set_motion_state(MOTION_RUN); - sr_request_status_report(SR_REQUEST_IMMEDIATE); - } else { - cm_set_motion_state(MOTION_STOP); - } -} -*/ - /* * Forward difference math explained: * @@ -836,7 +794,6 @@ static void _init_forward_diffs(const float v_0, const float v_1) // E = 0 // F = Vi - const float h = 1/(mr->segments); const float h_2 = h * h; const float h_3 = h_2 * h; From dee29211d3eb9bf29bad1b2a8fb17c05f82b9e7e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 09:00:33 -0500 Subject: [PATCH 070/283] Removed {switch} and {return} commands --- g2core/canonical_machine.cpp | 64 +++++++++++++++--------------------- g2core/canonical_machine.h | 18 ++++------ g2core/config_app.cpp | 4 +-- 3 files changed, 36 insertions(+), 50 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index e3f74621..e0f11046 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1777,7 +1777,7 @@ stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 operations from within the secondary context. Oddities of the general solution: - - Should we allow a feedhold to be peformed if the tool is not moving? + - Should we allow a feedhold to be performed if the tool is not moving? Right now we don't, but with the secondary context this might be useful What you see here is a Q&D to only allow feedholds from the primary context. @@ -1801,7 +1801,11 @@ void cm_request_feedhold(void) return; } // only generate request if not already in a feedhold and the machine is in motion - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { +// if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + + // only generate request if not already in a feedhold + // It's OK if the machine is stopped - this just enters the feedhold context + if (cm1.hold_state == FEEDHOLD_OFF) { cm1.hold_state = FEEDHOLD_REQUESTED; } } @@ -1834,7 +1838,7 @@ stat_t cm_feedhold_sequencing_callback() } if (cm1.hold_state == FEEDHOLD_FINALIZING) { cm1.hold_state = FEEDHOLD_HOLD; - cm_switch_to_hold(); // perform Z lift, spindle & coolant operations + cm_switch_to_hold_context(); // perform Z lift, spindle & coolant operations } if (cm1.queue_flush_state == FLUSH_REQUESTED) { cm_queue_flush(); // queue flush won't run until runtime is idle @@ -1860,8 +1864,6 @@ bool cm_has_hold() void cm_start_hold() { if (mp_has_runnable_buffer(mp)) { //+++++ // meaning there's something running -// cm_spindle_optional_pause(spindle.pause_on_hold); // pause if this option is selected -// cm_coolant_optional_pause(coolant.pause_on_hold); // pause if this option is selected cm_set_motion_state(MOTION_HOLD); cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } @@ -1871,39 +1873,18 @@ void cm_end_hold() { if (cm1.hold_state == FEEDHOLD_HOLD) { cm1.end_hold_requested = false; - cm_return_from_hold(); + cm_return_from_hold_context(); } } /* - * cm_switch_to_hold() - switch canonical machine to secondary machine - * cm_return_from_hold() - return secondary canoncial machine to primary machine + * cm_switch_to_hold_context() - switch to secondary machine context * - * Doing a Switch is only safe when the machine has completely stopped during a feedhold - * Switch works to switch from the primary planer to the secondary planner - * Use Return to return to the primary planner + * Moving between contexts is only safe when the machine is completely stopped + * either during a feedhold or when idle. */ -stat_t cm_switch(nvObj_t *nv) -{ - stat_t status = cm_switch_to_hold(); - if (status != STAT_OK) { - nv->valuetype = TYPE_NULL; - } - return (status); -} - -stat_t cm_return(nvObj_t *nv) -{ - stat_t status = cm_return_from_hold(); - cm_end_hold(); - if (status != STAT_OK) { - nv->valuetype = TYPE_NULL; - } - return (status); -} - -stat_t cm_switch_to_hold() +stat_t cm_switch_to_hold_context() { // Must be in the primary CM and fully stopped in a hold if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { @@ -1957,13 +1938,22 @@ stat_t cm_switch_to_hold() return (STAT_OK); } +/* + * cm_return_from_hold_context() - initiate return from secondary context + * cm_return_from_hold_callback() - main loop callback to finsh return once moves are done + * _planner_done_callback() - callback to sync to end of planner operations + * + * Moving between contexts is only safe when the machine is completely stopped + * either during a feedhold or when idle. + */ + // Callback to run at when the G30 return move is finished -static void _return_move_callback(float* vect, bool* flag) +static void _planner_done_callback(float* vect, bool* flag) { - cm2.waiting_for_motion_end = false; + cm2.waiting_for_planner_done = false; } -stat_t cm_return_from_hold() // LATER: if value == true return with offset corrections +stat_t cm_return_from_hold_context() // LATER: if value == true return with offset corrections { // Must be in the secondary CM and fully stopped if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { @@ -1984,8 +1974,8 @@ stat_t cm_return_from_hold() // LATER: if value == true return with offset c float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move - cm->waiting_for_motion_end = true; // indicates running the final G30 move in the secondary - mp_queue_command(_return_move_callback, nullptr, nullptr); + cm->waiting_for_planner_done = true; // indicates running the final G30 move in the secondary + mp_queue_command(_planner_done_callback, nullptr, nullptr); cm_select = CM_SECONDARY_RETURN; return (STAT_OK); @@ -1997,7 +1987,7 @@ stat_t cm_return_from_hold_callback() if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner return (STAT_NOOP); } - if (cm->waiting_for_motion_end) { // sync to planner move ends (via _return_move_callback) + if (cm->waiting_for_planner_done) { // sync to planner move ends (via _return_move_callback) return (STAT_EAGAIN); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 19428ce0..90abd505 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -257,7 +257,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot - bool waiting_for_motion_end; // set true during a return-to-primary planner operation (G30 is completing) + bool waiting_for_planner_done; // cm_return_from_hold_context() uses this to tell when secondary planner finished bool end_hold_requested; // request restart after feedhold bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) @@ -433,28 +433,24 @@ stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50 stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1 // See spindle.cpp for cm_sso_control() // M51 -// Program Functions (4.3.10) +// Feedhold and related functions void cm_request_feedhold(void); void cm_request_end_hold(void); void cm_request_queue_flush(void); -void cm_request_end_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests -stat_t cm_return_callback(void); // return from secondary planner -// Feedhold and related functions bool cm_has_hold(void); void cm_start_hold(void); void cm_end_hold(void); +stat_t cm_switch_to_hold_context(void); // move to secondary planner for in-hold actions +stat_t cm_return_from_hold_context(void); // return to primary planner +stat_t cm_return_from_hold_callback(void); // main loop callback for synchronization + void cm_queue_flush(void); // flush serial and planner queues with coordinate resets void cm_end_queue_flush(void); -stat_t cm_switch(nvObj_t *nv); -stat_t cm_return(nvObj_t *nv); -stat_t cm_switch_to_hold(void); -stat_t cm_return_from_hold(void); -stat_t cm_return_from_hold_callback(void); - +// Program Functions (4.3.10) void cm_cycle_start(void); // (no Gcode) void cm_cycle_end(void); // (no Gcode) void cm_canned_cycle_end(void); // end of canned cycle diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index dee95c51..b547ab02 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -906,8 +906,8 @@ const cfgItem_t cfgArray[] = { { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, - { "", "switch",_f0,0, tx_print_nul, get_nul, cm_switch, (float *)&cs.null,0 }, - { "", "return",_f0,0, tx_print_nul, get_nul, cm_return, (float *)&cs.null,0 }, +// { "", "switch",_f0,0, tx_print_nul, get_nul, cm_switch, (float *)&cs.null,0 }, +// { "", "return",_f0,0, tx_print_nul, get_nul, cm_return, (float *)&cs.null,0 }, #ifdef __HELP_SCREENS { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen From fb10abfff8fc52283454ba3e70897725d3fc7251 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 10:04:32 -0500 Subject: [PATCH 071/283] Separated canonical machine feedhold functions and alarm handlers into separate files --- g2core/alarm.cpp | 247 +++++++++++++ g2core/canonical_machine.cpp | 678 ++++------------------------------- g2core/canonical_machine.h | 41 +-- g2core/cycle_feedhold.cpp | 377 +++++++++++++++++++ g2core/g2core.cppproj | 6 + 5 files changed, 716 insertions(+), 633 deletions(-) create mode 100644 g2core/alarm.cpp create mode 100644 g2core/cycle_feedhold.cpp diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp new file mode 100644 index 00000000..7a962f5d --- /dev/null +++ b/g2core/alarm.cpp @@ -0,0 +1,247 @@ +/* + * alarm.cpp - canonical machine alarm handlers + * This file is part of the g2core project + * + * Copyright (c) 2010 - 2017 Alden S Hart, Jr. + * Copyright (c) 2014 - 2017 Robert Giseburt + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "g2core.h" // #1 +#include "config.h" // #2 +#include "gcode.h" // #3 +#include "canonical_machine.h" +#include "planner.h" +#include "report.h" +#include "spindle.h" +#include "coolant.h" +#include "temperature.h" +#include "util.h" + +/******************************************************************************** + * ALARM, SHUTDOWN, and PANIC are nested dolls. + * + * cm_alrm() - invoke alarm from command + * cm_shutd() - invoke shutdown from command + * cm_pnic() - invoke panic from command + * cm_clr() - clear alarm or shutdown from command + * + * The alarm states can be invoked from the above commands for testing and clearing + */ +stat_t cm_alrm(nvObj_t *nv) // invoke alarm from command +{ + cm_alarm(STAT_ALARM, "sent by host"); + return (STAT_OK); +} + +stat_t cm_shutd(nvObj_t *nv) // invoke shutdown from command +{ + cm_shutdown(STAT_SHUTDOWN, "sent by host"); + return (STAT_OK); +} + +stat_t cm_pnic(nvObj_t *nv) // invoke panic from command +{ + cm_panic(STAT_PANIC, "sent by host"); + return (STAT_OK); +} + +stat_t cm_clr(nvObj_t *nv) // clear alarm or shutdown from command line +{ + cm_clear(); + return (STAT_OK); +} + +/* + * cm_clear() - clear ALARM and SHUTDOWN states + * cm_parse_clear() - parse incoming gcode for M30 or M2 clears if in ALARM state + * + * Parse clear interprets an M30 or M2 PROGRAM_END as a $clear condition and clear ALARM + * but not SHUTDOWN or PANIC. Assumes Gcode string has no leading or embedded whitespace + */ + +void cm_clear() +{ + if (cm->machine_state == MACHINE_ALARM) { + cm->machine_state = MACHINE_PROGRAM_STOP; + } else if (cm->machine_state == MACHINE_SHUTDOWN) { + cm->machine_state = MACHINE_READY; + } +} + +void cm_parse_clear(const char *s) +{ + if (cm->machine_state == MACHINE_ALARM) { + if (toupper(s[0]) == 'M') { + if (( (s[1]=='3') && (s[2]=='0') && (s[3]==0)) || ((s[1]=='2') && (s[2]==0) )) { + cm_clear(); + } + } + } +} + +/* + * cm_is_alarmed() - return alarm status code or OK if no alarms + */ + +stat_t cm_is_alarmed() +{ + if (cm->machine_state == MACHINE_ALARM) { return (STAT_COMMAND_REJECTED_BY_ALARM); } + if (cm->machine_state == MACHINE_SHUTDOWN) { return (STAT_COMMAND_REJECTED_BY_SHUTDOWN); } + if (cm->machine_state == MACHINE_PANIC) { return (STAT_COMMAND_REJECTED_BY_PANIC); } + return (STAT_OK); +} + +/* + * cm_halt_all() - stop, spindle and coolant immediately + * cm_halt_motion() - stop motion immediately. Does not affect spindle, coolant, or other IO + * + * Stop motors and reset all system states accordingly. + * Does not de-energize motors as in some cases the motors must remain energized + * in order to prevent an axis from crashing. + */ + +void cm_halt_all(void) +{ + cm_halt_motion(); + cm_spindle_off_immediate(); + cm_coolant_off_immediate(); +} + +void cm_halt_motion(void) +{ + mp_halt_runtime(); // stop the runtime. Do this immediately. (Reset is in cm_clear) + canonical_machine_reset(cm); // halt the currently active machine + cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone + cm->motion_state = MOTION_STOP; + cm->hold_state = FEEDHOLD_OFF; +} + +/* + * cm_alarm() - enter ALARM state + * + * An ALARM sets the ALARM machine state, starts a feedhold to stop motion, stops the + * spindle, turns off coolant, clears out queued planner moves and serial input, + * and rejects new action commands (gcode blocks, SET commands, and other actions) + * until the alarm is cleared. + * + * ALARM is typically entered by a soft limit or a limit switch being hit. In the + * limit switch case the INPUT_ACTION will override the feedhold - i.e. if the + * input action is "FAST_STOP" or "HALT" that setting will take precedence over + * the feedhold native to the alarm function. + * + * Gcode and machine state is preserved. It may be possible to recover the job from + * an alarm, but in many cases this is not possible. Since ALARM attempts to preserve + * Gcode and machine state it does not END the job. + * + * ALARM may also be invoked from the command line using {alarm:n} or $alarm + * ALARM can be manually cleared by entering: {clear:n}, {clr:n}, $clear, or $clr + * ALARMs will also clear on receipt of an M30 or M2 command if one is received + * while draining the host command queue. + */ + +stat_t cm_alarm(const stat_t status, const char *msg) +{ + if ((cm->machine_state == MACHINE_ALARM) || (cm->machine_state == MACHINE_SHUTDOWN) || + (cm->machine_state == MACHINE_PANIC)) { + return (STAT_OK); // don't alarm if already in an alarm state + } + cm->machine_state = MACHINE_ALARM; + cm_request_feedhold(); // stop motion + cm_request_queue_flush(); // do a queue flush once runtime is not busy + +// TBD - these functions should probably be called - See cm_shutdown() +// cm_spindle_control_immediate(SPINDLE_OFF); +// cm_coolant_off_immediate(); +// cm_spindle_optional_pause(spindle.pause_on_hold); +// cm_coolant_optional_pause(coolant.pause_on_hold); + rpt_exception(status, msg); // send alarm message + + // If "stat" is in the status report, we need to poke it to send. + sr_request_status_report(SR_REQUEST_TIMED); + return (status); +} +/* + * cm_shutdown() - enter shutdown state + * + * SHUTDOWN stops all motion, spindle and coolant immediately, sets a SHUTDOWN machine + * state, clears out queued moves and serial input, and rejects new action commands + * (gcode blocks, SET commands, and some others). + * + * Shutdown is typically invoked as an electrical input signal sent to the board as + * part of an external emergency stop (Estop). Shutdown is meant to augment but not + * replace the external Estop functions that shut down power to motors, spindles and + * other moving parts. + * + * Shutdown may also be invoked from the command line using {shutd:n} or $shutd + * Shutdown must be manually cleared by entering: {clear:n}, {clr:n}, $clear, or $clr + * Shutdown does not clear on M30 or M2 Gcode commands + */ + +stat_t cm_shutdown(const stat_t status, const char *msg) +{ + if ((cm->machine_state == MACHINE_SHUTDOWN) || (cm->machine_state == MACHINE_PANIC)) { + return (STAT_OK); // don't shutdown if shutdown or panic'd + } + cm_halt_motion(); // halt motors (may have already been done from GPIO) + spindle_reset(); // stop spindle immediately and set speed to 0 RPM + coolant_reset(); // stop coolant immediately + temperature_reset(); // turn off heaters and fans + cm_queue_flush(); // flush all queues and reset positions + + for (uint8_t i = 0; i < HOMING_AXES; i++) { // unhome axes and the machine + cm->homed[i] = false; + } + cm->homing_state = HOMING_NOT_HOMED; + + cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity + rpt_exception(status, msg); // send exception report + return (status); +} + +/* + * cm_panic() - enter panic state + * + * PANIC occurs if the firmware has detected an unrecoverable internal error + * such as an assertion failure or a code condition that should never occur. + * It sets PANIC machine state, and leaves the system inspect able (if possible). + * + * PANIC can only be exited by a hardware reset or soft reset (^x) + */ + +stat_t cm_panic(const stat_t status, const char *msg) +{ + _debug_trap(msg); + + if (cm->machine_state == MACHINE_PANIC) { // only do this once + return (STAT_OK); + } + cm_halt_motion(); // halt motors (may have already been done from GPIO) + spindle_reset(); // stop spindle immediately and set speed to 0 RPM + coolant_reset(); // stop coolant immediately + temperature_reset(); // turn off heaters and fans + cm_queue_flush(); // flush all queues and reset positions + + cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + rpt_exception(status, msg); // send panic report + return (status); +} diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index e0f11046..4117289c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -107,7 +107,7 @@ #include "temperature.h" #include "hardware.h" #include "util.h" -#include "xio.h" // for serial queue flush +#include "xio.h" /*********************************************************************************** **** CM GLOBALS & STRUCTURE ALLOCATIONS ******************************************* @@ -136,6 +136,9 @@ static int8_t _axis(const index_t index); **** CODE ************************************************************************* ***********************************************************************************/ +/*********************************************************************************** + **** Initialization *************************************************************** + ***********************************************************************************/ /* * canonical_machine_inits() - combined cm inits * canonical_machine_init() - initialize cm struct @@ -247,10 +250,9 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) return (STAT_OK); } -/************************************* - * Internal getters and setters * - * Canonical Machine State functions * - *************************************/ +/*********************************************************************************** + **** Canonical Machine State Management ******************************************* + ***********************************************************************************/ /* * cm_set_motion_state() - adjusts active model pointer as well */ @@ -331,10 +333,9 @@ cmCombinedState cm_get_combined_state() } } -/*********************************** - * Model State Getters and Setters * - ***********************************/ - +/*********************************************************************************** + **** Model State Getters and Setters ********************************************** + ***********************************************************************************/ /* These getters and setters will work on any gm model with inputs: * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct @@ -377,7 +378,8 @@ void cm_set_model_linenum(const uint32_t linenum) } /*********************************************************************************** - * COORDINATE SYSTEMS AND OFFSETS + **** COORDINATE SYSTEMS AND OFFSETS *********************************************** + *********************************************************************************** * Functions to get, set and report coordinate systems and work offsets * These functions are not part of the NIST defined functions ***********************************************************************************/ @@ -478,7 +480,8 @@ float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) } /*********************************************************************************** - * CRITICAL HELPERS + **** CRITICAL HELPERS ************************************************************* + *********************************************************************************** * Core functions supporting the canonical machining functions * These functions are not part of the NIST defined functions ***********************************************************************************/ @@ -761,233 +764,17 @@ stat_t cm_test_soft_limits(const float target[]) return (STAT_OK); } -/************************************************************************* - * CANONICAL MACHINING FUNCTIONS - * Values are passed in pre-unit_converted state (from gn structure) - * All operations occur on gm (current model state) - * - * These are organized by section number (x.x.x) in the order they are - * found in NIST RS274 NGCv3 - ************************************************************************/ +/*********************************************************************************** + **** CANONICAL MACHINING FUNCTIONS ************************************************ + *********************************************************************************** + * Organized by section number in the order they are found in NIST RS274 NGCv3 + **********************************************************************************/ -/************************** - * Alarms * - **************************/ +/*********************************************************************************** + **** Representation (4.3.3) ******************************************************* + ***********************************************************************************/ -/******************************************************************************** - * ALARM, SHUTDOWN, and PANIC are nested dolls. - * - * cm_alrm() - invoke alarm from command - * cm_shutd() - invoke shutdown from command - * cm_pnic() - invoke panic from command - * cm_clr() - clear alarm or shutdown from command - * - * The alarm states can be invoked from the above commands for testing and clearing - */ -stat_t cm_alrm(nvObj_t *nv) // invoke alarm from command -{ - cm_alarm(STAT_ALARM, "sent by host"); - return (STAT_OK); -} - -stat_t cm_shutd(nvObj_t *nv) // invoke shutdown from command -{ - cm_shutdown(STAT_SHUTDOWN, "sent by host"); - return (STAT_OK); -} - -stat_t cm_pnic(nvObj_t *nv) // invoke panic from command -{ - cm_panic(STAT_PANIC, "sent by host"); - return (STAT_OK); -} - -stat_t cm_clr(nvObj_t *nv) // clear alarm or shutdown from command line -{ - cm_clear(); - return (STAT_OK); -} - -/* - * cm_clear() - clear ALARM and SHUTDOWN states - * cm_parse_clear() - parse incoming gcode for M30 or M2 clears if in ALARM state - * - * Parse clear interprets an M30 or M2 PROGRAM_END as a $clear condition and clear ALARM - * but not SHUTDOWN or PANIC. Assumes Gcode string has no leading or embedded whitespace - */ - -void cm_clear() -{ - if (cm->machine_state == MACHINE_ALARM) { - cm->machine_state = MACHINE_PROGRAM_STOP; - } else if (cm->machine_state == MACHINE_SHUTDOWN) { - cm->machine_state = MACHINE_READY; - } -} - -void cm_parse_clear(const char *s) -{ - if (cm->machine_state == MACHINE_ALARM) { - if (toupper(s[0]) == 'M') { - if (( (s[1]=='3') && (s[2]=='0') && (s[3]==NUL)) || ((s[1]=='2') && (s[2]==NUL) )) { - cm_clear(); - } - } - } -} - -/* - * cm_is_alarmed() - return alarm status code or OK if no alarms - */ - -stat_t cm_is_alarmed() -{ - if (cm->machine_state == MACHINE_ALARM) { return (STAT_COMMAND_REJECTED_BY_ALARM); } - if (cm->machine_state == MACHINE_SHUTDOWN) { return (STAT_COMMAND_REJECTED_BY_SHUTDOWN); } - if (cm->machine_state == MACHINE_PANIC) { return (STAT_COMMAND_REJECTED_BY_PANIC); } - return (STAT_OK); -} - -/* - * cm_halt_all() - stop, spindle and coolant immediately - * cm_halt_motion() - stop motion immediately. Does not affect spindle, coolant, or other IO - * - * Stop motors and reset all system states accordingly. - * Does not de-energize motors as in some cases the motors must remain energized - * in order to prevent an axis from crashing. - */ - -void cm_halt_all(void) -{ - cm_halt_motion(); - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); -} - -void cm_halt_motion(void) -{ - mp_halt_runtime(); // stop the runtime. Do this immediately. (Reset is in cm_clear) - canonical_machine_reset(cm); // halt the currently active machine - cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone - cm->motion_state = MOTION_STOP; - cm->hold_state = FEEDHOLD_OFF; -} - -/* - * cm_alarm() - enter ALARM state - * - * An ALARM sets the ALARM machine state, starts a feedhold to stop motion, stops the - * spindle, turns off coolant, clears out queued planner moves and serial input, - * and rejects new action commands (gcode blocks, SET commands, and other actions) - * until the alarm is cleared. - * - * ALARM is typically entered by a soft limit or a limit switch being hit. In the - * limit switch case the INPUT_ACTION will override the feedhold - i.e. if the - * input action is "FAST_STOP" or "HALT" that setting will take precedence over - * the feedhold native to the alarm function. - * - * Gcode and machine state is preserved. It may be possible to recover the job from - * an alarm, but in many cases this is not possible. Since ALARM attempts to preserve - * Gcode and machine state it does not END the job. - * - * ALARM may also be invoked from the command line using {alarm:n} or $alarm - * ALARM can be manually cleared by entering: {clear:n}, {clr:n}, $clear, or $clr - * ALARMs will also clear on receipt of an M30 or M2 command if one is received - * while draining the host command queue. - */ - -stat_t cm_alarm(const stat_t status, const char *msg) -{ - if ((cm->machine_state == MACHINE_ALARM) || (cm->machine_state == MACHINE_SHUTDOWN) || - (cm->machine_state == MACHINE_PANIC)) { - return (STAT_OK); // don't alarm if already in an alarm state - } - cm->machine_state = MACHINE_ALARM; - cm_request_feedhold(); // stop motion - cm_request_queue_flush(); // do a queue flush once runtime is not busy - -// TBD - these functions should probably be called - See cm_shutdown() -// cm_spindle_control_immediate(SPINDLE_OFF); -// cm_coolant_off_immediate(); -// cm_spindle_optional_pause(spindle.pause_on_hold); -// cm_coolant_optional_pause(coolant.pause_on_hold); - rpt_exception(status, msg); // send alarm message - - // If "stat" is in the status report, we need to poke it to send. - sr_request_status_report(SR_REQUEST_TIMED); - return (status); -} -/* - * cm_shutdown() - enter shutdown state - * - * SHUTDOWN stops all motion, spindle and coolant immediately, sets a SHUTDOWN machine - * state, clears out queued moves and serial input, and rejects new action commands - * (gcode blocks, SET commands, and some others). - * - * Shutdown is typically invoked as an electrical input signal sent to the board as - * part of an external emergency stop (Estop). Shutdown is meant to augment but not - * replace the external Estop functions that shut down power to motors, spindles and - * other moving parts. - * - * Shutdown may also be invoked from the command line using {shutd:n} or $shutd - * Shutdown must be manually cleared by entering: {clear:n}, {clr:n}, $clear, or $clr - * Shutdown does not clear on M30 or M2 Gcode commands - */ - -stat_t cm_shutdown(const stat_t status, const char *msg) -{ - if ((cm->machine_state == MACHINE_SHUTDOWN) || (cm->machine_state == MACHINE_PANIC)) { - return (STAT_OK); // don't shutdown if shutdown or panic'd - } - cm_halt_motion(); // halt motors (may have already been done from GPIO) - spindle_reset(); // stop spindle immediately and set speed to 0 RPM - coolant_reset(); // stop coolant immediately - temperature_reset(); // turn off heaters and fans - cm_queue_flush(); // flush all queues and reset positions - - for (uint8_t i = 0; i < HOMING_AXES; i++) { // unhome axes and the machine - cm->homed[i] = false; - } - cm->homing_state = HOMING_NOT_HOMED; - - cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity - rpt_exception(status, msg); // send exception report - return (status); -} - -/* - * cm_panic() - enter panic state - * - * PANIC occurs if the firmware has detected an unrecoverable internal error - * such as an assertion failure or a code condition that should never occur. - * It sets PANIC machine state, and leaves the system inspect able (if possible). - * - * PANIC can only be exited by a hardware reset or soft reset (^x) - */ - -stat_t cm_panic(const stat_t status, const char *msg) -{ - _debug_trap(msg); - - if (cm->machine_state == MACHINE_PANIC) { // only do this once - return (STAT_OK); - } - cm_halt_motion(); // halt motors (may have already been done from GPIO) - spindle_reset(); // stop spindle immediately and set speed to 0 RPM - coolant_reset(); // stop coolant immediately - temperature_reset(); // turn off heaters and fans - cm_queue_flush(); // flush all queues and reset positions - - cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable - rpt_exception(status, msg); // send panic report - return (status); -} - -/************************** - * Representation (4.3.3) * - **************************/ - -/************************************************************************** +/************************************************************************************ * Representation functions that affect the Gcode model only (asynchronous) * * cm_select_plane() - G17,G18,G19 select axis plane @@ -1092,12 +879,11 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, /****************************************************************************************** * Representation functions that affect gcode model and are queued to planner (synchronous) - */ -/* + * * cm_set_tl_offset() - G43 * cm_cancel_tl_offset() - G49 * cm_set_coord_system() - G54-G59 - * _exec_offset() - callback from planner + * _exec_offset() - callback from planner */ stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool apply_additional) @@ -1293,9 +1079,9 @@ stat_t cm_resume_origin_offsets() return (STAT_OK); } -/***************************** - * Free Space Motion (4.3.4) * - *****************************/ +/*********************************************************************************** + **** Free Space Motion (4.3.4) **************************************************** + ***********************************************************************************/ /* * cm_straight_traverse() - G0 linear rapid */ @@ -1323,7 +1109,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) return (status); } -/* +/*********************************************************************************** * cm_set_g28_position() - G28.1 * cm_goto_g28_position() - G28 * cm_set_g30_position() - G30.1 @@ -1384,9 +1170,9 @@ stat_t cm_goto_g30_position(const float target[], const bool flags[]) return (_goto_stored_position(cm->gmx.g30_position, target, flags)); } -/******************************** - * Machining Attributes (4.3.5) * - ********************************/ +/*********************************************************************************** + **** Machining Attributes (4.3.5) ************************************************* + ***********************************************************************************/ /* * cm_set_feed_rate() - F parameter (affects MODEL only) * @@ -1406,7 +1192,7 @@ stat_t cm_set_feed_rate(const float feed_rate) return (STAT_OK); } -/* +/*********************************************************************************** * cm_set_feed_rate_mode() - G93, G94 (affects MODEL only) * * INVERSE_TIME_MODE = 0, // G93 @@ -1420,7 +1206,7 @@ stat_t cm_set_feed_rate_mode(const uint8_t mode) return (STAT_OK); } -/* +/*********************************************************************************** * cm_set_path_control() - G61, G61.1, G64 */ @@ -1430,15 +1216,14 @@ stat_t cm_set_path_control(GCodeState_t *gcode_state, const uint8_t mode) return (STAT_OK); } - -/******************************* - * Machining Functions (4.3.6) * - *******************************/ +/*********************************************************************************** + **** Machining Functions (4.3.6) ************************************************** + ***********************************************************************************/ /* * cm_arc_feed() - SEE plan_arc.cpp */ -/* +/*********************************************************************************** * cm_dwell() - G4, P parameter (seconds) */ stat_t cm_dwell(const float seconds) @@ -1448,7 +1233,7 @@ stat_t cm_dwell(const float seconds) return (STAT_OK); } -/* +/*********************************************************************************** * cm_straight_feed() - G1 */ stat_t cm_straight_feed(const float target[], const bool flags[]) @@ -1480,14 +1265,14 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) return (status); } -/***************************** - * Spindle Functions (4.3.7) * - *****************************/ +/*********************************************************************************** + **** Spindle Functions (4.3.7) **************************************************** + ***********************************************************************************/ // see spindle.cpp/.h -/************************** - * Tool Functions (4.3.8) * - **************************/ +/*********************************************************************************** + **** Tool Functions (4.3.8) ******************************************************* + ***********************************************************************************/ /* * cm_select_tool() - T parameter * _exec_select_tool() - execution callback @@ -1527,12 +1312,12 @@ static void _exec_change_tool(float *value, bool *flag) cm->gm.tool = (uint8_t)value[0]; } -/*********************************** - * Miscellaneous Functions (4.3.9) * - ***********************************/ +/*********************************************************************************** + **** Miscellaneous Functions (4.3.9) ********************************************** + ***********************************************************************************/ // see coolant.cpp/.h -/* +/*********************************************************************************** * cm_message() - queue a RAM string as a message in the response (unconditionally) */ @@ -1541,7 +1326,11 @@ void cm_message(const char *message) nv_add_string((const char *)"msg", message); // add message to the response object } -/* +/*********************************************************************************** + **** Overrides ******************************************************************** + ***********************************************************************************/ + +/*********************************************************************************** * cm_reset_overrides() - reset manual feedrate and spindle overrides to initial conditions */ @@ -1560,7 +1349,7 @@ static void _exec_feed_override(const bool m48_enable, const bool m50_enable, co } */ -/* +/*********************************************************************************** * cm_m48_enable() - M48, M49 * * M48 is the master enable for manual feedrate override and spindle override @@ -1590,8 +1379,9 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 return (STAT_OK); } -/* +/*********************************************************************************** * cm_mfo_control() - M50 manual feed rate override comtrol + * cm_mto_control() - M50.1 manual traverse override comtrol * * M50 enables manual feedrate override and the optional P override parameter. * P is expressed as M% to N% of programmed feedrate, typically a value from 0.05 to 2.000. @@ -1688,351 +1478,10 @@ stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 cm->gmx.mto_enable = new_enable; // always update the enable state return (STAT_OK); } -/************************************************ - * Feedhold and Related Functions (no NIST ref) * - ************************************************/ -/* - * Feedholds, queue flushes and end_holds are all related. The request functions set flags - * or change state to "REQUESTED". The sequencing callback interprets the flags as so: - * - A feedhold request received during motion should be honored - * - A feedhold request received during a feedhold should be ignored - * - A feedhold request received during a motion stop should be ignored - * - * - A queue flush request should only be honored while in a feedhold - * - Said queue flush request received during a feedhold should be deferred until - * the feedhold enters a HOLD state (i.e. until deceleration is complete and motors stop). - * - A queue flush request received during a motion stop should be honored - * - * - An end_hold (cycle start) request should only be honored while in a feedhold - * - Said end_hold request received during a feedhold should be deferred until the - * feedhold enters a HOLD state (i.e. until deceleration is complete). - * If a queue flush request is also present the queue flush should be done first - * - * Below the request level, feedholds work like this: - * - The hold is initiated by calling cm_start_hold(). cm->hold_state is set to - * FEEDHOLD_SYNC, motion_state is set to MOTION_HOLD, and the spindle is turned off - * (if it it on). The remainder of feedhold - * processing occurs in plan_exec.c in the mp_exec_aline() function. - * - * - MOTION_HOLD and FEEDHOLD_SYNC tells mp_exec_aline() to begin feedhold processing - * after the current move segment is finished (< 5 ms later). (Cases handled by - * feedhold processing are listed in plan_exec.c). - * - * - FEEDHOLD_SYNC causes the current move in mr to be replanned into a deceleration. - * If the distance remaining in the executing move is sufficient for a full deceleration - * then motion will stop in the current block. Otherwise the deceleration phase - * will extend across as many blocks necessary until one will stop. - * - * - Once deceleration is complete hold state transitions to FEEDHOLD_FINALIZING and - * the distance remaining in the bf last block is replanned up from zero velocity. - * The move in the bf block is NOT released (unlike normal operation), as it will - * be used again to restart from hold. - * - * - When cm_end_hold() is called it releases the hold, restarts the move and restarts - * the spindle if the spindle is active. - */ -/* Queue Flush operation - * - * This one's complicated. See here first: - * https://github.com/synthetos/g2/wiki/Alarm-Processing - * https://github.com/synthetos/g2/wiki/Job-Exception-Handling - * - * We want to use queue flush for a few different use cases, as per the above wiki pages. - * The % behavior implements Exception Handling cases 1 and 2 - Stop a Single Move and - * Stop Multiple Moves. This is complicated further by the processing in single USB and - * dual USB being different. Also, the state handling is located in xio.cpp / readline(), - * controller.cpp _dispatch_kernel() and cm_request_queue_flush(), below. - * So it's documented here. - * - * Single or Dual USB Channels: - * - If a % is received outside of a feed hold or ALARM state, ignore it. - * Change the % to a ; comment symbol (xio) - * - * Single USB Channel Operation: - * - Enter a feedhold (!) - * - Receive a queue flush (%) Both dispatch it and store a marker (ACK) in the input - * buffer in place of the the % (xio) - * - Execute the feedhold to a hold condition (plan_exec) - * - Execute the dispatched % to flush queues (canonical_machine) - * - Silently reject any commands up to the % in the input queue (controller) - * - When ETX is encountered transition to STOP state (controller/canonical_machine) - * - * Dual USB Channel Operation: - * - Same as above except that we expect the % to arrive on the control channel - * - The system will read and dump all commands in the data channel until either a - * clear is encountered ({clear:n} or $clear), or an ETX is encountered on either - * channel, but it really should be on the data channel to ensure all queued commands - * are dumped. It is the host's responsibility to both write the clear (or ETX), and - * to ensure that it either arrives on the data channel or that the data channel is - * empty before writing it to the control channel. - */ -/* With the addition of the secondary CM, feedhold state management gets tricky. - What you see below is a temporary solution until we decide the general solution. - - The general solution causes a feedhold from the primary context to switch - into the secondary context to perform feedhold actions. When in the secondary - context an additional feedhold will perform the usual STOP operation, but - will remain in the secondary context, and therefore not perform any feedhold - actions (lifts, spindle, etc.). This is needed to support homing and probing - operations from within the secondary context. - - Oddities of the general solution: - - Should we allow a feedhold to be performed if the tool is not moving? - Right now we don't, but with the secondary context this might be useful - - What you see here is a Q&D to only allow feedholds from the primary context. - It has the following limitations: - - Feedhold requests are only honored form the primary context - - Queue flush requests are only honored form the primary context - - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart - */ -/* - * cm_request_feedhold() - * cm_request_end_hold() - * cm_request_queue_flush() - * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests - */ - -void cm_request_feedhold(void) -{ - // do not generate a feedhold request from the secondary context - if (cm_select != CM_PRIMARY) { - return; - } - // only generate request if not already in a feedhold and the machine is in motion -// if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - - // only generate request if not already in a feedhold - // It's OK if the machine is stopped - this just enters the feedhold context - if (cm1.hold_state == FEEDHOLD_OFF) { - cm1.hold_state = FEEDHOLD_REQUESTED; - } -} - -void cm_request_end_hold(void) // This is usually requested form the secondary context -{ - if (cm1.hold_state != FEEDHOLD_OFF) { - cm1.end_hold_requested = true; - } -} - -void cm_request_queue_flush() -{ - // do not generate a queue flush request from the secondary context - if (cm_select != CM_PRIMARY) { - return; - } - if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once - cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped - - // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now - } -} - -stat_t cm_feedhold_sequencing_callback() -{ - if (cm1.hold_state == FEEDHOLD_REQUESTED) { - cm_start_hold(); // feed won't run unless the machine is moving - } - if (cm1.hold_state == FEEDHOLD_FINALIZING) { - cm1.hold_state = FEEDHOLD_HOLD; - cm_switch_to_hold_context(); // perform Z lift, spindle & coolant operations - } - if (cm1.queue_flush_state == FLUSH_REQUESTED) { - cm_queue_flush(); // queue flush won't run until runtime is idle - } - if (cm1.end_hold_requested) { - if (cm1.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing - cm_end_hold(); - } - } - return (STAT_OK); -} - -/* - * cm_has_hold() - return true if a hold condition exists (or a pending hold request) - * cm_start_hold() - start a feedhhold by signalling the exec - * cm_end_hold() - end a feedhold by returning the system to normal operation - */ -bool cm_has_hold() -{ - return (cm1.hold_state != FEEDHOLD_OFF); -} - -void cm_start_hold() -{ - if (mp_has_runnable_buffer(mp)) { //+++++ // meaning there's something running - cm_set_motion_state(MOTION_HOLD); - cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} - -void cm_end_hold() -{ - if (cm1.hold_state == FEEDHOLD_HOLD) { - cm1.end_hold_requested = false; - cm_return_from_hold_context(); - } -} - -/* - * cm_switch_to_hold_context() - switch to secondary machine context - * - * Moving between contexts is only safe when the machine is completely stopped - * either during a feedhold or when idle. - */ - -stat_t cm_switch_to_hold_context() -{ - // Must be in the primary CM and fully stopped in a hold - if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { - return (STAT_COMMAND_NOT_ACCEPTED); - } - - // copy the primary canonical machine to the secondary, - // fix the planner pointer, and reset the secondary planner - memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // set parameters in cm, gm and gmx so you can actually use it - cmMachine_t *_cm = &cm2; - _cm->hold_state = FEEDHOLD_OFF; - _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - _cm->gm.feed_rate = 0; - - // clear the target and set the positions to the current hold position - memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); - copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation - copy_vector(_cm->gmx.position, mr->position); - copy_vector(mp2.position, mr->position); - copy_vector(mr2.position, mr->position); - - // reassign the globals to the secondary CM - cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // mp is a void pointer - mr = mp->mr; - cm_select = CM_SECONDARY; - - // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 - cm_set_g30_position(); - cm_set_motion_state(MOTION_STOP); - - // optional Z lift - if (fp_NOT_ZERO(cm->feedhold_z_lift)) { - float stored_distance_mode = cm_get_distance_mode(MODEL); - cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); - bool flags[] = { 0,0,1,0,0,0 }; - float target[] = { 0,0, cm->feedhold_z_lift, 0,0,0 }; - cm_straight_traverse(target, flags); - cm_set_distance_mode(stored_distance_mode); - } - - // optional spindle stop - if (spindle.pause_on_hold) { - - } - return (STAT_OK); -} - -/* - * cm_return_from_hold_context() - initiate return from secondary context - * cm_return_from_hold_callback() - main loop callback to finsh return once moves are done - * _planner_done_callback() - callback to sync to end of planner operations - * - * Moving between contexts is only safe when the machine is completely stopped - * either during a feedhold or when idle. - */ - -// Callback to run at when the G30 return move is finished -static void _planner_done_callback(float* vect, bool* flag) -{ - cm2.waiting_for_planner_done = false; -} - -stat_t cm_return_from_hold_context() // LATER: if value == true return with offset corrections -{ - // Must be in the secondary CM and fully stopped - if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { - return (STAT_COMMAND_NOT_ACCEPTED); - } - - // *** While still in secondary machine: -/* - if (cm->machine_state == MACHINE_ALARM) { - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); -*/ - // restart spindle (with optional dwell) - - // restart coolant - - // perform the G30 move and queue a wait - float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z - bool flags[] = { 0,0,0,0,0,0 }; - cm_goto_g30_position(target, flags); // initiate a return move - cm->waiting_for_planner_done = true; // indicates running the final G30 move in the secondary - mp_queue_command(_planner_done_callback, nullptr, nullptr); - cm_select = CM_SECONDARY_RETURN; - return (STAT_OK); - - // return_to_primary completes in cm_return_callback() after the wait -} - -stat_t cm_return_from_hold_callback() -{ - if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner - return (STAT_NOOP); - } - if (cm->waiting_for_planner_done) { // sync to planner move ends (via _return_move_callback) - return (STAT_EAGAIN); - } - - // return to primary machine - cm = &cm1; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; - cm_select = CM_PRIMARY; - - cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? - cm_set_motion_state(MOTION_RUN); - cm_cycle_start(); - st_request_exec_move(); - sr_request_status_report(SR_REQUEST_IMMEDIATE); - } else { - cm_set_motion_state(MOTION_STOP); - cm_cycle_end(); - } - return (STAT_OK); -} - -/* - * cm_queue_flush() - Flush planner queue and correct model positions - */ - -void cm_queue_flush() -{ - if (mp_runtime_is_idle()) { // can't flush planner during movement - mp_flush_planner(mp); // +++++ Active planner. Potential cleanup - - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions - cm_set_position(axis, mp_get_runtime_absolute_position(axis)); - } - if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one - cm_end_hold(); - } - cm->queue_flush_state = FLUSH_OFF; - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available - } -} - -/****************************** - * Program Functions (4.3.10) * - ******************************/ +/*********************************************************************************** + **** Program Functions (4.3.10) *************************************************** + ***********************************************************************************/ /* This group implements stop, start, and end functions. * It is extended beyond the NIST spec to handle various situations. * @@ -2163,7 +1612,9 @@ void cm_program_end() mp_queue_command(_exec_program_finalize, value, flags); } - +/*********************************************************************************** + **** Additional Fucntions ********************************************************* + ***********************************************************************************/ /* * cm_json_command() - M100 */ @@ -2186,7 +1637,8 @@ stat_t cm_json_wait(char *json_string) **************************************/ /*********************************************************************************** - * CONFIGURATION AND INTERFACE FUNCTIONS + **** CONFIGURATION AND INTERFACE FUNCTIONS **************************************** + *********************************************************************************** * Functions to get and set variables from the cfgArray table * These functions are not part of the NIST defined functions ***********************************************************************************/ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 90abd505..821bb900 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -289,9 +289,10 @@ typedef struct cmToolTable { // struct to keep a global tool tabl /**** Externs - See canonical_machine.cpp for allocation ****/ -extern cmMachine_t *cm; // pointer to active canonical machine -extern cmMachine_t cm1; // canonical machine primary machine -extern cmMachine_t cm2; // canonical machine secondary machine +extern cmMachineSelect cm_select; // CM_PRIMARY, CM_SECONDARY, CM_SECONDARY_RETURN +extern cmMachine_t *cm; // pointer to active canonical machine +extern cmMachine_t cm1; // canonical machine primary machine +extern cmMachine_t cm2; // canonical machine secondary machine extern cmToolTable_t tt; /***************************************************************************** @@ -433,7 +434,20 @@ stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50 stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1 // See spindle.cpp for cm_sso_control() // M51 -// Feedhold and related functions +// Program Functions (4.3.10) +void cm_cycle_start(void); // (no Gcode) +void cm_cycle_end(void); // (no Gcode) +void cm_canned_cycle_end(void); // end of canned cycle +void cm_program_stop(void); // M0 +void cm_optional_program_stop(void); // M1 +void cm_program_end(void); // M2 + +stat_t cm_json_command(char *json_string); // M100 +stat_t cm_json_wait(char *json_string); // M102 + +/*--- Cycles ---*/ + +// Feedhold and related functions (cycle_feedhold.cpp) void cm_request_feedhold(void); void cm_request_end_hold(void); void cm_request_queue_flush(void); @@ -450,32 +464,19 @@ stat_t cm_return_from_hold_callback(void); // main loop cal void cm_queue_flush(void); // flush serial and planner queues with coordinate resets void cm_end_queue_flush(void); -// Program Functions (4.3.10) -void cm_cycle_start(void); // (no Gcode) -void cm_cycle_end(void); // (no Gcode) -void cm_canned_cycle_end(void); // end of canned cycle -void cm_program_stop(void); // M0 -void cm_optional_program_stop(void); // M1 -void cm_program_end(void); // M2 - -stat_t cm_json_command(char *json_string); // M100 -stat_t cm_json_wait(char *json_string); // M102 - -/*--- Cycles ---*/ - -// Homing cycles +// Homing cycles (cycle_homing.cpp) stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2 stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]); // G28.4 stat_t cm_homing_cycle_callback(void); // G28.2/.4 main loop callback -// Probe cycles +// Probe cycles (cycle_probing.cpp) stat_t cm_straight_probe(float target[], bool flags[], bool failure_is_fatal, bool moving_toward_switch); // G38.x stat_t cm_probing_cycle_callback(void); // G38.x main loop callback -// Jogging cycle +// Jogging cycle (cycle_jogging.cpp) stat_t cm_jogging_cycle_callback(void); // jogging cycle main loop stat_t cm_jogging_cycle_start(uint8_t axis); // {"jogx":-100.3} float cm_get_jogging_dest(void); // get jogging destination diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp new file mode 100644 index 00000000..a0a5efa1 --- /dev/null +++ b/g2core/cycle_feedhold.cpp @@ -0,0 +1,377 @@ +/* + * cycle_feedhold.cpp - canonical machine feedhold processing + * This file is part of the g2core project + * + * Copyright (c) 2010 - 2017 Alden S Hart, Jr. + * Copyright (c) 2014 - 2017 Robert Giseburt + * + * This file ("the software") is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 as published by the + * Free Software Foundation. You should have received a copy of the GNU General Public + * License, version 2 along with the software. If not, see . + * + * As a special exception, you may use this file as part of a software library without + * restriction. Specifically, if other files instantiate templates or use macros or + * inline functions from this file, or you compile this file and link it with other + * files to produce an executable, this file does not by itself cause the resulting + * executable to be covered by the GNU General Public License. This exception does not + * however invalidate any other reasons why the executable file might be covered by the + * GNU General Public License. + * + * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "g2core.h" // #1 +#include "config.h" // #2 +#include "gcode.h" // #3 +#include "canonical_machine.h" +#include "planner.h" +#include "stepper.h" +#include "spindle.h" +#include "coolant.h" +#include "util.h" + +/*********************************************************************************** + **** CODE ************************************************************************* + ***********************************************************************************/ +/* + * Feedholds, queue flushes and end_holds are all related. The request functions set flags + * or change state to "REQUESTED". The sequencing callback interprets the flags as so: + * - A feedhold request received during motion should be honored + * - A feedhold request received during a feedhold should be ignored + * - A feedhold request received during a motion stop should be ignored + * + * - A queue flush request should only be honored while in a feedhold + * - Said queue flush request received during a feedhold should be deferred until + * the feedhold enters a HOLD state (i.e. until deceleration is complete and motors stop). + * - A queue flush request received during a motion stop should be honored + * + * - An end_hold (cycle start) request should only be honored while in a feedhold + * - Said end_hold request received during a feedhold should be deferred until the + * feedhold enters a HOLD state (i.e. until deceleration is complete). + * If a queue flush request is also present the queue flush should be done first + * + * Below the request level, feedholds work like this: + * - The hold is initiated by calling cm_start_hold(). cm->hold_state is set to + * FEEDHOLD_SYNC, motion_state is set to MOTION_HOLD, and the spindle is turned off + * (if it it on). The remainder of feedhold + * processing occurs in plan_exec.c in the mp_exec_aline() function. + * + * - MOTION_HOLD and FEEDHOLD_SYNC tells mp_exec_aline() to begin feedhold processing + * after the current move segment is finished (< 5 ms later). (Cases handled by + * feedhold processing are listed in plan_exec.c). + * + * - FEEDHOLD_SYNC causes the current move in mr to be replanned into a deceleration. + * If the distance remaining in the executing move is sufficient for a full deceleration + * then motion will stop in the current block. Otherwise the deceleration phase + * will extend across as many blocks necessary until one will stop. + * + * - Once deceleration is complete hold state transitions to FEEDHOLD_FINALIZING and + * the distance remaining in the bf last block is replanned up from zero velocity. + * The move in the bf block is NOT released (unlike normal operation), as it will + * be used again to restart from hold. + * + * - When cm_end_hold() is called it releases the hold, restarts the move and restarts + * the spindle if the spindle is active. + */ + +/* With the addition of the secondary CM, feedhold state management gets tricky. + What you see below is a temporary solution until we decide the general solution. + + The general solution causes a feedhold from the primary context to switch + into the secondary context to perform feedhold actions. When in the secondary + context an additional feedhold will perform the usual STOP operation, but + will remain in the secondary context, and therefore not perform any feedhold + actions (lifts, spindle, etc.). This is needed to support homing and probing + operations from within the secondary context. + + Oddities of the general solution: + - Should we allow a feedhold to be performed if the tool is not moving? + Right now we don't, but with the secondary context this might be useful + + What you see here is a Q&D to only allow feedholds from the primary context. + It has the following limitations: + - Feedhold requests are only honored form the primary context + - Queue flush requests are only honored form the primary context + - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart + */ + +/* + * cm_request_feedhold() + * cm_request_end_hold() + * cm_request_queue_flush() + * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests + */ + +void cm_request_feedhold(void) +{ + // do not generate a feedhold request from the secondary context + if (cm_select != CM_PRIMARY) { + return; + } + // only generate request if not already in a feedhold and the machine is in motion + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + cm1.hold_state = FEEDHOLD_REQUESTED; + } +} + +void cm_request_end_hold(void) // This is usually requested form the secondary context +{ + if (cm1.hold_state != FEEDHOLD_OFF) { + cm1.end_hold_requested = true; + } +} + +void cm_request_queue_flush() +{ + // do not generate a queue flush request from the secondary context + if (cm_select != CM_PRIMARY) { + return; + } + if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold + (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once + cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + + // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now + } +} + +stat_t cm_feedhold_sequencing_callback() +{ + if (cm1.hold_state == FEEDHOLD_REQUESTED) { + cm_start_hold(); // feed won't run unless the machine is moving + } + if (cm1.hold_state == FEEDHOLD_FINALIZING) { + cm1.hold_state = FEEDHOLD_HOLD; + cm_switch_to_hold_context(); // perform Z lift, spindle & coolant operations + } + if (cm1.queue_flush_state == FLUSH_REQUESTED) { + cm_queue_flush(); // queue flush won't run until runtime is idle + } + if (cm1.end_hold_requested) { + if (cm1.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing + cm_end_hold(); + } + } + return (STAT_OK); +} + +/* + * cm_has_hold() - return true if a hold condition exists (or a pending hold request) + * cm_start_hold() - start a feedhhold by signalling the exec + * cm_end_hold() - end a feedhold by returning the system to normal operation + */ +bool cm_has_hold() +{ + return (cm1.hold_state != FEEDHOLD_OFF); +} + +void cm_start_hold() +{ + if (mp_has_runnable_buffer(mp)) { //+++++ // meaning there's something running + cm_set_motion_state(MOTION_HOLD); + cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } +} + +void cm_end_hold() +{ + if (cm1.hold_state == FEEDHOLD_HOLD) { + cm1.end_hold_requested = false; + cm_return_from_hold_context(); + } +} + +/* + * cm_switch_to_hold_context() - switch to secondary machine context + * + * Moving between contexts is only safe when the machine is completely stopped + * either during a feedhold or when idle. + */ + +stat_t cm_switch_to_hold_context() +{ + // Must be in the primary CM and fully stopped in a hold + if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { + return (STAT_COMMAND_NOT_ACCEPTED); + } + + // copy the primary canonical machine to the secondary, + // fix the planner pointer, and reset the secondary planner + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // set parameters in cm, gm and gmx so you can actually use it + cmMachine_t *_cm = &cm2; + _cm->hold_state = FEEDHOLD_OFF; + _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + _cm->gm.feed_rate = 0; + + // clear the target and set the positions to the current hold position + memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); + copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation + copy_vector(_cm->gmx.position, mr->position); + copy_vector(mp2.position, mr->position); + copy_vector(mr2.position, mr->position); + + // reassign the globals to the secondary CM + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer + mr = mp->mr; + cm_select = CM_SECONDARY; + + // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 + cm_set_g30_position(); + cm_set_motion_state(MOTION_STOP); + + // optional Z lift + if (fp_NOT_ZERO(cm->feedhold_z_lift)) { + float stored_distance_mode = cm_get_distance_mode(MODEL); + cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); + bool flags[] = { 0,0,1,0,0,0 }; + float target[] = { 0,0, cm->feedhold_z_lift, 0,0,0 }; + cm_straight_traverse(target, flags); + cm_set_distance_mode(stored_distance_mode); + } + + // optional spindle stop + if (spindle.pause_on_hold) { + + } + return (STAT_OK); +} + +/* + * cm_return_from_hold_context() - initiate return from secondary context + * cm_return_from_hold_callback() - main loop callback to finsh return once moves are done + * _planner_done_callback() - callback to sync to end of planner operations + * + * Moving between contexts is only safe when the machine is completely stopped + * either during a feedhold or when idle. + */ + +// Callback to run at when the G30 return move is finished +static void _planner_done_callback(float* vect, bool* flag) +{ + cm2.waiting_for_planner_done = false; +} + +stat_t cm_return_from_hold_context() // LATER: if value == true return with offset corrections +{ + // Must be in the secondary CM and fully stopped + if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { + return (STAT_COMMAND_NOT_ACCEPTED); + } + + // *** While still in secondary machine: +/* + if (cm->machine_state == MACHINE_ALARM) { + cm_spindle_off_immediate(); + cm_coolant_off_immediate(); +*/ + // restart spindle (with optional dwell) + + // restart coolant + + // perform the G30 move and queue a wait + float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z + bool flags[] = { 0,0,0,0,0,0 }; + cm_goto_g30_position(target, flags); // initiate a return move + cm->waiting_for_planner_done = true; // indicates running the final G30 move in the secondary + mp_queue_command(_planner_done_callback, nullptr, nullptr); + cm_select = CM_SECONDARY_RETURN; + return (STAT_OK); + + // return_to_primary completes in cm_return_callback() after the wait +} + +stat_t cm_return_from_hold_callback() +{ + if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner + return (STAT_NOOP); + } + if (cm->waiting_for_planner_done) { // sync to planner move ends (via _return_move_callback) + return (STAT_EAGAIN); + } + + // return to primary machine + cm = &cm1; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + cm_select = CM_PRIMARY; + + cm->hold_state = FEEDHOLD_OFF; + if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? + cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); + sr_request_status_report(SR_REQUEST_IMMEDIATE); + } else { + cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); + } + return (STAT_OK); +} + +/* Queue Flush operation + * + * This one's complicated. See here first: + * https://github.com/synthetos/g2/wiki/Alarm-Processing + * https://github.com/synthetos/g2/wiki/Job-Exception-Handling + * + * We want to use queue flush for a few different use cases, as per the above wiki pages. + * The % behavior implements Exception Handling cases 1 and 2 - Stop a Single Move and + * Stop Multiple Moves. This is complicated further by the processing in single USB and + * dual USB being different. Also, the state handling is located in xio.cpp / readline(), + * controller.cpp _dispatch_kernel() and cm_request_queue_flush(), below. + * So it's documented here. + * + * Single or Dual USB Channels: + * - If a % is received outside of a feed hold or ALARM state, ignore it. + * Change the % to a ; comment symbol (xio) + * + * Single USB Channel Operation: + * - Enter a feedhold (!) + * - Receive a queue flush (%) Both dispatch it and store a marker (ACK) in the input + * buffer in place of the the % (xio) + * - Execute the feedhold to a hold condition (plan_exec) + * - Execute the dispatched % to flush queues (canonical_machine) + * - Silently reject any commands up to the % in the input queue (controller) + * - When ETX is encountered transition to STOP state (controller/canonical_machine) + * + * Dual USB Channel Operation: + * - Same as above except that we expect the % to arrive on the control channel + * - The system will read and dump all commands in the data channel until either a + * clear is encountered ({clear:n} or $clear), or an ETX is encountered on either + * channel, but it really should be on the data channel to ensure all queued commands + * are dumped. It is the host's responsibility to both write the clear (or ETX), and + * to ensure that it either arrives on the data channel or that the data channel is + * empty before writing it to the control channel. + */ +/* + * cm_queue_flush() - Flush planner queue and correct model positions + */ + +void cm_queue_flush() +{ + if (mp_runtime_is_idle()) { // can't flush planner during movement + mp_flush_planner(mp); // +++++ Active planner. Potential cleanup + + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions + cm_set_position(axis, mp_get_runtime_absolute_position(axis)); + } + if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one + cm_end_hold(); + } + cm->queue_flush_state = FLUSH_OFF; + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available + } +} + diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index c8cc86a8..af27d1e0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -1521,6 +1521,9 @@ bin\TestQuadratic\ + + compile + compile @@ -1692,6 +1695,9 @@ compile + + compile + compile From c456b5ce88984b72a3f3c5f8f2378c4d5035233a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 14:36:48 -0500 Subject: [PATCH 072/283] Added spindle speed min/max values; added spindle mode; Separated spindle into its own group (SP); Made spindle standalone from canonical machine --- g2core/alarm.cpp | 2 +- g2core/canonical_machine.cpp | 3 +- g2core/config_app.cpp | 36 ++-- g2core/cycle_feedhold.cpp | 33 ++-- g2core/cycle_probing.cpp | 4 +- g2core/gcode_parser.cpp | 6 +- g2core/gpio.h | 18 ++ g2core/settings/settings_default.h | 16 ++ g2core/spindle.cpp | 256 +++++++++++++++++------------ g2core/spindle.h | 158 ++++++++++++------ 10 files changed, 339 insertions(+), 193 deletions(-) mode change 100755 => 100644 g2core/gpio.h diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 7a962f5d..9516d98e 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -123,7 +123,7 @@ stat_t cm_is_alarmed() void cm_halt_all(void) { cm_halt_motion(); - cm_spindle_off_immediate(); + spindle_off_immediate(); cm_coolant_off_immediate(); } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 4117289c..fbbe3c84 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1555,7 +1555,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_select_plane(cm->default_select_plane); // reset to default arc plane cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default - cm_spindle_off_immediate(); // M5 + spindle_off_immediate(); // M5 cm_coolant_off_immediate(); // M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. @@ -2262,7 +2262,6 @@ stat_t cm_run_jog(nvObj_t *nv) return (STAT_OK); } - /*********************************************************************************** * Debugging Commands ***********************************************************************************/ diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index b547ab02..18d75cc8 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -852,16 +852,29 @@ const cfgItem_t cfgArray[] = { { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors // Spindle functions - { "sys","spep",_fipn,0, cm_print_spep,get_ui8, set_01, (float *)&spindle.enable_polarity, SPINDLE_ENABLE_POLARITY }, - { "sys","spdp",_fipn,0, cm_print_spdp,get_ui8, set_01, (float *)&spindle.dir_polarity, SPINDLE_DIR_POLARITY }, - { "sys","spph",_fipn,0, cm_print_spph,get_ui8, set_01, (float *)&spindle.pause_on_hold, SPINDLE_PAUSE_ON_HOLD }, - { "sys","spdw",_fipn,2, cm_print_spdw,get_flt, set_flt, (float *)&spindle.dwell_seconds, SPINDLE_DWELL_TIME }, - { "sys","ssoe",_fipn,0, cm_print_ssoe,get_ui8, set_01, (float *)&spindle.sso_enable, SPINDLE_OVERRIDE_ENABLE}, - { "sys","sso", _fipn,3, cm_print_sso, get_flt,cm_set_sso,(float *)&spindle.sso_factor, SPINDLE_OVERRIDE_FACTOR}, - { "", "spe", _fiz, 0, cm_print_spe, get_ui8, set_nul, (float *)&spindle.enable, 0 }, // get spindle enable - { "", "spd", _fiz, 0, cm_print_spd, get_ui8,cm_set_dir,(float *)&spindle.direction, 0 }, // get spindle direction - { "", "sps", _fiz, 0, cm_print_sps, get_flt, set_nul, (float *)&spindle.speed, 0 }, // get spindle speed - + { "sp","spmo",_fipn, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, + { "sp","spep",_fipn, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, + { "sp","spdp",_fipn, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, + { "sp","spph",_fipn, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, + { "sp","spdw",_fipn, 2, sp_print_spdw, sp_get_spdw, sp_set_spdw, (float *)&cs.null, SPINDLE_DWELL_TIME }, + { "sp","spsn",_fipn, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, + { "sp","spsm",_fipn, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, + { "sp","ssoe",_fipn, 0, sp_print_ssoe, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, + { "sp","sso", _fipn, 3, sp_print_sso, sp_get_sso, sp_set_sso, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, + { "", "sps", _fiz, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // get spindle speed + { "", "spe", _fiz, 0, sp_print_spe, sp_get_spe, set_nul, (float *)&cs.null, 0 }, // get spindle enable state + { "", "spd", _fiz, 0, sp_print_spd, sp_get_spd, sp_set_spd, (float *)&cs.null, 0 }, // get spindle direction +/* + { "sys","spep",_fipn,0, sp_print_spep, get_ui8, set_01, (float *)&spindle.enable_polarity, SPINDLE_ENABLE_POLARITY }, + { "sys","spdp",_fipn,0, sp_print_spdp, get_ui8, set_01, (float *)&spindle.dir_polarity, SPINDLE_DIR_POLARITY }, + { "sys","spph",_fipn,0, sp_print_spph, get_ui8, set_01, (float *)&spindle.pause_on_hold, SPINDLE_PAUSE_ON_HOLD }, + { "sys","spdw",_fipn,2, sp_print_spdw, get_flt, set_flt, (float *)&spindle.dwell_seconds, SPINDLE_DWELL_TIME }, + { "sys","ssoe",_fipn,0, sp_print_ssoe, get_ui8, set_01, (float *)&spindle.sso_enable, SPINDLE_OVERRIDE_ENABLE}, + { "sys","sso", _fipn,3, sp_print_sso, sp_get_sso, sp_set_sso,(float *)&spindle.sso_factor, SPINDLE_OVERRIDE_FACTOR}, + { "", "spe", _fiz, 0, sp_print_spe, get_ui8, set_nul, (float *)&spindle.state, 0 }, // get spindle enable state + { "", "spd", _fiz, 0, sp_print_spd, get_ui8,sp_set_dir,(float *)&spindle.direction, 0 }, // get spindle direction + { "", "sps", _fiz, 0, sp_print_sps, get_flt, set_nul, (float *)&spindle.speed, 0 }, // get spindle speed +*/ // Coolant functions { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, @@ -1059,9 +1072,10 @@ const cfgItem_t cfgArray[] = { // - Optional DIAGNOSTIC_PARAMETERS // - Uber groups (count these separately) -#define FIXED_GROUPS 2 +#define FIXED_GROUPS 3 { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // system group { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PWM 1 group + { "","sp", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // Spindle group #define AXIS_GROUPS AXES { "","x", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis groups diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index a0a5efa1..9fd22510 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -37,11 +37,20 @@ #include "util.h" /*********************************************************************************** - **** CODE ************************************************************************* + **** Feedholds ******************************************************************** ***********************************************************************************/ /* - * Feedholds, queue flushes and end_holds are all related. The request functions set flags - * or change state to "REQUESTED". The sequencing callback interprets the flags as so: + * Feedholds, queue flushes and end_holds are all related and are in this file. + * Feedholds are implemented as a state machine (cmFeedholdState) that runs in the + * planner (plan_exec.cpp, see Feedhold Processing around line 500) and in this file. + * + * Feedholds also use the dual planner (secondary context, or hold context) where a + * new canonical machine and planner are spun up and entered when a feedhold is initiated. + * This allows (almost) all of the machine operations to be accessible during a feedhold. + * + * Feedholds are initiated and ended by a series of request flags (requests). + * The request functions set flags or change state to "REQUESTED". + * The sequencing callback interprets the flags as so: * - A feedhold request received during motion should be honored * - A feedhold request received during a feedhold should be ignored * - A feedhold request received during a motion stop should be ignored @@ -55,8 +64,8 @@ * - Said end_hold request received during a feedhold should be deferred until the * feedhold enters a HOLD state (i.e. until deceleration is complete). * If a queue flush request is also present the queue flush should be done first - * - * Below the request level, feedholds work like this: + */ +/* Below the request level, feedholds work like this: * - The hold is initiated by calling cm_start_hold(). cm->hold_state is set to * FEEDHOLD_SYNC, motion_state is set to MOTION_HOLD, and the spindle is turned off * (if it it on). The remainder of feedhold @@ -101,7 +110,7 @@ - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart */ -/* +/*********************************************************************************** * cm_request_feedhold() * cm_request_end_hold() * cm_request_queue_flush() @@ -161,7 +170,7 @@ stat_t cm_feedhold_sequencing_callback() return (STAT_OK); } -/* +/*********************************************************************************** * cm_has_hold() - return true if a hold condition exists (or a pending hold request) * cm_start_hold() - start a feedhhold by signalling the exec * cm_end_hold() - end a feedhold by returning the system to normal operation @@ -187,7 +196,7 @@ void cm_end_hold() } } -/* +/*********************************************************************************** * cm_switch_to_hold_context() - switch to secondary machine context * * Moving between contexts is only safe when the machine is completely stopped @@ -248,7 +257,7 @@ stat_t cm_switch_to_hold_context() return (STAT_OK); } -/* +/*********************************************************************************** * cm_return_from_hold_context() - initiate return from secondary context * cm_return_from_hold_callback() - main loop callback to finsh return once moves are done * _planner_done_callback() - callback to sync to end of planner operations @@ -320,7 +329,8 @@ stat_t cm_return_from_hold_callback() return (STAT_OK); } -/* Queue Flush operation +/*********************************************************************************** + * Queue Flush operations * * This one's complicated. See here first: * https://github.com/synthetos/g2/wiki/Alarm-Processing @@ -355,7 +365,8 @@ stat_t cm_return_from_hold_callback() * to ensure that it either arrives on the data channel or that the data channel is * empty before writing it to the control channel. */ -/* + +/*********************************************************************************** * cm_queue_flush() - Flush planner queue and correct model positions */ diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 425b77a2..ff254fda 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -251,7 +251,7 @@ static uint8_t _probing_init() { gpio_set_probing_mode(pb.probe_input, true); // turn off spindle and start the move - cm_spindle_optional_pause(true); // pause the spindle if it's on + spindle_optional_pause(true); // pause the spindle if it's on return (_set_pb_func(_probing_start)); // start the probe move } @@ -391,7 +391,7 @@ static void _probe_restore_settings() { cm_set_distance_mode(pb.saved_distance_mode); // restart spindle if it was paused - cm_spindle_resume(spindle.dwell_seconds); + spindle_resume(spindle.dwell_seconds); // cancel the feed modes used during probing cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 656068e0..b51f6699 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -733,14 +733,14 @@ static stat_t _execute_gcode_block(char *active_comment) cm_set_model_linenum(gv.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, F_word); // F - EXEC_FUNC(cm_set_spindle_speed, S_word); // S + EXEC_FUNC(spindle_queue_speed, S_word); // S if (gf.sso_control) { // spindle speed override - ritorno(cm_sso_control(gv.P_word, gf.P_word)); + ritorno(spindle_override_control(gv.P_word, gf.P_word)); } EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written EXEC_FUNC(cm_change_tool, tool_change); // M6 - EXEC_FUNC(cm_spindle_control, spindle_control); // spindle CW, CCW, OFF + EXEC_FUNC(spindle_queue_control, spindle_control); // spindle CW, CCW, OFF EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF diff --git a/g2core/gpio.h b/g2core/gpio.h old mode 100755 new mode 100644 index e156caad..9caf5644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -53,6 +53,24 @@ typedef enum { #define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent #define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent +// *** NOTE: The active hi/low values currently agree with spindle and coolant values +// The above will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 +// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types + +/* The above will become: +typedef enum { + IO_ACTIVE_HIGH = 0, // input is active high (aka normally closed) + IO_ACTIVE_LOW = 1 // input is active low (aka normally open) +} ioPolarity; +#define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent +#define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent + +typedef enum { + IO_DISABLED = 0, // IO will not operate + IO_ENABLED // IO will operate +} ioMode; +*/ + typedef enum { // actions are initiated from within the input's ISR INPUT_ACTION_NONE = 0, INPUT_ACTION_STOP, // stop at normal jerk - preserves positional accuracy diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 09f6bd6c..f87a3ee7 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -81,6 +81,10 @@ #define SAFETY_INTERLOCK_ENABLE 1 // {saf: 0=off, 1=on #endif +#ifndef SPINDLE_MODE +#define SPINDLE_MODE 1 // {spmo; 0=diabled, 1=plan to stop, 2=continuous +#endif + #ifndef SPINDLE_ENABLE_POLARITY #define SPINDLE_ENABLE_POLARITY SPINDLE_ACTIVE_HIGH // {spep: 0=active low, 1=active high #endif @@ -97,6 +101,18 @@ #define SPINDLE_DWELL_TIME 1.0 // {spdw: #endif +#ifndef SPINDLE_DWELL_MAX +#define SPINDLE_DWELL_MAX 10000000.0 // maximum allowable dwell time. May be overridden in settings files +#endif + +#ifndef SPINDLE_SPEED_MIN +#define SPINDLE_SPEED_MIN 0.0 // {spsn: +#endif + +#ifndef SPINDLE_SPEED_MAX +#define SPINDLE_SPEED_MAX 1000000.0 // {spsm: +#endif + #ifndef COOLANT_MIST_POLARITY #define COOLANT_MIST_POLARITY 1 // {comp: 0=active low, 1=active high #endif diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index de3ebb8d..0e5dcca6 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -33,6 +33,7 @@ #include "spindle.h" #include "planner.h" #include "hardware.h" +#include "settings.h" #include "pwm.h" #include "util.h" @@ -44,9 +45,9 @@ cmSpindleton_t spindle; static void _exec_spindle_speed(float *value, bool *flag); static void _exec_spindle_control(float *value, bool *flag); -static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction); +static float _get_spindle_pwm (spState state, spDir direction); -/* +/*********************************************************************************** * spindle_init() * spindle_reset() - stop spindle, set speed to zero, and reset values */ @@ -64,20 +65,58 @@ void spindle_reset() float value[AXES] = { 0,0,0,0,0,0 }; // set spindle speed to zero bool flags[] = { 1,0,0,0,0,0 }; _exec_spindle_speed(value, flags); - cm_spindle_off_immediate(); // turn spindle off + spindle_off_immediate(); // turn spindle off } -/* - * cm_set_spindle_speed() - queue the S parameter to the planner buffer +/*********************************************************************************** + * spindle_off_immediate() - turn on/off spindle w/o planning + * spindle_optional_pause() - pause spindle immediately if option is true + * spindle_resume() - restart a paused spindle with an optional dwell + */ + +void spindle_off_immediate() +{ + spindle.state = SPINDLE_OFF; + float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; + bool flags[] = { 1,0,0,0,0,0 }; + _exec_spindle_control(value, flags); +} + +void spindle_optional_pause(bool option) +{ + if (option && spindle.state == SPINDLE_ON) { + spindle_off_immediate(); + spindle.state = SPINDLE_PAUSE; + } +} + +void spindle_resume(float dwell_seconds) +{ + if(spindle.state == SPINDLE_PAUSE) { + spindle.state = SPINDLE_ON; + mp_request_out_of_band_dwell(dwell_seconds); + float value[] = { (float)SPINDLE_ON, (float)spindle.direction, 0,0,0,0 }; + bool flags[] = { 1,0,0,0,0,0 }; + _exec_spindle_control(value, flags); + } +} + +/*********************************************************************************** + * spindle_queue_speed() - queue the S parameter to the planner buffer * _exec_spindle_speed() - spindle speed callback from planner queue */ -stat_t cm_set_spindle_speed(float speed) +stat_t spindle_queue_speed(float speed) { -// if (speed > cfg.max_spindle speed) { return (STAT_MAX_SPINDLE_SPEED_EXCEEDED);} + if (speed < spindle.speed_min) { + return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); + } + if (speed > spindle.speed_max) { + return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); + } float value[AXES] = { speed, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; + bool flags[] = { 1,0,0,0,0,0 }; mp_queue_command(_exec_spindle_speed, value, flags); return (STAT_OK); } @@ -89,81 +128,47 @@ static void _exec_spindle_speed(float *value, bool *flag) } if (flag[1]) { - spindle.direction = (cmSpindleDir)value[1]; + spindle.direction = (spDir)value[1]; } // update spindle speed if we're running - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.enable, spindle.direction)); + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } -/* - * cm_spindle_off_immediate() - turn on/off spindle w/o planning - * cm_spindle_optional_pause() - pause spindle immediately if option is true - * cm_spindle_resume() - restart a paused spindle with an optional dwell - */ - -void cm_spindle_off_immediate() -{ - spindle.enable = SPINDLE_OFF; - float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_control(value, flags); -} - -void cm_spindle_optional_pause(bool option) -{ - if (option && spindle.enable == SPINDLE_ON) { - cm_spindle_off_immediate(); - spindle.enable = SPINDLE_PAUSE; - } -} - -void cm_spindle_resume(float dwell_seconds) -{ - if(spindle.enable == SPINDLE_PAUSE) { - spindle.enable = SPINDLE_ON; - mp_request_out_of_band_dwell(dwell_seconds); - float value[] = { (float)SPINDLE_ON, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_control(value, flags); - } -} - -/* - * cm_spindle_control() - queue the spindle command to the planner buffer. Observe PAUSE +/*********************************************************************************** + * spindle_queue_control() - queue the spindle command to the planner buffer. Observe PAUSE * _exec_spindle_control() - actually execute the spindle command */ -stat_t cm_spindle_control(uint8_t control) // requires SPINDLE_CONTROL_xxx style args +stat_t spindle_queue_control(uint8_t control) // requires SPINDLE_CONTROL_xxx style args { if (control == SPINDLE_CONTROL_OFF) { - spindle.enable = SPINDLE_OFF; + spindle.state = SPINDLE_OFF; } else { - spindle.enable = SPINDLE_ON; + spindle.state = SPINDLE_ON; if (control == SPINDLE_CONTROL_CW) { spindle.direction = SPINDLE_CW; } else { spindle.direction = SPINDLE_CCW; } } - - float value[] = { (float)spindle.enable, (float)spindle.direction, 0,0,0,0 }; + float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; bool flags[] = { 1,1,0,0,0,0 }; mp_queue_command(_exec_spindle_control, value, flags); return(STAT_OK); } - #define _set_spindle_enable_bit_hi() spindle_enable_pin.set() - #define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() - #define _set_spindle_direction_bit_hi() spindle_dir_pin.set() - #define _set_spindle_direction_bit_lo() spindle_dir_pin.clear() +#define _set_spindle_enable_bit_hi() spindle_enable_pin.set() +#define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() +#define _set_spindle_direction_bit_hi() spindle_dir_pin.set() +#define _set_spindle_direction_bit_lo() spindle_dir_pin.clear() static void _exec_spindle_control(float *value, bool *flag) { // set the direction first if (flag[1]) { - spindle.direction = (cmSpindleDir)value[1]; // record spindle direction in the struct + spindle.direction = (spDir)value[1]; // record spindle direction in the struct if (spindle.direction ^ spindle.dir_polarity) { _set_spindle_direction_bit_hi(); } else { @@ -174,22 +179,21 @@ static void _exec_spindle_control(float *value, bool *flag) if (flag[0]) { // set on/off. Mask out PAUSE and consider it OFF - spindle.enable = (cmSpindleEnable)value[0]; // record spindle enable in the struct - if ((spindle.enable & 0x01) ^ spindle.enable_polarity) { + spindle.state = (spState)value[0]; // record spindle state in the struct + if ((spindle.state & 0x01) ^ spindle.enable_polarity) { _set_spindle_enable_bit_lo(); } else { _set_spindle_enable_bit_hi(); } } - - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.enable, spindle.direction)); + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } -/* +/*********************************************************************************** * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ -static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) +static float _get_spindle_pwm (spState state, spDir direction) { float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; if (direction == SPINDLE_CW ) { @@ -204,7 +208,7 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) phase_hi = pwm.c[PWM_1].ccw_phase_hi; } - if (enable == SPINDLE_ON) { + if (state == SPINDLE_ON) { // clamp spindle speed to lo/hi range if (spindle.speed < speed_lo) { spindle.speed = speed_lo; @@ -220,24 +224,23 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction) } } - -/* - * cm_spindle_override_control() - * cm_start_spindle_override() - * cm_end_spindle_override() +/*********************************************************************************** + * spindle_override_control() + * spindle_sp_start_spindle_override() + * sp_end_spindle_override() */ -void cm_start_spindle_override(const float ramp_time, const float override_factor) +void spindle_start_override(const float ramp_time, const float override_factor) { return; } -void cm_end_spindle_override(const float ramp_time) +void spindle_end_override(const float ramp_time) { return; } -stat_t cm_sso_control(const float P_word, const bool P_flag) // M51 +stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 { bool new_enable = true; bool new_override = false; @@ -257,9 +260,9 @@ stat_t cm_sso_control(const float P_word, const bool P_flag) // M51 } if (cm->gmx.m48_enable) { // if master enable is ON if (new_enable && (new_override || !spindle.sso_enable)) { // 3 cases to start a ramp - cm_start_spindle_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.sso_factor); + spindle_start_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.sso_factor); } else if (spindle.sso_enable && !new_enable) { // case to turn off the ramp - cm_end_spindle_override(SPINDLE_OVERRIDE_RAMP_TIME); + spindle_end_override(SPINDLE_OVERRIDE_RAMP_TIME); } } spindle.sso_enable = new_enable; // always update the enable state @@ -275,37 +278,66 @@ stat_t cm_sso_control(const float P_word, const bool P_flag) // M51 * Functions to get and set variables from the cfgArray table ***********************************************************************************/ -/* - * cm_set_dir() - a cheat to set direction w/o using the M commands - * - * This is provided as a way to set and clear spindle direction without using M commands - * It's here because disabling a spindle (M5) does not change the direction, only the enable. +/*********************************************************************************** + **** Spindle Settings + ***********************************************************************************/ + +stat_t sp_get_spmo(nvObj_t *nv) { return(get_int(nv, spindle.mode)); } +stat_t sp_set_spmo(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.mode, SPINDLE_DISABLED, SPINDLE_MODE_MAX)); } + +stat_t sp_get_spep(nvObj_t *nv) { return(get_int(nv, spindle.enable_polarity)); } +stat_t sp_set_spep(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.enable_polarity, 0, 1)); } +stat_t sp_get_spdp(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } +stat_t sp_set_spdp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1)); } +stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } +stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1)); } + +stat_t sp_get_spdw(nvObj_t *nv) { return(get_float(nv, spindle.dwell_seconds)); } +stat_t sp_set_spdw(nvObj_t *nv) { return(set_float_range(nv, spindle.dwell_seconds, 0, SPINDLE_DWELL_MAX)); } +stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } +stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } +stat_t sp_get_spsm(nvObj_t *nv) { return(get_float(nv, spindle.speed_max)); } +stat_t sp_set_spsm(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_max, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } + +stat_t sp_get_ssoe(nvObj_t *nv) { return(get_int(nv, spindle.sso_enable)); } +stat_t sp_set_ssoe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.sso_enable, 0, 1)); } +stat_t sp_get_sso(nvObj_t *nv) { return(get_float(nv, spindle.sso_factor)); } +stat_t sp_set_sso(nvObj_t *nv) { return(set_float_range(nv, spindle.sso_factor, SPINDLE_OVERRIDE_MIN, SPINDLE_OVERRIDE_MAX)); } + +/* These are provided as a way to set and clear spindle states without using M commands + * SPD is useful because disabling a spindle (M5) does not change the direction, only the enable. */ -stat_t cm_set_dir(nvObj_t *nv) +stat_t sp_get_sps(nvObj_t *nv) { return(get_float(nv, spindle.speed)); } +stat_t sp_set_sps(nvObj_t *nv) { - set_01(nv); - float value[] = { (float)spindle.enable, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; - _exec_spindle_control(value, flags); + set_float_range(nv, spindle.speed, spindle.speed_min, spindle.speed_max); + float value[] = { spindle.speed, 0,0,0,0,0 }; + bool flags[] = { 1,0,0,0,0,0 }; + _exec_spindle_speed(value, flags); return (STAT_OK); } - +stat_t sp_get_spe(nvObj_t *nv) { return(get_int(nv, spindle.state)); } /* - * cm_set_sso() - set spindle speed feedrate override factor - */ - -stat_t cm_set_sso(nvObj_t *nv) +stat_t sp_set_spe(nvObj_t *nv) { - if (nv->value < SPINDLE_OVERRIDE_MIN) { - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value > SPINDLE_OVERRIDE_MAX) { - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - set_flt(nv); - return(STAT_OK); +// set_int(nv, (uint8_t &)spindle.state, 0, 1); + float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; + bool flags[] = { 1,1,0,0,0,0 }; + _exec_spindle_control(value, flags); + return (STAT_OK); +} +*/ + +stat_t sp_get_spd(nvObj_t *nv) { return(get_int(nv, spindle.direction)); } +stat_t sp_set_spd(nvObj_t *nv) +{ + set_int(nv, (uint8_t &)spindle.direction, 0, 1); + float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; + bool flags[] = { 1,1,0,0,0,0 }; + _exec_spindle_control(value, flags); + return (STAT_OK); } /*********************************************************************************** @@ -315,24 +347,30 @@ stat_t cm_set_sso(nvObj_t *nv) #ifdef __TEXT_MODE +const char fmt_spmo[] = "[spmo] spindle mode%16d [0=disabled,1=plan-to-stop,2=continuous]\n"; const char fmt_spep[] = "[spep] spindle enable polarity%5d [0=active_low,1=active_high]\n"; const char fmt_spdp[] = "[spdp] spindle direction polarity%2d [0=CW_low,1=CW_high]\n"; const char fmt_spph[] = "[spph] spindle pause on hold%7d [0=no,1=pause_on_hold]\n"; const char fmt_spdw[] = "[spdw] spindle dwell time%12.1f seconds\n"; -const char fmt_ssoe[] ="[ssoe] spindle speed override ena%2d [0=disable,1=enable]\n"; -const char fmt_sso[] ="[sso] spindle speed override%11.3f [0.050 < sso < 2.000]\n"; -const char fmt_spe[] = "Spindle Enable:%7d [0=OFF,1=ON,2=PAUSE]\n"; -const char fmt_spd[] = "Spindle Direction:%4d [0=CW,1=CCW]\n"; -const char fmt_sps[] = "Spindle Speed: %7.0f rpm\n"; +const char fmt_spsn[] = "[spsn] spindle speed min%14.2f rpm\n"; +const char fmt_spsm[] = "[spsm] spindle speed max%14.2f rpm\n"; +const char fmt_ssoe[] = "[ssoe] spindle speed override ena%2d [0=disable,1=enable]\n"; +const char fmt_sso[] = "[sso] spindle speed override%10.3f [0.050 < sso < 2.000]\n"; +const char fmt_sps[] = "Spindle Speed: %7.0f rpm\n"; +const char fmt_spe[] = "Spindle Enable:%7d [0=OFF,1=ON,2=PAUSE]\n"; +const char fmt_spd[] = "Spindle Direction:%4d [0=CW,1=CCW]\n"; -void cm_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT -void cm_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT -void cm_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT -void cm_print_spdw(nvObj_t *nv) { text_print(nv, fmt_spdw);} // TYPE_FLOAT -void cm_print_ssoe(nvObj_t *nv) { text_print(nv, fmt_ssoe);} // TYPE INT -void cm_print_sso(nvObj_t *nv) { text_print(nv, fmt_sso);} // TYPE FLOAT -void cm_print_spe(nvObj_t *nv) { text_print(nv, fmt_spe);} // TYPE_INT -void cm_print_spd(nvObj_t *nv) { text_print(nv, fmt_spd);} // TYPE_INT -void cm_print_sps(nvObj_t *nv) { text_print(nv, fmt_sps);} // TYPE_FLOAT +void sp_print_spmo(nvObj_t *nv) { text_print(nv, fmt_spmo);} // TYPE_INT +void sp_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT +void sp_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT +void sp_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT +void sp_print_spdw(nvObj_t *nv) { text_print(nv, fmt_spdw);} // TYPE_FLOAT +void sp_print_spsn(nvObj_t *nv) { text_print(nv, fmt_spsn);} // TYPE_FLOAT +void sp_print_spsm(nvObj_t *nv) { text_print(nv, fmt_spsm);} // TYPE_FLOAT +void sp_print_ssoe(nvObj_t *nv) { text_print(nv, fmt_ssoe);} // TYPE INT +void sp_print_sso(nvObj_t *nv) { text_print(nv, fmt_sso);} // TYPE FLOAT +void sp_print_spe(nvObj_t *nv) { text_print(nv, fmt_spe);} // TYPE_INT +void sp_print_spd(nvObj_t *nv) { text_print(nv, fmt_spd);} // TYPE_INT +void sp_print_sps(nvObj_t *nv) { text_print(nv, fmt_sps);} // TYPE_FLOAT #endif // __TEXT_MODE diff --git a/g2core/spindle.h b/g2core/spindle.h index 5ed3e877..f2446155 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -32,23 +32,36 @@ typedef enum { // how spindle controls are presented by the Gco SPINDLE_CONTROL_OFF = 0, // M5 SPINDLE_CONTROL_CW, // M3 SPINDLE_CONTROL_CCW // M4 -} cmSpindleControl; - -typedef enum { - SPINDLE_OFF = 0, - SPINDLE_ON, - SPINDLE_PAUSE // meaning it was on and now it's off -} cmSpindleEnable; +} spControl; typedef enum { // spindle direction state SPINDLE_CW = 0, SPINDLE_CCW -} cmSpindleDir; +} spDir; -typedef enum { - SPINDLE_ACTIVE_LOW = 0, - SPINDLE_ACTIVE_HIGH -} cmSpindlePolarity; + +// *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h +// These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 +// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types + +typedef enum { + SPINDLE_DISABLED = 0, // spindle will not operate + SPINDLE_PLAN_TO_STOP, // spindle operating, plans to stop + SPINDLE_CONTINUOUS, // spindle operating, does not plan to stop +} spMode; +#define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS + +typedef enum { // Note: These values agree with + SPINDLE_ACTIVE_LOW = 0, // Will set output to 0 to enable the spindle or CW direction + SPINDLE_ACTIVE_HIGH = 1, // Will set output to 1 to enable the spindle or CW direction +} spPolarity; + +typedef enum { // basic spindle state machine + SPINDLE_OFF = 0, + SPINDLE_ON, // spindle on and at speed + SPINDLE_PAUSE, // meaning it was on and now it's off + SPINDLE_WAITING // spindle not at speed yet +} spState; typedef enum { ESC_ONLINE = 0, @@ -56,7 +69,7 @@ typedef enum { ESC_LOCKOUT, ESC_REBOOTING, ESC_LOCKOUT_AND_REBOOTING, -} cmESCState; +} ESCState; #define SPINDLE_OVERRIDE_ENABLE false #define SPINDLE_OVERRIDE_FACTOR 1.00 @@ -69,21 +82,27 @@ typedef enum { */ typedef struct cmSpindleSingleton { - float speed; // S in RPM - cmSpindleEnable enable; // OFF, ON, PAUSE - cmSpindleDir direction; // CW, CCW - bool pause_on_hold; // pause on feedhold - cmSpindlePolarity enable_polarity; // 0=active low, 1=active high - cmSpindlePolarity dir_polarity; // 0=clockwise low, 1=clockwise high - float dwell_seconds; // dwell on spindle resume + // Public and settable + spMode mode; // spondle operating mode + float speed; // S in RPM + float speed_min; // minimum settable spindle speed + float speed_max; // maximum settable spindle speed + spDir direction; // CW, CCW + spPolarity enable_polarity; // 0=active low, 1=active high + spPolarity dir_polarity; // 0=clockwise low, 1=clockwise high + float dwell_seconds; // dwell on spindle resume + bool pause_on_hold; // pause on feedhold + bool sso_enable; // TRUE = spindle speed override enabled (see also m48_enable in canonical machine) + float sso_factor; // 1.0000 x S spindle speed. Go up or down from there + + // Spindle internal state - not directly settable by user or program + spState state; // OFF, ON, PAUSE, WAITING - bool sso_enable; // TRUE = spindle speed override enabled (see also m48_enable in canonical machine) - float sso_factor; // 1.0000 x S spindle speed. Go up or down from there - - cmESCState esc_state; // state management for ESC controller - uint32_t esc_boot_timer; // When the ESC last booted up - uint32_t esc_lockout_timer; // When the ESC lockout last triggered + // Spindle speed controller variables + ESCState esc_state; // state management for ESC controller + uint32_t esc_boot_timer; // When the ESC last booted up + uint32_t esc_lockout_timer; // When the ESC lockout last triggered } cmSpindleton_t; extern cmSpindleton_t spindle; @@ -94,44 +113,75 @@ extern cmSpindleton_t spindle; void spindle_init(); void spindle_reset(); -stat_t cm_set_spindle_speed(float speed); // S parameter -stat_t cm_spindle_control(uint8_t control); // M3, M4, M5 integrated spindle control -void cm_spindle_off_immediate(void); -void cm_spindle_optional_pause(bool option); // stop spindle based on system options selected -void cm_spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state +stat_t spindle_queue_speed(float speed); // S parameter +stat_t spindle_queue_control(uint8_t control); // M3, M4, M5 integrated spindle control +void spindle_off_immediate(void); +void spindle_optional_pause(bool option); // stop spindle based on system options selected +void spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state -stat_t cm_sso_control(const float P_word, const bool P_flag); // M51 -void cm_start_spindle_override(const float ramp_time, const float override_factor); -void cm_end_spindle_override(const float ramp_time); +stat_t spindle_override_control(const float P_word, const bool P_flag); // M51 +void spindle_start_override(const float ramp_time, const float override_factor); +void spindle_end_override(const float ramp_time); -stat_t cm_set_dir(nvObj_t* nv); -stat_t cm_set_sso(nvObj_t* nv); +stat_t sp_get_spmo(nvObj_t *nv); +stat_t sp_set_spmo(nvObj_t *nv); +stat_t sp_get_spep(nvObj_t *nv); +stat_t sp_set_spep(nvObj_t *nv); +stat_t sp_get_spdp(nvObj_t *nv); +stat_t sp_set_spdp(nvObj_t *nv); +stat_t sp_get_spph(nvObj_t *nv); +stat_t sp_set_spph(nvObj_t *nv); + +stat_t sp_get_spdw(nvObj_t *nv); +stat_t sp_set_spdw(nvObj_t *nv); +stat_t sp_get_spsn(nvObj_t *nv); +stat_t sp_set_spsn(nvObj_t *nv); +stat_t sp_get_spsm(nvObj_t *nv); +stat_t sp_set_spsm(nvObj_t *nv); + +stat_t sp_get_ssoe(nvObj_t* nv); +stat_t sp_set_ssoe(nvObj_t* nv); +stat_t sp_get_sso(nvObj_t* nv); +stat_t sp_set_sso(nvObj_t* nv); + +stat_t sp_get_sps(nvObj_t* nv); +stat_t sp_set_sps(nvObj_t* nv); +stat_t sp_get_spe(nvObj_t* nv); +stat_t sp_set_spe(nvObj_t* nv); +stat_t sp_get_spd(nvObj_t* nv); +stat_t sp_set_spd(nvObj_t* nv); /*--- text_mode support functions ---*/ #ifdef __TEXT_MODE - void cm_print_spep(nvObj_t* nv); - void cm_print_spdp(nvObj_t* nv); - void cm_print_spph(nvObj_t* nv); - void cm_print_spdw(nvObj_t* nv); - void cm_print_ssoe(nvObj_t* nv); - void cm_print_sso(nvObj_t* nv); - void cm_print_spe(nvObj_t* nv); - void cm_print_spd(nvObj_t* nv); - void cm_print_sps(nvObj_t* nv); + void sp_print_spmo(nvObj_t* nv); + void sp_print_spep(nvObj_t* nv); + void sp_print_spdp(nvObj_t* nv); + void sp_print_spph(nvObj_t* nv); + void sp_print_spdw(nvObj_t* nv); + void sp_print_spsn(nvObj_t* nv); + void sp_print_spsm(nvObj_t* nv); + void sp_print_ssoe(nvObj_t* nv); + void sp_print_sso(nvObj_t* nv); + void sp_print_sps(nvObj_t* nv); + void sp_print_spe(nvObj_t* nv); + void sp_print_spd(nvObj_t* nv); #else - #define cm_print_spep tx_print_stub - #define cm_print_spdp tx_print_stub - #define cm_print_spph tx_print_stub - #define cm_print_spdw tx_print_stub - #define cm_print_ssoe tx_print_stub - #define cm_print_spe tx_print_stub - #define cm_print_sso tx_print_stub - #define cm_print_spd tx_print_stub - #define cm_print_sps tx_print_stub + #define sp_print_spmo tx_print_stub + #define sp_print_spep tx_print_stub + #define sp_print_spdp tx_print_stub + #define sp_print_spph tx_print_stub + #define sp_print_spdw tx_print_stub + #define sp_print_spsn tx_print_stub + #define sp_print_spsm tx_print_stub + #define sp_print_ssoe tx_print_stub + #define sp_print_spe tx_print_stub + #define sp_print_sps tx_print_stub + #define sp_print_sso tx_print_stub + #define sp_print_spd tx_print_stub #endif // __TEXT_MODE From 2b07f865c6417324b4187d9cb58422ffbf767b51 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 13 Jan 2017 16:09:13 -0500 Subject: [PATCH 073/283] Changed base spindle control and speed functions --- g2core/alarm.cpp | 2 +- g2core/canonical_machine.cpp | 2 +- g2core/cycle_probing.cpp | 6 +- g2core/gcode_parser.cpp | 8 +- g2core/spindle.cpp | 214 ++++++++++++++++++----------------- g2core/spindle.h | 67 +++++------ 6 files changed, 155 insertions(+), 144 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 9516d98e..e5e23334 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -123,7 +123,7 @@ stat_t cm_is_alarmed() void cm_halt_all(void) { cm_halt_motion(); - spindle_off_immediate(); + spindle_control_immediate(SPINDLE_OFF, false); cm_coolant_off_immediate(); } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index fbbe3c84..974a6235 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1555,7 +1555,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_select_plane(cm->default_select_plane); // reset to default arc plane cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default - spindle_off_immediate(); // M5 + spindle_control_immediate(SPINDLE_OFF, false); // M5 cm_coolant_off_immediate(); // M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index ff254fda..68751fa7 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -251,8 +251,8 @@ static uint8_t _probing_init() { gpio_set_probing_mode(pb.probe_input, true); // turn off spindle and start the move - spindle_optional_pause(true); // pause the spindle if it's on - return (_set_pb_func(_probing_start)); // start the probe move + spindle_pause(); // pause the spindle if it's on + return (_set_pb_func(_probing_start)); // start the probe move } /* @@ -391,7 +391,7 @@ static void _probe_restore_settings() { cm_set_distance_mode(pb.saved_distance_mode); // restart spindle if it was paused - spindle_resume(spindle.dwell_seconds); + spindle_resume(); // cancel the feed modes used during probing cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index b51f6699..ba840539 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -733,14 +733,18 @@ static stat_t _execute_gcode_block(char *active_comment) cm_set_model_linenum(gv.linenum); EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, F_word); // F - EXEC_FUNC(spindle_queue_speed, S_word); // S + EXEC_FUNC(spindle_speed_sync, S_word); // S + if (gf.sso_control) { // spindle speed override ritorno(spindle_override_control(gv.P_word, gf.P_word)); } EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written EXEC_FUNC(cm_change_tool, tool_change); // M6 - EXEC_FUNC(spindle_queue_control, spindle_control); // spindle CW, CCW, OFF + + if (gf.spindle_control) { // spindle OFF, CW, CCW + ritorno(spindle_control_sync(gv.spindle_control, false)); + } EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 0e5dcca6..750174c5 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -39,13 +39,13 @@ /**** Allocate structures ****/ -cmSpindleton_t spindle; +spSpindle_t spindle; /**** Static functions ****/ static void _exec_spindle_speed(float *value, bool *flag); static void _exec_spindle_control(float *value, bool *flag); -static float _get_spindle_pwm (spState state, spDir direction); +static float _get_spindle_pwm (spState state, spControl direction); /*********************************************************************************** * spindle_init() @@ -65,95 +65,55 @@ void spindle_reset() float value[AXES] = { 0,0,0,0,0,0 }; // set spindle speed to zero bool flags[] = { 1,0,0,0,0,0 }; _exec_spindle_speed(value, flags); - spindle_off_immediate(); // turn spindle off + spindle_control_immediate(SPINDLE_CONTROL_OFF, false); // turn spindle off } /*********************************************************************************** - * spindle_off_immediate() - turn on/off spindle w/o planning - * spindle_optional_pause() - pause spindle immediately if option is true - * spindle_resume() - restart a paused spindle with an optional dwell + * spindle_pause() - pause spindle immediately if option is true + * spindle_resume() - restart a paused spindle with an optional dwell + * spindle_control_immediate() - execute spindle control immediately + * spindle_control_sync() - queue a spindle control to the planner buffer + * _exec_spindle_control() - actually execute the spindle command */ -void spindle_off_immediate() +void spindle_pause() +{ + if (spindle.state == SPINDLE_ON) { + spindle_control_sync(SPINDLE_CONTROL_OFF, true); + } +} + +void spindle_resume() +{ + if (spindle.state == SPINDLE_PAUSE) { + spindle_control_sync(SPINDLE_CONTROL_CW, false); + } +} + +stat_t spindle_control_immediate(uint8_t control, bool pause) { - spindle.state = SPINDLE_OFF; float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; + bool flags[] = { 1,0, pause, 0,0,0 }; + + if (control != SPINDLE_CONTROL_OFF) { + value[0] = SPINDLE_ON; + value[1] = control; + flags[1] = true; + } _exec_spindle_control(value, flags); + return(STAT_OK); } -void spindle_optional_pause(bool option) +stat_t spindle_control_sync(uint8_t control, bool pause) // uses spControl arg: OFF, CW, CCW { - if (option && spindle.state == SPINDLE_ON) { - spindle_off_immediate(); - spindle.state = SPINDLE_PAUSE; + float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; + bool flags[] = { 1,0, pause, 0,0,0 }; + + if (control != SPINDLE_CONTROL_OFF) { + value[0] = SPINDLE_ON; + value[1] = control; + flags[1] = true; } -} - -void spindle_resume(float dwell_seconds) -{ - if(spindle.state == SPINDLE_PAUSE) { - spindle.state = SPINDLE_ON; - mp_request_out_of_band_dwell(dwell_seconds); - float value[] = { (float)SPINDLE_ON, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_control(value, flags); - } -} - -/*********************************************************************************** - * spindle_queue_speed() - queue the S parameter to the planner buffer - * _exec_spindle_speed() - spindle speed callback from planner queue - */ - -stat_t spindle_queue_speed(float speed) -{ - if (speed < spindle.speed_min) { - return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); - } - if (speed > spindle.speed_max) { - return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); - } - - float value[AXES] = { speed, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_spindle_speed, value, flags); - return (STAT_OK); -} - -static void _exec_spindle_speed(float *value, bool *flag) -{ - if (flag[0]) { - spindle.speed = value[0]; - } - - if (flag[1]) { - spindle.direction = (spDir)value[1]; - } - - // update spindle speed if we're running - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); -} - -/*********************************************************************************** - * spindle_queue_control() - queue the spindle command to the planner buffer. Observe PAUSE - * _exec_spindle_control() - actually execute the spindle command - */ - -stat_t spindle_queue_control(uint8_t control) // requires SPINDLE_CONTROL_xxx style args -{ - if (control == SPINDLE_CONTROL_OFF) { - spindle.state = SPINDLE_OFF; - } else { - spindle.state = SPINDLE_ON; - if (control == SPINDLE_CONTROL_CW) { - spindle.direction = SPINDLE_CW; - } else { - spindle.direction = SPINDLE_CCW; - } - } - float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; mp_queue_command(_exec_spindle_control, value, flags); return(STAT_OK); } @@ -165,27 +125,70 @@ stat_t spindle_queue_control(uint8_t control) // requires SPINDLE_CONTROL_xxx s static void _exec_spindle_control(float *value, bool *flag) { - // set the direction first - if (flag[1]) - { - spindle.direction = (spDir)value[1]; // record spindle direction in the struct - if (spindle.direction ^ spindle.dir_polarity) { + if (flag[1]) { // set the direction first + spindle.direction = (spControl)value[1]; // record spindle direction in the struct + if ((spindle.direction-1) ^ spindle.dir_polarity) { // take CW/CCW down to 0 or 1 _set_spindle_direction_bit_hi(); } else { _set_spindle_direction_bit_lo(); } } - - if (flag[0]) - { - // set on/off. Mask out PAUSE and consider it OFF - spindle.state = (spState)value[0]; // record spindle state in the struct - if ((spindle.state & 0x01) ^ spindle.enable_polarity) { + if (flag[0]) { // set on/off + spindle.state = (spState)value[0]; // record spindle state in the struct + if ((spindle.state & 0x01) ^ spindle.enable_polarity) { // mask out PAUSE bit and consider it to be OFF _set_spindle_enable_bit_lo(); } else { _set_spindle_enable_bit_hi(); } } + if (flag[2]) { // set pause + spindle.state = SPINDLE_PAUSE; + } + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); +} + +/*********************************************************************************** + * spindle_queue_speed() - queue the S parameter to the planner buffer + * _exec_spindle_speed() - spindle speed callback from planner queue + */ + +stat_t spindle_speed_immediate(float speed) +{ + if (speed < spindle.speed_min) { + return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); + } + if (speed > spindle.speed_max) { + return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); + } + float value[AXES] = { speed, 0,0,0,0,0 }; +// bool flags[] = { 1,0,0,0,0,0 }; + _exec_spindle_speed(value, nullptr); + return (STAT_OK); +} + +stat_t spindle_speed_sync(float speed) +{ + if (speed < spindle.speed_min) { + return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); + } + if (speed > spindle.speed_max) { + return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); + } + float value[AXES] = { speed, 0,0,0,0,0 }; +// bool flags[] = { 1,0,0,0,0,0 }; + mp_queue_command(_exec_spindle_speed, value, nullptr); + return (STAT_OK); +} + +static void _exec_spindle_speed(float *value, bool *flag) +{ + spindle.speed = value[0]; +/* + if (flag[1]) { + spindle.direction = (spDir)value[1]; + } +*/ + // update spindle speed if we're running pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } @@ -193,15 +196,15 @@ static void _exec_spindle_control(float *value, bool *flag) * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ -static float _get_spindle_pwm (spState state, spDir direction) +static float _get_spindle_pwm (spState state, spControl direction) { float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; - if (direction == SPINDLE_CW ) { + if (direction == SPINDLE_CONTROL_CW ) { speed_lo = pwm.c[PWM_1].cw_speed_lo; speed_hi = pwm.c[PWM_1].cw_speed_hi; phase_lo = pwm.c[PWM_1].cw_phase_lo; phase_hi = pwm.c[PWM_1].cw_phase_hi; - } else { // if (direction == SPINDLE_CCW ) { + } else { // if (direction == SPINDLE_CONTROL_CCW ) { speed_lo = pwm.c[PWM_1].ccw_speed_lo; speed_hi = pwm.c[PWM_1].ccw_speed_hi; phase_lo = pwm.c[PWM_1].ccw_phase_lo; @@ -226,20 +229,10 @@ static float _get_spindle_pwm (spState state, spDir direction) /*********************************************************************************** * spindle_override_control() - * spindle_sp_start_spindle_override() - * sp_end_spindle_override() + * spindle_start_override() + * spindle_end_override() */ -void spindle_start_override(const float ramp_time, const float override_factor) -{ - return; -} - -void spindle_end_override(const float ramp_time) -{ - return; -} - stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 { bool new_enable = true; @@ -269,6 +262,17 @@ stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 return (STAT_OK); } +void spindle_start_override(const float ramp_time, const float override_factor) +{ + return; +} + +void spindle_end_override(const float ramp_time) +{ + return; +} + + /**************************** * END OF SPINDLE FUNCTIONS * ****************************/ diff --git a/g2core/spindle.h b/g2core/spindle.h index f2446155..9258f2f3 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -28,22 +28,6 @@ #ifndef SPINDLE_H_ONCE #define SPINDLE_H_ONCE -typedef enum { // how spindle controls are presented by the Gcode parser - SPINDLE_CONTROL_OFF = 0, // M5 - SPINDLE_CONTROL_CW, // M3 - SPINDLE_CONTROL_CCW // M4 -} spControl; - -typedef enum { // spindle direction state - SPINDLE_CW = 0, - SPINDLE_CCW -} spDir; - - -// *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h -// These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 -// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types - typedef enum { SPINDLE_DISABLED = 0, // spindle will not operate SPINDLE_PLAN_TO_STOP, // spindle operating, plans to stop @@ -51,19 +35,32 @@ typedef enum { } spMode; #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS +// Note on spControl: +// This enum is used to both request the spindle operation (ON, CW, CCW), +// and to record spindle direction (1=CW, 2=CCW) in spindle.direction +typedef enum { // how spindle controls are presented by the Gcode parser + SPINDLE_CONTROL_OFF = 0, // M5 + SPINDLE_CONTROL_CW = 1, // M3 + SPINDLE_CONTROL_CCW = 2 // M4 +} spControl; + +// *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h +// These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 +// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types + typedef enum { // Note: These values agree with SPINDLE_ACTIVE_LOW = 0, // Will set output to 0 to enable the spindle or CW direction SPINDLE_ACTIVE_HIGH = 1, // Will set output to 1 to enable the spindle or CW direction } spPolarity; -typedef enum { // basic spindle state machine +typedef enum { // basic spindle state machine. Do not change this enum SPINDLE_OFF = 0, - SPINDLE_ON, // spindle on and at speed - SPINDLE_PAUSE, // meaning it was on and now it's off - SPINDLE_WAITING // spindle not at speed yet + SPINDLE_ON = 1, // spindle on and at speed + SPINDLE_PAUSE = 2, // meaning it was on and now it's off + SPINDLE_WAITING = 3 // spindle not at speed yet } spState; -typedef enum { +typedef enum { // electronic speed controller for some spindles ESC_ONLINE = 0, ESC_OFFLINE, ESC_LOCKOUT, @@ -73,22 +70,22 @@ typedef enum { #define SPINDLE_OVERRIDE_ENABLE false #define SPINDLE_OVERRIDE_FACTOR 1.00 -#define SPINDLE_OVERRIDE_MIN 0.05 // 5% -#define SPINDLE_OVERRIDE_MAX 2.00 // 200% +#define SPINDLE_OVERRIDE_MIN 0.05 // 5% +#define SPINDLE_OVERRIDE_MAX 2.00 // 200% #define SPINDLE_OVERRIDE_RAMP_TIME 1 // change sped in seconds /* * Spindle control structure */ -typedef struct cmSpindleSingleton { +typedef struct spSpindle { // Public and settable spMode mode; // spondle operating mode float speed; // S in RPM float speed_min; // minimum settable spindle speed float speed_max; // maximum settable spindle speed - spDir direction; // CW, CCW + spControl direction; // 1=CW, 2=CCW spPolarity enable_polarity; // 0=active low, 1=active high spPolarity dir_polarity; // 0=clockwise low, 1=clockwise high float dwell_seconds; // dwell on spindle resume @@ -104,8 +101,8 @@ typedef struct cmSpindleSingleton { uint32_t esc_boot_timer; // When the ESC last booted up uint32_t esc_lockout_timer; // When the ESC lockout last triggered -} cmSpindleton_t; -extern cmSpindleton_t spindle; +} spSpindle_t; +extern spSpindle_t spindle; /* * Global Scope Functions @@ -113,11 +110,17 @@ extern cmSpindleton_t spindle; void spindle_init(); void spindle_reset(); -stat_t spindle_queue_speed(float speed); // S parameter -stat_t spindle_queue_control(uint8_t control); // M3, M4, M5 integrated spindle control -void spindle_off_immediate(void); -void spindle_optional_pause(bool option); // stop spindle based on system options selected -void spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state + +void spindle_pause(void); +void spindle_resume(void); +stat_t spindle_control_immediate(uint8_t control, bool pause); +stat_t spindle_control_sync(uint8_t control, bool pause); +stat_t spindle_speed_immediate(float speed); // S parameter +stat_t spindle_speed_sync(float speed); // S parameter + +//void spindle_off_immediate(void); +//void spindle_optional_pause(bool option); // stop spindle based on system options selected +//void spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state stat_t spindle_override_control(const float P_word, const bool P_flag); // M51 void spindle_start_override(const float ramp_time, const float override_factor); From 59c4cbad7ee54aa91a7b9cbb40b7954f041acd60 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 14 Jan 2017 09:02:25 -0500 Subject: [PATCH 074/283] Checkpoint on spindle functions --- g2core/alarm.cpp | 2 +- g2core/canonical_machine.cpp | 2 +- g2core/config_app.cpp | 12 +-- g2core/cycle_probing.cpp | 4 +- g2core/g2core.cppproj | 4 +- g2core/gcode_parser.cpp | 8 +- g2core/pwm.cpp | 2 +- g2core/pwm.h | 6 +- g2core/spindle.cpp | 200 +++++++++++++++++++++++------------ g2core/spindle.h | 42 +++++--- 10 files changed, 175 insertions(+), 107 deletions(-) mode change 100755 => 100644 g2core/pwm.cpp mode change 100755 => 100644 g2core/pwm.h diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index e5e23334..9b580c3b 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -123,7 +123,7 @@ stat_t cm_is_alarmed() void cm_halt_all(void) { cm_halt_motion(); - spindle_control_immediate(SPINDLE_OFF, false); + spindle_control_immediate(SPINDLE_OFF); cm_coolant_off_immediate(); } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 974a6235..ab85fa20 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1555,7 +1555,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_select_plane(cm->default_select_plane); // reset to default arc plane cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default - spindle_control_immediate(SPINDLE_OFF, false); // M5 + spindle_control_immediate(SPINDLE_OFF); // M5 cm_coolant_off_immediate(); // M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 18d75cc8..0dd3b4eb 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -864,17 +864,7 @@ const cfgItem_t cfgArray[] = { { "", "sps", _fiz, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // get spindle speed { "", "spe", _fiz, 0, sp_print_spe, sp_get_spe, set_nul, (float *)&cs.null, 0 }, // get spindle enable state { "", "spd", _fiz, 0, sp_print_spd, sp_get_spd, sp_set_spd, (float *)&cs.null, 0 }, // get spindle direction -/* - { "sys","spep",_fipn,0, sp_print_spep, get_ui8, set_01, (float *)&spindle.enable_polarity, SPINDLE_ENABLE_POLARITY }, - { "sys","spdp",_fipn,0, sp_print_spdp, get_ui8, set_01, (float *)&spindle.dir_polarity, SPINDLE_DIR_POLARITY }, - { "sys","spph",_fipn,0, sp_print_spph, get_ui8, set_01, (float *)&spindle.pause_on_hold, SPINDLE_PAUSE_ON_HOLD }, - { "sys","spdw",_fipn,2, sp_print_spdw, get_flt, set_flt, (float *)&spindle.dwell_seconds, SPINDLE_DWELL_TIME }, - { "sys","ssoe",_fipn,0, sp_print_ssoe, get_ui8, set_01, (float *)&spindle.sso_enable, SPINDLE_OVERRIDE_ENABLE}, - { "sys","sso", _fipn,3, sp_print_sso, sp_get_sso, sp_set_sso,(float *)&spindle.sso_factor, SPINDLE_OVERRIDE_FACTOR}, - { "", "spe", _fiz, 0, sp_print_spe, get_ui8, set_nul, (float *)&spindle.state, 0 }, // get spindle enable state - { "", "spd", _fiz, 0, sp_print_spd, get_ui8,sp_set_dir,(float *)&spindle.direction, 0 }, // get spindle direction - { "", "sps", _fiz, 0, sp_print_sps, get_flt, set_nul, (float *)&spindle.speed, 0 }, // get spindle speed -*/ + // Coolant functions { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 68751fa7..554e33a3 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -251,7 +251,7 @@ static uint8_t _probing_init() { gpio_set_probing_mode(pb.probe_input, true); // turn off spindle and start the move - spindle_pause(); // pause the spindle if it's on + spindle_control_immediate(SPINDLE_PAUSE); // pause the spindle if it's on return (_set_pb_func(_probing_start)); // start the probe move } @@ -391,7 +391,7 @@ static void _probe_restore_settings() { cm_set_distance_mode(pb.saved_distance_mode); // restart spindle if it was paused - spindle_resume(); + spindle_control_immediate(SPINDLE_RESUME); // cancel the feed modes used during probing cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index af27d1e0..36e55b55 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index ba840539..5faef621 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -634,9 +634,9 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) SET_MODAL (MODAL_GROUP_M4, program_flow, PROGRAM_STOP); case 2: case 30: SET_MODAL (MODAL_GROUP_M4, program_flow, PROGRAM_END); - case 3: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_CONTROL_CW); - case 4: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_CONTROL_CCW); - case 5: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_CONTROL_OFF); + case 3: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_CW); + case 4: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_CCW); + case 5: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_OFF); case 6: SET_NON_MODAL (tool_change, true); case 7: SET_MODAL (MODAL_GROUP_M8, mist_coolant, true); case 8: SET_MODAL (MODAL_GROUP_M8, flood_coolant, true); @@ -743,7 +743,7 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_change_tool, tool_change); // M6 if (gf.spindle_control) { // spindle OFF, CW, CCW - ritorno(spindle_control_sync(gv.spindle_control, false)); + ritorno(spindle_control_sync((spState)gv.spindle_control)); } EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp old mode 100755 new mode 100644 index ecc5212b..5e4c96b9 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -36,7 +36,7 @@ /***** PWM defines, structures and memory allocation *****/ -pwmSingleton_t pwm; +pwmControl_t pwm; // Setup motate PWM pins diff --git a/g2core/pwm.h b/g2core/pwm.h old mode 100755 new mode 100644 index eac4a081..eb4f1549 --- a/g2core/pwm.h +++ b/g2core/pwm.h @@ -45,12 +45,12 @@ typedef struct pwmChannel { // no data required in ARM } pwmChannel_t; -typedef struct pwmSingleton { +typedef struct pwmControl { pwmConfigChannel_t c[PWMS]; // array of channel configs pwmChannel_t p[PWMS]; // array of PWM channels -} pwmSingleton_t; +} pwmControl_t; -extern pwmSingleton_t pwm; +extern pwmControl_t pwm; /*** function prototypes ***/ diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 750174c5..61b69d19 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -44,8 +44,8 @@ spSpindle_t spindle; /**** Static functions ****/ static void _exec_spindle_speed(float *value, bool *flag); -static void _exec_spindle_control(float *value, bool *flag); -static float _get_spindle_pwm (spState state, spControl direction); +//static void _exec_spindle_control(float *value, bool *flag); +static float _get_spindle_pwm (spState state, spState direction); /*********************************************************************************** * spindle_init() @@ -65,59 +65,36 @@ void spindle_reset() float value[AXES] = { 0,0,0,0,0,0 }; // set spindle speed to zero bool flags[] = { 1,0,0,0,0,0 }; _exec_spindle_speed(value, flags); - spindle_control_immediate(SPINDLE_CONTROL_OFF, false); // turn spindle off + spindle_control_immediate(SPINDLE_OFF); } /*********************************************************************************** - * spindle_pause() - pause spindle immediately if option is true - * spindle_resume() - restart a paused spindle with an optional dwell * spindle_control_immediate() - execute spindle control immediately * spindle_control_sync() - queue a spindle control to the planner buffer * _exec_spindle_control() - actually execute the spindle command + * + * Basic operation: Spindle function is effected by _exec_spindle_control(). + * Spindle_control_immediate() runs command as soon as it's received. + * Spindle_control_sync() inserts spindle move into the planner, and handles optional dwells + * + * Valid inputs to Spindle_control_immediate() and Spindle_control_sync() are: + * + * - SPINDLE_OFF turns off spindle and sets spindle state to SPINDLE_OFF. + * The spindle.direction value is not affected (although this doesn't really matter). + * + * - SPINDLE_CW or SPINDLE_CCW turns spindle on and sets direction accordingly. + * If spindle_control_sync() has a non-zero dwell a dwell move is added to the planner queue. + * In this case spindle.state is SPINDLE_WAIT until move is "played", and dwell completes. + * spindle_control_immediate() has no dwell behavior. + * + * - SPINDLE_PAUSE, when in CW or CCW state, turns spindle OFF and preserves PAUSE in spindle.state. + * If PAUSE is received when not in CW or CCW state it is ignored. + * + * - SPINDLE_RESUME, if in a PAUSE state, reverts to previous SPINDLE_CW or SPINDLE_CCW. + * If RESUME is received from spindle_control_sync() the same dwell and WAIT behavior occurs. + * If RESUME is received when not in a PAUSED state it is ignored. */ -void spindle_pause() -{ - if (spindle.state == SPINDLE_ON) { - spindle_control_sync(SPINDLE_CONTROL_OFF, true); - } -} - -void spindle_resume() -{ - if (spindle.state == SPINDLE_PAUSE) { - spindle_control_sync(SPINDLE_CONTROL_CW, false); - } -} - -stat_t spindle_control_immediate(uint8_t control, bool pause) -{ - float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; - bool flags[] = { 1,0, pause, 0,0,0 }; - - if (control != SPINDLE_CONTROL_OFF) { - value[0] = SPINDLE_ON; - value[1] = control; - flags[1] = true; - } - _exec_spindle_control(value, flags); - return(STAT_OK); -} - -stat_t spindle_control_sync(uint8_t control, bool pause) // uses spControl arg: OFF, CW, CCW -{ - float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; - bool flags[] = { 1,0, pause, 0,0,0 }; - - if (control != SPINDLE_CONTROL_OFF) { - value[0] = SPINDLE_ON; - value[1] = control; - flags[1] = true; - } - mp_queue_command(_exec_spindle_control, value, flags); - return(STAT_OK); -} - #define _set_spindle_enable_bit_hi() spindle_enable_pin.set() #define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() #define _set_spindle_direction_bit_hi() spindle_dir_pin.set() @@ -125,28 +102,89 @@ stat_t spindle_control_sync(uint8_t control, bool pause) // uses spControl arg: static void _exec_spindle_control(float *value, bool *flag) { - if (flag[1]) { // set the direction first - spindle.direction = (spControl)value[1]; // record spindle direction in the struct - if ((spindle.direction-1) ^ spindle.dir_polarity) { // take CW/CCW down to 0 or 1 + spState control = (spState)value[0]; + if (control > SPINDLE_RESUME) { + return; + } + + uint8_t on_bit = SPINDLE_OFF; + int8_t dir_bit = -1; // use this value to skip setting the direction + + spindle.state = control; // record spindle state + + if ((control == SPINDLE_CW) || (control == SPINDLE_CCW)) { + on_bit = 1; // use 1 (not true) to indicate this is a bitmask + dir_bit = control-1; // adjust direction so it can be used as a bitmask + spindle.direction = control; +// spindle.state = control; + } + else if (control == SPINDLE_RESUME) { + on_bit = 1; + dir_bit = spindle.direction-1; // Note: spindle direction is stored as 1 & 2 + spindle.state = spindle.direction; + } + + // set the direction first + if (dir_bit >= 0) { + if (dir_bit ^ spindle.dir_polarity) { _set_spindle_direction_bit_hi(); } else { _set_spindle_direction_bit_lo(); } } - if (flag[0]) { // set on/off - spindle.state = (spState)value[0]; // record spindle state in the struct - if ((spindle.state & 0x01) ^ spindle.enable_polarity) { // mask out PAUSE bit and consider it to be OFF - _set_spindle_enable_bit_lo(); - } else { - _set_spindle_enable_bit_hi(); - } + + // set on/off + if (on_bit ^ spindle.enable_polarity) { + _set_spindle_enable_bit_lo(); + } else { + _set_spindle_enable_bit_hi(); } - if (flag[2]) { // set pause - spindle.state = SPINDLE_PAUSE; - } + +// if (flag[2]) { // set pause +// spindle.state = SPINDLE_PAUSE; +// } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } +stat_t spindle_control_immediate(spState control) +{ +// bool pause = (control == SPINDLE_PAUSE) ? true : false; + +// float value[] = { (float)control, 0,0,0,0,0 }; + float value[] = { (float)control }; +// bool flags[] = { 1,0, pause, 0,0,0 }; + +// if (control != SPINDLE_CONTROL_OFF) { +// value[0] = SPINDLE_ON; +// value[1] = control; +// flags[1] = true; +// } + _exec_spindle_control(value, nullptr); + return(STAT_OK); +} + +stat_t spindle_control_sync(spState control) // uses spControl arg: OFF, CW, CCW +{ +/* + bool pause = (control == SPINDLE_PAUSE) ? true : false; + float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; + bool flags[] = { 1,0, pause, 0,0,0 }; + + if (control != SPINDLE_CONTROL_OFF) { + value[0] = SPINDLE_ON; + value[1] = control; + flags[1] = true; + } +*/ + float value[] = { (float)control, 0,0,0,0,0 }; + mp_queue_command(_exec_spindle_control, value, nullptr); + + if (fp_NOT_ZERO(spindle.dwell_seconds)) { +// mp_queue_command(dwell); + } + return(STAT_OK); +} + /*********************************************************************************** * spindle_queue_speed() - queue the S parameter to the planner buffer * _exec_spindle_speed() - spindle speed callback from planner queue @@ -195,23 +233,55 @@ static void _exec_spindle_speed(float *value, bool *flag) /*********************************************************************************** * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ +/* +static float _get_spindle_pwm (spSpindle_t *sp, pwmControl_t *pwm) +{ + float speed_lo, speed_hi, phase_lo, phase_hi; + if (sp->direction == SPINDLE_CW ) { + speed_lo = pwm->c[PWM_1].cw_speed_lo; + speed_hi = pwm->c[PWM_1].cw_speed_hi; + phase_lo = pwm->c[PWM_1].cw_phase_lo; + phase_hi = pwm->c[PWM_1].cw_phase_hi; + } else { // if (direction == SPINDLE_CCW ) { + speed_lo = pwm->c[PWM_1].ccw_speed_lo; + speed_hi = pwm->c[PWM_1].ccw_speed_hi; + phase_lo = pwm->c[PWM_1].ccw_phase_lo; + phase_hi = pwm->c[PWM_1].ccw_phase_hi; + } -static float _get_spindle_pwm (spState state, spControl direction) + if ((sp->state == SPINDLE_CW) || (sp->state == SPINDLE_CCW)) { + // clamp spindle speed to lo/hi range + if (spindle->speed < speed_lo) { + spindle->speed = speed_lo; + } + if (spindle->speed > speed_hi) { + spindle->speed = speed_hi; + } + // normalize speed to [0..1] + float speed = (spindle->speed - speed_lo) / (speed_hi - speed_lo); + return (speed * (phase_hi - phase_lo)) + phase_lo; + } else { + return pwm->c[PWM_1].phase_off; + } +} +*/ + +static float _get_spindle_pwm (spState state, spState direction) { float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; - if (direction == SPINDLE_CONTROL_CW ) { + if (direction == SPINDLE_CW ) { speed_lo = pwm.c[PWM_1].cw_speed_lo; speed_hi = pwm.c[PWM_1].cw_speed_hi; phase_lo = pwm.c[PWM_1].cw_phase_lo; phase_hi = pwm.c[PWM_1].cw_phase_hi; - } else { // if (direction == SPINDLE_CONTROL_CCW ) { + } else { // if (direction == SPINDLE_CCW ) { speed_lo = pwm.c[PWM_1].ccw_speed_lo; speed_hi = pwm.c[PWM_1].ccw_speed_hi; phase_lo = pwm.c[PWM_1].ccw_phase_lo; phase_hi = pwm.c[PWM_1].ccw_phase_hi; } - if (state == SPINDLE_ON) { + if ((state == SPINDLE_CW) || (state == SPINDLE_CCW)) { // clamp spindle speed to lo/hi range if (spindle.speed < speed_lo) { spindle.speed = speed_lo; @@ -222,7 +292,7 @@ static float _get_spindle_pwm (spState state, spControl direction) // normalize speed to [0..1] float speed = (spindle.speed - speed_lo) / (speed_hi - speed_lo); return (speed * (phase_hi - phase_lo)) + phase_lo; - } else { + } else { return pwm.c[PWM_1].phase_off; } } diff --git a/g2core/spindle.h b/g2core/spindle.h index 9258f2f3..56dac343 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -35,14 +35,22 @@ typedef enum { } spMode; #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS -// Note on spControl: -// This enum is used to both request the spindle operation (ON, CW, CCW), -// and to record spindle direction (1=CW, 2=CCW) in spindle.direction +// spState is used for multiple purposes: +// - request the spindle operation (OFF, CW, CCW) +// - request PAUSE and RESUME +// - run the spindle state machine for spindle wait states +// - store current direction (1=CW, 2=CCW) in spindle.direction typedef enum { // how spindle controls are presented by the Gcode parser - SPINDLE_CONTROL_OFF = 0, // M5 - SPINDLE_CONTROL_CW = 1, // M3 - SPINDLE_CONTROL_CCW = 2 // M4 -} spControl; + SPINDLE_OFF = 0, // M5 + SPINDLE_CW = 1, // M3 and store CW to spindle.direction + SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction + SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state + SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW + SPINDLE_WAIT // handle transient WAIT states +} spState; + +// SPINDLE_ON is either of SPINDLE_CW or SPINDLE_CCW +//#define SPINDLE_ON(s) ((s == SPINDLE_CW) || (s == SPINDLE__CCW)) // *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h // These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 @@ -53,12 +61,14 @@ typedef enum { // Note: These values agree with SPINDLE_ACTIVE_HIGH = 1, // Will set output to 1 to enable the spindle or CW direction } spPolarity; +/* typedef enum { // basic spindle state machine. Do not change this enum SPINDLE_OFF = 0, SPINDLE_ON = 1, // spindle on and at speed SPINDLE_PAUSE = 2, // meaning it was on and now it's off SPINDLE_WAITING = 3 // spindle not at speed yet } spState; +*/ typedef enum { // electronic speed controller for some spindles ESC_ONLINE = 0, @@ -80,22 +90,22 @@ typedef enum { // electronic speed controller for some spindles typedef struct spSpindle { - // Public and settable - spMode mode; // spondle operating mode + spMode mode; // spindle operating mode + spState state; // OFF, ON, PAUSE, RESUME, WAIT + spState direction; // 1=CW, 2=CCW (subset of above state) + float speed; // S in RPM float speed_min; // minimum settable spindle speed float speed_max; // maximum settable spindle speed - spControl direction; // 1=CW, 2=CCW + spPolarity enable_polarity; // 0=active low, 1=active high spPolarity dir_polarity; // 0=clockwise low, 1=clockwise high float dwell_seconds; // dwell on spindle resume bool pause_on_hold; // pause on feedhold + bool sso_enable; // TRUE = spindle speed override enabled (see also m48_enable in canonical machine) float sso_factor; // 1.0000 x S spindle speed. Go up or down from there - // Spindle internal state - not directly settable by user or program - spState state; // OFF, ON, PAUSE, WAITING - // Spindle speed controller variables ESCState esc_state; // state management for ESC controller uint32_t esc_boot_timer; // When the ESC last booted up @@ -111,10 +121,8 @@ extern spSpindle_t spindle; void spindle_init(); void spindle_reset(); -void spindle_pause(void); -void spindle_resume(void); -stat_t spindle_control_immediate(uint8_t control, bool pause); -stat_t spindle_control_sync(uint8_t control, bool pause); +stat_t spindle_control_immediate(spState control); +stat_t spindle_control_sync(spState control); stat_t spindle_speed_immediate(float speed); // S parameter stat_t spindle_speed_sync(float speed); // S parameter From 65eeab7ac7c78dad9cb4c536c4597197d433c4ad Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 14 Jan 2017 11:49:23 -0500 Subject: [PATCH 075/283] Testing and tweaks --- g2core/canonical_machine.cpp | 4 +- g2core/canonical_machine.h | 2 +- g2core/config.cpp | 4 +- g2core/config_app.cpp | 43 +++---- g2core/gcode_parser.cpp | 2 +- g2core/spindle.cpp | 227 ++++++++++++++--------------------- g2core/spindle.h | 102 +++++++--------- 7 files changed, 160 insertions(+), 224 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ab85fa20..c1083edb 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1353,8 +1353,8 @@ static void _exec_feed_override(const bool m48_enable, const bool m50_enable, co * cm_m48_enable() - M48, M49 * * M48 is the master enable for manual feedrate override and spindle override - * If M48 is asserted M50 (mfo), M50.1 (mto) and M51 (sso) settings are in effect - * If M49 is asserted M50 (mfo), M501. (mto) and M51 (sso) settings are in ignored + * If M48 is asserted M50 (mfo), M50.1 (mto) and M51 (spo) settings are in effect + * If M49 is asserted M50 (mfo), M501. (mto) and M51 (spo) settings are in ignored * * See http://linuxcnc.org/docs/html/gcode/m-code.html#sec:M48,-M49-Speed-and-Feed-Override-Control */ diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 821bb900..23386d38 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -432,7 +432,7 @@ void cm_reset_overrides(void); stat_t cm_m48_enable(uint8_t enable); // M48, M49 stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50 stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1 -// See spindle.cpp for cm_sso_control() // M51 +// See spindle.cpp for cm_spo_control() // M51 // Program Functions (4.3.10) void cm_cycle_start(void); // (no Gcode) diff --git a/g2core/config.cpp b/g2core/config.cpp index 4ef94f40..2e380328 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -532,13 +532,13 @@ void nv_get_nvObj(nvObj_t *nv) // special processing for system groups and stripping tokens for groups if (nv->group[0] != NUL) { - if (GET_TABLE_BYTE(flags) & F_NOSTRIP) { + if (cfgArray[nv->index].flags & F_NOSTRIP) { nv->group[0] = NUL; } else { strcpy(nv->token, &nv->token[strlen(nv->group)]); // strip group from the token } } - ((fptrCmd)GET_TABLE_WORD(get))(nv); // populate the value + ((fptrCmd)cfgArray[nv->index].get)(nv); // populate the value } nvObj_t *nv_reset_nv(nvObj_t *nv) // clear a single nvObj structure diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 0dd3b4eb..a615368f 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -835,6 +835,28 @@ const cfgItem_t cfgArray[] = { { "jid","jidc",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, + // Spindle functions + { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, + { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, + { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spinup delay +// { "sp","spds", _fip, 2, sp_print_spds, sp_get_spds, sp_set_spds, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spindown delay +// { "sp","spdr", _fip, 2, sp_print_spdr, sp_get_spdr, sp_set_spdr, (float *)&cs.null, SPINDLE_DWELL_TIME }, // direction reversal delay + { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, + { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, + { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, + { "sp","spdp", _fip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, + { "sp","spoe", _fip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, + { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, + { "sp","spc", _f0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state + { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed + + // Coolant functions + { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, + { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, + { "sys","coph",_fipn,0, cm_print_coph,get_ui8, set_01, (float *)&coolant.pause_on_hold, COOLANT_PAUSE_ON_HOLD }, + { "", "com", _fiz, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable + { "", "cof", _fiz, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable + // General system parameters { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, @@ -851,27 +873,6 @@ const cfgItem_t cfgArray[] = { { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors - // Spindle functions - { "sp","spmo",_fipn, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, - { "sp","spep",_fipn, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, - { "sp","spdp",_fipn, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, - { "sp","spph",_fipn, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, - { "sp","spdw",_fipn, 2, sp_print_spdw, sp_get_spdw, sp_set_spdw, (float *)&cs.null, SPINDLE_DWELL_TIME }, - { "sp","spsn",_fipn, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, - { "sp","spsm",_fipn, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, - { "sp","ssoe",_fipn, 0, sp_print_ssoe, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, - { "sp","sso", _fipn, 3, sp_print_sso, sp_get_sso, sp_set_sso, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, - { "", "sps", _fiz, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // get spindle speed - { "", "spe", _fiz, 0, sp_print_spe, sp_get_spe, set_nul, (float *)&cs.null, 0 }, // get spindle enable state - { "", "spd", _fiz, 0, sp_print_spd, sp_get_spd, sp_set_spd, (float *)&cs.null, 0 }, // get spindle direction - - // Coolant functions - { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, - { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, - { "sys","coph",_fipn,0, cm_print_coph,get_ui8, set_01, (float *)&coolant.pause_on_hold, COOLANT_PAUSE_ON_HOLD }, - { "", "com", _fiz, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable - { "", "cof", _fiz, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable - // Communications and reporting parameters #ifdef __TEXT_MODE { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 5faef621..b834198b 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -743,7 +743,7 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_change_tool, tool_change); // M6 if (gf.spindle_control) { // spindle OFF, CW, CCW - ritorno(spindle_control_sync((spState)gv.spindle_control)); + ritorno(spindle_control_sync((spControl)gv.spindle_control)); } EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 61b69d19..63f32e50 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -45,7 +45,7 @@ spSpindle_t spindle; static void _exec_spindle_speed(float *value, bool *flag); //static void _exec_spindle_control(float *value, bool *flag); -static float _get_spindle_pwm (spState state, spState direction); +static float _get_spindle_pwm (spControl state, spControl direction); /*********************************************************************************** * spindle_init() @@ -87,36 +87,45 @@ void spindle_reset() * In this case spindle.state is SPINDLE_WAIT until move is "played", and dwell completes. * spindle_control_immediate() has no dwell behavior. * - * - SPINDLE_PAUSE, when in CW or CCW state, turns spindle OFF and preserves PAUSE in spindle.state. - * If PAUSE is received when not in CW or CCW state it is ignored. + * - SPINDLE_PAUSE is only applicable to CW and CCW states. It forces the spindle OFF and + * sets spindle.state to PAUSE. If PAUSE is received when not in CW or CCW state it is ignored. * * - SPINDLE_RESUME, if in a PAUSE state, reverts to previous SPINDLE_CW or SPINDLE_CCW. - * If RESUME is received from spindle_control_sync() the same dwell and WAIT behavior occurs. - * If RESUME is received when not in a PAUSED state it is ignored. + * The SPEED is not changed, and if it were changed in the interim the "new" speed is used. + * If RESUME is received from spindle_control_sync() the usual dwell and WAIT behavior occurs. + * If RESUME is received when not in a PAUSED state it is ignored. This recognizes that the main + * reason an immediate command would be issued - either manually by the user or by an alarm or + * some other program function - is to stop a spindle. So the Resume should be ignored for safety. + * + * Notes: + * - Changes to polarities and other setup parameters take effect on the next spindle action. + * There is no reason to make these occur instantly. + * + * - Since it's possible to queue a sync'd control, then set any control value with an + * immediate() before the queued command is reached, _exec_spindle_control() must gracefully + * handle any arbitrary state transition (not just the "legal" ones) + * + * - Do we need a spin-down for direction reversal? + * - Should the JSON be able to pause and resume? */ -#define _set_spindle_enable_bit_hi() spindle_enable_pin.set() -#define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() -#define _set_spindle_direction_bit_hi() spindle_dir_pin.set() -#define _set_spindle_direction_bit_lo() spindle_dir_pin.clear() - static void _exec_spindle_control(float *value, bool *flag) { - spState control = (spState)value[0]; - if (control > SPINDLE_RESUME) { + spControl control = (spControl)value[0]; + if (control >= SPINDLE_ACTION_MAX) { return; } - - uint8_t on_bit = SPINDLE_OFF; - int8_t dir_bit = -1; // use this value to skip setting the direction - - spindle.state = control; // record spindle state + if ((control == SPINDLE_RESUME) && (spindle.state != SPINDLE_PAUSE)) { + return; + } + spindle.state = control; // record new spindle state + uint8_t on_bit = SPINDLE_OFF; // default to off + int8_t dir_bit = -1; // -1 will skip setting the direction if ((control == SPINDLE_CW) || (control == SPINDLE_CCW)) { on_bit = 1; // use 1 (not true) to indicate this is a bitmask dir_bit = control-1; // adjust direction so it can be used as a bitmask spindle.direction = control; -// spindle.state = control; } else if (control == SPINDLE_RESUME) { on_bit = 1; @@ -127,97 +136,46 @@ static void _exec_spindle_control(float *value, bool *flag) // set the direction first if (dir_bit >= 0) { if (dir_bit ^ spindle.dir_polarity) { - _set_spindle_direction_bit_hi(); + spindle_dir_pin.set(); // drive pin HI } else { - _set_spindle_direction_bit_lo(); + spindle_dir_pin.clear(); // drive pin LO } } // set on/off if (on_bit ^ spindle.enable_polarity) { - _set_spindle_enable_bit_lo(); + spindle_enable_pin.clear(); // drive pin LO } else { - _set_spindle_enable_bit_hi(); + spindle_enable_pin.set(); // drive pin HI } - -// if (flag[2]) { // set pause -// spindle.state = SPINDLE_PAUSE; -// } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } -stat_t spindle_control_immediate(spState control) +stat_t spindle_control_immediate(spControl control) { -// bool pause = (control == SPINDLE_PAUSE) ? true : false; - -// float value[] = { (float)control, 0,0,0,0,0 }; float value[] = { (float)control }; -// bool flags[] = { 1,0, pause, 0,0,0 }; - -// if (control != SPINDLE_CONTROL_OFF) { -// value[0] = SPINDLE_ON; -// value[1] = control; -// flags[1] = true; -// } _exec_spindle_control(value, nullptr); return(STAT_OK); } -stat_t spindle_control_sync(spState control) // uses spControl arg: OFF, CW, CCW +stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, CCW { -/* - bool pause = (control == SPINDLE_PAUSE) ? true : false; - float value[] = { (float)SPINDLE_OFF, 0,0,0,0,0 }; - bool flags[] = { 1,0, pause, 0,0,0 }; - - if (control != SPINDLE_CONTROL_OFF) { - value[0] = SPINDLE_ON; - value[1] = control; - flags[1] = true; - } -*/ - float value[] = { (float)control, 0,0,0,0,0 }; +// float value[] = { (float)control, 0,0,0,0,0 }; + float value[] = { (float)control }; mp_queue_command(_exec_spindle_control, value, nullptr); - if (fp_NOT_ZERO(spindle.dwell_seconds)) { + if (fp_NOT_ZERO(spindle.spinup_delay)) { // mp_queue_command(dwell); } return(STAT_OK); } /*********************************************************************************** - * spindle_queue_speed() - queue the S parameter to the planner buffer - * _exec_spindle_speed() - spindle speed callback from planner queue + * spindle_speed_immediate() - execute spindle speed change immediately + * spindle_speed_sync() - queue a spindle speed change to the planner buffer + * _exec_spindle_speed() - actually execute the spindle speed command */ -stat_t spindle_speed_immediate(float speed) -{ - if (speed < spindle.speed_min) { - return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); - } - if (speed > spindle.speed_max) { - return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); - } - float value[AXES] = { speed, 0,0,0,0,0 }; -// bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_speed(value, nullptr); - return (STAT_OK); -} - -stat_t spindle_speed_sync(float speed) -{ - if (speed < spindle.speed_min) { - return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); - } - if (speed > spindle.speed_max) { - return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); - } - float value[AXES] = { speed, 0,0,0,0,0 }; -// bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_spindle_speed, value, nullptr); - return (STAT_OK); -} - static void _exec_spindle_speed(float *value, bool *flag) { spindle.speed = value[0]; @@ -230,6 +188,29 @@ static void _exec_spindle_speed(float *value, bool *flag) pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); } +static stat_t _casey_jones(float speed) +{ + if (speed < spindle.speed_min) { return (STAT_SPINDLE_SPEED_BELOW_MINIMUM); } + if (speed > spindle.speed_max) { return (STAT_SPINDLE_SPEED_MAX_EXCEEDED); } + return (STAT_OK); +} + +stat_t spindle_speed_immediate(float speed) +{ + ritorno(_casey_jones(speed)); + float value[] = { speed }; + _exec_spindle_speed(value, nullptr); + return (STAT_OK); +} + +stat_t spindle_speed_sync(float speed) +{ + ritorno(_casey_jones(speed)); + float value[] = { speed }; + mp_queue_command(_exec_spindle_speed, value, nullptr); + return (STAT_OK); +} + /*********************************************************************************** * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ @@ -266,7 +247,7 @@ static float _get_spindle_pwm (spSpindle_t *sp, pwmControl_t *pwm) } */ -static float _get_spindle_pwm (spState state, spState direction) +static float _get_spindle_pwm (spControl state, spControl direction) { float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; if (direction == SPINDLE_CW ) { @@ -317,18 +298,18 @@ stat_t spindle_override_control(const float P_word, const bool P_flag) // M51 if (P_word > SPINDLE_OVERRIDE_MAX) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - spindle.sso_factor = P_word; // P word is valid, store it. + spindle.override_factor = P_word; // P word is valid, store it. new_override = true; } } if (cm->gmx.m48_enable) { // if master enable is ON - if (new_enable && (new_override || !spindle.sso_enable)) { // 3 cases to start a ramp - spindle_start_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.sso_factor); - } else if (spindle.sso_enable && !new_enable) { // case to turn off the ramp + if (new_enable && (new_override || !spindle.override_enable)) { // 3 cases to start a ramp + spindle_start_override(SPINDLE_OVERRIDE_RAMP_TIME, spindle.override_factor); + } else if (spindle.override_enable && !new_enable) { // case to turn off the ramp spindle_end_override(SPINDLE_OVERRIDE_RAMP_TIME); } } - spindle.sso_enable = new_enable; // always update the enable state + spindle.override_enable = new_enable; // always update the enable state return (STAT_OK); } @@ -366,53 +347,23 @@ stat_t sp_set_spdp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_pola stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1)); } -stat_t sp_get_spdw(nvObj_t *nv) { return(get_float(nv, spindle.dwell_seconds)); } -stat_t sp_set_spdw(nvObj_t *nv) { return(set_float_range(nv, spindle.dwell_seconds, 0, SPINDLE_DWELL_MAX)); } +stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } +stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } stat_t sp_get_spsm(nvObj_t *nv) { return(get_float(nv, spindle.speed_max)); } stat_t sp_set_spsm(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_max, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } -stat_t sp_get_ssoe(nvObj_t *nv) { return(get_int(nv, spindle.sso_enable)); } -stat_t sp_set_ssoe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.sso_enable, 0, 1)); } -stat_t sp_get_sso(nvObj_t *nv) { return(get_float(nv, spindle.sso_factor)); } -stat_t sp_set_sso(nvObj_t *nv) { return(set_float_range(nv, spindle.sso_factor, SPINDLE_OVERRIDE_MIN, SPINDLE_OVERRIDE_MAX)); } - -/* These are provided as a way to set and clear spindle states without using M commands - * SPD is useful because disabling a spindle (M5) does not change the direction, only the enable. - */ +stat_t sp_get_spoe(nvObj_t *nv) { return(get_int(nv, spindle.override_enable)); } +stat_t sp_set_spoe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.override_enable, 0, 1)); } +stat_t sp_get_spo(nvObj_t *nv) { return(get_float(nv, spindle.override_factor)); } +stat_t sp_set_spo(nvObj_t *nv) { return(set_float_range(nv, spindle.override_factor, SPINDLE_OVERRIDE_MIN, SPINDLE_OVERRIDE_MAX)); } +// These are provided as a way to view and control spindles without using M commands +stat_t sp_get_spc(nvObj_t *nv) { return(get_int(nv, spindle.state)); } +stat_t sp_set_spc(nvObj_t *nv) { return(spindle_control_immediate((spControl)nv->value)); } stat_t sp_get_sps(nvObj_t *nv) { return(get_float(nv, spindle.speed)); } -stat_t sp_set_sps(nvObj_t *nv) -{ - set_float_range(nv, spindle.speed, spindle.speed_min, spindle.speed_max); - float value[] = { spindle.speed, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_speed(value, flags); - return (STAT_OK); -} - -stat_t sp_get_spe(nvObj_t *nv) { return(get_int(nv, spindle.state)); } -/* -stat_t sp_set_spe(nvObj_t *nv) -{ -// set_int(nv, (uint8_t &)spindle.state, 0, 1); - float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; - _exec_spindle_control(value, flags); - return (STAT_OK); -} -*/ - -stat_t sp_get_spd(nvObj_t *nv) { return(get_int(nv, spindle.direction)); } -stat_t sp_set_spd(nvObj_t *nv) -{ - set_int(nv, (uint8_t &)spindle.direction, 0, 1); - float value[] = { (float)spindle.state, (float)spindle.direction, 0,0,0,0 }; - bool flags[] = { 1,1,0,0,0,0 }; - _exec_spindle_control(value, flags); - return (STAT_OK); -} +stat_t sp_set_sps(nvObj_t *nv) { return(spindle_speed_immediate(nv->value)); } /*********************************************************************************** * TEXT MODE SUPPORT @@ -421,30 +372,28 @@ stat_t sp_set_spd(nvObj_t *nv) #ifdef __TEXT_MODE +const char fmt_spc[] = "[spc] spindle control:%12d [0=OFF,1=CW,2=CCW]\n"; +const char fmt_sps[] = "[sps] spindle speed:%14.0f rpm\n"; const char fmt_spmo[] = "[spmo] spindle mode%16d [0=disabled,1=plan-to-stop,2=continuous]\n"; const char fmt_spep[] = "[spep] spindle enable polarity%5d [0=active_low,1=active_high]\n"; const char fmt_spdp[] = "[spdp] spindle direction polarity%2d [0=CW_low,1=CW_high]\n"; const char fmt_spph[] = "[spph] spindle pause on hold%7d [0=no,1=pause_on_hold]\n"; -const char fmt_spdw[] = "[spdw] spindle dwell time%12.1f seconds\n"; +const char fmt_spde[] = "[spde] spindle spinup delay%10.1f seconds\n"; const char fmt_spsn[] = "[spsn] spindle speed min%14.2f rpm\n"; const char fmt_spsm[] = "[spsm] spindle speed max%14.2f rpm\n"; -const char fmt_ssoe[] = "[ssoe] spindle speed override ena%2d [0=disable,1=enable]\n"; -const char fmt_sso[] = "[sso] spindle speed override%10.3f [0.050 < sso < 2.000]\n"; -const char fmt_sps[] = "Spindle Speed: %7.0f rpm\n"; -const char fmt_spe[] = "Spindle Enable:%7d [0=OFF,1=ON,2=PAUSE]\n"; -const char fmt_spd[] = "Spindle Direction:%4d [0=CW,1=CCW]\n"; +const char fmt_spoe[] = "[spoe] spindle speed override ena%2d [0=disable,1=enable]\n"; +const char fmt_spo[] = "[spo] spindle speed override%10.3f [0.050 < spo < 2.000]\n"; +void sp_print_spc(nvObj_t *nv) { text_print(nv, fmt_spc);} // TYPE_INT +void sp_print_sps(nvObj_t *nv) { text_print(nv, fmt_sps);} // TYPE_FLOAT void sp_print_spmo(nvObj_t *nv) { text_print(nv, fmt_spmo);} // TYPE_INT void sp_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT void sp_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT void sp_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT -void sp_print_spdw(nvObj_t *nv) { text_print(nv, fmt_spdw);} // TYPE_FLOAT +void sp_print_spde(nvObj_t *nv) { text_print(nv, fmt_spde);} // TYPE_FLOAT void sp_print_spsn(nvObj_t *nv) { text_print(nv, fmt_spsn);} // TYPE_FLOAT void sp_print_spsm(nvObj_t *nv) { text_print(nv, fmt_spsm);} // TYPE_FLOAT -void sp_print_ssoe(nvObj_t *nv) { text_print(nv, fmt_ssoe);} // TYPE INT -void sp_print_sso(nvObj_t *nv) { text_print(nv, fmt_sso);} // TYPE FLOAT -void sp_print_spe(nvObj_t *nv) { text_print(nv, fmt_spe);} // TYPE_INT -void sp_print_spd(nvObj_t *nv) { text_print(nv, fmt_spd);} // TYPE_INT -void sp_print_sps(nvObj_t *nv) { text_print(nv, fmt_sps);} // TYPE_FLOAT +void sp_print_spoe(nvObj_t *nv) { text_print(nv, fmt_spoe);} // TYPE INT +void sp_print_spo(nvObj_t *nv) { text_print(nv, fmt_spo);} // TYPE FLOAT #endif // __TEXT_MODE diff --git a/g2core/spindle.h b/g2core/spindle.h index 56dac343..42a0b1a4 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -28,6 +28,12 @@ #ifndef SPINDLE_H_ONCE #define SPINDLE_H_ONCE +#define SPINDLE_OVERRIDE_ENABLE false +#define SPINDLE_OVERRIDE_FACTOR 1.00 +#define SPINDLE_OVERRIDE_MIN 0.05 // 5% +#define SPINDLE_OVERRIDE_MAX 2.00 // 200% +#define SPINDLE_OVERRIDE_RAMP_TIME 1 // change sped in seconds + typedef enum { SPINDLE_DISABLED = 0, // spindle will not operate SPINDLE_PLAN_TO_STOP, // spindle operating, plans to stop @@ -35,22 +41,19 @@ typedef enum { } spMode; #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS -// spState is used for multiple purposes: -// - request the spindle operation (OFF, CW, CCW) -// - request PAUSE and RESUME +// spControl is used for multiple purposes: +// - request a spindle operation (OFF, CW, CCW, PAUSE, RESUME) // - run the spindle state machine for spindle wait states -// - store current direction (1=CW, 2=CCW) in spindle.direction +// - CW and CCW values are stored as current direction in spindle.direction typedef enum { // how spindle controls are presented by the Gcode parser SPINDLE_OFF = 0, // M5 SPINDLE_CW = 1, // M3 and store CW to spindle.direction SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW - SPINDLE_WAIT // handle transient WAIT states -} spState; - -// SPINDLE_ON is either of SPINDLE_CW or SPINDLE_CCW -//#define SPINDLE_ON(s) ((s == SPINDLE_CW) || (s == SPINDLE__CCW)) + SPINDLE_WAIT // handle transient WAIT states (not an action state) +} spControl; +#define SPINDLE_ACTION_MAX SPINDLE_RESUME // *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h // These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 @@ -61,15 +64,6 @@ typedef enum { // Note: These values agree with SPINDLE_ACTIVE_HIGH = 1, // Will set output to 1 to enable the spindle or CW direction } spPolarity; -/* -typedef enum { // basic spindle state machine. Do not change this enum - SPINDLE_OFF = 0, - SPINDLE_ON = 1, // spindle on and at speed - SPINDLE_PAUSE = 2, // meaning it was on and now it's off - SPINDLE_WAITING = 3 // spindle not at speed yet -} spState; -*/ - typedef enum { // electronic speed controller for some spindles ESC_ONLINE = 0, ESC_OFFLINE, @@ -78,33 +72,29 @@ typedef enum { // electronic speed controller for some spindles ESC_LOCKOUT_AND_REBOOTING, } ESCState; -#define SPINDLE_OVERRIDE_ENABLE false -#define SPINDLE_OVERRIDE_FACTOR 1.00 -#define SPINDLE_OVERRIDE_MIN 0.05 // 5% -#define SPINDLE_OVERRIDE_MAX 2.00 // 200% -#define SPINDLE_OVERRIDE_RAMP_TIME 1 // change sped in seconds - /* * Spindle control structure */ typedef struct spSpindle { - spMode mode; // spindle operating mode - spState state; // OFF, ON, PAUSE, RESUME, WAIT - spState direction; // 1=CW, 2=CCW (subset of above state) + spMode mode; // {spm:} spindle operating mode + spControl state; // {spc:} OFF, ON, PAUSE, RESUME, WAIT + spControl direction; // 1=CW, 2=CCW (subset of above state) - float speed; // S in RPM - float speed_min; // minimum settable spindle speed - float speed_max; // maximum settable spindle speed + float speed; // {sps:} S in RPM + float speed_min; // {spsn:} minimum settable spindle speed + float speed_max; // {spsm:} maximum settable spindle speed - spPolarity enable_polarity; // 0=active low, 1=active high - spPolarity dir_polarity; // 0=clockwise low, 1=clockwise high - float dwell_seconds; // dwell on spindle resume - bool pause_on_hold; // pause on feedhold + spPolarity enable_polarity; // {spep:} 0=active low, 1=active high + spPolarity dir_polarity; // {spdp:} 0=clockwise low, 1=clockwise high + bool pause_on_hold; // {spph:} pause on feedhold + float spinup_delay; // {spde:} optional delay on spindle start (set to 0 to disable) + float spindown_delay; // {spds:} optional delay on spindle stop (set to 0 to disable) + float reversal_delay; // {spdr:} optional delay on direction reversal (set to 0 to disable) - bool sso_enable; // TRUE = spindle speed override enabled (see also m48_enable in canonical machine) - float sso_factor; // 1.0000 x S spindle speed. Go up or down from there + bool override_enable; // {spoe:} TRUE = spindle speed override enabled (see also m48_enable in canonical machine) + float override_factor; // {spo:} 1.0000 x S spindle speed. Go up or down from there // Spindle speed controller variables ESCState esc_state; // state management for ESC controller @@ -121,8 +111,8 @@ extern spSpindle_t spindle; void spindle_init(); void spindle_reset(); -stat_t spindle_control_immediate(spState control); -stat_t spindle_control_sync(spState control); +stat_t spindle_control_immediate(spControl control); +stat_t spindle_control_sync(spControl control); stat_t spindle_speed_immediate(float speed); // S parameter stat_t spindle_speed_sync(float speed); // S parameter @@ -143,24 +133,22 @@ stat_t sp_set_spdp(nvObj_t *nv); stat_t sp_get_spph(nvObj_t *nv); stat_t sp_set_spph(nvObj_t *nv); -stat_t sp_get_spdw(nvObj_t *nv); -stat_t sp_set_spdw(nvObj_t *nv); +stat_t sp_get_spde(nvObj_t *nv); +stat_t sp_set_spde(nvObj_t *nv); stat_t sp_get_spsn(nvObj_t *nv); stat_t sp_set_spsn(nvObj_t *nv); stat_t sp_get_spsm(nvObj_t *nv); stat_t sp_set_spsm(nvObj_t *nv); -stat_t sp_get_ssoe(nvObj_t* nv); -stat_t sp_set_ssoe(nvObj_t* nv); -stat_t sp_get_sso(nvObj_t* nv); -stat_t sp_set_sso(nvObj_t* nv); +stat_t sp_get_spoe(nvObj_t* nv); +stat_t sp_set_spoe(nvObj_t* nv); +stat_t sp_get_spo(nvObj_t* nv); +stat_t sp_set_spo(nvObj_t* nv); +stat_t sp_get_spc(nvObj_t* nv); +stat_t sp_set_spc(nvObj_t* nv); stat_t sp_get_sps(nvObj_t* nv); stat_t sp_set_sps(nvObj_t* nv); -stat_t sp_get_spe(nvObj_t* nv); -stat_t sp_set_spe(nvObj_t* nv); -stat_t sp_get_spd(nvObj_t* nv); -stat_t sp_set_spd(nvObj_t* nv); /*--- text_mode support functions ---*/ @@ -170,14 +158,13 @@ stat_t sp_set_spd(nvObj_t* nv); void sp_print_spep(nvObj_t* nv); void sp_print_spdp(nvObj_t* nv); void sp_print_spph(nvObj_t* nv); - void sp_print_spdw(nvObj_t* nv); + void sp_print_spde(nvObj_t* nv); void sp_print_spsn(nvObj_t* nv); void sp_print_spsm(nvObj_t* nv); - void sp_print_ssoe(nvObj_t* nv); - void sp_print_sso(nvObj_t* nv); + void sp_print_spoe(nvObj_t* nv); + void sp_print_spo(nvObj_t* nv); + void sp_print_spc(nvObj_t* nv); void sp_print_sps(nvObj_t* nv); - void sp_print_spe(nvObj_t* nv); - void sp_print_spd(nvObj_t* nv); #else @@ -185,14 +172,13 @@ stat_t sp_set_spd(nvObj_t* nv); #define sp_print_spep tx_print_stub #define sp_print_spdp tx_print_stub #define sp_print_spph tx_print_stub - #define sp_print_spdw tx_print_stub + #define sp_print_spde tx_print_stub #define sp_print_spsn tx_print_stub #define sp_print_spsm tx_print_stub - #define sp_print_ssoe tx_print_stub - #define sp_print_spe tx_print_stub + #define sp_print_spoe tx_print_stub + #define sp_print_spo tx_print_stub + #define sp_print_spc tx_print_stub #define sp_print_sps tx_print_stub - #define sp_print_sso tx_print_stub - #define sp_print_spd tx_print_stub #endif // __TEXT_MODE From 831a8c9011da020b1fad9bad798922d3a709316a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 14 Jan 2017 12:38:33 -0500 Subject: [PATCH 076/283] Testing and tweaks --- g2core/settings/settings_default.h | 8 +- g2core/spindle.cpp | 118 +++++++++++++---------------- 2 files changed, 58 insertions(+), 68 deletions(-) diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index f87a3ee7..b0333b6f 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -892,16 +892,16 @@ #define P1_CW_PHASE_HI 0.17 #endif #ifndef P1_CCW_SPEED_LO -#define P1_CCW_SPEED_LO 0.0 +#define P1_CCW_SPEED_LO 7900 // 0.0 #endif #ifndef P1_CCW_SPEED_HI -#define P1_CCW_SPEED_HI 0.0 +#define P1_CCW_SPEED_HI 12800 // 0.0 #endif #ifndef P1_CCW_PHASE_LO -#define P1_CCW_PHASE_LO 0.1 +#define P1_CCW_PHASE_LO 0.13 // 0.1 #endif #ifndef P1_CCW_PHASE_HI -#define P1_CCW_PHASE_HI 0.1 +#define P1_CCW_PHASE_HI 0.17 // 0.1 #endif #ifndef P1_PWM_PHASE_OFF #define P1_PWM_PHASE_OFF 0.1 diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 63f32e50..08211965 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -43,9 +43,7 @@ spSpindle_t spindle; /**** Static functions ****/ -static void _exec_spindle_speed(float *value, bool *flag); -//static void _exec_spindle_control(float *value, bool *flag); -static float _get_spindle_pwm (spControl state, spControl direction); +static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm); /*********************************************************************************** * spindle_init() @@ -62,9 +60,7 @@ void spindle_init() void spindle_reset() { - float value[AXES] = { 0,0,0,0,0,0 }; // set spindle speed to zero - bool flags[] = { 1,0,0,0,0,0 }; - _exec_spindle_speed(value, flags); + spindle_speed_immediate(0); spindle_control_immediate(SPINDLE_OFF); } @@ -148,7 +144,7 @@ static void _exec_spindle_control(float *value, bool *flag) } else { spindle_enable_pin.set(); // drive pin HI } - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); } stat_t spindle_control_immediate(spControl control) @@ -160,7 +156,6 @@ stat_t spindle_control_immediate(spControl control) stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, CCW { -// float value[] = { (float)control, 0,0,0,0,0 }; float value[] = { (float)control }; mp_queue_command(_exec_spindle_control, value, nullptr); @@ -179,13 +174,7 @@ stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, static void _exec_spindle_speed(float *value, bool *flag) { spindle.speed = value[0]; -/* - if (flag[1]) { - spindle.direction = (spDir)value[1]; - } -*/ - // update spindle speed if we're running - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle.state, spindle.direction)); + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); } static stat_t _casey_jones(float speed) @@ -214,70 +203,71 @@ stat_t spindle_speed_sync(float speed) /*********************************************************************************** * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ + +static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm) +{ + float speed_lo, speed_hi, phase_lo, phase_hi; + if (_spindle.direction == SPINDLE_CW ) { + speed_lo = _pwm.c[PWM_1].cw_speed_lo; + speed_hi = _pwm.c[PWM_1].cw_speed_hi; + phase_lo = _pwm.c[PWM_1].cw_phase_lo; + phase_hi = _pwm.c[PWM_1].cw_phase_hi; + } else { // if (direction == SPINDLE_CCW ) { + speed_lo = _pwm.c[PWM_1].ccw_speed_lo; + speed_hi = _pwm.c[PWM_1].ccw_speed_hi; + phase_lo = _pwm.c[PWM_1].ccw_phase_lo; + phase_hi = _pwm.c[PWM_1].ccw_phase_hi; + } + + if ((_spindle.state == SPINDLE_CW) || (_spindle.state == SPINDLE_CCW)) { + // clamp spindle speed to lo/hi range + if (_spindle.speed < speed_lo) { + _spindle.speed = speed_lo; + } + if (_spindle.speed > speed_hi) { + _spindle.speed = speed_hi; + } + // normalize speed to [0..1] + float speed = (_spindle.speed - speed_lo) / (speed_hi - speed_lo); + return ((speed * (phase_hi - phase_lo)) + phase_lo); + } else { + return (_pwm.c[PWM_1].phase_off); + } +} + /* -static float _get_spindle_pwm (spSpindle_t *sp, pwmControl_t *pwm) +static float _get_spindle_pwm (spSpindle_t *sp, pwmControl_t *_pwm) { float speed_lo, speed_hi, phase_lo, phase_hi; if (sp->direction == SPINDLE_CW ) { - speed_lo = pwm->c[PWM_1].cw_speed_lo; - speed_hi = pwm->c[PWM_1].cw_speed_hi; - phase_lo = pwm->c[PWM_1].cw_phase_lo; - phase_hi = pwm->c[PWM_1].cw_phase_hi; - } else { // if (direction == SPINDLE_CCW ) { - speed_lo = pwm->c[PWM_1].ccw_speed_lo; - speed_hi = pwm->c[PWM_1].ccw_speed_hi; - phase_lo = pwm->c[PWM_1].ccw_phase_lo; - phase_hi = pwm->c[PWM_1].ccw_phase_hi; + speed_lo = _pwm->c[PWM_1].cw_speed_lo; + speed_hi = _pwm->c[PWM_1].cw_speed_hi; + phase_lo = _pwm->c[PWM_1].cw_phase_lo; + phase_hi = _pwm->c[PWM_1].cw_phase_hi; + } else { // if (direction == SPINDLE_CCW ) { + speed_lo = _pwm->c[PWM_1].ccw_speed_lo; + speed_hi = _pwm->c[PWM_1].ccw_speed_hi; + phase_lo = _pwm->c[PWM_1].ccw_phase_lo; + phase_hi = _pwm->c[PWM_1].ccw_phase_hi; } if ((sp->state == SPINDLE_CW) || (sp->state == SPINDLE_CCW)) { // clamp spindle speed to lo/hi range - if (spindle->speed < speed_lo) { - spindle->speed = speed_lo; + if (sp->speed < speed_lo) { + sp->speed = speed_lo; } - if (spindle->speed > speed_hi) { - spindle->speed = speed_hi; + if (sp->speed > speed_hi) { + sp->speed = speed_hi; } // normalize speed to [0..1] - float speed = (spindle->speed - speed_lo) / (speed_hi - speed_lo); - return (speed * (phase_hi - phase_lo)) + phase_lo; - } else { - return pwm->c[PWM_1].phase_off; - } -} -*/ - -static float _get_spindle_pwm (spControl state, spControl direction) -{ - float speed_lo=0, speed_hi=0, phase_lo=0, phase_hi=0; - if (direction == SPINDLE_CW ) { - speed_lo = pwm.c[PWM_1].cw_speed_lo; - speed_hi = pwm.c[PWM_1].cw_speed_hi; - phase_lo = pwm.c[PWM_1].cw_phase_lo; - phase_hi = pwm.c[PWM_1].cw_phase_hi; - } else { // if (direction == SPINDLE_CCW ) { - speed_lo = pwm.c[PWM_1].ccw_speed_lo; - speed_hi = pwm.c[PWM_1].ccw_speed_hi; - phase_lo = pwm.c[PWM_1].ccw_phase_lo; - phase_hi = pwm.c[PWM_1].ccw_phase_hi; - } - - if ((state == SPINDLE_CW) || (state == SPINDLE_CCW)) { - // clamp spindle speed to lo/hi range - if (spindle.speed < speed_lo) { - spindle.speed = speed_lo; - } - if (spindle.speed > speed_hi) { - spindle.speed = speed_hi; - } - // normalize speed to [0..1] - float speed = (spindle.speed - speed_lo) / (speed_hi - speed_lo); - return (speed * (phase_hi - phase_lo)) + phase_lo; + float speed = (sp->speed - speed_lo) / (speed_hi - speed_lo); + return ((speed * (phase_hi - phase_lo)) + phase_lo); } else { - return pwm.c[PWM_1].phase_off; + return (_pwm->c[PWM_1].phase_off); } } +*/ /*********************************************************************************** * spindle_override_control() * spindle_start_override() From 6551f4e232952fa87e2945e255614bd7e03c6ea9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 14 Jan 2017 15:14:48 -0500 Subject: [PATCH 077/283] Testing and tweaking --- g2core/config_app.cpp | 1 - g2core/cycle_feedhold.cpp | 20 +++++++------------- g2core/spindle.cpp | 37 ++++--------------------------------- g2core/spindle.h | 3 ++- 4 files changed, 13 insertions(+), 48 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index a615368f..42167c15 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -840,7 +840,6 @@ const cfgItem_t cfgArray[] = { { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spinup delay // { "sp","spds", _fip, 2, sp_print_spds, sp_get_spds, sp_set_spds, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spindown delay -// { "sp","spdr", _fip, 2, sp_print_spdr, sp_get_spdr, sp_set_spdr, (float *)&cs.null, SPINDLE_DWELL_TIME }, // direction reversal delay { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 9fd22510..9709249c 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -249,11 +249,10 @@ stat_t cm_switch_to_hold_context() cm_straight_traverse(target, flags); cm_set_distance_mode(stored_distance_mode); } - - // optional spindle stop - if (spindle.pause_on_hold) { - - } + + spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause + // coolant_control_sync(COOLANT_PAUSE); // optional coolant pause + return (STAT_OK); } @@ -280,14 +279,9 @@ stat_t cm_return_from_hold_context() // LATER: if value == true return with } // *** While still in secondary machine: -/* - if (cm->machine_state == MACHINE_ALARM) { - cm_spindle_off_immediate(); - cm_coolant_off_immediate(); -*/ - // restart spindle (with optional dwell) - - // restart coolant + + spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused +// coolant_control_sync(COOLANT_RESUME); // resume coolant if paused // perform the G30 move and queue a wait float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 08211965..b60a26d9 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -114,6 +114,10 @@ static void _exec_spindle_control(float *value, bool *flag) if ((control == SPINDLE_RESUME) && (spindle.state != SPINDLE_PAUSE)) { return; } + if ((control == SPINDLE_PAUSE) && (spindle.state != SPINDLE_OFF)) { + return; + } + spindle.state = control; // record new spindle state uint8_t on_bit = SPINDLE_OFF; // default to off int8_t dir_bit = -1; // -1 will skip setting the direction @@ -235,39 +239,6 @@ static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm) } } -/* -static float _get_spindle_pwm (spSpindle_t *sp, pwmControl_t *_pwm) -{ - float speed_lo, speed_hi, phase_lo, phase_hi; - if (sp->direction == SPINDLE_CW ) { - speed_lo = _pwm->c[PWM_1].cw_speed_lo; - speed_hi = _pwm->c[PWM_1].cw_speed_hi; - phase_lo = _pwm->c[PWM_1].cw_phase_lo; - phase_hi = _pwm->c[PWM_1].cw_phase_hi; - } else { // if (direction == SPINDLE_CCW ) { - speed_lo = _pwm->c[PWM_1].ccw_speed_lo; - speed_hi = _pwm->c[PWM_1].ccw_speed_hi; - phase_lo = _pwm->c[PWM_1].ccw_phase_lo; - phase_hi = _pwm->c[PWM_1].ccw_phase_hi; - } - - if ((sp->state == SPINDLE_CW) || (sp->state == SPINDLE_CCW)) { - // clamp spindle speed to lo/hi range - if (sp->speed < speed_lo) { - sp->speed = speed_lo; - } - if (sp->speed > speed_hi) { - sp->speed = speed_hi; - } - // normalize speed to [0..1] - float speed = (sp->speed - speed_lo) / (speed_hi - speed_lo); - return ((speed * (phase_hi - phase_lo)) + phase_lo); - } else { - return (_pwm->c[PWM_1].phase_off); - } -} - -*/ /*********************************************************************************** * spindle_override_control() * spindle_start_override() diff --git a/g2core/spindle.h b/g2core/spindle.h index 42a0b1a4..8f6d1a4d 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -51,7 +51,8 @@ typedef enum { // how spindle controls are presented by the Gco SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW - SPINDLE_WAIT // handle transient WAIT states (not an action state) + SPINDLE_SPINUP, // spindle is coming up to speed + SPINDLE_SPINDOWN // spindle is spinning down to stop } spControl; #define SPINDLE_ACTION_MAX SPINDLE_RESUME From c735a27cef986bab2fc827b13aee2548ce572491 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Jan 2017 07:01:43 -0500 Subject: [PATCH 078/283] Different approach to _exec_spindle_control(); Basic function only - no spinup or spindown or reverses --- g2core/spindle.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++ g2core/spindle.h | 14 +++++- 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index b60a26d9..f4731d33 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -104,6 +104,38 @@ void spindle_reset() * - Do we need a spin-down for direction reversal? * - Should the JSON be able to pause and resume? */ +/* State/Control matrix. Read "If you are in state X and get control Y do action Z" + + Control: OFF CW CCW PAUSE RESUME SPINUP SPINDN + State: |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + OFF | RELOAD | CW | CCW | OFF | NOP | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + CW | OFF | NOP | REVERSE | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + CCW | OFF | REVERSE | NOP | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + PAUSE | OFF | CW | CCW | NOP | RESUME | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + RESUME | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + SPINUP | OFF | NOP|CW | NOP|CCW | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + SPINDN | NOP | NOP|CW | NOP|CCW | NOP(OFF) | NOP(OFF) | XXXXXXXXX | XXXXXXXXX | + |-----------|-----------|-----------|-----------|-----------|-----------|-----------| + NOP(OFF)s are effectively OFFs + Actions: + - NOP No operation, ignore + - NOPCW No-op if spinning up to CW. If the spinning to CCW perform a REVERSE + - NOPCCW No-op if spinning up to CCW. If the spinning to CW perform a REVERSE + - OFF Turn spindle off + - CW Turn spindle on clockwise + - CCW Turn spindle on counterclockwise + - PAUSE Turn off spindle, enter PAUSE state + - RESUME Turn spindle n CW or CCW as before + - REV Reverse spindle direction (implies a cycle) + - RELOAD Reload (LOAD) settings from spindle structure to spindle bits + - XXXXXXX Impossible state. RESUME is not a state and PSINOP/SPINDN are not inputs + */ static void _exec_spindle_control(float *value, bool *flag) { @@ -111,6 +143,81 @@ static void _exec_spindle_control(float *value, bool *flag) if (control >= SPINDLE_ACTION_MAX) { return; } + + uint matrix[35] = { SPINDLE_LOAD, SPINDLE_CW, SPINDLE_CCW, SPINDLE_OFF, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_NOP, SPINDLE_REV, SPINDLE_PAUSE, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_REV, SPINDLE_NOP, SPINDLE_PAUSE, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_RESUME, + SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_PAUSE, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_NOP, SPINDLE_NOP + }; + uint8_t index = ((spindle.state & 0x07) * 5) + control; + uint8_t action = matrix[index]; + + spindle.state = control; // record new spindle state + uint8_t on_bit = SPINDLE_OFF; // default to off + int8_t dir_bit = -1; // -1 will skip setting the direction + + switch (action) { + case SPINDLE_NOP: { return; } + case SPINDLE_OFF: { break; } // on_nit and state are already set for this case + case SPINDLE_PAUSE : { break; } // on_nit and state are also already set for this case + + case SPINDLE_CW: case SPINDLE_CCW: { + on_bit = 1; // use 1 (not true) - this is a bitmask + dir_bit = control-1; // adjust direction to be used as a bitmask + spindle.direction = control; + break; + } + + case SPINDLE_RESUME: { + on_bit = 1; + dir_bit = spindle.direction-1; // Note: spindle direction was stored as '1' & '2' + spindle.state = spindle.direction; + break; + } + + case SPINDLE_LOAD: { // can be used to change enable and dir polarities + dir_bit = control-1; // adjust direction to be used as a bitmask + break; + } + + case SPINDLE_REV: { // for now we treat this as a simple CW or CCW request + on_bit = 1; // use 1 (not true) - this is a bitmask + dir_bit = control-1; // adjust direction to be used as a bitmask + spindle.direction = control; + break; + } + case SPINDLE_NOPCW: { return; } // reversal case not handled yet + case SPINDLE_NOPCCW: { return; } // reversal case not handled yet + } + + // Apply the enable and direction bits and adjust the PWM as required + + // set the direction first + if (dir_bit >= 0) { + if (dir_bit ^ spindle.dir_polarity) { + spindle_dir_pin.set(); // drive pin HI + } else { + spindle_dir_pin.clear(); // drive pin LO + } + } + + // set on/off + if (on_bit ^ spindle.enable_polarity) { + spindle_enable_pin.clear(); // drive pin LO + } else { + spindle_enable_pin.set(); // drive pin HI + } + pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); +} + +/* + spControl control = (spControl)value[0]; + if (control >= SPINDLE_ACTION_MAX) { + return; + } if ((control == SPINDLE_RESUME) && (spindle.state != SPINDLE_PAUSE)) { return; } @@ -150,6 +257,7 @@ static void _exec_spindle_control(float *value, bool *flag) } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); } +*/ stat_t spindle_control_immediate(spControl control) { diff --git a/g2core/spindle.h b/g2core/spindle.h index 8f6d1a4d..a16844f5 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -41,10 +41,11 @@ typedef enum { } spMode; #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS -// spControl is used for multiple purposes: +// spControl enum is used for multiple purposes: // - request a spindle operation (OFF, CW, CCW, PAUSE, RESUME) // - run the spindle state machine for spindle wait states // - CW and CCW values are stored as current direction in spindle.direction +// - NOP, REVERSE and RELOAD are operations an are not stes or controls typedef enum { // how spindle controls are presented by the Gcode parser SPINDLE_OFF = 0, // M5 SPINDLE_CW = 1, // M3 and store CW to spindle.direction @@ -52,10 +53,19 @@ typedef enum { // how spindle controls are presented by the Gco SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW SPINDLE_SPINUP, // spindle is coming up to speed - SPINDLE_SPINDOWN // spindle is spinning down to stop + SPINDLE_SPINDOWN, // spindle is spinning down to stop + + SPINDLE_NOP, // no operation + SPINDLE_NOPCW, // no operation, starts from clockwise + SPINDLE_NOPCCW, // no operation, starts from counterclockwise + SPINDLE_REV, // operation to reverse spindle direction + SPINDLE_LOAD // operation to reload spindle structure into spindle bits + } spControl; #define SPINDLE_ACTION_MAX SPINDLE_RESUME + + // *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h // These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 // See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types From cbd34dfb5813ad03c1cb913d9ce9b306e94d980b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Jan 2017 09:42:37 -0500 Subject: [PATCH 079/283] Testing pause and resume cases. Check. --- g2core/spindle.cpp | 200 +++++++++++++++++++-------------------------- g2core/spindle.h | 9 +- 2 files changed, 87 insertions(+), 122 deletions(-) diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index f4731d33..cbed79c5 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -45,12 +45,19 @@ spSpindle_t spindle; static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm); +#define SPINDLE_DIRECTION_ASSERT \ + if ((spindle.direction < SPINDLE_CW) || (spindle.direction > SPINDLE_CCW)) { \ + spindle.direction = SPINDLE_CW; \ + } + /*********************************************************************************** * spindle_init() * spindle_reset() - stop spindle, set speed to zero, and reset values */ void spindle_init() { + SPINDLE_DIRECTION_ASSERT // spindle needs an initial direction + if( pwm.c[PWM_1].frequency < 0 ) { pwm.c[PWM_1].frequency = 0; } @@ -70,45 +77,47 @@ void spindle_reset() * _exec_spindle_control() - actually execute the spindle command * * Basic operation: Spindle function is effected by _exec_spindle_control(). - * Spindle_control_immediate() runs command as soon as it's received. - * Spindle_control_sync() inserts spindle move into the planner, and handles optional dwells + * Spindle_control_immediate() performs the control as soon as it's received. + * Spindle_control_sync() inserts spindle move into the planner, and handles spinup and spindowns * * Valid inputs to Spindle_control_immediate() and Spindle_control_sync() are: * * - SPINDLE_OFF turns off spindle and sets spindle state to SPINDLE_OFF. + * This will also re-load enable and direction polarity to the pins if they have changed. * The spindle.direction value is not affected (although this doesn't really matter). * - * - SPINDLE_CW or SPINDLE_CCW turns spindle on and sets direction accordingly. - * If spindle_control_sync() has a non-zero dwell a dwell move is added to the planner queue. - * In this case spindle.state is SPINDLE_WAIT until move is "played", and dwell completes. - * spindle_control_immediate() has no dwell behavior. + * - SPINDLE_CW or SPINDLE_CCW turns sets direction accordingly and spindle on. + * In spindle_control_sync() a non-zero spinup delay puts a dwell in the planner queue. + * In this case spindle.state is SPINDLE_SPINUP until spindle command is "played", and dwell completes. + * Spindle_control_immediate() has no spinup delay or dwell behavior. * - * - SPINDLE_PAUSE is only applicable to CW and CCW states. It forces the spindle OFF and + * - SPINDLE_PAUSE is only applicable to CW, CCW and SPINUP states. It forces the spindle OFF and * sets spindle.state to PAUSE. If PAUSE is received when not in CW or CCW state it is ignored. * * - SPINDLE_RESUME, if in a PAUSE state, reverts to previous SPINDLE_CW or SPINDLE_CCW. * The SPEED is not changed, and if it were changed in the interim the "new" speed is used. - * If RESUME is received from spindle_control_sync() the usual dwell and WAIT behavior occurs. + * If RESUME is received from spindle_control_sync() the usual spinup delay behavior occurs. * If RESUME is received when not in a PAUSED state it is ignored. This recognizes that the main * reason an immediate command would be issued - either manually by the user or by an alarm or * some other program function - is to stop a spindle. So the Resume should be ignored for safety. * * Notes: - * - Changes to polarities and other setup parameters take effect on the next spindle action. - * There is no reason to make these occur instantly. + * - Since it's possible to queue a sync'd control, and then set any spindle state with an + * immediate() before the queued command is reached, _exec_spindle_control() must gracefully + * handle any arbitrary state transition (not just the "legal" ones). + * + * - The spinup and spindown rows are present, but are not implemented unless we findwe need them. + * It's easy enough to set these flags using the bit vector passed from sync(), but unsetting + * them once the delay is complete would take some more work. * - * - Since it's possible to queue a sync'd control, then set any control value with an - * immediate() before the queued command is reached, _exec_spindle_control() must gracefully - * handle any arbitrary state transition (not just the "legal" ones) - * - * - Do we need a spin-down for direction reversal? - * - Should the JSON be able to pause and resume? + * Q: Do we need a spin-down for direction reversal? + * Q: Should the JSON be able to pause and resume? For test purposes only? */ /* State/Control matrix. Read "If you are in state X and get control Y do action Z" Control: OFF CW CCW PAUSE RESUME SPINUP SPINDN State: |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - OFF | RELOAD | CW | CCW | OFF | NOP | XXXXXXXXX | XXXXXXXXX | + OFF | OFF | CW | CCW | NOP | NOP | XXXXXXXXX | XXXXXXXXX | |-----------|-----------|-----------|-----------|-----------|-----------|-----------| CW | OFF | NOP | REVERSE | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | |-----------|-----------|-----------|-----------|-----------|-----------|-----------| @@ -124,122 +133,71 @@ void spindle_reset() |-----------|-----------|-----------|-----------|-----------|-----------|-----------| NOP(OFF)s are effectively OFFs Actions: - - NOP No operation, ignore - - NOPCW No-op if spinning up to CW. If the spinning to CCW perform a REVERSE - - NOPCCW No-op if spinning up to CCW. If the spinning to CW perform a REVERSE - - OFF Turn spindle off + - OFF Turn spindle off. Even if it's already off (reloads polarities) - CW Turn spindle on clockwise - CCW Turn spindle on counterclockwise - PAUSE Turn off spindle, enter PAUSE state - - RESUME Turn spindle n CW or CCW as before - - REV Reverse spindle direction (implies a cycle) - - RELOAD Reload (LOAD) settings from spindle structure to spindle bits - - XXXXXXX Impossible state. RESUME is not a state and PSINOP/SPINDN are not inputs + - RESUME Turn spindle on CW or CCW as before + - NOP No operation, ignore + - NOPCW No-op if spinning up to CW. If the spinning to CCW perform a REVERSE + - NOPCCW No-op if spinning up to CCW. If the spinning to CW perform a REVERSE + - REV Reverse spindle direction (Q: need a cycle to spin down then back up again?) + - XXXXXXX Impossible box. RESUME is not a state and SPINUP/SPINDN are not inputs */ static void _exec_spindle_control(float *value, bool *flag) { spControl control = (spControl)value[0]; - if (control >= SPINDLE_ACTION_MAX) { + if (control > SPINDLE_ACTION_MAX) { return; } - - uint matrix[35] = { SPINDLE_LOAD, SPINDLE_CW, SPINDLE_CCW, SPINDLE_OFF, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_NOP, SPINDLE_REV, SPINDLE_PAUSE, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_REV, SPINDLE_NOP, SPINDLE_PAUSE, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_RESUME, - SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_PAUSE, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_NOP, SPINDLE_NOP - }; + spControl matrix[40] = { + SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_NOP, SPINDLE_REV, SPINDLE_PAUSE, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_REV, SPINDLE_NOP, SPINDLE_PAUSE, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_RESUME, + SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_PAUSE, SPINDLE_NOP, + SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_NOP, SPINDLE_NOP, + SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP // impossible row added for safety + }; uint8_t index = ((spindle.state & 0x07) * 5) + control; - uint8_t action = matrix[index]; + spControl action = matrix[index]; - spindle.state = control; // record new spindle state - uint8_t on_bit = SPINDLE_OFF; // default to off - int8_t dir_bit = -1; // -1 will skip setting the direction + SPINDLE_DIRECTION_ASSERT; // ensure that the spindle direction is sane + int8_t enable_bit = 0; // default to 0=off + int8_t dir_bit = -1; // -1 will skip setting the direction. 0 & 1 are valid values switch (action) { - case SPINDLE_NOP: { return; } - case SPINDLE_OFF: { break; } // on_nit and state are already set for this case - case SPINDLE_PAUSE : { break; } // on_nit and state are also already set for this case - - case SPINDLE_CW: case SPINDLE_CCW: { - on_bit = 1; // use 1 (not true) - this is a bitmask + case SPINDLE_NOP: case SPINDLE_NOPCW: case SPINDLE_NOPCCW: { return; } // reversals not handled yet + + case SPINDLE_OFF: { // enable_bit already set for this case + dir_bit = spindle.direction-1; // spindle direction was stored as '1' & '2' + spindle.state = SPINDLE_OFF; // the control might have been something other than SPINDLE_OFF + break; + } + case SPINDLE_CW: case SPINDLE_CCW: case SPINDLE_REV: { // REV is handled same as CW or CCW for now + enable_bit = 1; dir_bit = control-1; // adjust direction to be used as a bitmask spindle.direction = control; + spindle.state = control; break; } - + case SPINDLE_PAUSE : { + spindle.state = SPINDLE_PAUSE; + break; // enable bit is already set up to stop the move + } case SPINDLE_RESUME: { - on_bit = 1; - dir_bit = spindle.direction-1; // Note: spindle direction was stored as '1' & '2' + enable_bit = 1; + dir_bit = spindle.direction-1; // spindle direction was stored as '1' & '2' spindle.state = spindle.direction; break; } - - case SPINDLE_LOAD: { // can be used to change enable and dir polarities - dir_bit = control-1; // adjust direction to be used as a bitmask - break; - } - - case SPINDLE_REV: { // for now we treat this as a simple CW or CCW request - on_bit = 1; // use 1 (not true) - this is a bitmask - dir_bit = control-1; // adjust direction to be used as a bitmask - spindle.direction = control; - break; - } - case SPINDLE_NOPCW: { return; } // reversal case not handled yet - case SPINDLE_NOPCCW: { return; } // reversal case not handled yet + default: {} // keeps the compiler happy } // Apply the enable and direction bits and adjust the PWM as required - // set the direction first - if (dir_bit >= 0) { - if (dir_bit ^ spindle.dir_polarity) { - spindle_dir_pin.set(); // drive pin HI - } else { - spindle_dir_pin.clear(); // drive pin LO - } - } - - // set on/off - if (on_bit ^ spindle.enable_polarity) { - spindle_enable_pin.clear(); // drive pin LO - } else { - spindle_enable_pin.set(); // drive pin HI - } - pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); -} - -/* - spControl control = (spControl)value[0]; - if (control >= SPINDLE_ACTION_MAX) { - return; - } - if ((control == SPINDLE_RESUME) && (spindle.state != SPINDLE_PAUSE)) { - return; - } - if ((control == SPINDLE_PAUSE) && (spindle.state != SPINDLE_OFF)) { - return; - } - - spindle.state = control; // record new spindle state - uint8_t on_bit = SPINDLE_OFF; // default to off - int8_t dir_bit = -1; // -1 will skip setting the direction - - if ((control == SPINDLE_CW) || (control == SPINDLE_CCW)) { - on_bit = 1; // use 1 (not true) to indicate this is a bitmask - dir_bit = control-1; // adjust direction so it can be used as a bitmask - spindle.direction = control; - } - else if (control == SPINDLE_RESUME) { - on_bit = 1; - dir_bit = spindle.direction-1; // Note: spindle direction is stored as 1 & 2 - spindle.state = spindle.direction; - } - // set the direction first if (dir_bit >= 0) { if (dir_bit ^ spindle.dir_polarity) { @@ -249,15 +207,14 @@ static void _exec_spindle_control(float *value, bool *flag) } } - // set on/off - if (on_bit ^ spindle.enable_polarity) { + // set spindle enable + if (enable_bit ^ spindle.enable_polarity) { spindle_enable_pin.clear(); // drive pin LO } else { spindle_enable_pin.set(); // drive pin HI } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); } -*/ stat_t spindle_control_immediate(spControl control) { @@ -403,21 +360,34 @@ void spindle_end_override(const float ramp_time) ***********************************************************************************/ /*********************************************************************************** - **** Spindle Settings + **** Spindle Settings ************************************************************* ***********************************************************************************/ stat_t sp_get_spmo(nvObj_t *nv) { return(get_int(nv, spindle.mode)); } stat_t sp_set_spmo(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.mode, SPINDLE_DISABLED, SPINDLE_MODE_MAX)); } stat_t sp_get_spep(nvObj_t *nv) { return(get_int(nv, spindle.enable_polarity)); } -stat_t sp_set_spep(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.enable_polarity, 0, 1)); } +stat_t sp_set_spep(nvObj_t *nv) { + stat_t status = set_int(nv, (uint8_t &)spindle.enable_polarity, 0, 1); + spindle_control_immediate(SPINDLE_OFF); // stop spindle and apply new settings + return (status); +} + stat_t sp_get_spdp(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } -stat_t sp_set_spdp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1)); } -stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } -stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1)); } +stat_t sp_set_spdp(nvObj_t *nv) { + stat_t status = set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1); + spindle_control_immediate(SPINDLE_OFF); // stop spindle and apply new settings + return (status); +} + +stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.pause_on_hold)); } +stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.pause_on_hold, 0, 1)); } stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } +//stat_t sp_get_spdn(nvObj_t *nv) { return(get_float(nv, spindle.spindown_delay)); } +//stat_t sp_set_spdn(nvObj_t *nv) { return(set_float_range(nv, spindle.spindown_delay, 0, SPINDLE_DWELL_MAX)); } + stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } stat_t sp_get_spsm(nvObj_t *nv) { return(get_float(nv, spindle.speed_max)); } diff --git a/g2core/spindle.h b/g2core/spindle.h index a16844f5..07cb033e 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -52,20 +52,16 @@ typedef enum { // how spindle controls are presented by the Gco SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW + SPINDLE_SPINUP, // spindle is coming up to speed SPINDLE_SPINDOWN, // spindle is spinning down to stop - SPINDLE_NOP, // no operation SPINDLE_NOPCW, // no operation, starts from clockwise SPINDLE_NOPCCW, // no operation, starts from counterclockwise - SPINDLE_REV, // operation to reverse spindle direction - SPINDLE_LOAD // operation to reload spindle structure into spindle bits - + SPINDLE_REV // operation to reverse spindle direction } spControl; #define SPINDLE_ACTION_MAX SPINDLE_RESUME - - // *** NOTE: The spindle polarity active hi/low values currently agree with ioMode in gpio.h // These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 // See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types @@ -102,7 +98,6 @@ typedef struct spSpindle { bool pause_on_hold; // {spph:} pause on feedhold float spinup_delay; // {spde:} optional delay on spindle start (set to 0 to disable) float spindown_delay; // {spds:} optional delay on spindle stop (set to 0 to disable) - float reversal_delay; // {spdr:} optional delay on direction reversal (set to 0 to disable) bool override_enable; // {spoe:} TRUE = spindle speed override enabled (see also m48_enable in canonical machine) float override_factor; // {spo:} 1.0000 x S spindle speed. Go up or down from there From 51741fde2f8f6a7fa29e75a825e7f74a54dda433 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Jan 2017 11:03:27 -0500 Subject: [PATCH 080/283] =?UTF-8?q?Added=20spinup=20and=20spindown=20delay?= =?UTF-8?q?s=20for=20sync=E2=80=99d=20spindle=20commands;=20Added=20option?= =?UTF-8?q?=20on=20PAUSE=20and=20RESUME=20actions;=20Testing.=20Still=20ha?= =?UTF-8?q?ve=20some=20work=20to=20make=20the=20delays=20work=20correctly.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/config_app.cpp | 4 +-- g2core/settings/settings_default.h | 10 +++++-- g2core/settings/settings_makeblock.h | 41 +++++++++++++++------------- g2core/spindle.cpp | 17 ++++++++---- g2core/spindle.h | 7 ++++- 5 files changed, 49 insertions(+), 30 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 42167c15..cb3a17d5 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -838,8 +838,8 @@ const cfgItem_t cfgArray[] = { // Spindle functions { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, - { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spinup delay -// { "sp","spds", _fip, 2, sp_print_spds, sp_get_spds, sp_set_spds, (float *)&cs.null, SPINDLE_DWELL_TIME }, // spindown delay + { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, + { "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index b0333b6f..50b99688 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -94,11 +94,15 @@ #endif #ifndef SPINDLE_PAUSE_ON_HOLD -#define SPINDLE_PAUSE_ON_HOLD true // {spph: +#define SPINDLE_PAUSE_ON_HOLD false // {spph: #endif -#ifndef SPINDLE_DWELL_TIME -#define SPINDLE_DWELL_TIME 1.0 // {spdw: +#ifndef SPINDLE_SPINUP_DELAY +#define SPINDLE_SPINUP_DELAY 0 // {spde: +#endif + +#ifndef SPINDLE_SPINDOWN_DELAY +#define SPINDLE_SPINDOWN_DELAY 0 // {spdn: #endif #ifndef SPINDLE_DWELL_MAX diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 8d91e6ed..db63fd58 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -34,36 +34,39 @@ // Machine configuration settings -#define JUNCTION_INTEGRATION_TIME 1.25 // cornering - between 0.10 and 2.00 (higher is faster) -#define CHORDAL_TOLERANCE 0.1 // chordal tolerance for arcs (in mm) +#define JUNCTION_INTEGRATION_TIME 1.25 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.1 // chordal tolerance for arcs (in mm) -#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on -#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high -#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high -#define SPINDLE_PAUSE_ON_HOLD true -#define SPINDLE_DWELL_TIME 1.0 +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_SPINUP_DELAY 2.0 +#define SPINDLE_SPINDOWN_DELAY 0.0 +#define SPINDLE_SPEED_MIN 0.0 +#define SPINDLE_SPEED_MAX 20000.0 -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD false +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD false -#define FEEDHOLD_Z_LIFT 10 // mm to lift Z on feedhold +#define FEEDHOLD_Z_LIFT 10 // mm to lift Z on feedhold // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE -#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE -#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE #define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum #define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable //#define STATUS_REPORT_DEFAULTS diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index cbed79c5..d6ed0e42 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -225,11 +225,16 @@ stat_t spindle_control_immediate(spControl control) stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, CCW { + // skip the PAUSE operation if pause-enable is not enabled (pause-on-hold) + if ((control == SPINDLE_PAUSE) && (!spindle.pause_enable)) { + return (STAT_OK); + } + float value[] = { (float)control }; mp_queue_command(_exec_spindle_control, value, nullptr); if (fp_NOT_ZERO(spindle.spinup_delay)) { -// mp_queue_command(dwell); + mp_dwell(spindle.spinup_delay); } return(STAT_OK); } @@ -380,13 +385,13 @@ stat_t sp_set_spdp(nvObj_t *nv) { return (status); } -stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.pause_on_hold)); } -stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.pause_on_hold, 0, 1)); } +stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.pause_enable)); } +stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.pause_enable, 0, 1)); } stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } -//stat_t sp_get_spdn(nvObj_t *nv) { return(get_float(nv, spindle.spindown_delay)); } -//stat_t sp_set_spdn(nvObj_t *nv) { return(set_float_range(nv, spindle.spindown_delay, 0, SPINDLE_DWELL_MAX)); } +stat_t sp_get_spdn(nvObj_t *nv) { return(get_float(nv, spindle.spindown_delay)); } +stat_t sp_set_spdn(nvObj_t *nv) { return(set_float_range(nv, spindle.spindown_delay, 0, SPINDLE_DWELL_MAX)); } stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } @@ -418,6 +423,7 @@ const char fmt_spep[] = "[spep] spindle enable polarity%5d [0=active_low,1=activ const char fmt_spdp[] = "[spdp] spindle direction polarity%2d [0=CW_low,1=CW_high]\n"; const char fmt_spph[] = "[spph] spindle pause on hold%7d [0=no,1=pause_on_hold]\n"; const char fmt_spde[] = "[spde] spindle spinup delay%10.1f seconds\n"; +const char fmt_spdn[] = "[spdn] spindle spindown delay%8.1f seconds\n"; const char fmt_spsn[] = "[spsn] spindle speed min%14.2f rpm\n"; const char fmt_spsm[] = "[spsm] spindle speed max%14.2f rpm\n"; const char fmt_spoe[] = "[spoe] spindle speed override ena%2d [0=disable,1=enable]\n"; @@ -430,6 +436,7 @@ void sp_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT void sp_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT void sp_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT void sp_print_spde(nvObj_t *nv) { text_print(nv, fmt_spde);} // TYPE_FLOAT +void sp_print_spdn(nvObj_t *nv) { text_print(nv, fmt_spdn);} // TYPE_FLOAT void sp_print_spsn(nvObj_t *nv) { text_print(nv, fmt_spsn);} // TYPE_FLOAT void sp_print_spsm(nvObj_t *nv) { text_print(nv, fmt_spsm);} // TYPE_FLOAT void sp_print_spoe(nvObj_t *nv) { text_print(nv, fmt_spoe);} // TYPE INT diff --git a/g2core/spindle.h b/g2core/spindle.h index 07cb033e..a07cb423 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -95,7 +95,7 @@ typedef struct spSpindle { spPolarity enable_polarity; // {spep:} 0=active low, 1=active high spPolarity dir_polarity; // {spdp:} 0=clockwise low, 1=clockwise high - bool pause_on_hold; // {spph:} pause on feedhold + bool pause_enable; // {spph:} pause on feedhold float spinup_delay; // {spde:} optional delay on spindle start (set to 0 to disable) float spindown_delay; // {spds:} optional delay on spindle stop (set to 0 to disable) @@ -141,6 +141,9 @@ stat_t sp_set_spph(nvObj_t *nv); stat_t sp_get_spde(nvObj_t *nv); stat_t sp_set_spde(nvObj_t *nv); +stat_t sp_get_spdn(nvObj_t *nv); +stat_t sp_set_spdn(nvObj_t *nv); + stat_t sp_get_spsn(nvObj_t *nv); stat_t sp_set_spsn(nvObj_t *nv); stat_t sp_get_spsm(nvObj_t *nv); @@ -165,6 +168,7 @@ stat_t sp_set_sps(nvObj_t* nv); void sp_print_spdp(nvObj_t* nv); void sp_print_spph(nvObj_t* nv); void sp_print_spde(nvObj_t* nv); + void sp_print_spdn(nvObj_t* nv); void sp_print_spsn(nvObj_t* nv); void sp_print_spsm(nvObj_t* nv); void sp_print_spoe(nvObj_t* nv); @@ -179,6 +183,7 @@ stat_t sp_set_sps(nvObj_t* nv); #define sp_print_spdp tx_print_stub #define sp_print_spph tx_print_stub #define sp_print_spde tx_print_stub + #define sp_print_spdn tx_print_stub #define sp_print_spsn tx_print_stub #define sp_print_spsm tx_print_stub #define sp_print_spoe tx_print_stub From dddfa1ef13e215561dfaa9d8e363f20e7a5116d7 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 16 Jan 2017 07:40:36 -0500 Subject: [PATCH 081/283] Testing --- g2core/canonical_machine.cpp | 8 +-- g2core/canonical_machine.h | 36 ++++++------- g2core/gcode.h | 97 ------------------------------------ g2core/gcode_parser.cpp | 59 +++++++++++----------- g2core/spindle.cpp | 41 +++++++++++++-- g2core/spindle.h | 8 +-- 6 files changed, 94 insertions(+), 155 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index c1083edb..0d11172c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1380,8 +1380,8 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 } /*********************************************************************************** - * cm_mfo_control() - M50 manual feed rate override comtrol - * cm_mto_control() - M50.1 manual traverse override comtrol + * cm_fro_control() - M50 feed rate override comtrol + * cm_tro_control() - M50.1 traverse override comtrol * * M50 enables manual feedrate override and the optional P override parameter. * P is expressed as M% to N% of programmed feedrate, typically a value from 0.05 to 2.000. @@ -1421,7 +1421,7 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 * (Note: new ramp will supercede any existing ramp) */ -stat_t cm_mfo_control(const float P_word, const bool P_flag) // M50 +stat_t cm_fro_control(const float P_word, const bool P_flag) // M50 { bool new_enable = true; bool new_override = false; @@ -1450,7 +1450,7 @@ stat_t cm_mfo_control(const float P_word, const bool P_flag) // M50 return (STAT_OK); } -stat_t cm_mto_control(const float P_word, const bool P_flag) // M50.1 +stat_t cm_tro_control(const float P_word, const bool P_flag) // M50.1 { bool new_enable = true; bool new_override = false; diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 23386d38..1329817e 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -357,20 +357,6 @@ void canonical_machine_reset(cmMachine_t *_cm); void canonical_machine_init_assertions(cmMachine_t *_cm); stat_t canonical_machine_test_assertions(cmMachine_t *_cm); -// Alarms and state management -stat_t cm_alrm(nvObj_t *nv); // trigger alarm from command input -stat_t cm_shutd(nvObj_t *nv); // trigger shutdown from command input -stat_t cm_pnic(nvObj_t *nv); // trigger panic from command input -stat_t cm_clr(nvObj_t *nv); // clear alarm and shutdown from command input -void cm_clear(void); // raw clear command -void cm_parse_clear(const char *s); // parse gcode for M30 or M2 clear condition -stat_t cm_is_alarmed(void); // return non-zero status if alarm, shutdown or panic -void cm_halt_all(void); // halt motion, spindle and coolant -void cm_halt_motion(void); // halt motion (immediate stop) but not spindle & other IO -stat_t cm_alarm(const stat_t status, const char *msg); // enter alarm state - preserve Gcode state -stat_t cm_shutdown(const stat_t status, const char *msg); // enter shutdown state - dump all state -stat_t cm_panic(const stat_t status, const char *msg); // enter panic state - needs RESET - // Representation (4.3.3) stat_t cm_select_plane(const uint8_t plane); // G17, G18, G19 stat_t cm_set_units_mode(const uint8_t mode); // G20, G21 @@ -430,8 +416,8 @@ void cm_message(const char *message); // msg to consol void cm_reset_overrides(void); stat_t cm_m48_enable(uint8_t enable); // M48, M49 -stat_t cm_mfo_control(const float P_word, const bool P_flag); // M50 -stat_t cm_mto_control(const float P_word, const bool P_flag); // M50.1 +stat_t cm_fro_control(const float P_word, const bool P_flag); // M50 +stat_t cm_tro_control(const float P_word, const bool P_flag); // M50.1 // See spindle.cpp for cm_spo_control() // M51 // Program Functions (4.3.10) @@ -445,7 +431,7 @@ void cm_program_end(void); // M2 stat_t cm_json_command(char *json_string); // M100 stat_t cm_json_wait(char *json_string); // M102 -/*--- Cycles ---*/ +/**** Cycles and External FIles ****/ // Feedhold and related functions (cycle_feedhold.cpp) void cm_request_feedhold(void); @@ -481,7 +467,21 @@ stat_t cm_jogging_cycle_callback(void); // jogging cycle stat_t cm_jogging_cycle_start(uint8_t axis); // {"jogx":-100.3} float cm_get_jogging_dest(void); // get jogging destination -/*--- cfgArray interface functions ---*/ +// Alarm management (alarm.cpp) +stat_t cm_alrm(nvObj_t *nv); // trigger alarm from command input +stat_t cm_shutd(nvObj_t *nv); // trigger shutdown from command input +stat_t cm_pnic(nvObj_t *nv); // trigger panic from command input +stat_t cm_clr(nvObj_t *nv); // clear alarm and shutdown from command input +void cm_clear(void); // raw clear command +void cm_parse_clear(const char *s); // parse gcode for M30 or M2 clear condition +stat_t cm_is_alarmed(void); // return non-zero status if alarm, shutdown or panic +void cm_halt_all(void); // halt motion, spindle and coolant +void cm_halt_motion(void); // halt motion (immediate stop) but not spindle & other IO +stat_t cm_alarm(const stat_t status, const char *msg); // enter alarm state - preserve Gcode state +stat_t cm_shutdown(const stat_t status, const char *msg); // enter shutdown state - dump all state +stat_t cm_panic(const stat_t status, const char *msg); // enter panic state - needs RESET + +/**** cfgArray interface functions ****/ char cm_get_axis_char(const int8_t axis); cmAxisType cm_get_axis_type(const index_t index); diff --git a/g2core/gcode.h b/g2core/gcode.h index 39b5a28c..acb66e0b 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -279,103 +279,6 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used uint16_t magic_end; } GCodeStateX_t; -/* -// Structures used by Gcode parser - -typedef struct GCodeInput { // Gcode model inputs - meaning depends on context - - uint8_t next_action; // handles G modal group 1 moves & non-modals - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 - // G83, G84, G85, G86, G87, G88, G89 - - uint8_t program_flow; // used only by the gcode_parser - uint32_t linenum; // N word - float target[AXES]; // XYZABC where the move should go - - uint8_t H_word; // H word - used by G43s - uint8_t L_word; // L word - used by G10s - - float feed_rate; // F - normalized to millimeters/minute - uint8_t feed_rate_mode; // See cmFeedRateMode for settings - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... - float arc_radius; // R - radius value in arc radius mode - float arc_offset[3]; // IJK - used by arc commands - - bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_control; // M50 feedrate override control - bool mto_control; // M50.1 traverse override control - bool sso_control; // M51 spindle speed override control - - uint8_t select_plane; // G17,G18,G19 - values to set plane to - uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - uint8_t coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement - uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode - uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) - uint8_t tool; // Tool after T and M6 (tool_select and tool_change) - uint8_t tool_select; // T value - T sets this value - uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" - uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) - uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) - - uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - float spindle_speed; // in RPM - float spindle_override_factor; // 1.0000 x S spindle speed. Go up or down from there - uint8_t spindle_override_enable; // TRUE = override enabled -} GCodeInput_t; - -typedef struct GCodeFlags { // Gcode model input flags - bool next_action; - bool motion_mode; - bool modals[MODAL_GROUP_COUNT]; - bool program_flow; - bool linenum; - bool target[AXES]; - - bool H_word; - bool L_word; - bool feed_rate; - bool feed_rate_mode; - - bool m48_enable; - bool mfo_control; - bool mto_control; - bool sso_control; - - bool select_plane; - bool units_mode; - bool coord_system; - bool path_control; - bool distance_mode; - bool arc_distance_mode; - bool origin_offset_mode; - bool absolute_override; - bool tool; - bool tool_select; - bool tool_change; - bool mist_coolant; - bool flood_coolant; - - bool spindle_control; - bool spindle_speed; - bool spindle_override_factor; - bool spindle_override_enable; - - bool parameter; - bool arc_radius; - bool arc_offset[3]; -} GCodeFlags_t; - -typedef struct GCodeParser { - GCodeInput_t gn; // gcode input values - transient - GCodeFlags_t gf; // gcode input flags - transient -} GCodeParser_t; - -extern GCodeParser_t gp; -*/ - /* * Global Scope Functions */ diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index b834198b..e28a17cb 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -63,9 +63,9 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_control; // M50 feedrate override control - bool mto_control; // M50.1 traverse override control - bool sso_control; // M51 spindle speed override control + bool fro_control; // M50 feedrate override control + bool tro_control; // M50.1 traverse override control + bool spo_control; // M51 spindle speed override control } GCodeValue_t; typedef struct GCodeFlags { // Gcode input flags @@ -102,9 +102,9 @@ typedef struct GCodeFlags { // Gcode input flags bool spindle_control; bool m48_enable; - bool mfo_control; - bool mto_control; - bool sso_control; + bool fro_control; + bool tro_control; + bool spo_control; } GCodeFlag_t; typedef struct GCodeParser { @@ -643,14 +643,14 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 9: SET_MODAL (MODAL_GROUP_M8, flood_coolant, false); case 48: SET_MODAL (MODAL_GROUP_M9, m48_enable, true); case 49: SET_MODAL (MODAL_GROUP_M9, m48_enable, false); - case 50: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); + case 50: switch (_point(value)) { - case 0: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); - case 1: SET_MODAL (MODAL_GROUP_M9, mto_control, true); + case 0: SET_MODAL (MODAL_GROUP_M9, fro_control, true); + case 1: SET_MODAL (MODAL_GROUP_M9, tro_control, true); default: status = STAT_GCODE_COMMAND_UNSUPPORTED; } break; - case 51: SET_MODAL (MODAL_GROUP_M9, sso_control, true); + case 51: SET_MODAL (MODAL_GROUP_M9, spo_control, true); case 100: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC); case 101: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_WAIT); default: status = STAT_MCODE_COMMAND_UNSUPPORTED; @@ -689,23 +689,23 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) /* * _execute_gcode_block() - execute parsed block * - * Conditionally (based on whether a flag is set in gf) call the canonical - * machining functions in order of execution as per RS274NGC_3 table 8 - * (below, with modifications): + * Conditionally (based on whether a flag is set in gf) call the canonical machining + * functions in order of execution. Derived from RS274NGC_3 table 8: * * 0. record the line number * 1. comment (includes message) [handled during block normalization] + * 1a. enable or disable overrides (M48, M49) + * 1b. set feed override rate (M50) + * 1c. set traverse override rate (M50.1) + * 1d. set spindle override rate (M51) * 2. set feed rate mode (G93, G94 - inverse time or per minute) * 3. set feed rate (F) - * 3a. set feed override rate (M50.1) - * 3a. set traverse override rate (M50.2) * 4. set spindle speed (S) - * 4a. set spindle override rate (M51.1) * 5. select tool (T) * 6. change tool (M6) * 7. spindle on or off (M3, M4, M5) * 8. coolant on or off (M7, M8, M9) - * 9. enable or disable overrides (M48, M49, M50, M51) + * // 9. enable or disable overrides (M48, M49, M50, M51) (see 1a) * 10. dwell (G4) * 11. set active plane (G17, G18, G19) * 12. set length units (G20, G21) @@ -731,14 +731,23 @@ static stat_t _execute_gcode_block(char *active_comment) stat_t status = STAT_OK; cm_set_model_linenum(gv.linenum); + + EXEC_FUNC(cm_m48_enable, m48_enable); + + if (gf.fro_control) { // feedrate override + ritorno(cm_fro_control(gv.P_word, gf.P_word)); + } + if (gf.tro_control) { // traverse override + ritorno(cm_tro_control(gv.P_word, gf.P_word)); + } + if (gf.spo_control) { // spindle speed override + ritorno(spindle_override_control(gv.P_word, gf.P_word)); + } + EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, F_word); // F EXEC_FUNC(spindle_speed_sync, S_word); // S - if (gf.sso_control) { // spindle speed override - ritorno(spindle_override_control(gv.P_word, gf.P_word)); - } - EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written EXEC_FUNC(cm_change_tool, tool_change); // M6 @@ -748,14 +757,6 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF - EXEC_FUNC(cm_m48_enable, m48_enable); - - if (gf.mfo_control) { // manual feedrate override - ritorno(cm_mfo_control(gv.P_word, gf.P_word)); - } - if (gf.mto_control) { // manual traverse override - ritorno(cm_mto_control(gv.P_word, gf.P_word)); - } if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index d6ed0e42..6b6d6215 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -216,6 +216,33 @@ static void _exec_spindle_control(float *value, bool *flag) pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); } +/* + * spindle_control_immediate() - execute spindle control immediately + * spindle_control_sync() - queue a spindle control to the planner buffer + * + * Spinup and Spindown delays + * + * For starters, spinup and spindown delays are only meaningful for queued (sync'd) + * spindle operations (M3/M4/M5) because they introduce delays before or after the + * M code - relative to other Gcode commands. Immediate() spindle operations do not + * observe these delays; that's the responsibility of the sender. + * + * The "right" way to do spinup and spindown delays is to conditionally execute them + * in _exec_spindle_control() if you know you have an actual spindle state transition. + * This is hard because the delays would need to run "out of band" of the planner/runtime. + * This affects the planner, as it may or may not have already planned preceding/following + * moves to zero, and for other reasons. + * + * The easy way is to queue dwells to the planner in advance, before and after the + * actual spindle command. The problem with this is that you don't always know beforehand + * if the spindle command will run any real action. The S word might be zero. Or the + * feedhold PAUSE or RESUME might be executed, but no actual transition occurs because + * the spindle might have been OFF when this happened. + * + * Our (admittedly imperfect) hack is to best determine the conditions that will be seen + * when the queued delay is executed, and plan on that in spindle_control_sync(). + */ + stat_t spindle_control_immediate(spControl control) { float value[] = { (float)control }; @@ -230,11 +257,19 @@ stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, return (STAT_OK); } + // queue the spindle control float value[] = { (float)control }; mp_queue_command(_exec_spindle_control, value, nullptr); - - if (fp_NOT_ZERO(spindle.spinup_delay)) { - mp_dwell(spindle.spinup_delay); + + // conditionally queue a dwell for spinup delay + if ((spindle.mode == SPINDLE_PLAN_TO_STOP) && (fp_NOT_ZERO(spindle.spinup_delay))) { + if ((control == SPINDLE_CW) || (control == SPINDLE_CCW)) { + if (spindle.state != control) { + if (spindle.speed > 0) { + mp_dwell(spindle.spinup_delay); + } + } + } } return(STAT_OK); } diff --git a/g2core/spindle.h b/g2core/spindle.h index a07cb423..15f466f4 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -42,10 +42,10 @@ typedef enum { #define SPINDLE_MODE_MAX SPINDLE_CONTINUOUS // spControl enum is used for multiple purposes: -// - request a spindle operation (OFF, CW, CCW, PAUSE, RESUME) -// - run the spindle state machine for spindle wait states -// - CW and CCW values are stored as current direction in spindle.direction -// - NOP, REVERSE and RELOAD are operations an are not stes or controls +// - request a spindle action (OFF, CW, CCW, PAUSE, RESUME) +// - keep current spindle state in spindle.state +// - store as current direction (CW/CCW) in spindle.direction +// - enumerate internal actions such as NOP, REV that are neither states nor controls typedef enum { // how spindle controls are presented by the Gcode parser SPINDLE_OFF = 0, // M5 SPINDLE_CW = 1, // M3 and store CW to spindle.direction From 886b4041b3c221881c034ea8ad04a8eaec254bec Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 16 Jan 2017 11:02:35 -0500 Subject: [PATCH 082/283] Installed planner-level out-of-band-dwell to better handle pinup delays. Commented out spin down delays. These may be useful later for direction reversals, but for now they are not needed. --- g2core/config_app.cpp | 2 +- g2core/g2core.cppproj | 4 +-- g2core/plan_exec.cpp | 9 +++++- g2core/planner.cpp | 32 +++++++++++---------- g2core/planner.h | 4 ++- g2core/pwm.cpp | 6 ++-- g2core/spindle.cpp | 65 +++++++++++++------------------------------ g2core/spindle.h | 14 ++++------ g2core/stepper.cpp | 41 +++++++++++---------------- g2core/stepper.h | 2 +- 10 files changed, 77 insertions(+), 102 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index cb3a17d5..489cfe2b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -839,7 +839,7 @@ const cfgItem_t cfgArray[] = { { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, - { "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, +// { "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 36e55b55..af27d1e0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 13ab102b..9cfc373f 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -247,7 +247,14 @@ stat_t mp_exec_move() { mpBuf_t *bf; - // NULL means nothing's running - this is OK + // Run an out of band dwell. It was probably set in the previous st_load_move() + if (mr->out_of_band_dwell_flag) { + mr->out_of_band_dwell_flag = false; + st_prep_out_of_band_dwell(mr->out_of_band_dwell_seconds * 1000000); + return (STAT_OK); + } + + // Getting a NULL buffer means nothing's running in the queue - this is OK if ((bf = mp_get_run_buffer()) == NULL) { st_prep_null(); return (STAT_NOOP); diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 2b69f14b..4450544b 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -290,7 +290,7 @@ void mp_set_steps_to_runtime_position() } } -/************************************************************************************ +/*********************************************************************************** * mp_queue_command() - queue a synchronous Mcode, program control, or other command * _exec_command() - callback to execute command * @@ -346,8 +346,7 @@ stat_t mp_runtime_command(mpBuf_t *bf) return (STAT_OK); } - -/************************************************************************* +/*********************************************************************************** * mp_json_command() - queue a json command * _exec_json_command() - execute json string */ @@ -373,7 +372,7 @@ static void _exec_json_command(float *value, bool *flag) } -/************************************************************************* +/*********************************************************************************** * mp_json_wait() - queue a json wait command * _exec_json_wait() - execute json wait string */ @@ -427,7 +426,7 @@ static stat_t _exec_json_wait(mpBuf_t *bf) } -/************************************************************************* +/*********************************************************************************** * mp_dwell() - queue a dwell * _exec_dwell() - dwell execution * @@ -435,6 +434,7 @@ static stat_t _exec_json_wait(mpBuf_t *bf) * When the stepper driver sees a dwell it times the dwell on a separate * timer than the stepper pulse timer. */ + stat_t mp_dwell(float seconds) { mpBuf_t *bf; @@ -458,19 +458,23 @@ static stat_t _exec_dwell(mpBuf_t *bf) return (STAT_OK); } -//++++ stubbed ++++ +/*********************************************************************************** + * mp_request_out_of_band_dwell() - request that an out-of-band dwell be run + * + * This command is used to request that a dwell be run outside of the planner. + * This is useful for queuing a dwell after a spindle change. The dwell will + * only run if the runtime has been stopped, otherwise it is skipped. + * This function is typically called from an exec such as _exec_spindle_control(). + * The request is executed from mp_exec_move(). + */ + void mp_request_out_of_band_dwell(float seconds) { -// mr->out_of_band_dwell_time = seconds; -} -//++++ stubbed ++++ -stat_t mp_exec_out_of_band_dwell(void) -{ -// return _advance_dwell(mr->out_of_band_dwell_time); - return 0; + mr->out_of_band_dwell_flag = true; + mr->out_of_band_dwell_seconds = seconds; } -/********************************************************************************** +/*********************************************************************************** * Planner helpers * * mp_get_planner_buffers() - return # of available planner buffers diff --git a/g2core/planner.h b/g2core/planner.h index a985c2e8..359b1d9a 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -438,6 +438,9 @@ typedef struct mpPlannerRuntime { // persistent runtime variables moveSection section; // what section is the move in? sectionState section_state; // state within a move section + bool out_of_band_dwell_flag; // set true to conditionally execute out-of-band dwell + float out_of_band_dwell_seconds; // time for out-of-band dwell + float unit[AXES]; // unit vector for axis scaling & planning bool axis_flags[AXES]; // set true for axes participating in the move float target[AXES]; // final target for bf (used to correct rounding errors) @@ -552,7 +555,6 @@ stat_t mp_json_wait(char *json_string); stat_t mp_dwell(const float seconds); void mp_end_dwell(void); void mp_request_out_of_band_dwell(float seconds); -stat_t mp_exec_out_of_band_dwell(void); //**** planner functions and helpers uint8_t mp_get_planner_buffers(const mpPlanner_t *_mp); diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp index 5e4c96b9..3f69cdf9 100644 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -2,7 +2,7 @@ * pwm.cpp - pulse width modulation drivers * This file is part of the g2core project * - * Copyright (c) 2012 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -100,12 +100,12 @@ stat_t pwm_set_duty(uint8_t chan, float duty) if (chan == PWM_1) { // if (spindle_pwm_pin.isNull()) { -// cm_alarm(STAT_ALARM, "attempt to turn on a non-existant spindle"); +// cm_alarm(STAT_ALARM, "attempt to turn on a non-existent spindle"); // } spindle_pwm_pin = duty; } else if (chan == PWM_2) { // if (secondary_pwm_pin.isNull()) { -// cm_alarm(STAT_ALARM, "attempt to turn on a non-existant spindle"); +// cm_alarm(STAT_ALARM, "attempt to turn on a non-existent spindle"); // } secondary_pwm_pin = duty; } diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 6b6d6215..aa696f64 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -76,9 +76,9 @@ void spindle_reset() * spindle_control_sync() - queue a spindle control to the planner buffer * _exec_spindle_control() - actually execute the spindle command * - * Basic operation: Spindle function is effected by _exec_spindle_control(). + * Basic operation: Spindle function is executed by _exec_spindle_control(). * Spindle_control_immediate() performs the control as soon as it's received. - * Spindle_control_sync() inserts spindle move into the planner, and handles spinup and spindowns + * Spindle_control_sync() inserts spindle move into the planner, and handles spinups. * * Valid inputs to Spindle_control_immediate() and Spindle_control_sync() are: * @@ -87,12 +87,13 @@ void spindle_reset() * The spindle.direction value is not affected (although this doesn't really matter). * * - SPINDLE_CW or SPINDLE_CCW turns sets direction accordingly and spindle on. - * In spindle_control_sync() a non-zero spinup delay puts a dwell in the planner queue. - * In this case spindle.state is SPINDLE_SPINUP until spindle command is "played", and dwell completes. + * In spindle_control_sync() a non-zero spinup delay runs a dwell immediately following + * the spindle change, but only if the planner had planned the spindle operation to zero. + * (I.e. if the spindle controls / S words do not plan to zero the delay is not run). * Spindle_control_immediate() has no spinup delay or dwell behavior. * - * - SPINDLE_PAUSE is only applicable to CW, CCW and SPINUP states. It forces the spindle OFF and - * sets spindle.state to PAUSE. If PAUSE is received when not in CW or CCW state it is ignored. + * - SPINDLE_PAUSE is only applicable to CW and CCW states. It forces the spindle OFF and + * sets spindle.state to PAUSE. A PAUSE received when not in CW or CCW state is ignored. * * - SPINDLE_RESUME, if in a PAUSE state, reverts to previous SPINDLE_CW or SPINDLE_CCW. * The SPEED is not changed, and if it were changed in the interim the "new" speed is used. @@ -100,8 +101,8 @@ void spindle_reset() * If RESUME is received when not in a PAUSED state it is ignored. This recognizes that the main * reason an immediate command would be issued - either manually by the user or by an alarm or * some other program function - is to stop a spindle. So the Resume should be ignored for safety. - * - * Notes: + */ +/* Notes: * - Since it's possible to queue a sync'd control, and then set any spindle state with an * immediate() before the queued command is reached, _exec_spindle_control() must gracefully * handle any arbitrary state transition (not just the "legal" ones). @@ -167,6 +168,7 @@ static void _exec_spindle_control(float *value, bool *flag) SPINDLE_DIRECTION_ASSERT; // ensure that the spindle direction is sane int8_t enable_bit = 0; // default to 0=off int8_t dir_bit = -1; // -1 will skip setting the direction. 0 & 1 are valid values + bool spinup_delay = false; switch (action) { case SPINDLE_NOP: case SPINDLE_NOPCW: case SPINDLE_NOPCCW: { return; } // reversals not handled yet @@ -181,6 +183,7 @@ static void _exec_spindle_control(float *value, bool *flag) dir_bit = control-1; // adjust direction to be used as a bitmask spindle.direction = control; spindle.state = control; + spinup_delay = true; break; } case SPINDLE_PAUSE : { @@ -191,6 +194,7 @@ static void _exec_spindle_control(float *value, bool *flag) enable_bit = 1; dir_bit = spindle.direction-1; // spindle direction was stored as '1' & '2' spindle.state = spindle.direction; + spinup_delay = true; break; } default: {} // keeps the compiler happy @@ -214,33 +218,15 @@ static void _exec_spindle_control(float *value, bool *flag) spindle_enable_pin.set(); // drive pin HI } pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); + + if (spinup_delay) { + mp_request_out_of_band_dwell(spindle.spinup_delay); + } } /* * spindle_control_immediate() - execute spindle control immediately * spindle_control_sync() - queue a spindle control to the planner buffer - * - * Spinup and Spindown delays - * - * For starters, spinup and spindown delays are only meaningful for queued (sync'd) - * spindle operations (M3/M4/M5) because they introduce delays before or after the - * M code - relative to other Gcode commands. Immediate() spindle operations do not - * observe these delays; that's the responsibility of the sender. - * - * The "right" way to do spinup and spindown delays is to conditionally execute them - * in _exec_spindle_control() if you know you have an actual spindle state transition. - * This is hard because the delays would need to run "out of band" of the planner/runtime. - * This affects the planner, as it may or may not have already planned preceding/following - * moves to zero, and for other reasons. - * - * The easy way is to queue dwells to the planner in advance, before and after the - * actual spindle command. The problem with this is that you don't always know beforehand - * if the spindle command will run any real action. The S word might be zero. Or the - * feedhold PAUSE or RESUME might be executed, but no actual transition occurs because - * the spindle might have been OFF when this happened. - * - * Our (admittedly imperfect) hack is to best determine the conditions that will be seen - * when the queued delay is executed, and plan on that in spindle_control_sync(). */ stat_t spindle_control_immediate(spControl control) @@ -260,17 +246,6 @@ stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, // queue the spindle control float value[] = { (float)control }; mp_queue_command(_exec_spindle_control, value, nullptr); - - // conditionally queue a dwell for spinup delay - if ((spindle.mode == SPINDLE_PLAN_TO_STOP) && (fp_NOT_ZERO(spindle.spinup_delay))) { - if ((control == SPINDLE_CW) || (control == SPINDLE_CCW)) { - if (spindle.state != control) { - if (spindle.speed > 0) { - mp_dwell(spindle.spinup_delay); - } - } - } - } return(STAT_OK); } @@ -425,8 +400,8 @@ stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.pause_en stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } -stat_t sp_get_spdn(nvObj_t *nv) { return(get_float(nv, spindle.spindown_delay)); } -stat_t sp_set_spdn(nvObj_t *nv) { return(set_float_range(nv, spindle.spindown_delay, 0, SPINDLE_DWELL_MAX)); } +//stat_t sp_get_spdn(nvObj_t *nv) { return(get_float(nv, spindle.spindown_delay)); } +//stat_t sp_set_spdn(nvObj_t *nv) { return(set_float_range(nv, spindle.spindown_delay, 0, SPINDLE_DWELL_MAX)); } stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } @@ -458,7 +433,7 @@ const char fmt_spep[] = "[spep] spindle enable polarity%5d [0=active_low,1=activ const char fmt_spdp[] = "[spdp] spindle direction polarity%2d [0=CW_low,1=CW_high]\n"; const char fmt_spph[] = "[spph] spindle pause on hold%7d [0=no,1=pause_on_hold]\n"; const char fmt_spde[] = "[spde] spindle spinup delay%10.1f seconds\n"; -const char fmt_spdn[] = "[spdn] spindle spindown delay%8.1f seconds\n"; +//const char fmt_spdn[] = "[spdn] spindle spindown delay%8.1f seconds\n"; const char fmt_spsn[] = "[spsn] spindle speed min%14.2f rpm\n"; const char fmt_spsm[] = "[spsm] spindle speed max%14.2f rpm\n"; const char fmt_spoe[] = "[spoe] spindle speed override ena%2d [0=disable,1=enable]\n"; @@ -471,7 +446,7 @@ void sp_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT void sp_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT void sp_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT void sp_print_spde(nvObj_t *nv) { text_print(nv, fmt_spde);} // TYPE_FLOAT -void sp_print_spdn(nvObj_t *nv) { text_print(nv, fmt_spdn);} // TYPE_FLOAT +//void sp_print_spdn(nvObj_t *nv) { text_print(nv, fmt_spdn);} // TYPE_FLOAT void sp_print_spsn(nvObj_t *nv) { text_print(nv, fmt_spsn);} // TYPE_FLOAT void sp_print_spsm(nvObj_t *nv) { text_print(nv, fmt_spsm);} // TYPE_FLOAT void sp_print_spoe(nvObj_t *nv) { text_print(nv, fmt_spoe);} // TYPE INT diff --git a/g2core/spindle.h b/g2core/spindle.h index 15f466f4..9642022b 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -97,7 +97,7 @@ typedef struct spSpindle { spPolarity dir_polarity; // {spdp:} 0=clockwise low, 1=clockwise high bool pause_enable; // {spph:} pause on feedhold float spinup_delay; // {spde:} optional delay on spindle start (set to 0 to disable) - float spindown_delay; // {spds:} optional delay on spindle stop (set to 0 to disable) +// float spindown_delay; // {spds:} optional delay on spindle stop (set to 0 to disable) bool override_enable; // {spoe:} TRUE = spindle speed override enabled (see also m48_enable in canonical machine) float override_factor; // {spo:} 1.0000 x S spindle speed. Go up or down from there @@ -122,10 +122,6 @@ stat_t spindle_control_sync(spControl control); stat_t spindle_speed_immediate(float speed); // S parameter stat_t spindle_speed_sync(float speed); // S parameter -//void spindle_off_immediate(void); -//void spindle_optional_pause(bool option); // stop spindle based on system options selected -//void spindle_resume(float dwell_seconds); // restart spindle after pause based on previous state - stat_t spindle_override_control(const float P_word, const bool P_flag); // M51 void spindle_start_override(const float ramp_time, const float override_factor); void spindle_end_override(const float ramp_time); @@ -141,8 +137,8 @@ stat_t sp_set_spph(nvObj_t *nv); stat_t sp_get_spde(nvObj_t *nv); stat_t sp_set_spde(nvObj_t *nv); -stat_t sp_get_spdn(nvObj_t *nv); -stat_t sp_set_spdn(nvObj_t *nv); +//stat_t sp_get_spdn(nvObj_t *nv); +//stat_t sp_set_spdn(nvObj_t *nv); stat_t sp_get_spsn(nvObj_t *nv); stat_t sp_set_spsn(nvObj_t *nv); @@ -168,7 +164,7 @@ stat_t sp_set_sps(nvObj_t* nv); void sp_print_spdp(nvObj_t* nv); void sp_print_spph(nvObj_t* nv); void sp_print_spde(nvObj_t* nv); - void sp_print_spdn(nvObj_t* nv); +// void sp_print_spdn(nvObj_t* nv); void sp_print_spsn(nvObj_t* nv); void sp_print_spsm(nvObj_t* nv); void sp_print_spoe(nvObj_t* nv); @@ -183,7 +179,7 @@ stat_t sp_set_sps(nvObj_t* nv); #define sp_print_spdp tx_print_stub #define sp_print_spph tx_print_stub #define sp_print_spde tx_print_stub - #define sp_print_spdn tx_print_stub +// #define sp_print_spdn tx_print_stub #define sp_print_spsn tx_print_stub #define sp_print_spsm tx_print_stub #define sp_print_spoe tx_print_stub diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 31d99aa7..9136429c 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -44,8 +44,10 @@ #include "MotateDebug.h" +/* Note: stepper_debug statements removed 1/16/17 in SHA ______. See earlier commits to recover // Unless debugging, this should always read "#if 0 && ..." // DON'T COMMIT with anything else! +// #if 0 && (IN_DEBUGGER == 1) template void stepper_debug(const char (&str)[len]) { Motate::debug.write(str); }; @@ -53,6 +55,7 @@ void stepper_debug(const char (&str)[len]) { Motate::debug.write(str); }; template void stepper_debug(const char (&str)[len]) { ; }; #endif +*/ /**** Allocate structures ****/ @@ -352,12 +355,10 @@ void dda_timer_type::interrupt() void st_request_exec_move() { - stepper_debug("e"); if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) { // bother interrupting exec_timer.setInterruptPending(); return; } - stepper_debug("!\n"); } namespace Motate { // Define timer inside Motate namespace @@ -366,21 +367,17 @@ namespace Motate { // Define timer inside Motate namespace { exec_timer.getInterruptCause(); // clears the interrupt condition if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) { - stepper_debug("E>"); if (mp_exec_move() != STAT_NOOP) { - stepper_debug("E+\n"); st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // flip it back st_request_load_move(); return; } - stepper_debug("E-\n"); } } } // namespace Motate void st_request_forward_plan() { - stepper_debug("p"); fwd_plan_timer.setInterruptPending(); } @@ -389,13 +386,10 @@ namespace Motate { // Define timer inside Motate namespace void fwd_plan_timer_type::interrupt() { fwd_plan_timer.getInterruptCause(); // clears the interrupt condition - stepper_debug("P>"); if (mp_forward_plan() != STAT_NOOP) { // We now have a move to exec. - stepper_debug("P+\n"); st_request_exec_move(); return; } - stepper_debug("P-\n"); } } // namespace Motate @@ -414,9 +408,7 @@ void st_request_load_move() if (st_runtime_isbusy()) { // don't request a load if the runtime is busy return; } - stepper_debug("l"); if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_LOADER) { // bother interrupting - stepper_debug("_"); load_timer.setInterruptPending(); } } @@ -426,9 +418,7 @@ namespace Motate { // Define timer inside Motate namespace void load_timer_type::interrupt() { load_timer.getInterruptCause(); // read SR to clear interrupt condition - stepper_debug("L>"); _load_move(); - stepper_debug("L+\n"); } } // namespace Motate @@ -474,12 +464,9 @@ static void _load_move() #if (MOTORS > 5) motor_6.motionStopped(); #endif - stepper_debug("•"); return; } // if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) - stepper_debug("^"); - // handle aline loads first (most common case) NB: there are no more lines, only alines if (st_pre.block_type == BLOCK_TYPE_ALINE) { @@ -667,7 +654,6 @@ static void _load_move() stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time) { - stepper_debug("😶"); // trap assertion failures and other conditions that would prevent queuing the line if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_EXEC) { // never supposed to happen return (cm_panic(STAT_INTERNAL_ERROR, "st_prep_line() prep sync error")); @@ -746,7 +732,6 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment } st_pre.block_type = BLOCK_TYPE_ALINE; st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready - stepper_debug("👍🏻"); return (STAT_OK); } @@ -784,20 +769,26 @@ void st_prep_dwell(float microseconds) } /* - * st_request_out_of_band_dwell() - * (only usable while exec isn't running, e.g. in feedhold or stopped states...) - * add a dwell to the loader without going through the planner buffers + * st_prep_out_of_band_dwell() + * + * Add a dwell to the loader without going through the planner buffers. + * Only usable while exec isn't running, e.g. in feedhold or stopped states. + * Otherwise it is skipped. */ -void st_request_out_of_band_dwell(float microseconds) + +void st_prep_out_of_band_dwell(float microseconds) { - st_prep_dwell(microseconds); - st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready - st_request_load_move(); + if (!st_runtime_isbusy()) { + st_prep_dwell(microseconds); + st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready + st_request_load_move(); + } } /* * _set_hw_microsteps() - set microsteps in hardware */ + static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps) { if (motor >= MOTORS) { return; } diff --git a/g2core/stepper.h b/g2core/stepper.h index 35f1770c..0038722d 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -575,7 +575,7 @@ void st_request_load_move(void); void st_prep_null(void); void st_prep_command(void *bf); // use a void pointer since we don't know about mpBuf_t yet) void st_prep_dwell(float microseconds); -void st_request_out_of_band_dwell(float microseconds); +void st_prep_out_of_band_dwell(float microseconds); stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time); stat_t st_get_ma(nvObj_t *nv); From cde2bcc988bc552a674daab3a3131bddbfd57a0d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 16 Jan 2017 11:04:08 -0500 Subject: [PATCH 083/283] ignore --- g2core/stepper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 9136429c..c94fd051 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -44,7 +44,7 @@ #include "MotateDebug.h" -/* Note: stepper_debug statements removed 1/16/17 in SHA ______. See earlier commits to recover +/* Note: stepper_debug statements removed 1/16/17 in SHA eb0905ccae03c04f99e6f471cbe029002f0324c6. See earlier commits to recover // Unless debugging, this should always read "#if 0 && ..." // DON'T COMMIT with anything else! // From 43c3430930e71db179e4ec0c8869b915e0ac7da9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 16 Jan 2017 12:27:28 -0500 Subject: [PATCH 084/283] Some refinements to spindle function, out-of-band-dwell; testing --- g2core/error.h | 3 ++- g2core/planner.cpp | 16 +++++++----- g2core/spindle.cpp | 64 ++++++++++++++++++++++++---------------------- g2core/spindle.h | 5 ---- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/g2core/error.h b/g2core/error.h index a6e346a5..b452f75c 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -167,6 +167,7 @@ char *get_status_message(stat_t status); // Assertion failures - build down from 99 until they meet the system internal errors +#define STAT_SPINDLE_ASSERTION_FAILURE 86 #define STAT_EXEC_ALINE_ASSERTION_FAILURE 87 #define STAT_BUFFER_FREE_ASSERTION_FAILURE 88 #define STAT_STATE_MANAGEMENT_ASSERTION_FAILURE 89 @@ -468,8 +469,8 @@ static const char stat_82[] = "82"; static const char stat_83[] = "83"; static const char stat_84[] = "84"; static const char stat_85[] = "85"; -static const char stat_86[] = "86"; +static const char stat_86[] = "Spindle assertion failure"; static const char stat_87[] = "mp_exec_aline() assertion failure"; static const char stat_88[] = "Buffer free assertion failure"; static const char stat_89[] = "State management assertion failure"; diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 4450544b..78e762e5 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -459,19 +459,21 @@ static stat_t _exec_dwell(mpBuf_t *bf) } /*********************************************************************************** - * mp_request_out_of_band_dwell() - request that an out-of-band dwell be run + * mp_request_out_of_band_dwell() - request a dwell outside of the planner queue * * This command is used to request that a dwell be run outside of the planner. - * This is useful for queuing a dwell after a spindle change. The dwell will - * only run if the runtime has been stopped, otherwise it is skipped. - * This function is typically called from an exec such as _exec_spindle_control(). - * The request is executed from mp_exec_move(). + * The dwell will only be queued if the time is non-zero, and will only be executed + * if the runtime has been stopped. This function is typically called from an exec + * such as _exec_spindle_control(). The dwell move is executed from mp_exec_move(). + * This is useful for queuing a dwell after a spindle change. */ void mp_request_out_of_band_dwell(float seconds) { - mr->out_of_band_dwell_flag = true; - mr->out_of_band_dwell_seconds = seconds; + if (fp_NOT_ZERO(seconds)) { + mr->out_of_band_dwell_flag = true; + mr->out_of_band_dwell_seconds = seconds; + } } /*********************************************************************************** diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index aa696f64..35c8db51 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -116,23 +116,19 @@ void spindle_reset() */ /* State/Control matrix. Read "If you are in state X and get control Y do action Z" - Control: OFF CW CCW PAUSE RESUME SPINUP SPINDN - State: |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - OFF | OFF | CW | CCW | NOP | NOP | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - CW | OFF | NOP | REVERSE | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - CCW | OFF | REVERSE | NOP | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - PAUSE | OFF | CW | CCW | NOP | RESUME | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - RESUME | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - SPINUP | OFF | NOP|CW | NOP|CCW | PAUSE | NOP | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - SPINDN | NOP | NOP|CW | NOP|CCW | NOP(OFF) | NOP(OFF) | XXXXXXXXX | XXXXXXXXX | - |-----------|-----------|-----------|-----------|-----------|-----------|-----------| - NOP(OFF)s are effectively OFFs + Control: OFF CW CCW PAUSE RESUME + State: |-----------|-----------|-----------|-----------|-----------| + OFF | OFF | CW | CCW | NOP | NOP | + |-----------|-----------|-----------|-----------|-----------| + CW | OFF | NOP | REVERSE | PAUSE | NOP | + |-----------|-----------|-----------|-----------|-----------| + CCW | OFF | REVERSE | NOP | PAUSE | NOP | + |-----------|-----------|-----------|-----------|-----------| + PAUSE | OFF | CW | CCW | NOP | RESUME | + |-----------|-----------|-----------|-----------|-----------| + RESUME | invalid | invalid | invalid | invalid | invalid | + |-----------|-----------|-----------|-----------|-----------| + Actions: - OFF Turn spindle off. Even if it's already off (reloads polarities) - CW Turn spindle on clockwise @@ -140,10 +136,7 @@ void spindle_reset() - PAUSE Turn off spindle, enter PAUSE state - RESUME Turn spindle on CW or CCW as before - NOP No operation, ignore - - NOPCW No-op if spinning up to CW. If the spinning to CCW perform a REVERSE - - NOPCCW No-op if spinning up to CCW. If the spinning to CW perform a REVERSE - - REV Reverse spindle direction (Q: need a cycle to spin down then back up again?) - - XXXXXXX Impossible box. RESUME is not a state and SPINUP/SPINDN are not inputs + - REVERSE Reverse spindle direction (Q: need a cycle to spin down then back up again?) */ static void _exec_spindle_control(float *value, bool *flag) @@ -152,18 +145,18 @@ static void _exec_spindle_control(float *value, bool *flag) if (control > SPINDLE_ACTION_MAX) { return; } - spControl matrix[40] = { + spControl state = spindle.state; + if (state >= SPINDLE_ACTION_MAX) { +// rpt_exception(STAT_SPINDLE_ASSERTION_FAILURE, "illegal spindle state"); + return; + } + spControl matrix[20] = { SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_OFF, SPINDLE_NOP, SPINDLE_REV, SPINDLE_PAUSE, SPINDLE_NOP, SPINDLE_OFF, SPINDLE_REV, SPINDLE_NOP, SPINDLE_PAUSE, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_RESUME, - SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_PAUSE, SPINDLE_NOP, - SPINDLE_OFF, SPINDLE_NOPCW, SPINDLE_NOPCCW, SPINDLE_NOP, SPINDLE_NOP, - SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP, SPINDLE_NOP // impossible row added for safety + SPINDLE_OFF, SPINDLE_CW, SPINDLE_CCW, SPINDLE_NOP, SPINDLE_RESUME }; - uint8_t index = ((spindle.state & 0x07) * 5) + control; - spControl action = matrix[index]; + spControl action = matrix[(state*5)+control]; SPINDLE_DIRECTION_ASSERT; // ensure that the spindle direction is sane int8_t enable_bit = 0; // default to 0=off @@ -171,7 +164,7 @@ static void _exec_spindle_control(float *value, bool *flag) bool spinup_delay = false; switch (action) { - case SPINDLE_NOP: case SPINDLE_NOPCW: case SPINDLE_NOPCCW: { return; } // reversals not handled yet + case SPINDLE_NOP: { return; } case SPINDLE_OFF: { // enable_bit already set for this case dir_bit = spindle.direction-1; // spindle direction was stored as '1' & '2' @@ -197,7 +190,7 @@ static void _exec_spindle_control(float *value, bool *flag) spinup_delay = true; break; } - default: {} // keeps the compiler happy + default: {} // reversals not handled yet } // Apply the enable and direction bits and adjust the PWM as required @@ -253,12 +246,21 @@ stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, * spindle_speed_immediate() - execute spindle speed change immediately * spindle_speed_sync() - queue a spindle speed change to the planner buffer * _exec_spindle_speed() - actually execute the spindle speed command + * + * Setting S0 is considered as turning spindle off. Setting S to non-zero from S0 + * will enable a spinup delay if spinups are npn-zero. */ static void _exec_spindle_speed(float *value, bool *flag) { + float previous_speed = spindle.speed; + spindle.speed = value[0]; pwm_set_duty(PWM_1, _get_spindle_pwm(spindle, pwm)); + + if (fp_ZERO(previous_speed)) { + mp_request_out_of_band_dwell(spindle.spinup_delay); + } } static stat_t _casey_jones(float speed) diff --git a/g2core/spindle.h b/g2core/spindle.h index 9642022b..0ce83eef 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -52,12 +52,7 @@ typedef enum { // how spindle controls are presented by the Gco SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW - - SPINDLE_SPINUP, // spindle is coming up to speed - SPINDLE_SPINDOWN, // spindle is spinning down to stop SPINDLE_NOP, // no operation - SPINDLE_NOPCW, // no operation, starts from clockwise - SPINDLE_NOPCCW, // no operation, starts from counterclockwise SPINDLE_REV // operation to reverse spindle direction } spControl; #define SPINDLE_ACTION_MAX SPINDLE_RESUME From e9742a1a05425a22c3ceffa0a51ef37d35dbc15b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 17 Jan 2017 07:06:32 -0500 Subject: [PATCH 085/283] Coolant work. Checkpoint --- g2core/alarm.cpp | 2 +- g2core/canonical_machine.cpp | 2 +- g2core/config_app.cpp | 13 +- g2core/coolant.cpp | 231 ++++++++++++++++----------- g2core/coolant.h | 94 +++++++---- g2core/cycle_feedhold.cpp | 4 +- g2core/gcode_parser.cpp | 10 +- g2core/settings/settings_makeblock.h | 3 +- 8 files changed, 214 insertions(+), 145 deletions(-) mode change 100755 => 100644 g2core/coolant.cpp mode change 100755 => 100644 g2core/coolant.h diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 9b580c3b..dbbdfeab 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -124,7 +124,7 @@ void cm_halt_all(void) { cm_halt_motion(); spindle_control_immediate(SPINDLE_OFF); - cm_coolant_off_immediate(); + coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); } void cm_halt_motion(void) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0d11172c..53c6a6d6 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1556,7 +1556,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default spindle_control_immediate(SPINDLE_OFF); // M5 - cm_coolant_off_immediate(); // M9 + coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH);// M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. cm_reset_overrides(); // reset feedrate the spindle overrides diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 489cfe2b..f09d7654 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -850,11 +850,11 @@ const cfgItem_t cfgArray[] = { { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed // Coolant functions - { "sys","cofp",_fipn,0, cm_print_cofp,get_ui8, set_01, (float *)&coolant.flood_polarity, COOLANT_FLOOD_POLARITY }, - { "sys","comp",_fipn,0, cm_print_comp,get_ui8, set_01, (float *)&coolant.mist_polarity, COOLANT_MIST_POLARITY }, - { "sys","coph",_fipn,0, cm_print_coph,get_ui8, set_01, (float *)&coolant.pause_on_hold, COOLANT_PAUSE_ON_HOLD }, - { "", "com", _fiz, 0, cm_print_com, get_ui8, set_nul, (float *)&coolant.mist_enable, 0 }, // get mist coolant enable - { "", "cof", _fiz, 0, cm_print_cof, get_ui8, set_nul, (float *)&coolant.flood_enable, 0 }, // get flood coolant enable + { "co","coph", _fip, 0, co_print_coph, co_get_coph, co_set_coph, (float *)&cs.null, COOLANT_PAUSE_ON_HOLD }, + { "co","comp", _fip, 0, co_print_comp, co_get_comp, co_set_comp, (float *)&cs.null, COOLANT_MIST_POLARITY }, + { "co","cofp", _fip, 0, co_print_cofp, co_get_cofp, co_set_cofp, (float *)&cs.null, COOLANT_FLOOD_POLARITY }, + { "co","com", _f0, 0, co_print_com, co_get_com, co_set_com, (float *)&cs.null, 0 }, // mist coolant enable + { "co","cof", _f0, 0, co_print_cof, co_get_com, co_set_com, (float *)&cs.null, 0 }, // flood coolant enable // General system parameters { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, @@ -1062,10 +1062,11 @@ const cfgItem_t cfgArray[] = { // - Optional DIAGNOSTIC_PARAMETERS // - Uber groups (count these separately) -#define FIXED_GROUPS 3 +#define FIXED_GROUPS 4 { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // system group { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PWM 1 group { "","sp", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // Spindle group + { "","co", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // Coolant group #define AXIS_GROUPS AXES { "","x", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis groups diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp old mode 100755 new mode 100644 index f19cea95..31dee229 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -2,7 +2,7 @@ * coolant.cpp - canonical machine coolant driver * This file is part of the g2core project * - * Copyright (c) 2015 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -37,121 +37,160 @@ /**** Allocate structures ****/ -cmCoolantSingleton_t coolant; +coCoolant_t coolant; /**** Static functions ****/ -static void _exec_coolant_control(float* value, bool* flags); +static void _exec_coolant_control(float* value, bool* flag); /* * coolant_init() * coolant_reset() */ void coolant_init() { - coolant.mist_enable = COOLANT_OFF; - coolant.flood_enable = COOLANT_OFF; + coolant.mist_state = COOLANT_OFF; + coolant.flood_state = COOLANT_OFF; } void coolant_reset() { coolant_init(); - cm_coolant_off_immediate(); + coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); } /* - * cm_coolant_off_immediate() - turn off all coolant - * cm_coolant_optional_pause() - pause coolants if option is true - * cm_coolant_resume() - restart paused coolants + * coolant_control_immediate() - execute coolant control immediately + * coolant_control_sync() - queue a coolant control to the planner buffer + * _exec_coolant_control() - actually execute the coolant command */ -void cm_coolant_off_immediate() { - float value[] = {0, 0, 0, 0, 0, 0}; - bool flags[] = {1, 1, 0, 0, 0, 0}; +stat_t coolant_control_immediate(coControl control, coSelect select) +{ + float value[] = { (float)control }; + bool flags[] = { (select & COOLANT_MIST), (select & COOLANT_FLOOD) }; _exec_coolant_control(value, flags); -} + return(STAT_OK); +} -void cm_coolant_optional_pause(bool option) { - if (option) { - float value[] = {0, 0, 0, 0, 0, 0}; - bool flags[] = {0, 0, 0, 0, 0, 0}; - - if (coolant.flood_enable == COOLANT_ON) { - coolant.flood_enable = COOLANT_PAUSE; // mark as paused - flags[COOLANT_FLOOD] = 1; // set flag so it will turn off - } - if (coolant.mist_enable == COOLANT_ON) { - coolant.mist_enable = COOLANT_PAUSE; // mark as paused - flags[COOLANT_MIST] = 1; - } - _exec_coolant_control(value, flags); // execute (w/o changing local state) +stat_t coolant_control_sync(coControl control, coSelect select) +{ + // skip the PAUSE operation if pause-enable is not enabled (pause-on-hold) + if ((control == COOLANT_PAUSE) && (!coolant.pause_enable)) { + return (STAT_OK); } -} - -void cm_coolant_resume() { -// float value[] = { 1,1,0,0,0,0 }; // ++++ Will this work? No need to set 'value' below - float value[] = {0, 0, 0, 0, 0, 0}; - bool flags[] = {0, 0, 0, 0, 0, 0}; - - if (coolant.flood_enable == COOLANT_PAUSE) { - coolant.flood_enable = COOLANT_ON; - value[COOLANT_FLOOD] = 1; - flags[COOLANT_FLOOD] = true; - } - if (coolant.mist_enable == COOLANT_PAUSE) { - coolant.mist_enable = COOLANT_ON; - value[COOLANT_MIST] = 1; - flags[COOLANT_MIST] = true; - } - _exec_coolant_control(value, flags); -} - -/* - * cm_mist_coolant_control() - access points from Gcode parser - * cm_flood_coolant_control() - access points from Gcode parser - * _exec_coolant_control() - combined flood and mist coolant control - * - * - value[0] is flood state - * - value[1] is mist state - * - uses flags to determine which to run - */ - -stat_t cm_flood_coolant_control(uint8_t flood_enable) { - float value[] = {(float)flood_enable, 0, 0, 0, 0, 0}; - bool flags[] = {1, 0, 0, 0, 0, 0}; + + // queue the coolant control + float value[] = { (float)control }; + bool flags[] = { (select & COOLANT_MIST), (select & COOLANT_FLOOD) }; mp_queue_command(_exec_coolant_control, value, flags); - return (STAT_OK); + return(STAT_OK); } -stat_t cm_mist_coolant_control(uint8_t mist_enable) { - float value[] = {0, (float)mist_enable, 0, 0, 0, 0}; - bool flags[] = {0, 1, 0, 0, 0, 0}; - mp_queue_command(_exec_coolant_control, value, flags); - return (STAT_OK); -} - -// NOTE: flood and mist coolants are mapped to the same pin - see hardware.h -#define _set_flood_enable_bit_hi() flood_enable_pin.set() -#define _set_flood_enable_bit_lo() flood_enable_pin.clear() -#define _set_mist_enable_bit_hi() mist_enable_pin.set() -#define _set_mist_enable_bit_lo() mist_enable_pin.clear() - -static void _exec_coolant_control(float* value, bool* flags) { - if (flags[COOLANT_FLOOD]) { - coolant.flood_enable = (cmCoolantEnable)value[COOLANT_FLOOD]; - if (!((coolant.flood_enable & 0x01) ^ coolant.flood_polarity)) { // inverted XOR - _set_flood_enable_bit_hi(); - } else { - _set_flood_enable_bit_lo(); +static void _exec_coolant_control(float* value, bool* flag) { + + coControl control = (coControl)value[0]; + if (control > COOLANT_ACTION_MAX) { + return; + } + + bool action; // set true to perform the action + int8_t enable_bit; +// coControl previous_state = control.mist_state; + + if (flag[0]) { // Mist, M7 + action = true; + enable_bit = 0; + switch (control) { + case COOLANT_OFF: { + coolant.mist_state = COOLANT_OFF; + break; + } + case COOLANT_ON: { + coolant.mist_state = COOLANT_ON; + enable_bit = 1; + break; + } + case COOLANT_PAUSE: { + if (coolant.mist_state == COOLANT_ON) { + coolant.mist_state = COOLANT_PAUSE; + } else { + action = false; + } + break; + } + case COOLANT_RESUME: { + if (coolant.mist_state == COOLANT_PAUSE) { + coolant.mist_state = COOLANT_ON; + enable_bit = 1; + } else { + action = false; + } + break; + } + } + if (action) { + if (!(enable_bit ^ coolant.mist_polarity)) { // inverted XOR + mist_enable_pin.set(); + } else { + mist_enable_pin.clear(); + } } } - if (flags[COOLANT_MIST]) { - coolant.mist_enable = (cmCoolantEnable)value[COOLANT_MIST]; - if (!((coolant.mist_enable & 0x01) ^ coolant.mist_polarity)) { - _set_mist_enable_bit_hi(); - } else { - _set_mist_enable_bit_lo(); + if (flag[1]) { // Flood, M8 + action = true; + enable_bit = 0; + switch (control) { + case COOLANT_OFF: { + coolant.flood_state = COOLANT_OFF; + break; + } + case COOLANT_ON: { + coolant.flood_state = COOLANT_ON; + enable_bit = 1; + break; + } + case COOLANT_PAUSE: { + if (coolant.flood_state == COOLANT_ON) { + coolant.flood_state = COOLANT_PAUSE; + } else { + action = false; + } + break; + } + case COOLANT_RESUME: { + if (coolant.flood_state == COOLANT_PAUSE) { + coolant.flood_state = COOLANT_ON; + enable_bit = 1; + } else { + action = false; + } + break; + } } - } -} + if (action) { + if (!(enable_bit ^ coolant.flood_polarity)) { // inverted XOR + flood_enable_pin.set(); + } else { + flood_enable_pin.clear(); + } + } + } +} + +/*********************************************************************************** + **** Coolant Settings ************************************************************* + ***********************************************************************************/ + +stat_t co_get_coph(nvObj_t *nv) { return(get_int(nv, coolant.pause_enable)); } +stat_t co_set_coph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.pause_enable, 0, 1)); } +stat_t co_get_comp(nvObj_t *nv) { return(get_int(nv, coolant.mist_polarity)); } +stat_t co_set_comp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.mist_polarity, 0, 1)); } +stat_t co_get_cofp(nvObj_t *nv) { return(get_int(nv, coolant.flood_polarity)); } +stat_t co_set_cofp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.flood_polarity, 0, 1)); } + +stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.flood_state)); } +stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_MIST)); } +stat_t co_get_cof(nvObj_t *nv) { return(get_float(nv, coolant.mist_state)); } +stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_FLOOD)); } /*********************************************************************************** * TEXT MODE SUPPORT @@ -163,13 +202,13 @@ static void _exec_coolant_control(float* value, bool* flags) { const char fmt_coph[] = "[coph] coolant pause on hold%7d [0=no,1=pause_on_hold]\n"; const char fmt_comp[] = "[comp] coolant mist polarity%7d [0=low is ON,1=high is ON]\n"; const char fmt_cofp[] = "[cofp] coolant flood polarity%6d [0=low is ON,1=high is ON]\n"; -const char fmt_com[] = "Mist coolant:%6d [0=OFF,1=ON]\n"; -const char fmt_cof[] = "Flood coolant:%5d [0=OFF,1=ON]\n"; +const char fmt_com[] = "[com] coolant mist%16d [0=OFF,1=ON]\n"; +const char fmt_cof[] = "[cof] coolant flood%15d [0=OFF,1=ON]\n"; -void cm_print_coph(nvObj_t* nv) { text_print(nv, fmt_coph); } // TYPE_INT -void cm_print_comp(nvObj_t* nv) { text_print(nv, fmt_comp); } // TYPE_INT -void cm_print_cofp(nvObj_t* nv) { text_print(nv, fmt_cofp); } // TYPE_INT -void cm_print_com(nvObj_t* nv) { text_print(nv, fmt_com); } // TYPE_INT -void cm_print_cof(nvObj_t* nv) { text_print(nv, fmt_cof); } // TYPE_INT +void co_print_coph(nvObj_t* nv) { text_print(nv, fmt_coph); } // TYPE_INT +void co_print_comp(nvObj_t* nv) { text_print(nv, fmt_comp); } // TYPE_INT +void co_print_cofp(nvObj_t* nv) { text_print(nv, fmt_cofp); } // TYPE_INT +void co_print_com(nvObj_t* nv) { text_print(nv, fmt_com); } // TYPE_INT +void co_print_cof(nvObj_t* nv) { text_print(nv, fmt_cof); } // TYPE_INT #endif // __TEXT_MODE diff --git a/g2core/coolant.h b/g2core/coolant.h old mode 100755 new mode 100644 index b30df2a4..d961fea8 --- a/g2core/coolant.h +++ b/g2core/coolant.h @@ -2,7 +2,7 @@ * coolant.h - coolant driver * This file is part of the g2core project * - * Copyright (c) 2015 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -31,31 +31,49 @@ typedef enum { COOLANT_OFF = 0, // don't change the order. It gets masked. COOLANT_ON, - COOLANT_PAUSE -} cmCoolantEnable; + COOLANT_PAUSE, + COOLANT_RESUME +} coControl; +#define COOLANT_ACTION_MAX COOLANT_RESUME -typedef enum { COOLANT_ACTIVE_LOW = 0, COOLANT_ACTIVE_HIGH } cmCoolantPolarity; +// *** NOTE: The coolant polarity active hi/low values currently agree with ioMode in gpio.h +// These will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 +// See: https://github.com/synthetos/g2_private/wiki/GPIO-Design-Discussion#settings-common-to-all-io-types -typedef enum { // used to index the value and flag vectors for coolant execs - COOLANT_FLOOD = 0, - COOLANT_MIST -} cmCoolantIndex; +typedef enum { + COOLANT_ACTIVE_LOW = 0, + COOLANT_ACTIVE_HIGH +} coPolarity; + +typedef enum { // used as a bitmask + COOLANT_NONE = 0, // none selected + COOLANT_MIST = 1, // mist coolant + COOLANT_FLOOD = 2, // flood coolant + COOLANT_BOTH = 3 // both types ('or' of both coolants) +} coSelect; /* - * Coolant control structure + * Coolant control structures */ -typedef struct cmCoolantSingleton { - bool pause_on_hold; // true to pause coolant on feedhold +typedef struct coCoolantChannel { + bool pause_enable; // {coph:} pause on feedhold + coControl state; // coolant state: coControl + coPolarity polarity; // 0=active low, 1=active high +} coCoolantChannel_t; - cmCoolantEnable flood_enable; // COOLANT_ON = flood on (M8), COOLANT_OFF = off (M9) - cmCoolantPolarity flood_polarity; // 0=active low, 1=active high +typedef struct coCoolant { - cmCoolantEnable mist_enable; // COOLANT_ON = mist on (M7), COOLANT_OFF = off (M9) - cmCoolantPolarity mist_polarity; // 0=active low, 1=active high - -} cmCoolantSingleton_t; -extern cmCoolantSingleton_t coolant; +// coCoolantChannel_t mist; +// coCoolantChannel_t flood; + + bool pause_enable; // {coph:} pause on feedhold + coControl mist_state; // M7 coolant + coPolarity mist_polarity; // 0=active low, 1=active high + coControl flood_state; // M8 coolant + coPolarity flood_polarity; // 0=active low, 1=active high +} coCoolant_t; +extern coCoolant_t coolant; /* * Global Scope Functions @@ -64,29 +82,39 @@ extern cmCoolantSingleton_t coolant; void coolant_init(); void coolant_reset(); -stat_t cm_mist_coolant_control(uint8_t mist_enable); // M7 -stat_t cm_flood_coolant_control(uint8_t flood_enable); // M8, M9 -void cm_coolant_off_immediate(void); -void cm_coolant_optional_pause(bool option); -void cm_coolant_resume(void); +stat_t coolant_control_immediate(coControl control, coSelect select); +stat_t coolant_control_sync(coControl control, coSelect select); + +stat_t co_get_coph(nvObj_t *nv); +stat_t co_set_coph(nvObj_t *nv); + +stat_t co_get_comp(nvObj_t *nv); +stat_t co_set_comp(nvObj_t *nv); +stat_t co_get_cofp(nvObj_t *nv); +stat_t co_set_cofp(nvObj_t *nv); + +stat_t co_get_com(nvObj_t *nv); +stat_t co_set_com(nvObj_t *nv); +stat_t co_get_cof(nvObj_t *nv); +stat_t co_set_cof(nvObj_t *nv); /*--- text_mode support functions ---*/ #ifdef __TEXT_MODE -void cm_print_coph(nvObj_t* nv); // coolant pause on hold -void cm_print_comp(nvObj_t* nv); // coolant polarity mist -void cm_print_cofp(nvObj_t* nv); // coolant polarity flood -void cm_print_com(nvObj_t* nv); // report mist coolant state -void cm_print_cof(nvObj_t* nv); // report flood coolant state +void co_print_coph(nvObj_t* nv); // coolant pause on hold +void co_print_comp(nvObj_t* nv); // coolant polarity mist +void co_print_cofp(nvObj_t* nv); // coolant polarity flood +void co_print_com(nvObj_t* nv); // report mist coolant state +void co_print_cof(nvObj_t* nv); // report flood coolant state #else -#define cm_print_coph tx_print_stub -#define cm_print_comp tx_print_stub -#define cm_print_cofp tx_print_stub -#define cm_print_com tx_print_stub -#define cm_print_cof tx_print_stub +#define co_print_coph tx_print_stub +#define co_print_comp tx_print_stub +#define co_print_cofp tx_print_stub +#define co_print_com tx_print_stub +#define co_print_cof tx_print_stub #endif // __TEXT_MODE diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 9709249c..54a44887 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -251,7 +251,7 @@ stat_t cm_switch_to_hold_context() } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause - // coolant_control_sync(COOLANT_PAUSE); // optional coolant pause + coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause return (STAT_OK); } @@ -281,7 +281,7 @@ stat_t cm_return_from_hold_context() // LATER: if value == true return with // *** While still in secondary machine: spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused -// coolant_control_sync(COOLANT_RESUME); // resume coolant if paused + coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused // perform the G30 move and queue a wait float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index e28a17cb..f75288b1 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -754,10 +754,12 @@ static stat_t _execute_gcode_block(char *active_comment) if (gf.spindle_control) { // spindle OFF, CW, CCW ritorno(spindle_control_sync((spControl)gv.spindle_control)); } - - EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 - EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF - + if (gf.mist_coolant) { + ritorno(coolant_control_sync((coControl)gv.mist_coolant, COOLANT_MIST)); // M7, M9 + } + if (gf.flood_coolant) { + ritorno(coolant_control_sync((coControl)gv.flood_coolant, COOLANT_FLOOD)); // M8, M9 also disables mist coolant if OFF + } if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block } diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index db63fd58..68a44ae0 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -45,13 +45,12 @@ #define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high #define SPINDLE_PAUSE_ON_HOLD true #define SPINDLE_SPINUP_DELAY 2.0 -#define SPINDLE_SPINDOWN_DELAY 0.0 #define SPINDLE_SPEED_MIN 0.0 #define SPINDLE_SPEED_MAX 20000.0 #define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high #define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD false +#define COOLANT_PAUSE_ON_HOLD true #define FEEDHOLD_Z_LIFT 10 // mm to lift Z on feedhold From 7ebf75314ed54839731f47ba6aef1affc36b7adb Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 17 Jan 2017 07:41:24 -0500 Subject: [PATCH 086/283] Checkpoint coolant control --- g2core/coolant.cpp | 163 +++++++++++++++++++-------------------------- g2core/coolant.h | 11 +-- 2 files changed, 72 insertions(+), 102 deletions(-) diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index 31dee229..8084eae1 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -48,8 +48,8 @@ static void _exec_coolant_control(float* value, bool* flag); * coolant_reset() */ void coolant_init() { - coolant.mist_state = COOLANT_OFF; - coolant.flood_state = COOLANT_OFF; + coolant.mist.state = COOLANT_OFF; + coolant.flood.state = COOLANT_OFF; } void coolant_reset() { @@ -74,7 +74,7 @@ stat_t coolant_control_immediate(coControl control, coSelect select) stat_t coolant_control_sync(coControl control, coSelect select) { // skip the PAUSE operation if pause-enable is not enabled (pause-on-hold) - if ((control == COOLANT_PAUSE) && (!coolant.pause_enable)) { + if ((control == COOLANT_PAUSE) && (!coolant.mist.pause_enable)) { return (STAT_OK); } @@ -85,111 +85,88 @@ stat_t coolant_control_sync(coControl control, coSelect select) return(STAT_OK); } +//static void _exec_coolant_helper(coControl control, coCoolantChannel_t *co, (*void)set(), (*void)clear()) { +static void _exec_coolant_helper(coCoolantChannel_t &co, coControl control) { + + bool action = true; + int8_t enable_bit = 0; + switch (control) { + case COOLANT_OFF: { + co.state = COOLANT_OFF; + break; + } + case COOLANT_ON: { + co.state = COOLANT_ON; + enable_bit = 1; + break; + } + case COOLANT_PAUSE: { + if (co.state == COOLANT_ON) { + co.state = COOLANT_PAUSE; + } else { + action = false; + } + break; + } + case COOLANT_RESUME: { + if (co.state == COOLANT_PAUSE) { + co.state = COOLANT_ON; + enable_bit = 1; + } else { + action = false; + } + break; + } + } + if (action) { + if (&co == &coolant.mist) { + if (!(enable_bit ^ coolant.mist.polarity)) { // inverted XOR + mist_enable_pin.set(); + } else { + mist_enable_pin.clear(); + } + } else { + if (!(enable_bit ^ coolant.flood.polarity)) { // inverted XOR + flood_enable_pin.set(); + } else { + flood_enable_pin.clear(); + } + } + } +} + static void _exec_coolant_control(float* value, bool* flag) { coControl control = (coControl)value[0]; if (control > COOLANT_ACTION_MAX) { return; } - - bool action; // set true to perform the action - int8_t enable_bit; -// coControl previous_state = control.mist_state; - if (flag[0]) { // Mist, M7 - action = true; - enable_bit = 0; - switch (control) { - case COOLANT_OFF: { - coolant.mist_state = COOLANT_OFF; - break; - } - case COOLANT_ON: { - coolant.mist_state = COOLANT_ON; - enable_bit = 1; - break; - } - case COOLANT_PAUSE: { - if (coolant.mist_state == COOLANT_ON) { - coolant.mist_state = COOLANT_PAUSE; - } else { - action = false; - } - break; - } - case COOLANT_RESUME: { - if (coolant.mist_state == COOLANT_PAUSE) { - coolant.mist_state = COOLANT_ON; - enable_bit = 1; - } else { - action = false; - } - break; - } - } - if (action) { - if (!(enable_bit ^ coolant.mist_polarity)) { // inverted XOR - mist_enable_pin.set(); - } else { - mist_enable_pin.clear(); - } - } + _exec_coolant_helper(coolant.mist, control); } - if (flag[1]) { // Flood, M8 - action = true; - enable_bit = 0; - switch (control) { - case COOLANT_OFF: { - coolant.flood_state = COOLANT_OFF; - break; - } - case COOLANT_ON: { - coolant.flood_state = COOLANT_ON; - enable_bit = 1; - break; - } - case COOLANT_PAUSE: { - if (coolant.flood_state == COOLANT_ON) { - coolant.flood_state = COOLANT_PAUSE; - } else { - action = false; - } - break; - } - case COOLANT_RESUME: { - if (coolant.flood_state == COOLANT_PAUSE) { - coolant.flood_state = COOLANT_ON; - enable_bit = 1; - } else { - action = false; - } - break; - } - } - if (action) { - if (!(enable_bit ^ coolant.flood_polarity)) { // inverted XOR - flood_enable_pin.set(); - } else { - flood_enable_pin.clear(); - } - } - } -} + if (flag[1]) { // Flood, M8 + _exec_coolant_helper(coolant.flood, control); + } +} /*********************************************************************************** **** Coolant Settings ************************************************************* ***********************************************************************************/ -stat_t co_get_coph(nvObj_t *nv) { return(get_int(nv, coolant.pause_enable)); } -stat_t co_set_coph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.pause_enable, 0, 1)); } -stat_t co_get_comp(nvObj_t *nv) { return(get_int(nv, coolant.mist_polarity)); } -stat_t co_set_comp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.mist_polarity, 0, 1)); } -stat_t co_get_cofp(nvObj_t *nv) { return(get_int(nv, coolant.flood_polarity)); } -stat_t co_set_cofp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.flood_polarity, 0, 1)); } +stat_t co_get_coph(nvObj_t *nv) { return(get_int(nv, coolant.mist.pause_enable)); } +stat_t co_set_coph(nvObj_t *nv) { + ritorno(set_int(nv, (uint8_t &)coolant.mist.pause_enable, 0, 1)); + return (set_int(nv, (uint8_t &)coolant.flood.pause_enable, 0, 1)); +} -stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.flood_state)); } +stat_t co_get_comp(nvObj_t *nv) { return(get_int(nv, coolant.mist.polarity)); } +stat_t co_set_comp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.mist.polarity, 0, 1)); } +stat_t co_get_cofp(nvObj_t *nv) { return(get_int(nv, coolant.flood.polarity)); } +stat_t co_set_cofp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.flood.polarity, 0, 1)); } + +stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.flood.state)); } stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_MIST)); } -stat_t co_get_cof(nvObj_t *nv) { return(get_float(nv, coolant.mist_state)); } +stat_t co_get_cof(nvObj_t *nv) { return(get_float(nv, coolant.mist.state)); } stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_FLOOD)); } /*********************************************************************************** diff --git a/g2core/coolant.h b/g2core/coolant.h index d961fea8..8948b336 100644 --- a/g2core/coolant.h +++ b/g2core/coolant.h @@ -63,15 +63,8 @@ typedef struct coCoolantChannel { } coCoolantChannel_t; typedef struct coCoolant { - -// coCoolantChannel_t mist; -// coCoolantChannel_t flood; - - bool pause_enable; // {coph:} pause on feedhold - coControl mist_state; // M7 coolant - coPolarity mist_polarity; // 0=active low, 1=active high - coControl flood_state; // M8 coolant - coPolarity flood_polarity; // 0=active low, 1=active high + coCoolantChannel_t mist; // M7 - treated as the "master" for reading pause setting + coCoolantChannel_t flood; // M8 } coCoolant_t; extern coCoolant_t coolant; From 956840358cd86dd6133a5611a21b29c2ef51dd57 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 17 Jan 2017 08:53:59 -0500 Subject: [PATCH 087/283] Coolant testing and minor fixes. Passes current regressions. Pause and resume tested manually. --- g2core/config_app.cpp | 220 ++++++++++++++++++++-------------------- g2core/coolant.cpp | 10 +- g2core/coolant.h | 13 +-- g2core/gcode_parser.cpp | 27 +++-- 4 files changed, 139 insertions(+), 131 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index f09d7654..c213b35e 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -597,6 +597,117 @@ const cfgItem_t cfgArray[] = { { "g30","g30b",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, { "g30","g30c",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + // this is a 128bit UUID for identifying a previously committed job state + { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, + { "jid","jidb",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0}, + { "jid","jidc",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, + { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, + + // Spindle functions + { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, + { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, + { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, + // { "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, + { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, + { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, + { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, + { "sp","spdp", _fip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, + { "sp","spoe", _fip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, + { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, + { "sp","spc", _f0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state + { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed + + // Coolant functions + { "co","coph", _fip, 0, co_print_coph, co_get_coph, co_set_coph, (float *)&cs.null, COOLANT_PAUSE_ON_HOLD }, + { "co","comp", _fip, 0, co_print_comp, co_get_comp, co_set_comp, (float *)&cs.null, COOLANT_MIST_POLARITY }, + { "co","cofp", _fip, 0, co_print_cofp, co_get_cofp, co_set_cofp, (float *)&cs.null, COOLANT_FLOOD_POLARITY }, + { "co","com", _f0, 0, co_print_com, co_get_com, co_set_com, (float *)&cs.null, 0 }, // mist coolant enable + { "co","cof", _f0, 0, co_print_cof, co_get_cof, co_set_cof, (float *)&cs.null, 0 }, // flood coolant enable + + // General system parameters + { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, + { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, + { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT}, + { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, + { "sys","lim", _fipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, + { "sys","saf", _fipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, + { "sys","m48", _fipn, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 0 }, // M48/M49 feedrate & spindle override enable + { "sys","froe",_fipn, 0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, + { "sys","fro", _fipn, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, + { "sys","troe",_fipn, 0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","tro", _fipn, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, + { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors + { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors + + // Communications and reporting parameters +#ifdef __TEXT_MODE + { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, +#endif + { "sys","ej", _fipn, 0, js_print_ej, js_get_ej, js_set_ej, (float *)&cs.null, COMM_MODE }, + { "sys","jv", _fipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, + { "sys","qv", _fipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, + { "sys","sv", _fipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, + { "sys","si", _fipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, + + // Gcode defaults + // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco + { "sys","gpl", _fipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, (float *)&cs.null, GCODE_DEFAULT_PLANE }, + { "sys","gun", _fipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, (float *)&cs.null, GCODE_DEFAULT_UNITS }, + { "sys","gco", _fipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, + { "sys","gpa", _fipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, + { "sys","gdi", _fipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, + { "", "gc", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group + + // Actions and Reports + { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports + { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available + { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue + { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue + { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing + { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush + { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets + { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages + { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm + { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic + { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown + { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state + { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" + { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic + { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes + { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen + { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, + // { "", "switch",_f0,0, tx_print_nul, get_nul, cm_switch, (float *)&cs.null,0 }, + // { "", "return",_f0,0, tx_print_nul, get_nul, cm_return, (float *)&cs.null,0 }, + +#ifdef __HELP_SCREENS + { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen + { "", "h", _f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // alias for "help" +#endif + +#ifdef __USER_DATA + // User defined data groups + { "uda","uda0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[0], USER_DATA_A0 }, + { "uda","uda1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[1], USER_DATA_A1 }, + { "uda","uda2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[2], USER_DATA_A2 }, + { "uda","uda3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[3], USER_DATA_A3 }, + + { "udb","udb0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[0], USER_DATA_B0 }, + { "udb","udb1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[1], USER_DATA_B1 }, + { "udb","udb2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[2], USER_DATA_B2 }, + { "udb","udb3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[3], USER_DATA_B3 }, + + { "udc","udc0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[0], USER_DATA_C0 }, + { "udc","udc1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[1], USER_DATA_C1 }, + { "udc","udc2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[2], USER_DATA_C2 }, + { "udc","udc3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[3], USER_DATA_C3 }, + + { "udd","udd0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[0], USER_DATA_D0 }, + { "udd","udd1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[1], USER_DATA_D1 }, + { "udd","udd2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[2], USER_DATA_D2 }, + { "udd","udd3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[3], USER_DATA_D3 }, +#endif + // Tool table offsets { "tof","tofx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, { "tof","tofy",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, @@ -829,116 +940,7 @@ const cfgItem_t cfgArray[] = { { "tt32","tt32b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_B], TT32_B_OFFSET }, { "tt32","tt32c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_C], TT32_C_OFFSET }, - // this is a 128bit UUID for identifying a previously committed job state - { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, - { "jid","jidb",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0}, - { "jid","jidc",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, - { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, - // Spindle functions - { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, - { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, - { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, -// { "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, - { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, - { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, - { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, - { "sp","spdp", _fip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, - { "sp","spoe", _fip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, - { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, - { "sp","spc", _f0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state - { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed - - // Coolant functions - { "co","coph", _fip, 0, co_print_coph, co_get_coph, co_set_coph, (float *)&cs.null, COOLANT_PAUSE_ON_HOLD }, - { "co","comp", _fip, 0, co_print_comp, co_get_comp, co_set_comp, (float *)&cs.null, COOLANT_MIST_POLARITY }, - { "co","cofp", _fip, 0, co_print_cofp, co_get_cofp, co_set_cofp, (float *)&cs.null, COOLANT_FLOOD_POLARITY }, - { "co","com", _f0, 0, co_print_com, co_get_com, co_set_com, (float *)&cs.null, 0 }, // mist coolant enable - { "co","cof", _f0, 0, co_print_cof, co_get_com, co_set_com, (float *)&cs.null, 0 }, // flood coolant enable - - // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, - { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT}, - { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, - { "sys","lim", _fipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, - { "sys","saf", _fipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48", _fipn, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 0 }, // M48/M49 feedrate & spindle override enable - { "sys","froe",_fipn, 0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, - { "sys","fro", _fipn, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, - { "sys","troe",_fipn, 0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","tro", _fipn, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, - { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, - { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors - { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors - - // Communications and reporting parameters -#ifdef __TEXT_MODE - { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, -#endif - { "sys","ej", _fipn, 0, js_print_ej, js_get_ej, js_set_ej, (float *)&cs.null, COMM_MODE }, - { "sys","jv", _fipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, - { "sys","qv", _fipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, - { "sys","sv", _fipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, - { "sys","si", _fipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, - - // Gcode defaults - // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco - { "sys","gpl", _fipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, (float *)&cs.null, GCODE_DEFAULT_PLANE }, - { "sys","gun", _fipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, (float *)&cs.null, GCODE_DEFAULT_UNITS }, - { "sys","gco", _fipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, - { "sys","gpa", _fipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, - { "sys","gdi", _fipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, - { "", "gc", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group - - // Actions and Reports - { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports - { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available - { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue - { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue - { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing - { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush - { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets - { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages - { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm - { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic - { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown - { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state - { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" - { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic - { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes - { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen - { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, -// { "", "switch",_f0,0, tx_print_nul, get_nul, cm_switch, (float *)&cs.null,0 }, -// { "", "return",_f0,0, tx_print_nul, get_nul, cm_return, (float *)&cs.null,0 }, - -#ifdef __HELP_SCREENS - { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen - { "", "h", _f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // alias for "help" -#endif - -#ifdef __USER_DATA - // User defined data groups - { "uda","uda0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[0], USER_DATA_A0 }, - { "uda","uda1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[1], USER_DATA_A1 }, - { "uda","uda2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[2], USER_DATA_A2 }, - { "uda","uda3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[3], USER_DATA_A3 }, - - { "udb","udb0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[0], USER_DATA_B0 }, - { "udb","udb1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[1], USER_DATA_B1 }, - { "udb","udb2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[2], USER_DATA_B2 }, - { "udb","udb3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[3], USER_DATA_B3 }, - - { "udc","udc0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[0], USER_DATA_C0 }, - { "udc","udc1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[1], USER_DATA_C1 }, - { "udc","udc2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[2], USER_DATA_C2 }, - { "udc","udc3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[3], USER_DATA_C3 }, - - { "udd","udd0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[0], USER_DATA_D0 }, - { "udd","udd1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[1], USER_DATA_D1 }, - { "udd","udd2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[2], USER_DATA_D2 }, - { "udd","udd3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[3], USER_DATA_D3 }, -#endif // Diagnostic parameters #ifdef __DIAGNOSTIC_PARAMETERS diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index 8084eae1..5cea29cd 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -153,6 +153,11 @@ static void _exec_coolant_control(float* value, bool* flag) { **** Coolant Settings ************************************************************* ***********************************************************************************/ +stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.mist.state)); } +stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_MIST)); } +stat_t co_get_cof(nvObj_t *nv) { return(get_int(nv, coolant.flood.state)); } +stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_FLOOD)); } + stat_t co_get_coph(nvObj_t *nv) { return(get_int(nv, coolant.mist.pause_enable)); } stat_t co_set_coph(nvObj_t *nv) { ritorno(set_int(nv, (uint8_t &)coolant.mist.pause_enable, 0, 1)); @@ -164,11 +169,6 @@ stat_t co_set_comp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.mist.pol stat_t co_get_cofp(nvObj_t *nv) { return(get_int(nv, coolant.flood.polarity)); } stat_t co_set_cofp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.flood.polarity, 0, 1)); } -stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.flood.state)); } -stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_MIST)); } -stat_t co_get_cof(nvObj_t *nv) { return(get_float(nv, coolant.mist.state)); } -stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_FLOOD)); } - /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table diff --git a/g2core/coolant.h b/g2core/coolant.h index 8948b336..8755f48b 100644 --- a/g2core/coolant.h +++ b/g2core/coolant.h @@ -29,10 +29,11 @@ #define COOLANT_H_ONCE typedef enum { - COOLANT_OFF = 0, // don't change the order. It gets masked. - COOLANT_ON, - COOLANT_PAUSE, - COOLANT_RESUME + COOLANT_OFF = 0, // don't change the order. 0/1 get masked. + COOLANT_ON = 1, +// COOLANT_RESERVED = 2, // not used. ALigns pause and resume with spindle enum + COOLANT_PAUSE = 3, + COOLANT_RESUME = 4 } coControl; #define COOLANT_ACTION_MAX COOLANT_RESUME @@ -42,10 +43,10 @@ typedef enum { typedef enum { COOLANT_ACTIVE_LOW = 0, - COOLANT_ACTIVE_HIGH + COOLANT_ACTIVE_HIGH = 1 } coPolarity; -typedef enum { // used as a bitmask +typedef enum { // don't change the order. used as a bitmask COOLANT_NONE = 0, // none selected COOLANT_MIST = 1, // mist coolant COOLANT_FLOOD = 2, // flood coolant diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index f75288b1..e45c6497 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -58,8 +58,9 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context uint8_t tool; // Tool after T and M6 (tool_select and tool_change) uint8_t tool_select; // T value - T sets this value uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" - uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) - uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) + uint8_t coolant_mist; // TRUE = mist on (M7) + uint8_t coolant_flood; // TRUE = flood on (M8) + uint8_t coolant_off; // TRUE = turn off all coolants (M9) uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) bool m48_enable; // M48/M49 input (enables for feed and spindle) @@ -97,8 +98,9 @@ typedef struct GCodeFlags { // Gcode input flags bool tool; bool tool_select; bool tool_change; - bool mist_coolant; - bool flood_coolant; + bool coolant_mist; + bool coolant_flood; + bool coolant_off; bool spindle_control; bool m48_enable; @@ -638,9 +640,9 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 4: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_CCW); case 5: SET_MODAL (MODAL_GROUP_M7, spindle_control, SPINDLE_OFF); case 6: SET_NON_MODAL (tool_change, true); - case 7: SET_MODAL (MODAL_GROUP_M8, mist_coolant, true); - case 8: SET_MODAL (MODAL_GROUP_M8, flood_coolant, true); - case 9: SET_MODAL (MODAL_GROUP_M8, flood_coolant, false); + case 7: SET_MODAL (MODAL_GROUP_M8, coolant_mist, COOLANT_ON); + case 8: SET_MODAL (MODAL_GROUP_M8, coolant_flood, COOLANT_ON); + case 9: SET_MODAL (MODAL_GROUP_M8, coolant_off, COOLANT_OFF); case 48: SET_MODAL (MODAL_GROUP_M9, m48_enable, true); case 49: SET_MODAL (MODAL_GROUP_M9, m48_enable, false); case 50: @@ -754,11 +756,14 @@ static stat_t _execute_gcode_block(char *active_comment) if (gf.spindle_control) { // spindle OFF, CW, CCW ritorno(spindle_control_sync((spControl)gv.spindle_control)); } - if (gf.mist_coolant) { - ritorno(coolant_control_sync((coControl)gv.mist_coolant, COOLANT_MIST)); // M7, M9 + if (gf.coolant_mist) { + ritorno(coolant_control_sync((coControl)gv.coolant_mist, COOLANT_MIST)); // M7 } - if (gf.flood_coolant) { - ritorno(coolant_control_sync((coControl)gv.flood_coolant, COOLANT_FLOOD)); // M8, M9 also disables mist coolant if OFF + if (gf.coolant_flood) { + ritorno(coolant_control_sync((coControl)gv.coolant_flood, COOLANT_FLOOD)); // M8 + } + if (gf.coolant_off) { + ritorno(coolant_control_sync((coControl)gv.coolant_off, COOLANT_BOTH)); // M9 } if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block From d1e37dd57e3e1a6cd106353fb23a6776066660af Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 17 Jan 2017 08:59:01 -0500 Subject: [PATCH 088/283] Some comments --- g2core/coolant.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index 5cea29cd..23a57829 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -73,8 +73,9 @@ stat_t coolant_control_immediate(coControl control, coSelect select) stat_t coolant_control_sync(coControl control, coSelect select) { - // skip the PAUSE operation if pause-enable is not enabled (pause-on-hold) - if ((control == COOLANT_PAUSE) && (!coolant.mist.pause_enable)) { + // Skip the PAUSE operation if pause_enable is not enabled (pause-on-hold) + // The pause setting in mist coolant is treated as the master even though it's replicated in flood + if ((control == COOLANT_PAUSE) && (!coolant.mist.pause_enable)) { return (STAT_OK); } @@ -85,7 +86,6 @@ stat_t coolant_control_sync(coControl control, coSelect select) return(STAT_OK); } -//static void _exec_coolant_helper(coControl control, coCoolantChannel_t *co, (*void)set(), (*void)clear()) { static void _exec_coolant_helper(coCoolantChannel_t &co, coControl control) { bool action = true; From 9587f1338b7ce1055bdfd4d15da37a57e6311028 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 17 Jan 2017 09:37:54 -0500 Subject: [PATCH 089/283] Cleaned up some callback vector handling. --- g2core/canonical_machine.cpp | 83 ++++++++++++++++-------------------- g2core/config_app.cpp | 2 +- g2core/cycle_feedhold.cpp | 4 +- g2core/g2core_info.h | 2 +- g2core/planner.cpp | 7 +-- 5 files changed, 41 insertions(+), 57 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 53c6a6d6..80a392d7 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -910,9 +910,8 @@ stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool appl cm->tl_offset[axis] = tt.tt_offset[tool][axis]; } } - float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 };// pass coordinate system in value[0] element - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); // second vector (flags) is not used, so fake it + float value[] = { (float)cm->gm.coord_system }; // pass coordinate system in value[0] element + mp_queue_command(_exec_offset, value, nullptr); // second vector (flags) is not used, so fake it return (STAT_OK); } @@ -921,19 +920,17 @@ stat_t cm_cancel_tl_offset() for (uint8_t axis = AXIS_X; axis < AXES; axis++) { cm->tl_offset[axis] = 0; } - float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 };// pass coordinate system in value[0] element - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); // second vector (flags) is not used, so fake it + float value[] = { (float)cm->gm.coord_system }; + mp_queue_command(_exec_offset, value, nullptr); return (STAT_OK); } -stat_t cm_set_coord_system(const uint8_t coord_system) // set coordinate system sync'd with planner +stat_t cm_set_coord_system(const uint8_t coord_system) // set coordinate system sync'd with planner { cm->gm.coord_system = (cmCoordSystem)coord_system; - float value[] = { (float)coord_system,0,0,0,0,0 }; // pass coordinate system in value[0] element - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); // second vector (flags) is not used, so fake it + float value[] = { (float)coord_system }; + mp_queue_command(_exec_offset, value, nullptr); return (STAT_OK); } @@ -1043,9 +1040,8 @@ stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) } } // now pass the offset to the callback - setting the coordinate system also applies the offsets - float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; // pass coordinate system in value[0] element - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); + float value[] = { (float)cm->gm.coord_system }; // pass coordinate system in value[0] element + mp_queue_command(_exec_offset, value, nullptr); return (STAT_OK); } @@ -1055,27 +1051,24 @@ stat_t cm_reset_origin_offsets() for (uint8_t axis = AXIS_X; axis < AXES; axis++) { cm->gmx.origin_offset[axis] = 0; } - float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); + float value[] = { (float)cm->gm.coord_system }; + mp_queue_command(_exec_offset, value, nullptr); return (STAT_OK); } stat_t cm_suspend_origin_offsets() { cm->gmx.origin_offset_enable = false; - float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); + float value[] = { (float)cm->gm.coord_system }; + mp_queue_command(_exec_offset, value, nullptr); return (STAT_OK); } stat_t cm_resume_origin_offsets() { cm->gmx.origin_offset_enable = true; - float value[] = { (float)cm->gm.coord_system,0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_offset, value, flags); + float value[] = { (float)cm->gm.coord_system }; + mp_queue_command(_exec_offset, value, nullptr); return (STAT_OK); } @@ -1288,9 +1281,8 @@ stat_t cm_select_tool(const uint8_t tool_select) if (tool_select > TOOLS) { return (STAT_T_WORD_IS_INVALID); } - float value[] = { (float)tool_select, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_select_tool, value, flags); + float value[] = { (float)tool_select }; + mp_queue_command(_exec_select_tool, value, nullptr); return (STAT_OK); } @@ -1301,9 +1293,8 @@ static void _exec_select_tool(float *value, bool *flag) stat_t cm_change_tool(const uint8_t tool_change) { - float value[] = { (float)cm->gm.tool_select,0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_change_tool, value, flags); + float value[] = { (float)cm->gm.tool_select }; + mp_queue_command(_exec_change_tool, value, nullptr); return (STAT_OK); } @@ -1532,14 +1523,16 @@ stat_t cm_tro_control(const float P_word, const bool P_flag) // M50.1 static void _exec_program_finalize(float *value, bool *flag) { + cmMachineState machine_state = (cmMachineState)value[0]; cm_set_motion_state(MOTION_STOP); // Allow update in the alarm state, to accommodate queue flush (RAS) if ((cm->cycle_state == CYCLE_MACHINING || cm->cycle_state == CYCLE_OFF) && -// (cm->machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) +// (cm->machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) (cm->machine_state != MACHINE_SHUTDOWN)) { - cm->machine_state = (cmMachineState)value[0]; // don't update macs/cycs if we're in the middle of a canned cycle, - cm->cycle_state = CYCLE_OFF; // or if we're in machine alarm/shutdown mode +// cm->machine_state = (cmMachineState)value[0]; // don't update macs/cycs if we're in the middle of a canned cycle, + cm->machine_state = machine_state; // don't update macs/cycs if we're in the middle of a canned cycle, + cm->cycle_state = CYCLE_OFF; // or if we're in machine alarm/shutdown mode } // reset the rest of the states @@ -1548,7 +1541,8 @@ static void _exec_program_finalize(float *value, bool *flag) mp_zero_segment_velocity(); // for reporting purposes // perform the following resets if it's a program END - if (((uint8_t)value[0]) == MACHINE_PROGRAM_END) { +// if (((uint8_t)value[0]) == MACHINE_PROGRAM_END) { + if (machine_state == MACHINE_PROGRAM_END) { cm_suspend_origin_offsets(); // G92.2 - as per NIST // cm_reset_origin_offsets(); // G92.1 - alternative to above cm_set_coord_system(cm->default_coord_system); // reset to default coordinate system @@ -1577,39 +1571,34 @@ void cm_cycle_start() void cm_cycle_end() { if(cm->cycle_state == CYCLE_MACHINING) { - float value[] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_program_finalize(value, flags); + float value[] = { (float)MACHINE_PROGRAM_STOP }; + _exec_program_finalize(value, nullptr); } } void cm_canned_cycle_end() { cm->cycle_state = CYCLE_OFF; - float value[] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - _exec_program_finalize(value, flags); + float value[] = { (float)MACHINE_PROGRAM_STOP }; + _exec_program_finalize(value, nullptr); } void cm_program_stop() { - float value[] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_program_finalize, value, flags); + float value[] = { (float)MACHINE_PROGRAM_STOP }; + mp_queue_command(_exec_program_finalize, value, nullptr); } void cm_optional_program_stop() { - float value[] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_program_finalize, value, flags); + float value[] = { (float)MACHINE_PROGRAM_STOP }; + mp_queue_command(_exec_program_finalize, value, nullptr); } void cm_program_end() { - float value[] = { (float)MACHINE_PROGRAM_END, 0,0,0,0,0 }; - bool flags[] = { 1,0,0,0,0,0 }; - mp_queue_command(_exec_program_finalize, value, flags); + float value[] = { (float)MACHINE_PROGRAM_END }; + mp_queue_command(_exec_program_finalize, value, nullptr); } /*********************************************************************************** diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index c213b35e..abfe3496 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -607,7 +607,7 @@ const cfgItem_t cfgArray[] = { { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, - // { "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, + //{ "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 54a44887..a4d514df 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -280,8 +280,8 @@ stat_t cm_return_from_hold_context() // LATER: if value == true return with // *** While still in secondary machine: - spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused - coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused + spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused + coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused // perform the G30 move and queue a wait float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index f78002bb..8a253ea3 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.19 // fix Issue #209 Random Pauses +#define G2CORE_FIRMWARE_BUILD 100.19 // dev-195 Laserweb support. Based on feedhold lift branch p24 #define G2CORE_FIRMWARE_VERSION 0.99 #ifdef GIT_VERSION diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 78e762e5..e7d00b1f 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -355,12 +355,7 @@ stat_t mp_json_command(char *json_string) { // Never supposed to fail, since we stopped parsing when we were full jc.write_buffer(json_string); - - // We don't actually use these... - float value[] = { 0,0,0,0,0,0 }; - bool flags[] = { 0,0,0,0,0,0 }; - - mp_queue_command(_exec_json_command, value, flags); + mp_queue_command(_exec_json_command, nullptr, nullptr); return (STAT_OK); } From eb78d8aac2e8b3e9e5f24b874e0eed15b592f48d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 17 Jan 2017 12:24:26 -0500 Subject: [PATCH 090/283] Changed tool table to use getters and setters --- g2core/canonical_machine.cpp | 379 ++++++++++++++++---------------- g2core/canonical_machine.h | 2 + g2core/config_app.cpp | 403 +++++++++++++++++------------------ g2core/error.h | 2 +- 4 files changed, 391 insertions(+), 395 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 80a392d7..ad1e6a83 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1530,7 +1530,6 @@ static void _exec_program_finalize(float *value, bool *flag) if ((cm->cycle_state == CYCLE_MACHINING || cm->cycle_state == CYCLE_OFF) && // (cm->machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) (cm->machine_state != MACHINE_SHUTDOWN)) { -// cm->machine_state = (cmMachineState)value[0]; // don't update macs/cycs if we're in the middle of a canned cycle, cm->machine_state = machine_state; // don't update macs/cycs if we're in the middle of a canned cycle, cm->cycle_state = CYCLE_OFF; // or if we're in machine alarm/shutdown mode } @@ -1541,7 +1540,6 @@ static void _exec_program_finalize(float *value, bool *flag) mp_zero_segment_velocity(); // for reporting purposes // perform the following resets if it's a program END -// if (((uint8_t)value[0]) == MACHINE_PROGRAM_END) { if (machine_state == MACHINE_PROGRAM_END) { cm_suspend_origin_offsets(); // G92.2 - as per NIST // cm_reset_origin_offsets(); // G92.1 - alternative to above @@ -1632,6 +1630,163 @@ stat_t cm_json_wait(char *json_string) * These functions are not part of the NIST defined functions ***********************************************************************************/ +/***** AXIS HELPERS ***************************************************************** + * _coord() - return coordinate system number or -1 if error + * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) + * cm_get_axis_type() - return linear axis (0), rotary axis (1) or error (-1) + * cm_get_axis_char() - return ASCII char for axis given the axis number + */ + +static int8_t _coord(char *token) // extract coordinate system from 3rd character +{ + char *ptr; + char coord_list[] = {"456789"}; + + if ((ptr = strchr(coord_list, token[2])) == NULL) { // test the 3rd character against the string + return (-1); + } + return (ptr - coord_list); +} + +/* _axis() + * + * Cases that are handled by _get_axis(): + * - sys/... value is a system parameter (global), there is no axis + * - xam any axis parameter will return the axis number + * - 1ma any motor parameter will return the mapped axis for that motor + * - 1su an example of the above + * - mpox readouts + * - g54x offsets + * - tlx tool length offset + * - tt1x tool table + * - tt32x tool table + * - _tex diagnostic parameters + * + * Note that this function will return an erroneous value if called by a non-axis tag, + * such as 'coph' But it should not be called in these cases in any event. + */ + +static int8_t _axis(const index_t index) +{ + // test if this is a SYS parameter (global), in which case there will be no axis + if (strcmp("sys", cfgArray[index].group) == 0) { + return (AXIS_TYPE_SYSTEM); + } + + // if the leading character of the token is a number it's a motor + char c = cfgArray[index].token[0]; + if (isdigit(cfgArray[index].token[0])) { + return(st_cfg.mot[c-0x31].motor_map); + } + + // otherwise it's an axis. Or undefined, which is usually a global. + char *ptr; + char axes[] = {"xyzabc"}; + + if ((ptr = strchr(axes, c)) == NULL) { // test for prefixed axis + c = *(cfgArray[index].token + strlen(cfgArray[index].token) -1); // test for postfixed axis + if ((ptr = strchr(axes, c)) == NULL) { + return (AXIS_TYPE_UNDEFINED); + } + } + return (ptr - axes); +} + +cmAxisType cm_get_axis_type(const index_t index) +{ + int8_t axis = _axis(index); + if (axis <= AXIS_TYPE_UNDEFINED) { + return ((cmAxisType)axis); + } + if (axis >= AXIS_A) { + return (AXIS_TYPE_ROTARY); + } + return (AXIS_TYPE_LINEAR); +} + +char cm_get_axis_char(const int8_t axis) +{ + char axis_char[] = "XYZABC"; + if ((axis < 0) || (axis > AXES)) return (' '); + return (axis_char[axis]); +} + +/*********************************************************************************** + * Run Commands + * + * cm_run_qf() - flush planner queue + * cm_run_home() - run homing sequence + */ + +stat_t cm_run_qf(nvObj_t *nv) +{ + cm_request_queue_flush(); + return (STAT_OK); +} + +stat_t cm_run_home(nvObj_t *nv) +{ + if (fp_TRUE(nv->value)) { + float axes[] = { 1,1,1,1,1,1 }; + bool flags[] = { 1,1,1,1,1,1 }; + cm_homing_cycle_start(axes, flags); + } + return (STAT_OK); +} + +/* + * Jogging Commands + * + * cm_get_jogging_dest() + * cm_run_jog() + */ + +float cm_get_jogging_dest(void) +{ + return cm->jogging_dest; +} + +stat_t cm_run_jog(nvObj_t *nv) +{ + set_float(nv, cm->jogging_dest); + cm_jogging_cycle_start(_axis(nv->index)); + return (STAT_OK); +} + +/**** Functions called directly from cfgArray table - mostly wrappers **** + * _get_msg_helper() - helper to get string values + * + * cm_get_stat() - get combined machine state as value and string + * cm_get_macs() - get raw machine state as value and string + * cm_get_cycs() - get raw cycle state as value and string + * cm_get_mots() - get raw motion state as value and string + * cm_get_hold() - get raw hold state as value and string + * cm_get_home() - get raw homing state as value and string + * + * cm_get_unit() - get units mode as integer and display string + * cm_get_coor() - get goodinate system + * cm_get_momo() - get runtime motion mode + * cm_get_plan() - get model plane select + * cm_get_path() - get model path control mode + * cm_get_dist() - get model distance mode + * cm_get_admo() - get model arc distance mode + * cm_get_frmo() - get model feed rate mode + * cm_get_tool() - get tool + * cm_get_feed() - get feed rate + * cm_get_mline()- get model line number for status reports + * cm_get_line() - get active (model or runtime) line number for status reports + * cm_get_vel() - get runtime velocity + * cm_get_ofs() - get current work offset (runtime) + * cm_get_pos() - get current work position (runtime) + * cm_get_mpos() - get current machine position (runtime) + * + * cm_print_pos()- print work position (with proper units) + * cm_print_mpos()- print machine position (always mm units) + * cm_print_coor()- print coordinate offsets with linear units + * cm_print_corr()- print coordinate offsets with rotary units + */ + + // Strings for writing settings as nvObj string values // Ref: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=120881&start=0 @@ -1668,9 +1823,9 @@ static const char msg_stat11[] = "Interlock"; static const char msg_stat12[] = "Shutdown"; static const char msg_stat13[] = "Panic"; static const char *const msg_stat[] = { msg_stat0, msg_stat1, msg_stat2, msg_stat3, - msg_stat4, msg_stat5, msg_stat6, msg_stat7, - msg_stat8, msg_stat9, msg_stat10, msg_stat11, - msg_stat12, msg_stat13 }; + msg_stat4, msg_stat5, msg_stat6, msg_stat7, + msg_stat8, msg_stat9, msg_stat10, msg_stat11, + msg_stat12, msg_stat13 }; static const char msg_macs0[] = "Initializing"; static const char msg_macs1[] = "Ready"; static const char msg_macs2[] = "Alarm"; @@ -1681,8 +1836,8 @@ static const char msg_macs6[] = "Interlock"; static const char msg_macs7[] = "SHUTDOWN"; static const char msg_macs8[] = "PANIC"; static const char *const msg_macs[] = { msg_macs0, msg_macs1, msg_macs2, msg_macs3, - msg_macs4, msg_macs5, msg_macs6, msg_macs7, - msg_macs8 }; + msg_macs4, msg_macs5, msg_macs6, msg_macs7, + msg_macs8 }; static const char msg_cycs0[] = "Off"; static const char msg_cycs1[] = "Machining"; static const char msg_cycs2[] = "Homing"; @@ -1705,7 +1860,7 @@ static const char msg_hold5[] = "Decel Done"; static const char msg_hold6[] = "Pending"; static const char msg_hold7[] = "Hold"; static const char *const msg_hold[] = { msg_hold0, msg_hold1, msg_hold2, msg_hold3, - msg_hold4, msg_hold5, msg_hold6, msg_hold7 }; + msg_hold4, msg_hold5, msg_hold6, msg_hold7 }; static const char msg_home0[] = "Not Homed"; static const char msg_home1[] = "Homed"; @@ -1777,116 +1932,6 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; #endif // __TEXT_MODE - -/***** AXIS HELPERS ***************************************************************** - * _coord() - return coordinate system number or -1 if error - * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) - * cm_get_axis_type() - return linear axis (0), rotary axis (1) or error (-1) - * cm_get_axis_char() - return ASCII char for axis given the axis number - */ - -static int8_t _coord(char *token) // extract coordinate system from 3rd character -{ - char *ptr; - char coord_list[] = {"456789"}; - - if ((ptr = strchr(coord_list, token[2])) == NULL) { // test the 3rd character against the string - return (-1); - } - return (ptr - coord_list); -} - -/* _axis() - * - * Cases that are handled by _get_axis(): - * - sys/... value is a system parameter (global), there is no axis - * - xam any axis parameter will return the axis number - * - 1ma any motor parameter will return the mapped axis for that motor - * - 1su an example of the above - * - mpox readouts - * - g54x offsets - * - tlx tool length offset - * - tt1x tool table - * - tt32x tool table - * - _tex diagnostic parameters - */ - -static int8_t _axis(const index_t index) -{ - // test if this is a SYS parameter (global), in which case there will be no axis - if (strcmp("sys", cfgArray[index].group) == 0) { - return (AXIS_TYPE_SYSTEM); - } - - // if the leading character of the token is a number it's a motor - char c = cfgArray[index].token[0]; - if (isdigit(cfgArray[index].token[0])) { - return(st_cfg.mot[c-0x31].motor_map); - } - - // otherwise it's an axis. Or undefined, which is usually a global. - char *ptr; - char axes[] = {"xyzabc"}; - if ((ptr = strchr(axes, c)) == NULL) { // test the character in the 0 and 3 positions - if ((ptr = strchr(axes, cfgArray[index].token[3])) == NULL) { // to accommodate 'xam' and 'g54x' styles - return (AXIS_TYPE_UNDEFINED); - } - } - return (ptr - axes); -} - -cmAxisType cm_get_axis_type(const index_t index) -{ - int8_t axis = _axis(index); - if (axis <= AXIS_TYPE_UNDEFINED) { - return ((cmAxisType)axis); - } - if (axis >= AXIS_A) { - return (AXIS_TYPE_ROTARY); - } - return (AXIS_TYPE_LINEAR); -} - -char cm_get_axis_char(const int8_t axis) -{ - char axis_char[] = "XYZABC"; - if ((axis < 0) || (axis > AXES)) return (' '); - return (axis_char[axis]); -} - -/**** Functions called directly from cfgArray table - mostly wrappers **** - * _get_msg_helper() - helper to get string values - * - * cm_get_stat() - get combined machine state as value and string - * cm_get_macs() - get raw machine state as value and string - * cm_get_cycs() - get raw cycle state as value and string - * cm_get_mots() - get raw motion state as value and string - * cm_get_hold() - get raw hold state as value and string - * cm_get_home() - get raw homing state as value and string - * - * cm_get_unit() - get units mode as integer and display string - * cm_get_coor() - get goodinate system - * cm_get_momo() - get runtime motion mode - * cm_get_plan() - get model plane select - * cm_get_path() - get model path control mode - * cm_get_dist() - get model distance mode - * cm_get_admo() - get model arc distance mode - * cm_get_frmo() - get model feed rate mode - * cm_get_tool() - get tool - * cm_get_feed() - get feed rate - * cm_get_mline()- get model line number for status reports - * cm_get_line() - get active (model or runtime) line number for status reports - * cm_get_vel() - get runtime velocity - * cm_get_ofs() - get current work offset (runtime) - * cm_get_pos() - get current work position (runtime) - * cm_get_mpos() - get current machine position (runtime) - * - * cm_print_pos()- print work position (with proper units) - * cm_print_mpos()- print machine position (always mm units) - * cm_print_coor()- print coordinate offsets with linear units - * cm_print_corr()- print coordinate offsets with rotary units - */ - // Add the string for the enum to the nv, but leave it as a TYPE_INT stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], uint8_t value) { @@ -1913,28 +1958,7 @@ stat_t cm_get_frmo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_frmo, cm_get_fe stat_t cm_get_toolv(nvObj_t *nv) { return(get_int(nv, cm_get_tool(ACTIVE_MODEL))); } stat_t cm_get_mline(nvObj_t *nv) { return(get_int(nv, cm_get_linenum(MODEL))); } stat_t cm_get_line(nvObj_t *nv) { return(get_int(nv, cm_get_linenum(ACTIVE_MODEL))); } -/* -stat_t cm_get_toolv(nvObj_t *nv) -{ - nv->value = (float)cm_get_tool(ACTIVE_MODEL); - nv->valuetype = TYPE_INT; - return (STAT_OK); -} -stat_t cm_get_mline(nvObj_t *nv) -{ - nv->value = (float)cm_get_linenum(MODEL); - nv->valuetype = TYPE_INT; - return (STAT_OK); -} - -stat_t cm_get_line(nvObj_t *nv) -{ - nv->value = (float)cm_get_linenum(ACTIVE_MODEL); - nv->valuetype = TYPE_INT; - return (STAT_OK); -} -*/ stat_t cm_get_vel(nvObj_t *nv) { if (cm_get_motion_state() == MOTION_STOP) { @@ -1974,18 +1998,33 @@ stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_a **** TOOL TABLE AND OFFSET GET AND SET FUNCTIONS **** *****************************************************/ -stat_t cm_get_tof(nvObj_t *nv) +static uint8_t _tool(nvObj_t *nv) { - nv->value = cm->tl_offset[_axis(nv->index)]; - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return (STAT_OK); + if (nv->group[0] != 0) { + return (atoi(&nv->group[2])); // ttNN is the group, axis is in the token + } + return (atoi(&nv->token[2])); // ttNNx is all in the token } -stat_t cm_set_tof(nvObj_t *nv) +stat_t cm_get_tof(nvObj_t *nv) { return (get_float(nv, cm->tl_offset[_axis(nv->index)])); } +stat_t cm_set_tof(nvObj_t *nv) { return (set_float(nv, cm->tl_offset[_axis(nv->index)])); } + +stat_t cm_get_tt(nvObj_t *nv) +{ + uint8_t toolnum = _tool(nv); + if (toolnum > TOOLS) { + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + return (get_float(nv, tt.tt_offset[toolnum][_axis(nv->index)])); +} + +stat_t cm_set_tt(nvObj_t *nv) { - cm->tl_offset[_axis(nv->index)] = nv->value; - return (STAT_OK); + uint8_t toolnum = _tool(nv); + if (toolnum > TOOLS) { + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + return(set_float(nv, tt.tt_offset[toolnum][_axis(nv->index)])); } /************************************ @@ -2209,48 +2248,6 @@ stat_t cm_set_gpa(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_path_ stat_t cm_get_gdi(nvObj_t *nv) { return(get_int(nv, cm->default_distance_mode)); } stat_t cm_set_gdi(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_distance_mode, ABSOLUTE_DISTANCE_MODE, INCREMENTAL_DISTANCE_MODE)); } -/* - * Run Commands - * - * cm_run_qf() - flush planner queue - * cm_run_home() - run homing sequence - */ - -stat_t cm_run_qf(nvObj_t *nv) -{ - cm_request_queue_flush(); - return (STAT_OK); -} - -stat_t cm_run_home(nvObj_t *nv) -{ - if (fp_TRUE(nv->value)) { - float axes[] = { 1,1,1,1,1,1 }; - bool flags[] = { 1,1,1,1,1,1 }; - cm_homing_cycle_start(axes, flags); - } - return (STAT_OK); -} - -/* - * Jogging Commands - * - * cm_get_jogging_dest() - * cm_run_jog() - */ - -float cm_get_jogging_dest(void) -{ - return cm->jogging_dest; -} - -stat_t cm_run_jog(nvObj_t *nv) -{ - set_float(nv, cm->jogging_dest); - cm_jogging_cycle_start(_axis(nv->index)); - return (STAT_OK); -} - /*********************************************************************************** * Debugging Commands ***********************************************************************************/ @@ -2395,8 +2392,8 @@ void cm_print_tram(nvObj_t *nv) { text_print(nv, fmt_tram);}; // TYPE BOOL * cm_print_zb() * * cm_print_pos() - print position with unit displays for MM or Inches - * cm_print_mpo() - print position with fixed unit display - always in Degrees or MM - * cm_print_tram() - print if the coordinate system is rotated + * cm_print_mpo() - print position with fixed unit display - always in Degrees or MM + * cm_print_tram() - print if the coordinate system is rotated */ static const char fmt_Xam[] = "[%s%s] %s axis mode%18d %s\n"; diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 1329817e..51dcdc2a 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -531,6 +531,8 @@ stat_t cm_run_home(nvObj_t *nv); // start homing cycle stat_t cm_get_tof(nvObj_t *nv); // get tool offset stat_t cm_set_tof(nvObj_t *nv); // set tool offset +stat_t cm_get_tt(nvObj_t *nv); // get tool table value +stat_t cm_set_tt(nvObj_t *nv); // set tool table value stat_t cm_get_am(nvObj_t *nv); // get axis mode stat_t cm_set_am(nvObj_t *nv); // set axis mode diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index abfe3496..ba64bc8b 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -677,8 +677,6 @@ const cfgItem_t cfgArray[] = { { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, - // { "", "switch",_f0,0, tx_print_nul, get_nul, cm_switch, (float *)&cs.null,0 }, - // { "", "return",_f0,0, tx_print_nul, get_nul, cm_return, (float *)&cs.null,0 }, #ifdef __HELP_SCREENS { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen @@ -709,238 +707,237 @@ const cfgItem_t cfgArray[] = { #endif // Tool table offsets - { "tof","tofx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofy",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofz",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofa",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofb",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, - { "tof","tofc",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof,(float *)&cs.null, 0 }, + { "tof","tofx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofy",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofz",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofa",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofb",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofc",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tt1","tt1x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_X], TT1_X_OFFSET }, - { "tt1","tt1y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_Y], TT1_Y_OFFSET }, - { "tt1","tt1z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[1][AXIS_Z], TT1_Z_OFFSET }, - { "tt1","tt1a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_A], TT1_A_OFFSET }, - { "tt1","tt1b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_B], TT1_B_OFFSET }, - { "tt1","tt1c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[1][AXIS_C], TT1_C_OFFSET }, + // Tool table + { "tt1","tt1x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_X_OFFSET }, + { "tt1","tt1y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Y_OFFSET }, + { "tt1","tt1z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Z_OFFSET }, + { "tt1","tt1a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_A_OFFSET }, + { "tt1","tt1b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_B_OFFSET }, + { "tt1","tt1c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, - { "tt2","tt2x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[2][AXIS_X], TT2_X_OFFSET }, - { "tt2","tt2y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[2][AXIS_Y], TT2_Y_OFFSET }, - { "tt2","tt2z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[2][AXIS_Z], TT2_Z_OFFSET }, - { "tt2","tt2a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_A], TT2_A_OFFSET }, - { "tt2","tt2b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_B], TT2_B_OFFSET }, - { "tt2","tt2c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[2][AXIS_C], TT2_C_OFFSET }, + { "tt2","tt2x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_X_OFFSET }, + { "tt2","tt2y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Y_OFFSET }, + { "tt2","tt2z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Z_OFFSET }, + { "tt2","tt2a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_A_OFFSET }, + { "tt2","tt2b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_B_OFFSET }, + { "tt2","tt2c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_C_OFFSET }, - { "tt3","tt3x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[3][AXIS_X], TT3_X_OFFSET }, - { "tt3","tt3y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[3][AXIS_Y], TT3_Y_OFFSET }, - { "tt3","tt3z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[3][AXIS_Z], TT3_Z_OFFSET }, - { "tt3","tt3a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_A], TT3_A_OFFSET }, - { "tt3","tt3b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_B], TT3_B_OFFSET }, - { "tt3","tt3c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[3][AXIS_C], TT1_C_OFFSET }, + { "tt3","tt3x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_X_OFFSET }, + { "tt3","tt3y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Y_OFFSET }, + { "tt3","tt3z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Z_OFFSET }, + { "tt3","tt3a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_A_OFFSET }, + { "tt3","tt3b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_B_OFFSET }, + { "tt3","tt3c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, - { "tt4","tt4x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[4][AXIS_X], TT4_X_OFFSET }, - { "tt4","tt4y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[4][AXIS_Y], TT4_Y_OFFSET }, - { "tt4","tt4z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[4][AXIS_Z], TT4_Z_OFFSET }, - { "tt4","tt4a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_A], TT4_A_OFFSET }, - { "tt4","tt4b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_B], TT4_B_OFFSET }, - { "tt4","tt4c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[4][AXIS_C], TT4_C_OFFSET }, + { "tt4","tt4x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_X_OFFSET }, + { "tt4","tt4y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Y_OFFSET }, + { "tt4","tt4z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Z_OFFSET }, + { "tt4","tt4a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_A_OFFSET }, + { "tt4","tt4b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_B_OFFSET }, + { "tt4","tt4c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_C_OFFSET }, - { "tt5","tt5x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[5][AXIS_X], TT5_X_OFFSET }, - { "tt5","tt5y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[5][AXIS_Y], TT5_Y_OFFSET }, - { "tt5","tt5z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[5][AXIS_Z], TT5_Z_OFFSET }, - { "tt5","tt5a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_A], TT5_A_OFFSET }, - { "tt5","tt5b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_B], TT5_B_OFFSET }, - { "tt5","tt5c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[5][AXIS_C], TT5_C_OFFSET }, + { "tt5","tt5x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_X_OFFSET }, + { "tt5","tt5y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Y_OFFSET }, + { "tt5","tt5z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Z_OFFSET }, + { "tt5","tt5a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_A_OFFSET }, + { "tt5","tt5b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_B_OFFSET }, + { "tt5","tt5c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_C_OFFSET }, - { "tt6","tt6x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[6][AXIS_X], TT6_X_OFFSET }, - { "tt6","tt6y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[6][AXIS_Y], TT6_Y_OFFSET }, - { "tt6","tt6z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[6][AXIS_Z], TT6_Z_OFFSET }, - { "tt6","tt6a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_A], TT6_A_OFFSET }, - { "tt6","tt6b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_B], TT6_B_OFFSET }, - { "tt6","tt6c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[6][AXIS_C], TT6_C_OFFSET }, + { "tt6","tt6x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_X_OFFSET }, + { "tt6","tt6y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Y_OFFSET }, + { "tt6","tt6z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Z_OFFSET }, + { "tt6","tt6a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_A_OFFSET }, + { "tt6","tt6b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_B_OFFSET }, + { "tt6","tt6c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_C_OFFSET }, - { "tt7","tt7x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[7][AXIS_X], TT7_X_OFFSET }, - { "tt7","tt7y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[7][AXIS_Y], TT7_Y_OFFSET }, - { "tt7","tt7z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[7][AXIS_Z], TT7_Z_OFFSET }, - { "tt7","tt7a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_A], TT7_A_OFFSET }, - { "tt7","tt7b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_B], TT7_B_OFFSET }, - { "tt7","tt7c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[7][AXIS_C], TT7_C_OFFSET }, + { "tt7","tt7x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_X_OFFSET }, + { "tt7","tt7y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Y_OFFSET }, + { "tt7","tt7z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Z_OFFSET }, + { "tt7","tt7a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_A_OFFSET }, + { "tt7","tt7b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_B_OFFSET }, + { "tt7","tt7c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_C_OFFSET }, - { "tt8","tt8x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[8][AXIS_X], TT8_X_OFFSET }, - { "tt8","tt8y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[8][AXIS_Y], TT8_Y_OFFSET }, - { "tt8","tt8z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[8][AXIS_Z], TT8_Z_OFFSET }, - { "tt8","tt8a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_A], TT8_A_OFFSET }, - { "tt8","tt8b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_B], TT8_B_OFFSET }, - { "tt8","tt8c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[8][AXIS_C], TT8_C_OFFSET }, + { "tt8","tt8x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_X_OFFSET }, + { "tt8","tt8y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Y_OFFSET }, + { "tt8","tt8z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Z_OFFSET }, + { "tt8","tt8a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_A_OFFSET }, + { "tt8","tt8b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_B_OFFSET }, + { "tt8","tt8c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_C_OFFSET }, - { "tt9","tt9x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[9][AXIS_X], TT9_X_OFFSET }, - { "tt9","tt9y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[9][AXIS_Y], TT9_Y_OFFSET }, - { "tt9","tt9z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[9][AXIS_Z], TT9_Z_OFFSET }, - { "tt9","tt9a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_A], TT9_A_OFFSET }, - { "tt9","tt9b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_B], TT9_B_OFFSET }, - { "tt9","tt9c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[9][AXIS_C], TT9_C_OFFSET }, + { "tt9","tt9x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_X_OFFSET }, + { "tt9","tt9y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Y_OFFSET }, + { "tt9","tt9z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Z_OFFSET }, + { "tt9","tt9a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_A_OFFSET }, + { "tt9","tt9b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_B_OFFSET }, + { "tt9","tt9c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_C_OFFSET }, - { "tt10","tt10x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[10][AXIS_X], TT10_X_OFFSET }, - { "tt10","tt10y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[10][AXIS_Y], TT10_Y_OFFSET }, - { "tt10","tt10z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[10][AXIS_Z], TT10_Z_OFFSET }, - { "tt10","tt10a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_A], TT10_A_OFFSET }, - { "tt10","tt10b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_B], TT10_B_OFFSET }, - { "tt10","tt10c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[10][AXIS_C], TT10_C_OFFSET }, + { "tt10","tt10x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_X_OFFSET }, + { "tt10","tt10y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Y_OFFSET }, + { "tt10","tt10z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Z_OFFSET }, + { "tt10","tt10a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_A_OFFSET }, + { "tt10","tt10b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_B_OFFSET }, + { "tt10","tt10c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_C_OFFSET }, - { "tt11","tt11x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[11][AXIS_X], TT11_X_OFFSET }, - { "tt11","tt11y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[11][AXIS_Y], TT11_Y_OFFSET }, - { "tt11","tt11z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[11][AXIS_Z], TT11_Z_OFFSET }, - { "tt11","tt11a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_A], TT11_A_OFFSET }, - { "tt11","tt11b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_B], TT11_B_OFFSET }, - { "tt11","tt11c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[11][AXIS_C], TT11_C_OFFSET }, + { "tt11","tt11x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_X_OFFSET }, + { "tt11","tt11y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Y_OFFSET }, + { "tt11","tt11z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Z_OFFSET }, + { "tt11","tt11a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_A_OFFSET }, + { "tt11","tt11b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_B_OFFSET }, + { "tt11","tt11c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_C_OFFSET }, - { "tt12","tt12x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[12][AXIS_X], TT12_X_OFFSET }, - { "tt12","tt12y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[12][AXIS_Y], TT12_Y_OFFSET }, - { "tt12","tt12z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[12][AXIS_Z], TT12_Z_OFFSET }, - { "tt12","tt12a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_A], TT12_A_OFFSET }, - { "tt12","tt12b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_B], TT12_B_OFFSET }, - { "tt12","tt12c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[12][AXIS_C], TT12_C_OFFSET }, + { "tt12","tt12x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_X_OFFSET }, + { "tt12","tt12y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Y_OFFSET }, + { "tt12","tt12z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Z_OFFSET }, + { "tt12","tt12a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_A_OFFSET }, + { "tt12","tt12b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_B_OFFSET }, + { "tt12","tt12c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_C_OFFSET }, - { "tt13","tt13x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[13][AXIS_X], TT13_X_OFFSET }, - { "tt13","tt13y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[13][AXIS_Y], TT13_Y_OFFSET }, - { "tt13","tt13z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[13][AXIS_Z], TT13_Z_OFFSET }, - { "tt13","tt13a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_A], TT13_A_OFFSET }, - { "tt13","tt13b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_B], TT13_B_OFFSET }, - { "tt13","tt13c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[13][AXIS_C], TT13_C_OFFSET }, + { "tt13","tt13x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_X_OFFSET }, + { "tt13","tt13y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Y_OFFSET }, + { "tt13","tt13z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Z_OFFSET }, + { "tt13","tt13a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_A_OFFSET }, + { "tt13","tt13b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_B_OFFSET }, + { "tt13","tt13c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_C_OFFSET }, - { "tt14","tt14x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[14][AXIS_X], TT14_X_OFFSET }, - { "tt14","tt14y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[14][AXIS_Y], TT14_Y_OFFSET }, - { "tt14","tt14z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[14][AXIS_Z], TT14_Z_OFFSET }, - { "tt14","tt14a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_A], TT14_A_OFFSET }, - { "tt14","tt14b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_B], TT14_B_OFFSET }, - { "tt14","tt14c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[14][AXIS_C], TT14_C_OFFSET }, + { "tt14","tt14x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_X_OFFSET }, + { "tt14","tt14y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Y_OFFSET }, + { "tt14","tt14z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Z_OFFSET }, + { "tt14","tt14a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_A_OFFSET }, + { "tt14","tt14b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_B_OFFSET }, + { "tt14","tt14c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_C_OFFSET }, - { "tt15","tt15x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[15][AXIS_X], TT15_X_OFFSET }, - { "tt15","tt15y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[15][AXIS_Y], TT15_Y_OFFSET }, - { "tt15","tt15z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[15][AXIS_Z], TT15_Z_OFFSET }, - { "tt15","tt15a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_A], TT15_A_OFFSET }, - { "tt15","tt15b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_B], TT15_B_OFFSET }, - { "tt15","tt15c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[15][AXIS_C], TT15_C_OFFSET }, + { "tt15","tt15x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_X_OFFSET }, + { "tt15","tt15y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Y_OFFSET }, + { "tt15","tt15z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Z_OFFSET }, + { "tt15","tt15a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_A_OFFSET }, + { "tt15","tt15b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_B_OFFSET }, + { "tt15","tt15c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_C_OFFSET }, - { "tt16","tt16x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[16][AXIS_X], TT16_X_OFFSET }, - { "tt16","tt16y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[16][AXIS_Y], TT16_Y_OFFSET }, - { "tt16","tt16z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[16][AXIS_Z], TT16_Z_OFFSET }, - { "tt16","tt16a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_A], TT16_A_OFFSET }, - { "tt16","tt16b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_B], TT16_B_OFFSET }, - { "tt16","tt16c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[16][AXIS_C], TT16_C_OFFSET }, + { "tt16","tt16x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_X_OFFSET }, + { "tt16","tt16y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Y_OFFSET }, + { "tt16","tt16z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Z_OFFSET }, + { "tt16","tt16a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_A_OFFSET }, + { "tt16","tt16b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_B_OFFSET }, + { "tt16","tt16c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_C_OFFSET }, - { "tt17","tt17x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[17][AXIS_X], TT17_X_OFFSET }, - { "tt17","tt17y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[17][AXIS_Y], TT17_Y_OFFSET }, - { "tt17","tt17z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[17][AXIS_Z], TT17_Z_OFFSET }, - { "tt17","tt17a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_A], TT17_A_OFFSET }, - { "tt17","tt17b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_B], TT17_B_OFFSET }, - { "tt17","tt17c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[17][AXIS_C], TT17_C_OFFSET }, + { "tt17","tt17x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_X_OFFSET }, + { "tt17","tt17y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Y_OFFSET }, + { "tt17","tt17z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Z_OFFSET }, + { "tt17","tt17a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_A_OFFSET }, + { "tt17","tt17b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_B_OFFSET }, + { "tt17","tt17c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_C_OFFSET }, - { "tt18","tt18x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[18][AXIS_X], TT18_X_OFFSET }, - { "tt18","tt18y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[18][AXIS_Y], TT18_Y_OFFSET }, - { "tt18","tt18z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[18][AXIS_Z], TT18_Z_OFFSET }, - { "tt18","tt18a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_A], TT18_A_OFFSET }, - { "tt18","tt18b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_B], TT18_B_OFFSET }, - { "tt18","tt18c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[18][AXIS_C], TT18_C_OFFSET }, + { "tt18","tt18x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_X_OFFSET }, + { "tt18","tt18y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Y_OFFSET }, + { "tt18","tt18z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Z_OFFSET }, + { "tt18","tt18a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_A_OFFSET }, + { "tt18","tt18b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_B_OFFSET }, + { "tt18","tt18c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_C_OFFSET }, - { "tt19","tt19x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[19][AXIS_X], TT19_X_OFFSET }, - { "tt19","tt19y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[19][AXIS_Y], TT19_Y_OFFSET }, - { "tt19","tt19z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[19][AXIS_Z], TT19_Z_OFFSET }, - { "tt19","tt19a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_A], TT19_A_OFFSET }, - { "tt19","tt19b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_B], TT19_B_OFFSET }, - { "tt19","tt19c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[19][AXIS_C], TT19_C_OFFSET }, + { "tt19","tt19x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_X_OFFSET }, + { "tt19","tt19y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Y_OFFSET }, + { "tt19","tt19z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Z_OFFSET }, + { "tt19","tt19a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_A_OFFSET }, + { "tt19","tt19b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_B_OFFSET }, + { "tt19","tt19c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_C_OFFSET }, - { "tt20","tt20x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[20][AXIS_X], TT20_X_OFFSET }, - { "tt20","tt20y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[20][AXIS_Y], TT20_Y_OFFSET }, - { "tt20","tt20z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[20][AXIS_Z], TT20_Z_OFFSET }, - { "tt20","tt20a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_A], TT20_A_OFFSET }, - { "tt20","tt20b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_B], TT20_B_OFFSET }, - { "tt20","tt20c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[20][AXIS_C], TT20_C_OFFSET }, + { "tt20","tt20x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_X_OFFSET }, + { "tt20","tt20y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Y_OFFSET }, + { "tt20","tt20z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Z_OFFSET }, + { "tt20","tt20a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_A_OFFSET }, + { "tt20","tt20b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_B_OFFSET }, + { "tt20","tt20c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_C_OFFSET }, - { "tt21","tt21x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[21][AXIS_X], TT21_X_OFFSET }, - { "tt21","tt21y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[21][AXIS_Y], TT21_Y_OFFSET }, - { "tt21","tt21z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[21][AXIS_Z], TT21_Z_OFFSET }, - { "tt21","tt21a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_A], TT21_A_OFFSET }, - { "tt21","tt21b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_B], TT21_B_OFFSET }, - { "tt21","tt21c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[21][AXIS_C], TT21_C_OFFSET }, + { "tt21","tt21x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_X_OFFSET }, + { "tt21","tt21y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Y_OFFSET }, + { "tt21","tt21z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Z_OFFSET }, + { "tt21","tt21a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_A_OFFSET }, + { "tt21","tt21b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_B_OFFSET }, + { "tt21","tt21c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_C_OFFSET }, - { "tt22","tt22x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[22][AXIS_X], TT22_X_OFFSET }, - { "tt22","tt22y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[22][AXIS_Y], TT22_Y_OFFSET }, - { "tt22","tt22z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[22][AXIS_Z], TT22_Z_OFFSET }, - { "tt22","tt22a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_A], TT22_A_OFFSET }, - { "tt22","tt22b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_B], TT22_B_OFFSET }, - { "tt22","tt22c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[22][AXIS_C], TT22_C_OFFSET }, + { "tt22","tt22x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_X_OFFSET }, + { "tt22","tt22y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Y_OFFSET }, + { "tt22","tt22z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Z_OFFSET }, + { "tt22","tt22a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_A_OFFSET }, + { "tt22","tt22b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_B_OFFSET }, + { "tt22","tt22c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_C_OFFSET }, - { "tt23","tt23x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[23][AXIS_X], TT23_X_OFFSET }, - { "tt23","tt23y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[23][AXIS_Y], TT23_Y_OFFSET }, - { "tt23","tt23z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[23][AXIS_Z], TT23_Z_OFFSET }, - { "tt23","tt23a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_A], TT23_A_OFFSET }, - { "tt23","tt23b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_B], TT23_B_OFFSET }, - { "tt23","tt23c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[23][AXIS_C], TT23_C_OFFSET }, + { "tt23","tt23x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_X_OFFSET }, + { "tt23","tt23y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Y_OFFSET }, + { "tt23","tt23z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Z_OFFSET }, + { "tt23","tt23a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_A_OFFSET }, + { "tt23","tt23b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_B_OFFSET }, + { "tt23","tt23c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_C_OFFSET }, - { "tt24","tt24x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[24][AXIS_X], TT24_X_OFFSET }, - { "tt24","tt24y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[24][AXIS_Y], TT24_Y_OFFSET }, - { "tt24","tt24z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[24][AXIS_Z], TT24_Z_OFFSET }, - { "tt24","tt24a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_A], TT24_A_OFFSET }, - { "tt24","tt24b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_B], TT24_B_OFFSET }, - { "tt24","tt24c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[24][AXIS_C], TT24_C_OFFSET }, + { "tt24","tt24x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_X_OFFSET }, + { "tt24","tt24y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Y_OFFSET }, + { "tt24","tt24z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Z_OFFSET }, + { "tt24","tt24a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_A_OFFSET }, + { "tt24","tt24b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_B_OFFSET }, + { "tt24","tt24c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_C_OFFSET }, - { "tt25","tt25x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[25][AXIS_X], TT25_X_OFFSET }, - { "tt25","tt25y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[25][AXIS_Y], TT25_Y_OFFSET }, - { "tt25","tt25z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[25][AXIS_Z], TT25_Z_OFFSET }, - { "tt25","tt25a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_A], TT25_A_OFFSET }, - { "tt25","tt25b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_B], TT25_B_OFFSET }, - { "tt25","tt25c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[25][AXIS_C], TT25_C_OFFSET }, + { "tt25","tt25x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_X_OFFSET }, + { "tt25","tt25y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Y_OFFSET }, + { "tt25","tt25z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Z_OFFSET }, + { "tt25","tt25a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_A_OFFSET }, + { "tt25","tt25b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_B_OFFSET }, + { "tt25","tt25c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_C_OFFSET }, - { "tt26","tt26x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[26][AXIS_X], TT26_X_OFFSET }, - { "tt26","tt26y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[26][AXIS_Y], TT26_Y_OFFSET }, - { "tt26","tt26z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[26][AXIS_Z], TT26_Z_OFFSET }, - { "tt26","tt26a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_A], TT26_A_OFFSET }, - { "tt26","tt26b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_B], TT26_B_OFFSET }, - { "tt26","tt26c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[26][AXIS_C], TT26_C_OFFSET }, + { "tt26","tt26x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_X_OFFSET }, + { "tt26","tt26y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Y_OFFSET }, + { "tt26","tt26z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Z_OFFSET }, + { "tt26","tt26a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_A_OFFSET }, + { "tt26","tt26b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_B_OFFSET }, + { "tt26","tt26c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_C_OFFSET }, - { "tt27","tt27x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[27][AXIS_X], TT27_X_OFFSET }, - { "tt27","tt27y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[27][AXIS_Y], TT27_Y_OFFSET }, - { "tt27","tt27z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[27][AXIS_Z], TT27_Z_OFFSET }, - { "tt27","tt27a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_A], TT27_A_OFFSET }, - { "tt27","tt27b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_B], TT27_B_OFFSET }, - { "tt27","tt27c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[27][AXIS_C], TT27_C_OFFSET }, + { "tt27","tt27x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_X_OFFSET }, + { "tt27","tt27y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Y_OFFSET }, + { "tt27","tt27z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Z_OFFSET }, + { "tt27","tt27a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_A_OFFSET }, + { "tt27","tt27b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_B_OFFSET }, + { "tt27","tt27c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_C_OFFSET }, - { "tt28","tt28x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[28][AXIS_X], TT28_X_OFFSET }, - { "tt28","tt28y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[28][AXIS_Y], TT28_Y_OFFSET }, - { "tt28","tt28z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[28][AXIS_Z], TT28_Z_OFFSET }, - { "tt28","tt28a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_A], TT28_A_OFFSET }, - { "tt28","tt28b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_B], TT28_B_OFFSET }, - { "tt28","tt28c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[28][AXIS_C], TT28_C_OFFSET }, + { "tt28","tt28x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_X_OFFSET }, + { "tt28","tt28y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Y_OFFSET }, + { "tt28","tt28z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Z_OFFSET }, + { "tt28","tt28a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_A_OFFSET }, + { "tt28","tt28b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_B_OFFSET }, + { "tt28","tt28c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_C_OFFSET }, - { "tt29","tt29x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[29][AXIS_X], TT29_X_OFFSET }, - { "tt29","tt29y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[29][AXIS_Y], TT29_Y_OFFSET }, - { "tt29","tt29z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[29][AXIS_Z], TT29_Z_OFFSET }, - { "tt29","tt29a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_A], TT29_A_OFFSET }, - { "tt29","tt29b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_B], TT29_B_OFFSET }, - { "tt29","tt29c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[29][AXIS_C], TT29_C_OFFSET }, + { "tt29","tt29x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_X_OFFSET }, + { "tt29","tt29y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Y_OFFSET }, + { "tt29","tt29z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Z_OFFSET }, + { "tt29","tt29a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_A_OFFSET }, + { "tt29","tt29b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_B_OFFSET }, + { "tt29","tt29c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_C_OFFSET }, - { "tt30","tt30x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[30][AXIS_X], TT30_X_OFFSET }, - { "tt30","tt30y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[30][AXIS_Y], TT30_Y_OFFSET }, - { "tt30","tt30z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[30][AXIS_Z], TT30_Z_OFFSET }, - { "tt30","tt30a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_A], TT30_A_OFFSET }, - { "tt30","tt30b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_B], TT30_B_OFFSET }, - { "tt30","tt30c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[30][AXIS_C], TT30_C_OFFSET }, - - { "tt31","tt31x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[31][AXIS_X], TT31_X_OFFSET }, - { "tt31","tt31y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[31][AXIS_Y], TT31_Y_OFFSET }, - { "tt31","tt31z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[31][AXIS_Z], TT31_Z_OFFSET }, - { "tt31","tt31a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_A], TT31_A_OFFSET }, - { "tt31","tt31b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_B], TT31_B_OFFSET }, - { "tt31","tt31c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[31][AXIS_C], TT31_C_OFFSET }, - - { "tt32","tt32x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[32][AXIS_X], TT32_X_OFFSET }, - { "tt32","tt32y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[32][AXIS_Y], TT32_Y_OFFSET }, - { "tt32","tt32z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&tt.tt_offset[32][AXIS_Z], TT32_Z_OFFSET }, - { "tt32","tt32a",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_A], TT32_A_OFFSET }, - { "tt32","tt32b",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_B], TT32_B_OFFSET }, - { "tt32","tt32c",_fipc, 3, cm_print_cofs, get_flt, set_flt,(float *)&tt.tt_offset[32][AXIS_C], TT32_C_OFFSET }, + { "tt30","tt30x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_X_OFFSET }, + { "tt30","tt30y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Y_OFFSET }, + { "tt30","tt30z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Z_OFFSET }, + { "tt30","tt30a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_A_OFFSET }, + { "tt30","tt30b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_B_OFFSET }, + { "tt30","tt30c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_C_OFFSET }, + { "tt31","tt31x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_X_OFFSET }, + { "tt31","tt31y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Y_OFFSET }, + { "tt31","tt31z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Z_OFFSET }, + { "tt31","tt31a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_A_OFFSET }, + { "tt31","tt31b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_B_OFFSET }, + { "tt31","tt31c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_C_OFFSET }, + { "tt32","tt32x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_X_OFFSET }, + { "tt32","tt32y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Y_OFFSET }, + { "tt32","tt32z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Z_OFFSET }, + { "tt32","tt32a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_A_OFFSET }, + { "tt32","tt32b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_B_OFFSET }, + { "tt32","tt32c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_C_OFFSET }, // Diagnostic parameters #ifdef __DIAGNOSTIC_PARAMETERS @@ -1321,7 +1318,7 @@ void convert_outgoing_float(nvObj_t *nv) { return(_convert (nv, INCHES_PER_MM)); * set_float() - boilerplate for setting a floating point value with unit conversion * set_float_range() - set a floating point value with inclusive range check * - * get_float() returns a raw float value in internal canonical units (e.g. mm, degrees) + * get_float() loads nv->value with 'value' in internal canonical units (e.g. mm, degrees) * without units conversion. If conversion is required call convert_outgoing_float() * afterwards. The text mode and JSON display routines do this, so you generally don't * have to worry about this. diff --git a/g2core/error.h b/g2core/error.h index b452f75c..b3c3f68a 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -262,7 +262,7 @@ char *get_status_message(stat_t status); #define STAT_P_WORD_IS_ZERO 162 #define STAT_P_WORD_IS_NEGATIVE 163 // dwells require positive P values #define STAT_P_WORD_IS_NOT_AN_INTEGER 164 // G10s and other commands require integer P numbers -#define STAT_P_WORD_IS_NOT_VALID_TOOL_NUMBER 165 +#define STAT_P_WORD_IS_NOT_VALID_TOOL_NUMBER 165 // invalid tool number #define STAT_D_WORD_IS_MISSING 166 #define STAT_D_WORD_IS_INVALID 167 #define STAT_E_WORD_IS_MISSING 168 From a7b3cae61b24eef04007c46f47a7fc5912a6b578 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 19 Jan 2017 17:21:27 -0500 Subject: [PATCH 091/283] Fix for JSON G10 coordinate commands. --- g2core/board/gquadratic/hardware.cpp | 2 +- g2core/canonical_machine.cpp | 136 +++++++++++++-------------- g2core/canonical_machine.h | 2 +- g2core/config_app.cpp | 2 +- g2core/gcode_parser.cpp | 10 +- g2core/stepper.cpp | 2 +- 6 files changed, 75 insertions(+), 79 deletions(-) diff --git a/g2core/board/gquadratic/hardware.cpp b/g2core/board/gquadratic/hardware.cpp index 2963d328..f1e3fe50 100644 --- a/g2core/board/gquadratic/hardware.cpp +++ b/g2core/board/gquadratic/hardware.cpp @@ -3,7 +3,7 @@ * For: /board/gQuadratic * This file is part of the g2core project * - * Copyright (c) 2010 - 2015 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ad1e6a83..6a717131 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -130,7 +130,7 @@ static void _exec_select_tool(float *value, bool *flag); static void _exec_absolute_origin(float *value, bool *flag); static void _exec_program_finalize(float *value, bool *flag); -static int8_t _axis(const index_t index); +static int8_t _axis(const nvObj_t *nv); /*********************************************************************************** **** CODE ************************************************************************* @@ -1637,15 +1637,10 @@ stat_t cm_json_wait(char *json_string) * cm_get_axis_char() - return ASCII char for axis given the axis number */ -static int8_t _coord(char *token) // extract coordinate system from 3rd character +static int8_t _coord(nvObj_t *nv) // extract coordinate system from 3rd character { - char *ptr; - char coord_list[] = {"456789"}; - - if ((ptr = strchr(coord_list, token[2])) == NULL) { // test the 3rd character against the string - return (-1); - } - return (ptr - coord_list); + char *ptr = ((*nv->group == 0) ? &nv->token[1] : &nv->group[1]); // skip past the 'g' to the number + return (max ((atoi(ptr)-54), -1)); // return G54-G59 as 0-5, error as -1 } /* _axis() @@ -1666,35 +1661,37 @@ static int8_t _coord(char *token) // extract coordinate system from 3rd characte * such as 'coph' But it should not be called in these cases in any event. */ -static int8_t _axis(const index_t index) + +static int8_t _axis(const nvObj_t *nv) { // test if this is a SYS parameter (global), in which case there will be no axis - if (strcmp("sys", cfgArray[index].group) == 0) { + if (strcmp("sys", cfgArray[nv->index].group) == 0) { return (AXIS_TYPE_SYSTEM); } // if the leading character of the token is a number it's a motor - char c = cfgArray[index].token[0]; - if (isdigit(cfgArray[index].token[0])) { - return(st_cfg.mot[c-0x31].motor_map); + char c = cfgArray[nv->index].token[0]; + + if (isdigit(c)) { + return(st_cfg.mot[c-0x31].motor_map); // return the axis associated with the motor } // otherwise it's an axis. Or undefined, which is usually a global. char *ptr; char axes[] = {"xyzabc"}; - if ((ptr = strchr(axes, c)) == NULL) { // test for prefixed axis - c = *(cfgArray[index].token + strlen(cfgArray[index].token) -1); // test for postfixed axis - if ((ptr = strchr(axes, c)) == NULL) { + if ((ptr = strchr(axes, c)) == NULL) { // not NULL indicates a prefixed axis + c = *(cfgArray[nv->index].token + strlen(cfgArray[nv->index].token) -1); // get the last character + if ((ptr = strchr(axes, c)) == NULL) { // test for a postfixed axis return (AXIS_TYPE_UNDEFINED); } } return (ptr - axes); } -cmAxisType cm_get_axis_type(const index_t index) +cmAxisType cm_get_axis_type(const nvObj_t *nv) { - int8_t axis = _axis(index); + int8_t axis = _axis(nv); if (axis <= AXIS_TYPE_UNDEFINED) { return ((cmAxisType)axis); } @@ -1749,7 +1746,7 @@ float cm_get_jogging_dest(void) stat_t cm_run_jog(nvObj_t *nv) { set_float(nv, cm->jogging_dest); - cm_jogging_cycle_start(_axis(nv->index)); + cm_jogging_cycle_start(_axis(nv)); return (STAT_OK); } @@ -1975,24 +1972,23 @@ stat_t cm_get_vel(nvObj_t *nv) } stat_t cm_get_feed(nvObj_t *nv) { return (get_float(nv, cm_get_feed_rate(ACTIVE_MODEL))); } -stat_t cm_get_pos(nvObj_t *nv) { return (get_float(nv, cm_get_work_position(ACTIVE_MODEL, _axis(nv->index)))); } -stat_t cm_get_mpo(nvObj_t *nv) { return (get_float(nv, cm_get_absolute_position(ACTIVE_MODEL, _axis(nv->index)))); } -stat_t cm_get_ofs(nvObj_t *nv) { return (get_float(nv, cm_get_work_offset(ACTIVE_MODEL, _axis(nv->index)))); } +stat_t cm_get_pos(nvObj_t *nv) { return (get_float(nv, cm_get_work_position(ACTIVE_MODEL, _axis(nv)))); } +stat_t cm_get_mpo(nvObj_t *nv) { return (get_float(nv, cm_get_absolute_position(ACTIVE_MODEL, _axis(nv)))); } +stat_t cm_get_ofs(nvObj_t *nv) { return (get_float(nv, cm_get_work_offset(ACTIVE_MODEL, _axis(nv)))); } -stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state()));} +stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state())); } stat_t cm_set_home(nvObj_t *nv) { return (set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } -stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv->index)])); } +stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv)])); } -stat_t cm_get_prob(nvObj_t *nv) { return(_get_msg_helper(nv, msg_probe, cm_get_probe_state()));} -stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_axis(nv->index)])); } +stat_t cm_get_prob(nvObj_t *nv) { return(_get_msg_helper(nv, msg_probe, cm_get_probe_state())); } +stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_axis(nv)])); } -stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->offset[_coord(nv->token)][_axis(nv->index)]));} -stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->offset[_coord(nv->token)][_axis(nv->index)]));} - -stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv->index)]));} -stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv->index)]));} -stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv->index)]));} +stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->offset[_coord(nv)][_axis(nv)])); } +stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->offset[_coord(nv)][_axis(nv)])); } +stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv)])); } +stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv)])); } +stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv)])); } /***************************************************** **** TOOL TABLE AND OFFSET GET AND SET FUNCTIONS **** @@ -2006,8 +2002,8 @@ static uint8_t _tool(nvObj_t *nv) return (atoi(&nv->token[2])); // ttNNx is all in the token } -stat_t cm_get_tof(nvObj_t *nv) { return (get_float(nv, cm->tl_offset[_axis(nv->index)])); } -stat_t cm_set_tof(nvObj_t *nv) { return (set_float(nv, cm->tl_offset[_axis(nv->index)])); } +stat_t cm_get_tof(nvObj_t *nv) { return (get_float(nv, cm->tl_offset[_axis(nv)])); } +stat_t cm_set_tof(nvObj_t *nv) { return (set_float(nv, cm->tl_offset[_axis(nv)])); } stat_t cm_get_tt(nvObj_t *nv) { @@ -2015,7 +2011,7 @@ stat_t cm_get_tt(nvObj_t *nv) if (toolnum > TOOLS) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - return (get_float(nv, tt.tt_offset[toolnum][_axis(nv->index)])); + return (get_float(nv, tt.tt_offset[toolnum][_axis(nv)])); } stat_t cm_set_tt(nvObj_t *nv) @@ -2024,7 +2020,7 @@ stat_t cm_set_tt(nvObj_t *nv) if (toolnum > TOOLS) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - return(set_float(nv, tt.tt_offset[toolnum][_axis(nv->index)])); + return(set_float(nv, tt.tt_offset[toolnum][_axis(nv)])); } /************************************ @@ -2044,14 +2040,14 @@ stat_t cm_set_tt(nvObj_t *nv) stat_t cm_get_am(nvObj_t *nv) { - int8_t axis = _axis(nv->index); + int8_t axis = _axis(nv); nv->value = (float)cm->a[axis].axis_mode; return(_get_msg_helper(nv, msg_am, nv->value)); } stat_t cm_set_am(nvObj_t *nv) // axis mode { - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { + if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { if (nv->value > AXIS_MODE_LINEAR_MAX) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); @@ -2063,16 +2059,16 @@ stat_t cm_set_am(nvObj_t *nv) // axis mode } } nv->valuetype = TYPE_INT; - cm->a[_axis(nv->index)].axis_mode = (cmAxisMode)nv->value; + cm->a[_axis(nv)].axis_mode = (cmAxisMode)nv->value; return(STAT_OK); } -stat_t cm_get_tn(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].travel_min)); } -stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_min)); } -stat_t cm_get_tm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].travel_max)); } -stat_t cm_set_tm(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].travel_max)); } -stat_t cm_get_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].radius)); } -stat_t cm_set_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].radius)); } +stat_t cm_get_tn(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].travel_min)); } +stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv)].travel_min)); } +stat_t cm_get_tm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].travel_max)); } +stat_t cm_set_tm(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv)].travel_max)); } +stat_t cm_get_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].radius)); } +stat_t cm_set_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].radius)); } /**** Axis Jerk Primitives * cm_get_axis_jerk() - returns jerk for an axis @@ -2119,35 +2115,35 @@ void cm_set_axis_jerk(const uint8_t axis, const float jerk) * This is corrected to mm/min^3 by the internals of the code. */ -stat_t cm_get_vm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].velocity_max)); } +stat_t cm_get_vm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].velocity_max)); } stat_t cm_set_vm(nvObj_t *nv) { - uint8_t axis = _axis(nv->index); + uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].velocity_max, 0, MAX_LONG)); cm->a[axis].recip_velocity_max = 1/nv->value; return(STAT_OK); } -stat_t cm_get_fr(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].feedrate_max)); } +stat_t cm_get_fr(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].feedrate_max)); } stat_t cm_set_fr(nvObj_t *nv) { - uint8_t axis = _axis(nv->index); + uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].feedrate_max, 0, MAX_LONG)); cm->a[axis].recip_feedrate_max = 1/nv->value; return(STAT_OK); } -stat_t cm_get_jm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_max)); } +stat_t cm_get_jm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].jerk_max)); } stat_t cm_set_jm(nvObj_t *nv) { - uint8_t axis = _axis(nv->index); + uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].jerk_max, JERK_INPUT_MIN, JERK_INPUT_MAX)); cm_set_axis_jerk(axis, nv->value); return(STAT_OK); } -stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].jerk_high)); } -stat_t cm_set_jh(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->index)].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); } +stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].jerk_high)); } +stat_t cm_set_jh(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); } /**** Axis Homing Settings @@ -2165,18 +2161,18 @@ stat_t cm_set_jh(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->inde * cm_set_zb() - set homing zero backoff */ -stat_t cm_get_hi(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv->index)].homing_input)); } -stat_t cm_set_hi(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv->index)].homing_input, 0, D_IN_CHANNELS)); } -stat_t cm_get_hd(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv->index)].homing_dir)); } -stat_t cm_set_hd(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv->index)].homing_dir, 0, 1)); } -stat_t cm_get_sv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].search_velocity)); } -stat_t cm_set_sv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->index)].search_velocity, 0, MAX_LONG)); } -stat_t cm_get_lv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].latch_velocity)); } -stat_t cm_set_lv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv->index)].latch_velocity, 0, MAX_LONG)); } -stat_t cm_get_lb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].latch_backoff)); } -stat_t cm_set_lb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].latch_backoff)); } -stat_t cm_get_zb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv->index)].zero_backoff)); } -stat_t cm_set_zb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv->index)].zero_backoff)); } +stat_t cm_get_hi(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv)].homing_input)); } +stat_t cm_set_hi(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv)].homing_input, 0, D_IN_CHANNELS)); } +stat_t cm_get_hd(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv)].homing_dir)); } +stat_t cm_set_hd(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv)].homing_dir, 0, 1)); } +stat_t cm_get_sv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].search_velocity)); } +stat_t cm_set_sv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].search_velocity, 0, MAX_LONG)); } +stat_t cm_get_lv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].latch_velocity)); } +stat_t cm_set_lv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].latch_velocity, 0, MAX_LONG)); } +stat_t cm_get_lb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].latch_backoff)); } +stat_t cm_set_lb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv)].latch_backoff)); } +stat_t cm_get_zb(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].zero_backoff)); } +stat_t cm_set_zb(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv)].zero_backoff)); } /*** Canonical Machine Global Settings ***/ @@ -2428,7 +2424,7 @@ static void _print_axis_ui8(nvObj_t *nv, const char *format) static void _print_axis_flt(nvObj_t *nv, const char *format) { char *units; - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { + if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { units = (char *)GET_UNITS(MODEL); } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); @@ -2440,7 +2436,7 @@ static void _print_axis_flt(nvObj_t *nv, const char *format) static void _print_axis_coord_flt(nvObj_t *nv, const char *format) { char *units; - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { + if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { units = (char *)GET_UNITS(MODEL); } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); @@ -2452,7 +2448,7 @@ static void _print_axis_coord_flt(nvObj_t *nv, const char *format) static void _print_pos(nvObj_t *nv, const char *format, uint8_t units) { char axes[] = {"XYZABC"}; - uint8_t axis = _axis(nv->index); + uint8_t axis = _axis(nv); if (axis >= AXIS_A) { units = DEGREES;} sprintf(cs.out_buf, format, axes[axis], nv->value, GET_TEXT_ITEM(msg_units, units)); xio_writeline(cs.out_buf); @@ -2461,7 +2457,7 @@ static void _print_pos(nvObj_t *nv, const char *format, uint8_t units) static void _print_hom(nvObj_t *nv, const char *format) { char axes[] = {"XYZABC"}; - uint8_t axis = _axis(nv->index); + uint8_t axis = _axis(nv); sprintf(cs.out_buf, format, axes[axis], nv->value); xio_writeline(cs.out_buf); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 51dcdc2a..c024de86 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -484,7 +484,7 @@ stat_t cm_panic(const stat_t status, const char *msg); // enter panic s /**** cfgArray interface functions ****/ char cm_get_axis_char(const int8_t axis); -cmAxisType cm_get_axis_type(const index_t index); +cmAxisType cm_get_axis_type(const nvObj_t *nv); stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index ba64bc8b..1d76e058 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1296,7 +1296,7 @@ static void _convert(nvObj_t *nv, float conversion_factor) ///+++ transform these checks into NaN or INF strings with an error return? if (cm_get_units_mode(MODEL) == INCHES) { - cmAxisType axis_type = cm_get_axis_type(nv->index); // linear, rotary, global or error + cmAxisType axis_type = cm_get_axis_type(nv); // linear, rotary, global or error if ((axis_type == AXIS_TYPE_LINEAR) || (axis_type == AXIS_TYPE_SYSTEM)) { if (cfgArray[nv->index].flags & F_CONVERT) { // standard units conversion nv->value *= conversion_factor; diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index e45c6497..8f8f5fc1 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -750,20 +750,20 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_set_feed_rate, F_word); // F EXEC_FUNC(spindle_speed_sync, S_word); // S - EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written - EXEC_FUNC(cm_change_tool, tool_change); // M6 + EXEC_FUNC(cm_select_tool, tool_select); // T - tool_select is where it's written + EXEC_FUNC(cm_change_tool, tool_change); // M6 - is where it's effected - if (gf.spindle_control) { // spindle OFF, CW, CCW + if (gf.spindle_control) { // M3, M4, M5 (spindle OFF, CW, CCW) ritorno(spindle_control_sync((spControl)gv.spindle_control)); } if (gf.coolant_mist) { - ritorno(coolant_control_sync((coControl)gv.coolant_mist, COOLANT_MIST)); // M7 + ritorno(coolant_control_sync((coControl)gv.coolant_mist, COOLANT_MIST)); // M7 } if (gf.coolant_flood) { ritorno(coolant_control_sync((coControl)gv.coolant_flood, COOLANT_FLOOD)); // M8 } if (gf.coolant_off) { - ritorno(coolant_control_sync((coControl)gv.coolant_off, COOLANT_BOTH)); // M9 + ritorno(coolant_control_sync((coControl)gv.coolant_off, COOLANT_BOTH)); // M9 } if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index c94fd051..d092bb24 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -901,7 +901,7 @@ stat_t st_set_su(nvObj_t *nv) // Do unit conversion here because it's a reciprocal value (rather than process_incoming_float()) if (cm_get_units_mode(MODEL) == INCHES) { - if (cm_get_axis_type(nv->index) == AXIS_TYPE_LINEAR) { + if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { nv->value *= INCHES_PER_MM; } } From b7b5823db976f163b5781ff8b191d420064a0a95 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 20 Jan 2017 11:46:49 -0500 Subject: [PATCH 092/283] Increased precision of JSON positional values to 5 decimal places; Added nan and inf tests to floattoa() --- g2core/canonical_machine.cpp | 29 +- g2core/config_app.cpp | 624 +++++++++++++++++------------------ g2core/g2core.cppproj | 4 +- g2core/util.cpp | 261 ++++++++------- g2core/util.h | 13 +- 5 files changed, 474 insertions(+), 457 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 6a717131..9b7b283d 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1631,37 +1631,34 @@ stat_t cm_json_wait(char *json_string) ***********************************************************************************/ /***** AXIS HELPERS ***************************************************************** - * _coord() - return coordinate system number or -1 if error + * _coord() - return coordinate system number (53=0...59=6) or -1 if error * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) * cm_get_axis_type() - return linear axis (0), rotary axis (1) or error (-1) - * cm_get_axis_char() - return ASCII char for axis given the axis number + * cm_get_axis_char() - return ASCII char for axis number provided */ static int8_t _coord(nvObj_t *nv) // extract coordinate system from 3rd character { char *ptr = ((*nv->group == 0) ? &nv->token[1] : &nv->group[1]); // skip past the 'g' to the number - return (max ((atoi(ptr)-54), -1)); // return G54-G59 as 0-5, error as -1 + return (max ((atoi(ptr)-53), -1)); // return G54-G59 as 0-5, error as -1 } /* _axis() * - * Cases that are handled by _get_axis(): - * - sys/... value is a system parameter (global), there is no axis - * - xam any axis parameter will return the axis number - * - 1ma any motor parameter will return the mapped axis for that motor - * - 1su an example of the above - * - mpox readouts - * - g54x offsets - * - tlx tool length offset - * - tt1x tool table - * - tt32x tool table - * - _tex diagnostic parameters + * Cases handled: + * - sys/... value is a system parameter (global), there is no axis (AXIS_TYPE_SYSTEM) + * - xam, yvm any prefixed axis parameter + * - 1ma, 2tr any motor parameter will return mapped axis for that motor + * - posx, mpox readouts + * - g54x, g92z offsets + * - tofx tool offsets + * - tt1x, tt32x tool table + * - _tex, _tra diagnostic parameters * * Note that this function will return an erroneous value if called by a non-axis tag, * such as 'coph' But it should not be called in these cases in any event. */ - static int8_t _axis(const nvObj_t *nv) { // test if this is a SYS parameter (global), in which case there will be no axis @@ -1823,6 +1820,7 @@ static const char *const msg_stat[] = { msg_stat0, msg_stat1, msg_stat2, msg_sta msg_stat4, msg_stat5, msg_stat6, msg_stat7, msg_stat8, msg_stat9, msg_stat10, msg_stat11, msg_stat12, msg_stat13 }; + static const char msg_macs0[] = "Initializing"; static const char msg_macs1[] = "Ready"; static const char msg_macs2[] = "Alarm"; @@ -1835,6 +1833,7 @@ static const char msg_macs8[] = "PANIC"; static const char *const msg_macs[] = { msg_macs0, msg_macs1, msg_macs2, msg_macs3, msg_macs4, msg_macs5, msg_macs6, msg_macs7, msg_macs8 }; + static const char msg_cycs0[] = "Off"; static const char msg_cycs1[] = "Machining"; static const char msg_cycs2[] = "Homing"; diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 1d76e058..d0035306 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -137,26 +137,26 @@ const cfgItem_t cfgArray[] = { { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif - { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position + { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position + { "mpo","mpoy",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position + { "mpo","mpoz",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position + { "mpo","mpoa",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position + { "mpo","mpob",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position + { "mpo","mpoc",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position - { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position + { "pos","posx",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position + { "pos","posy",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position + { "pos","posz",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position + { "pos","posa",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position + { "pos","posb",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position + { "pos","posc",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position - { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset - { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset - { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Z work offset - { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // A work offset - { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset - { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset + { "ofs","ofsx",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset + { "ofs","ofsy",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset + { "ofs","ofsz",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Z work offset + { "ofs","ofsa",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // A work offset + { "ofs","ofsb",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset + { "ofs","ofsc",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group @@ -167,12 +167,12 @@ const cfgItem_t cfgArray[] = { { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results - { "prb","prby",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results - { "prb","prbz",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results - { "prb","prba",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // A probe results - { "prb","prbb",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // B probe results - { "prb","prbc",_f0, 3, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // C probe results + { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results + { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results + { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results + { "prb","prba",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // A probe results + { "prb","prbb",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // B probe results + { "prb","prbc",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // C probe results { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in X axis { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Y axis @@ -199,7 +199,7 @@ const cfgItem_t cfgArray[] = { // Motor parameters { "1","1ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, - { "1","1tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, + { "1","1tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M1_STEPS_PER_UNIT }, { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, { "1","1po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M1_POLARITY }, @@ -210,7 +210,7 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 2) { "2","2ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, - { "2","2tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, + { "2","2tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M2_STEPS_PER_UNIT }, { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, { "2","2po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M2_POLARITY }, @@ -222,7 +222,7 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 3) { "3","3ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, - { "3","3tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, + { "3","3tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M3_STEPS_PER_UNIT }, { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, { "3","3po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M3_POLARITY }, @@ -234,7 +234,7 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 4) { "4","4ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, - { "4","4tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, + { "4","4tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M4_STEPS_PER_UNIT }, { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, { "4","4po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M4_POLARITY }, @@ -246,7 +246,7 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 5) { "5","5ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, - { "5","5tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, + { "5","5tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M5_STEPS_PER_UNIT }, { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, { "5","5po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M5_POLARITY }, @@ -258,7 +258,7 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 6) { "6","6ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, - { "6","6tr",_fipc,4, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, + { "6","6tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M6_STEPS_PER_UNIT }, { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, { "6","6po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M6_POLARITY }, @@ -271,89 +271,89 @@ const cfgItem_t cfgArray[] = { { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, X_VELOCITY_MAX }, { "x","xfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, X_FEEDRATE_MAX }, - { "x","xtn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, - { "x","xtm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, + { "x","xtn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, + { "x","xtm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, { "x","xjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, X_JERK_MAX }, { "x","xjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, X_JERK_HIGH_SPEED }, { "x","xhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, X_HOMING_INPUT }, { "x","xhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, X_HOMING_DIRECTION }, { "x","xsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, X_SEARCH_VELOCITY }, { "x","xlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, X_LATCH_VELOCITY }, - { "x","xlb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, X_LATCH_BACKOFF }, - { "x","xzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, X_ZERO_BACKOFF }, + { "x","xlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, X_LATCH_BACKOFF }, + { "x","xzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, X_ZERO_BACKOFF }, { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Y_VELOCITY_MAX }, { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Y_FEEDRATE_MAX }, - { "y","ytn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Y_TRAVEL_MIN }, - { "y","ytm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Y_TRAVEL_MAX }, + { "y","ytn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Y_TRAVEL_MIN }, + { "y","ytm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Y_TRAVEL_MAX }, { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Y_JERK_MAX }, { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, Y_JERK_HIGH_SPEED }, { "y","yhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Y_HOMING_INPUT }, { "y","yhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Y_HOMING_DIRECTION }, { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Y_SEARCH_VELOCITY }, { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Y_LATCH_VELOCITY }, - { "y","ylb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Y_LATCH_BACKOFF }, - { "y","yzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, Y_ZERO_BACKOFF }, + { "y","ylb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Y_LATCH_BACKOFF }, + { "y","yzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, Y_ZERO_BACKOFF }, { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, { "z","zvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Z_VELOCITY_MAX }, { "z","zfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Z_FEEDRATE_MAX }, - { "z","ztn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Z_TRAVEL_MIN }, - { "z","ztm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Z_TRAVEL_MAX }, + { "z","ztn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Z_TRAVEL_MIN }, + { "z","ztm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Z_TRAVEL_MAX }, { "z","zjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Z_JERK_MAX }, { "z","zjh",_fipc, 0, cm_print_jh, cm_get_jm, cm_set_jh, (float *)&cs.null, Z_JERK_HIGH_SPEED }, { "z","zhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Z_HOMING_INPUT }, { "z","zhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Z_HOMING_DIRECTION }, { "z","zsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Z_SEARCH_VELOCITY }, { "z","zlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Z_LATCH_VELOCITY }, - { "z","zlb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Z_LATCH_BACKOFF }, - { "z","zzb",_fipc, 3, cm_print_zb, cm_get_lb, cm_set_zb, (float *)&cs.null, Z_ZERO_BACKOFF }, + { "z","zlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Z_LATCH_BACKOFF }, + { "z","zzb",_fipc, 5, cm_print_zb, cm_get_lb, cm_set_zb, (float *)&cs.null, Z_ZERO_BACKOFF }, { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, { "a","avm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, A_VELOCITY_MAX }, { "a","afr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, A_FEEDRATE_MAX }, - { "a","atn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, - { "a","atm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, A_TRAVEL_MAX }, + { "a","atn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, + { "a","atm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, A_TRAVEL_MAX }, { "a","ajm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, A_JERK_MAX }, { "a","ajh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, A_JERK_HIGH_SPEED }, - { "a","ara",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, A_RADIUS}, + { "a","ara",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, A_RADIUS}, { "a","ahi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, A_HOMING_INPUT }, { "a","ahd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, A_HOMING_DIRECTION }, { "a","asv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, A_SEARCH_VELOCITY }, { "a","alv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, A_LATCH_VELOCITY }, - { "a","alb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, - { "a","azb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, + { "a","alb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, + { "a","azb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, { "b","bvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, B_VELOCITY_MAX }, { "b","bfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, B_FEEDRATE_MAX }, - { "b","btn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, - { "b","btm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, B_TRAVEL_MAX }, + { "b","btn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, + { "b","btm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, B_TRAVEL_MAX }, { "b","bjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, B_JERK_MAX }, { "b","bjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, B_JERK_HIGH_SPEED }, - { "b","bra",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, B_RADIUS }, + { "b","bra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, B_RADIUS }, { "b","bhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, B_HOMING_INPUT }, { "b","bhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, B_HOMING_DIRECTION }, { "b","bsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, B_SEARCH_VELOCITY }, { "b","blv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, B_LATCH_VELOCITY }, - { "b","blb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, - { "b","bzb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, + { "b","blb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, + { "b","bzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, { "c","cvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, C_VELOCITY_MAX }, { "c","cfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, C_FEEDRATE_MAX }, - { "c","ctn",_fipc, 3, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, - { "c","ctm",_fipc, 3, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, C_TRAVEL_MAX }, + { "c","ctn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, + { "c","ctm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, C_TRAVEL_MAX }, { "c","cjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, C_JERK_MAX }, { "c","cjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, C_JERK_HIGH_SPEED }, - { "c","cra",_fipc, 3, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, C_RADIUS }, + { "c","cra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, C_RADIUS }, { "c","chi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, C_HOMING_INPUT }, { "c","chd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, C_HOMING_DIRECTION }, { "c","csv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, C_SEARCH_VELOCITY }, { "c","clv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, C_LATCH_VELOCITY }, - { "c","clb",_fipc, 3, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, - { "c","czb",_fipc, 3, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, + { "c","clb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, + { "c","czb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, // Digital input configs { "di1","di1mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, @@ -533,69 +533,69 @@ const cfgItem_t cfgArray[] = { { "he3","he3fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, // Coordinate system offsets (G54-G59 and G92) - { "g54","g54x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_X_OFFSET }, - { "g54","g54y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Y_OFFSET }, - { "g54","g54z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Z_OFFSET }, - { "g54","g54a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_A_OFFSET }, - { "g54","g54b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_B_OFFSET }, - { "g54","g54c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_C_OFFSET }, + { "g54","g54x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_X_OFFSET }, + { "g54","g54y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Y_OFFSET }, + { "g54","g54z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Z_OFFSET }, + { "g54","g54a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_A_OFFSET }, + { "g54","g54b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_B_OFFSET }, + { "g54","g54c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_C_OFFSET }, - { "g55","g55x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_X_OFFSET }, - { "g55","g55y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Y_OFFSET }, - { "g55","g55z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Z_OFFSET }, - { "g55","g55a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_A_OFFSET }, - { "g55","g55b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_B_OFFSET }, - { "g55","g55c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_C_OFFSET }, + { "g55","g55x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_X_OFFSET }, + { "g55","g55y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Y_OFFSET }, + { "g55","g55z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Z_OFFSET }, + { "g55","g55a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_A_OFFSET }, + { "g55","g55b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_B_OFFSET }, + { "g55","g55c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_C_OFFSET }, - { "g56","g56x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_X_OFFSET }, - { "g56","g56y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Y_OFFSET }, - { "g56","g56z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Z_OFFSET }, - { "g56","g56a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_A_OFFSET }, - { "g56","g56b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_B_OFFSET }, - { "g56","g56c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_C_OFFSET }, + { "g56","g56x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_X_OFFSET }, + { "g56","g56y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Y_OFFSET }, + { "g56","g56z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Z_OFFSET }, + { "g56","g56a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_A_OFFSET }, + { "g56","g56b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_B_OFFSET }, + { "g56","g56c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_C_OFFSET }, - { "g57","g57x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_X_OFFSET }, - { "g57","g57y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Y_OFFSET }, - { "g57","g57z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Z_OFFSET }, - { "g57","g57a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_A_OFFSET }, - { "g57","g57b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_B_OFFSET }, - { "g57","g57c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_C_OFFSET }, + { "g57","g57x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_X_OFFSET }, + { "g57","g57y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Y_OFFSET }, + { "g57","g57z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Z_OFFSET }, + { "g57","g57a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_A_OFFSET }, + { "g57","g57b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_B_OFFSET }, + { "g57","g57c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_C_OFFSET }, - { "g58","g58x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_X_OFFSET }, - { "g58","g58y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Y_OFFSET }, - { "g58","g58z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Z_OFFSET }, - { "g58","g58a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_A_OFFSET }, - { "g58","g58b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_B_OFFSET }, - { "g58","g58c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_C_OFFSET }, + { "g58","g58x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_X_OFFSET }, + { "g58","g58y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Y_OFFSET }, + { "g58","g58z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Z_OFFSET }, + { "g58","g58a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_A_OFFSET }, + { "g58","g58b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_B_OFFSET }, + { "g58","g58c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_C_OFFSET }, - { "g59","g59x",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_X_OFFSET }, - { "g59","g59y",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Y_OFFSET }, - { "g59","g59z",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Z_OFFSET }, - { "g59","g59a",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_A_OFFSET }, - { "g59","g59b",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, - { "g59","g59c",_fipc, 3, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, + { "g59","g59x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_X_OFFSET }, + { "g59","g59y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Y_OFFSET }, + { "g59","g59z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Z_OFFSET }, + { "g59","g59a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_A_OFFSET }, + { "g59","g59b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, + { "g59","g59c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, - { "g92","g92x",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently - { "g92","g92y",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92z",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92a",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92b",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92c",_fizc, 3, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92x",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently + { "g92","g92y",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92z",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92a",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92b",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92c",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently - { "g28","g28y",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28z",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28a",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28b",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28c",_fizc, 3, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28x",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently + { "g28","g28y",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28z",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28a",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28b",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28c",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g30","g30x",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently - { "g30","g30y",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30z",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30a",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30b",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30c",_fizc, 3, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30x",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently + { "g30","g30y",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30z",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30a",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30b",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30c",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, // this is a 128bit UUID for identifying a previously committed job state { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, @@ -707,237 +707,237 @@ const cfgItem_t cfgArray[] = { #endif // Tool table offsets - { "tof","tofx",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofy",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofz",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofa",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofb",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofc",_fipc, 3, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofx",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofy",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofz",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofa",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofb",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofc",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, // Tool table - { "tt1","tt1x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_X_OFFSET }, - { "tt1","tt1y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Y_OFFSET }, - { "tt1","tt1z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Z_OFFSET }, - { "tt1","tt1a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_A_OFFSET }, - { "tt1","tt1b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_B_OFFSET }, - { "tt1","tt1c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, + { "tt1","tt1x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_X_OFFSET }, + { "tt1","tt1y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Y_OFFSET }, + { "tt1","tt1z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Z_OFFSET }, + { "tt1","tt1a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_A_OFFSET }, + { "tt1","tt1b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_B_OFFSET }, + { "tt1","tt1c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, - { "tt2","tt2x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_X_OFFSET }, - { "tt2","tt2y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Y_OFFSET }, - { "tt2","tt2z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Z_OFFSET }, - { "tt2","tt2a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_A_OFFSET }, - { "tt2","tt2b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_B_OFFSET }, - { "tt2","tt2c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_C_OFFSET }, + { "tt2","tt2x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_X_OFFSET }, + { "tt2","tt2y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Y_OFFSET }, + { "tt2","tt2z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Z_OFFSET }, + { "tt2","tt2a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_A_OFFSET }, + { "tt2","tt2b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_B_OFFSET }, + { "tt2","tt2c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_C_OFFSET }, - { "tt3","tt3x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_X_OFFSET }, - { "tt3","tt3y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Y_OFFSET }, - { "tt3","tt3z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Z_OFFSET }, - { "tt3","tt3a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_A_OFFSET }, - { "tt3","tt3b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_B_OFFSET }, - { "tt3","tt3c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, + { "tt3","tt3x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_X_OFFSET }, + { "tt3","tt3y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Y_OFFSET }, + { "tt3","tt3z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Z_OFFSET }, + { "tt3","tt3a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_A_OFFSET }, + { "tt3","tt3b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_B_OFFSET }, + { "tt3","tt3c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, - { "tt4","tt4x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_X_OFFSET }, - { "tt4","tt4y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Y_OFFSET }, - { "tt4","tt4z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Z_OFFSET }, - { "tt4","tt4a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_A_OFFSET }, - { "tt4","tt4b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_B_OFFSET }, - { "tt4","tt4c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_C_OFFSET }, + { "tt4","tt4x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_X_OFFSET }, + { "tt4","tt4y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Y_OFFSET }, + { "tt4","tt4z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Z_OFFSET }, + { "tt4","tt4a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_A_OFFSET }, + { "tt4","tt4b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_B_OFFSET }, + { "tt4","tt4c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_C_OFFSET }, - { "tt5","tt5x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_X_OFFSET }, - { "tt5","tt5y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Y_OFFSET }, - { "tt5","tt5z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Z_OFFSET }, - { "tt5","tt5a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_A_OFFSET }, - { "tt5","tt5b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_B_OFFSET }, - { "tt5","tt5c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_C_OFFSET }, + { "tt5","tt5x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_X_OFFSET }, + { "tt5","tt5y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Y_OFFSET }, + { "tt5","tt5z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Z_OFFSET }, + { "tt5","tt5a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_A_OFFSET }, + { "tt5","tt5b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_B_OFFSET }, + { "tt5","tt5c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_C_OFFSET }, - { "tt6","tt6x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_X_OFFSET }, - { "tt6","tt6y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Y_OFFSET }, - { "tt6","tt6z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Z_OFFSET }, - { "tt6","tt6a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_A_OFFSET }, - { "tt6","tt6b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_B_OFFSET }, - { "tt6","tt6c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_C_OFFSET }, + { "tt6","tt6x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_X_OFFSET }, + { "tt6","tt6y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Y_OFFSET }, + { "tt6","tt6z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Z_OFFSET }, + { "tt6","tt6a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_A_OFFSET }, + { "tt6","tt6b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_B_OFFSET }, + { "tt6","tt6c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_C_OFFSET }, - { "tt7","tt7x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_X_OFFSET }, - { "tt7","tt7y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Y_OFFSET }, - { "tt7","tt7z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Z_OFFSET }, - { "tt7","tt7a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_A_OFFSET }, - { "tt7","tt7b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_B_OFFSET }, - { "tt7","tt7c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_C_OFFSET }, + { "tt7","tt7x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_X_OFFSET }, + { "tt7","tt7y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Y_OFFSET }, + { "tt7","tt7z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Z_OFFSET }, + { "tt7","tt7a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_A_OFFSET }, + { "tt7","tt7b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_B_OFFSET }, + { "tt7","tt7c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_C_OFFSET }, - { "tt8","tt8x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_X_OFFSET }, - { "tt8","tt8y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Y_OFFSET }, - { "tt8","tt8z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Z_OFFSET }, - { "tt8","tt8a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_A_OFFSET }, - { "tt8","tt8b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_B_OFFSET }, - { "tt8","tt8c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_C_OFFSET }, + { "tt8","tt8x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_X_OFFSET }, + { "tt8","tt8y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Y_OFFSET }, + { "tt8","tt8z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Z_OFFSET }, + { "tt8","tt8a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_A_OFFSET }, + { "tt8","tt8b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_B_OFFSET }, + { "tt8","tt8c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_C_OFFSET }, - { "tt9","tt9x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_X_OFFSET }, - { "tt9","tt9y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Y_OFFSET }, - { "tt9","tt9z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Z_OFFSET }, - { "tt9","tt9a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_A_OFFSET }, - { "tt9","tt9b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_B_OFFSET }, - { "tt9","tt9c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_C_OFFSET }, + { "tt9","tt9x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_X_OFFSET }, + { "tt9","tt9y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Y_OFFSET }, + { "tt9","tt9z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Z_OFFSET }, + { "tt9","tt9a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_A_OFFSET }, + { "tt9","tt9b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_B_OFFSET }, + { "tt9","tt9c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_C_OFFSET }, - { "tt10","tt10x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_X_OFFSET }, - { "tt10","tt10y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Y_OFFSET }, - { "tt10","tt10z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Z_OFFSET }, - { "tt10","tt10a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_A_OFFSET }, - { "tt10","tt10b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_B_OFFSET }, - { "tt10","tt10c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_C_OFFSET }, + { "tt10","tt10x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_X_OFFSET }, + { "tt10","tt10y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Y_OFFSET }, + { "tt10","tt10z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Z_OFFSET }, + { "tt10","tt10a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_A_OFFSET }, + { "tt10","tt10b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_B_OFFSET }, + { "tt10","tt10c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_C_OFFSET }, - { "tt11","tt11x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_X_OFFSET }, - { "tt11","tt11y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Y_OFFSET }, - { "tt11","tt11z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Z_OFFSET }, - { "tt11","tt11a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_A_OFFSET }, - { "tt11","tt11b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_B_OFFSET }, - { "tt11","tt11c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_C_OFFSET }, + { "tt11","tt11x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_X_OFFSET }, + { "tt11","tt11y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Y_OFFSET }, + { "tt11","tt11z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Z_OFFSET }, + { "tt11","tt11a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_A_OFFSET }, + { "tt11","tt11b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_B_OFFSET }, + { "tt11","tt11c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_C_OFFSET }, - { "tt12","tt12x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_X_OFFSET }, - { "tt12","tt12y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Y_OFFSET }, - { "tt12","tt12z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Z_OFFSET }, - { "tt12","tt12a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_A_OFFSET }, - { "tt12","tt12b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_B_OFFSET }, - { "tt12","tt12c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_C_OFFSET }, + { "tt12","tt12x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_X_OFFSET }, + { "tt12","tt12y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Y_OFFSET }, + { "tt12","tt12z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Z_OFFSET }, + { "tt12","tt12a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_A_OFFSET }, + { "tt12","tt12b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_B_OFFSET }, + { "tt12","tt12c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_C_OFFSET }, - { "tt13","tt13x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_X_OFFSET }, - { "tt13","tt13y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Y_OFFSET }, - { "tt13","tt13z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Z_OFFSET }, - { "tt13","tt13a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_A_OFFSET }, - { "tt13","tt13b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_B_OFFSET }, - { "tt13","tt13c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_C_OFFSET }, + { "tt13","tt13x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_X_OFFSET }, + { "tt13","tt13y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Y_OFFSET }, + { "tt13","tt13z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Z_OFFSET }, + { "tt13","tt13a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_A_OFFSET }, + { "tt13","tt13b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_B_OFFSET }, + { "tt13","tt13c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_C_OFFSET }, - { "tt14","tt14x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_X_OFFSET }, - { "tt14","tt14y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Y_OFFSET }, - { "tt14","tt14z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Z_OFFSET }, - { "tt14","tt14a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_A_OFFSET }, - { "tt14","tt14b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_B_OFFSET }, - { "tt14","tt14c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_C_OFFSET }, + { "tt14","tt14x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_X_OFFSET }, + { "tt14","tt14y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Y_OFFSET }, + { "tt14","tt14z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Z_OFFSET }, + { "tt14","tt14a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_A_OFFSET }, + { "tt14","tt14b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_B_OFFSET }, + { "tt14","tt14c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_C_OFFSET }, - { "tt15","tt15x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_X_OFFSET }, - { "tt15","tt15y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Y_OFFSET }, - { "tt15","tt15z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Z_OFFSET }, - { "tt15","tt15a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_A_OFFSET }, - { "tt15","tt15b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_B_OFFSET }, - { "tt15","tt15c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_C_OFFSET }, + { "tt15","tt15x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_X_OFFSET }, + { "tt15","tt15y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Y_OFFSET }, + { "tt15","tt15z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Z_OFFSET }, + { "tt15","tt15a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_A_OFFSET }, + { "tt15","tt15b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_B_OFFSET }, + { "tt15","tt15c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_C_OFFSET }, - { "tt16","tt16x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_X_OFFSET }, - { "tt16","tt16y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Y_OFFSET }, - { "tt16","tt16z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Z_OFFSET }, - { "tt16","tt16a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_A_OFFSET }, - { "tt16","tt16b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_B_OFFSET }, - { "tt16","tt16c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_C_OFFSET }, + { "tt16","tt16x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_X_OFFSET }, + { "tt16","tt16y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Y_OFFSET }, + { "tt16","tt16z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Z_OFFSET }, + { "tt16","tt16a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_A_OFFSET }, + { "tt16","tt16b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_B_OFFSET }, + { "tt16","tt16c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_C_OFFSET }, - { "tt17","tt17x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_X_OFFSET }, - { "tt17","tt17y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Y_OFFSET }, - { "tt17","tt17z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Z_OFFSET }, - { "tt17","tt17a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_A_OFFSET }, - { "tt17","tt17b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_B_OFFSET }, - { "tt17","tt17c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_C_OFFSET }, + { "tt17","tt17x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_X_OFFSET }, + { "tt17","tt17y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Y_OFFSET }, + { "tt17","tt17z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Z_OFFSET }, + { "tt17","tt17a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_A_OFFSET }, + { "tt17","tt17b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_B_OFFSET }, + { "tt17","tt17c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_C_OFFSET }, - { "tt18","tt18x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_X_OFFSET }, - { "tt18","tt18y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Y_OFFSET }, - { "tt18","tt18z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Z_OFFSET }, - { "tt18","tt18a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_A_OFFSET }, - { "tt18","tt18b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_B_OFFSET }, - { "tt18","tt18c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_C_OFFSET }, + { "tt18","tt18x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_X_OFFSET }, + { "tt18","tt18y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Y_OFFSET }, + { "tt18","tt18z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Z_OFFSET }, + { "tt18","tt18a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_A_OFFSET }, + { "tt18","tt18b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_B_OFFSET }, + { "tt18","tt18c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_C_OFFSET }, - { "tt19","tt19x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_X_OFFSET }, - { "tt19","tt19y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Y_OFFSET }, - { "tt19","tt19z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Z_OFFSET }, - { "tt19","tt19a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_A_OFFSET }, - { "tt19","tt19b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_B_OFFSET }, - { "tt19","tt19c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_C_OFFSET }, + { "tt19","tt19x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_X_OFFSET }, + { "tt19","tt19y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Y_OFFSET }, + { "tt19","tt19z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Z_OFFSET }, + { "tt19","tt19a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_A_OFFSET }, + { "tt19","tt19b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_B_OFFSET }, + { "tt19","tt19c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_C_OFFSET }, - { "tt20","tt20x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_X_OFFSET }, - { "tt20","tt20y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Y_OFFSET }, - { "tt20","tt20z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Z_OFFSET }, - { "tt20","tt20a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_A_OFFSET }, - { "tt20","tt20b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_B_OFFSET }, - { "tt20","tt20c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_C_OFFSET }, + { "tt20","tt20x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_X_OFFSET }, + { "tt20","tt20y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Y_OFFSET }, + { "tt20","tt20z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Z_OFFSET }, + { "tt20","tt20a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_A_OFFSET }, + { "tt20","tt20b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_B_OFFSET }, + { "tt20","tt20c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_C_OFFSET }, - { "tt21","tt21x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_X_OFFSET }, - { "tt21","tt21y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Y_OFFSET }, - { "tt21","tt21z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Z_OFFSET }, - { "tt21","tt21a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_A_OFFSET }, - { "tt21","tt21b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_B_OFFSET }, - { "tt21","tt21c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_C_OFFSET }, + { "tt21","tt21x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_X_OFFSET }, + { "tt21","tt21y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Y_OFFSET }, + { "tt21","tt21z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Z_OFFSET }, + { "tt21","tt21a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_A_OFFSET }, + { "tt21","tt21b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_B_OFFSET }, + { "tt21","tt21c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_C_OFFSET }, - { "tt22","tt22x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_X_OFFSET }, - { "tt22","tt22y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Y_OFFSET }, - { "tt22","tt22z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Z_OFFSET }, - { "tt22","tt22a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_A_OFFSET }, - { "tt22","tt22b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_B_OFFSET }, - { "tt22","tt22c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_C_OFFSET }, + { "tt22","tt22x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_X_OFFSET }, + { "tt22","tt22y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Y_OFFSET }, + { "tt22","tt22z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Z_OFFSET }, + { "tt22","tt22a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_A_OFFSET }, + { "tt22","tt22b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_B_OFFSET }, + { "tt22","tt22c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_C_OFFSET }, - { "tt23","tt23x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_X_OFFSET }, - { "tt23","tt23y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Y_OFFSET }, - { "tt23","tt23z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Z_OFFSET }, - { "tt23","tt23a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_A_OFFSET }, - { "tt23","tt23b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_B_OFFSET }, - { "tt23","tt23c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_C_OFFSET }, + { "tt23","tt23x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_X_OFFSET }, + { "tt23","tt23y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Y_OFFSET }, + { "tt23","tt23z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Z_OFFSET }, + { "tt23","tt23a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_A_OFFSET }, + { "tt23","tt23b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_B_OFFSET }, + { "tt23","tt23c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_C_OFFSET }, - { "tt24","tt24x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_X_OFFSET }, - { "tt24","tt24y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Y_OFFSET }, - { "tt24","tt24z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Z_OFFSET }, - { "tt24","tt24a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_A_OFFSET }, - { "tt24","tt24b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_B_OFFSET }, - { "tt24","tt24c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_C_OFFSET }, + { "tt24","tt24x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_X_OFFSET }, + { "tt24","tt24y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Y_OFFSET }, + { "tt24","tt24z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Z_OFFSET }, + { "tt24","tt24a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_A_OFFSET }, + { "tt24","tt24b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_B_OFFSET }, + { "tt24","tt24c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_C_OFFSET }, - { "tt25","tt25x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_X_OFFSET }, - { "tt25","tt25y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Y_OFFSET }, - { "tt25","tt25z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Z_OFFSET }, - { "tt25","tt25a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_A_OFFSET }, - { "tt25","tt25b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_B_OFFSET }, - { "tt25","tt25c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_C_OFFSET }, + { "tt25","tt25x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_X_OFFSET }, + { "tt25","tt25y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Y_OFFSET }, + { "tt25","tt25z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Z_OFFSET }, + { "tt25","tt25a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_A_OFFSET }, + { "tt25","tt25b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_B_OFFSET }, + { "tt25","tt25c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_C_OFFSET }, - { "tt26","tt26x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_X_OFFSET }, - { "tt26","tt26y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Y_OFFSET }, - { "tt26","tt26z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Z_OFFSET }, - { "tt26","tt26a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_A_OFFSET }, - { "tt26","tt26b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_B_OFFSET }, - { "tt26","tt26c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_C_OFFSET }, + { "tt26","tt26x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_X_OFFSET }, + { "tt26","tt26y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Y_OFFSET }, + { "tt26","tt26z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Z_OFFSET }, + { "tt26","tt26a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_A_OFFSET }, + { "tt26","tt26b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_B_OFFSET }, + { "tt26","tt26c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_C_OFFSET }, - { "tt27","tt27x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_X_OFFSET }, - { "tt27","tt27y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Y_OFFSET }, - { "tt27","tt27z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Z_OFFSET }, - { "tt27","tt27a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_A_OFFSET }, - { "tt27","tt27b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_B_OFFSET }, - { "tt27","tt27c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_C_OFFSET }, + { "tt27","tt27x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_X_OFFSET }, + { "tt27","tt27y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Y_OFFSET }, + { "tt27","tt27z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Z_OFFSET }, + { "tt27","tt27a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_A_OFFSET }, + { "tt27","tt27b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_B_OFFSET }, + { "tt27","tt27c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_C_OFFSET }, - { "tt28","tt28x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_X_OFFSET }, - { "tt28","tt28y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Y_OFFSET }, - { "tt28","tt28z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Z_OFFSET }, - { "tt28","tt28a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_A_OFFSET }, - { "tt28","tt28b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_B_OFFSET }, - { "tt28","tt28c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_C_OFFSET }, + { "tt28","tt28x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_X_OFFSET }, + { "tt28","tt28y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Y_OFFSET }, + { "tt28","tt28z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Z_OFFSET }, + { "tt28","tt28a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_A_OFFSET }, + { "tt28","tt28b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_B_OFFSET }, + { "tt28","tt28c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_C_OFFSET }, - { "tt29","tt29x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_X_OFFSET }, - { "tt29","tt29y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Y_OFFSET }, - { "tt29","tt29z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Z_OFFSET }, - { "tt29","tt29a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_A_OFFSET }, - { "tt29","tt29b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_B_OFFSET }, - { "tt29","tt29c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_C_OFFSET }, + { "tt29","tt29x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_X_OFFSET }, + { "tt29","tt29y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Y_OFFSET }, + { "tt29","tt29z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Z_OFFSET }, + { "tt29","tt29a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_A_OFFSET }, + { "tt29","tt29b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_B_OFFSET }, + { "tt29","tt29c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_C_OFFSET }, - { "tt30","tt30x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_X_OFFSET }, - { "tt30","tt30y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Y_OFFSET }, - { "tt30","tt30z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Z_OFFSET }, - { "tt30","tt30a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_A_OFFSET }, - { "tt30","tt30b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_B_OFFSET }, - { "tt30","tt30c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_C_OFFSET }, + { "tt30","tt30x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_X_OFFSET }, + { "tt30","tt30y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Y_OFFSET }, + { "tt30","tt30z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Z_OFFSET }, + { "tt30","tt30a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_A_OFFSET }, + { "tt30","tt30b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_B_OFFSET }, + { "tt30","tt30c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_C_OFFSET }, - { "tt31","tt31x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_X_OFFSET }, - { "tt31","tt31y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Y_OFFSET }, - { "tt31","tt31z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Z_OFFSET }, - { "tt31","tt31a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_A_OFFSET }, - { "tt31","tt31b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_B_OFFSET }, - { "tt31","tt31c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_C_OFFSET }, + { "tt31","tt31x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_X_OFFSET }, + { "tt31","tt31y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Y_OFFSET }, + { "tt31","tt31z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Z_OFFSET }, + { "tt31","tt31a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_A_OFFSET }, + { "tt31","tt31b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_B_OFFSET }, + { "tt31","tt31c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_C_OFFSET }, - { "tt32","tt32x",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_X_OFFSET }, - { "tt32","tt32y",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Y_OFFSET }, - { "tt32","tt32z",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Z_OFFSET }, - { "tt32","tt32a",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_A_OFFSET }, - { "tt32","tt32b",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_B_OFFSET }, - { "tt32","tt32c",_fipc, 3, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_C_OFFSET }, + { "tt32","tt32x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_X_OFFSET }, + { "tt32","tt32y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Y_OFFSET }, + { "tt32","tt32z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Z_OFFSET }, + { "tt32","tt32a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_A_OFFSET }, + { "tt32","tt32b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_B_OFFSET }, + { "tt32","tt32c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_C_OFFSET }, // Diagnostic parameters #ifdef __DIAGNOSTIC_PARAMETERS @@ -1296,12 +1296,12 @@ static void _convert(nvObj_t *nv, float conversion_factor) ///+++ transform these checks into NaN or INF strings with an error return? if (cm_get_units_mode(MODEL) == INCHES) { - cmAxisType axis_type = cm_get_axis_type(nv); // linear, rotary, global or error + cmAxisType axis_type = cm_get_axis_type(nv); // linear, rotary, global or error if ((axis_type == AXIS_TYPE_LINEAR) || (axis_type == AXIS_TYPE_SYSTEM)) { - if (cfgArray[nv->index].flags & F_CONVERT) { // standard units conversion + if (cfgArray[nv->index].flags & F_CONVERT) { // standard units conversion nv->value *= conversion_factor; } else - if (cfgArray[nv->index].flags & F_ICONVERT) { // inverse units conversion + if (cfgArray[nv->index].flags & F_ICONVERT) { // inverse units conversion nv->value /= conversion_factor; } } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index af27d1e0..0f767602 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 9836116 SWD @@ -102,7 +102,7 @@ true J41800030015 0x284E0A60 - 10000000 + 9836116 diff --git a/g2core/util.cpp b/g2core/util.cpp index 53608493..03091239 100644 --- a/g2core/util.cpp +++ b/g2core/util.cpp @@ -2,7 +2,8 @@ * util.cpp - a random assortment of useful functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -195,33 +196,6 @@ char *escape_string(char *dst, char *src) return (start_dst); } -/* - * fntoa() - return ASCII string given a float and a decimal precision value - * - * Like sprintf, fntoa returns length of string, less the terminating NUL character - */ -char fntoa(char *str, float n, uint8_t precision) -{ - // handle special cases - if (isnan(n)) { - strcpy(str, "nan"); - return (3); - - } else if (isinf(n)) { - strcpy(str, "inf"); - return (3); - - } else if (precision == 0 ) { return(sprintf(str, "%0.0f", (double) n)); - } else if (precision == 1 ) { return(sprintf(str, "%0.1f", (double) n)); - } else if (precision == 2 ) { return(sprintf(str, "%0.2f", (double) n)); - } else if (precision == 3 ) { return(sprintf(str, "%0.3f", (double) n)); - } else if (precision == 4 ) { return(sprintf(str, "%0.4f", (double) n)); - } else if (precision == 5 ) { return(sprintf(str, "%0.5f", (double) n)); - } else if (precision == 6 ) { return(sprintf(str, "%0.6f", (double) n)); - } else if (precision == 7 ) { return(sprintf(str, "%0.7f", (double) n)); - } else { return(sprintf(str, "%f", (double) n)); } -} - /* * compute_checksum() - calculate the checksum for a string * @@ -252,10 +226,146 @@ uint32_t SysTickTimer_getValue() return (SysTickTimer.getValue()); } -/*********************************************** - **** Very Fast Number to ASCII Conversions **** - ***********************************************/ -/* +/****************************************** + **** Fast Number to ASCII Conversions **** + ******************************************/ + +/*********************************************************************************** + * floattoa() - integer to float + * + * Floattoa() is a slightly smarter, much faster version of snprintf() + * It suppresses trailing zeros and decimal points, 20.100 --> 20.1, 20.000 --> 20 + * Like sprintf, floattoa returns length of string, less the terminating NUL character + * + * !!! Precision cannot be greater than 10 !!! + */ + +#if 0 // olde version using sprintf. Does not do trailing zero suppression + +static const char _fp0[] = "%1.0f"; +static const char _fp1[] = "%1.1f"; +static const char _fp2[] = "%1.2f"; +static const char _fp3[] = "%1.3f"; +static const char _fp4[] = "%1.4f"; +static const char _fp5[] = "%1.5f"; +static const char _fp6[] = "%1.6f"; +static const char _fp7[] = "%1.7f"; +static const char *const _fmt_precision[] = { _fp0, _fp1, _fp2, _fp3, _fp4, _fp5, _fp6, _fp7 }; + +char floattoa(char *str, float n, int precision, int maxlen /*= 16*/) +{ + // handle special cases + if (isnan(n)) { + strcpy(str, "nan"); + return (3); + } + else if (isinf(n)) { + strcpy(str, "inf"); + return (3); + } + return(snprintf(str, maxlen, _fmt_precision[precision], (double) n)); +} +#endif + +// *** floattoa() starts here *** + +constexpr float round_lookup_[] = { + 0.5, // precision 0 + 0.05, // precision 1 + 0.005, // precision 2 + 0.0005, // precision 3 + 0.00005, // precision 4 + 0.000005, // precision 5 + 0.0000005, // precision 6 + 0.00000005, // precision 7 + 0.000000005, // precision 8 + 0.0000000005, // precision 9 + 0.00000000005 // precision 10 +}; + +// It's assumed that the string buffer contains at least count_ non-\0 chars +int c_strreverse(char * const t, const int count_, char hold = 0) { + return count_>1 + // Note: It always returns the count_, for a consistent interface. + ? (hold=*t, *t=*(t+(count_-1)), *(t+(count_-1))=hold), c_strreverse(t+1, count_-2), count_ + : count_; +} + +char floattoa(char *str, float n, int precision, int maxlen /*= 16*/) // maxlen = 16 +{ + // handle special cases + if (isnan(n)) { + strcpy(str, "nan"); + return (3); + } + else if (isinf(n)) { + strcpy(str, "inf"); + return (3); + } + + int length_ = 0; + char *b_ = str; + + if (n < 0.0) { + *b_++ = '-'; + return floattoa(b_, -n, precision, maxlen-1) + 1; + } + + n += round_lookup_[precision]; + int int_length_ = 0; + int integer_part_ = (int)n; + + // do integer part + while (integer_part_ > 0) { + if (length_++ > maxlen) { + *str = 0; + return 0; + } + int t_ = integer_part_ / 10; + *b_++ = '0' + (integer_part_ - (t_*10)); + integer_part_ = t_; + int_length_++; + } + if (length_ > 0) { + c_strreverse(str, int_length_); + } else { + *b_++ = '0'; + int_length_++; + } + + // do fractional part + *b_++ = '.'; + length_ = int_length_+1; + + float frac_part_ = n; + frac_part_ -= (int)frac_part_; + while (precision-- > 0) { + if (length_++ > maxlen) { + *str = 0; + return 0; + } + frac_part_ *= 10.0; + // if (precision==0) { + // t_ += 0.5; + // } + *b_++ = ('0' + (int)frac_part_); + frac_part_ -= (int)frac_part_; + } + + // right strip trailing zeroes (OPTIONAL) + while (*(b_-1) == '0' && length_>1) { + *(b_--) = 0; + length_--; + } + + if (*(b_-1) == '.') { + *(b_--) = 0; + length_--; + } + return length_; +} + +/*********************************************************************************** * inttoa() - integer to ASCII * * Taking advantage of the fact that most ints we display are 8 bit quantities, @@ -586,90 +696,3 @@ char inttoa(char *str, int n) } return (strlen(str)); } - -constexpr float round_lookup_[] = { - 0.5, // precision 0 - 0.05, // precision 1 - 0.005, // precision 2 - 0.0005, // precision 3 - 0.00005, // precision 4 - 0.000005, // precision 5 - 0.0000005, // precision 6 - 0.00000005, // precision 7 - 0.000000005, // precision 8 - 0.0000000005, // precision 9 - 0.00000000005 // precision 10 -}; - -// It's assumed that the string buffer contains at lest count_ non-\0 chars -int c_strreverse(char * const t, const int count_, char hold = 0) { - return count_>1 - // Note: It always returns the count_, for a consistent interface. - ? (hold=*t, *t=*(t+(count_-1)), *(t+(count_-1))=hold), c_strreverse(t+1, count_-2), count_ - : count_; -} - -char floattoa(char *buffer, float in, int precision, int maxlen /*= 16*/) { - int length_ = 0; - char *b_ = buffer; - - if (in < 0.0) { - *b_++ = '-'; - return floattoa(b_, -in, precision, maxlen-1) + 1; - } - - in += round_lookup_[precision]; - int int_length_ = 0; - int integer_part_ = (int)in; - - // do integer part - while (integer_part_ > 0) { - if (length_++ > maxlen) { - *buffer = 0; - return 0; - } - int t_ = integer_part_ / 10; - *b_++ = '0' + (integer_part_ - (t_*10)); - integer_part_ = t_; - int_length_++; - } - if (length_ > 0) { - c_strreverse(buffer, int_length_); - } else { - *b_++ = '0'; - int_length_++; - } - - // do fractional part - *b_++ = '.'; - length_ = int_length_+1; - - float frac_part_ = in; - frac_part_ -= (int)frac_part_; - while (precision-- > 0) { - if (length_++ > maxlen) { - *buffer = 0; - return 0; - } - frac_part_ *= 10.0; - // if (precision==0) { - // t_ += 0.5; - // } - *b_++ = ('0' + (int)frac_part_); - frac_part_ -= (int)frac_part_; - } - - // right strip trailing zeroes (OPTIONAL) -#if 1 - while (*(b_-1) == '0' && length_>1) { - *(b_--) = 0; - length_--; - } - - if (*(b_-1) == '.') { - *(b_--) = 0; - length_--; - } -#endif - return length_; -} diff --git a/g2core/util.h b/g2core/util.h index 1880dee4..e9afc1ff 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -2,7 +2,8 @@ * util.h - a random assortment of useful functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -86,17 +87,11 @@ float max4(float x1, float x2, float x3, float x4); //*** string utilities *** -//#ifdef __ARM -//uint8_t * strcpy_U( uint8_t * dst, const uint8_t * src ); -//#endif - uint8_t isnumber(char c); char *escape_string(char *dst, char *src); -char inttoa(char *str, int n); -char floattoa(char *buffer, float in, int precision, int maxlen = 16); -//char fntoa(char *str, float n, uint8_t precision); - uint16_t compute_checksum(char const *string, const uint16_t length); +char floattoa(char *buffer, float in, int precision, int maxlen = 16); +char inttoa(char *str, int n); //*** other utilities *** From 39e3a06ed6a0c232b766a55764c5caa5547379dc Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 22 Jan 2017 15:38:42 -0500 Subject: [PATCH 093/283] =?UTF-8?q?Fixed=20=E2=80=98stat=E2=80=99=20report?= =?UTF-8?q?ing=20during=20feedhold?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/canonical_machine.cpp | 29 +++++++++++++++------------ g2core/canonical_machine.h | 3 ++- g2core/config_app.cpp | 39 ++++++++++++++++++------------------ g2core/g2core.cppproj | 8 ++++---- g2core/gcode.h | 4 ++-- 5 files changed, 44 insertions(+), 39 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 9b7b283d..02cf307c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -99,6 +99,7 @@ #include "planner.h" #include "stepper.h" #include "encoder.h" +//#include "toolhead.h" #include "spindle.h" #include "coolant.h" #include "pwm.h" @@ -294,22 +295,22 @@ cmProbeState cm_get_probe_state() { return cm->probe_state[0];} * cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "mots2"));//"mots is stop but machine is in cycle" * return (COMBINED_PANIC); */ -cmCombinedState cm_get_combined_state() +cmCombinedState cm_get_combined_state(cmMachine_t *_cm) { - if (cm->machine_state <= MACHINE_PROGRAM_END) { // replaces first 5 cm->machine_state cases - return ((cmCombinedState)cm->machine_state); //...where MACHINE_xxx == COMBINED_xxx + if (_cm->machine_state <= MACHINE_PROGRAM_END) { // replaces first 5 cm->machine_state cases + return ((cmCombinedState)_cm->machine_state); //...where MACHINE_xxx == COMBINED_xxx } - switch(cm->machine_state) { + switch(_cm->machine_state) { case MACHINE_INTERLOCK: { return (COMBINED_INTERLOCK); } case MACHINE_SHUTDOWN: { return (COMBINED_SHUTDOWN); } case MACHINE_PANIC: { return (COMBINED_PANIC); } case MACHINE_CYCLE: { - switch(cm->cycle_state) { + switch(_cm->cycle_state) { case CYCLE_HOMING: { return (COMBINED_HOMING); } case CYCLE_PROBE: { return (COMBINED_PROBE); } case CYCLE_JOG: { return (COMBINED_JOG); } case CYCLE_MACHINING: case CYCLE_OFF: { - switch(cm->motion_state) { + switch(_cm->motion_state) { case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE_1, above case MOTION_PLANNING: { return (COMBINED_RUN); } case MOTION_RUN: { return (COMBINED_RUN); } @@ -749,7 +750,7 @@ stat_t cm_test_soft_limits(const float target[]) if (cm->soft_limit_enable == true) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (cm->homed[axis] != true) { continue; } // skip axis if not homed - if (fp_EQ(cm->a[axis].travel_min, cm->a[axis].travel_max)) { continue; } // skip axis if identical + if (fp_EQ(cm->a[axis].travel_min, cm->a[axis].travel_max)) { continue; } // skip axis if identical if (fabs(cm->a[axis].travel_min) > DISABLE_SOFT_LIMIT) { continue; } // skip min test if disabled if (fabs(cm->a[axis].travel_max) > DISABLE_SOFT_LIMIT) { continue; } // skip max test if disabled @@ -1221,7 +1222,7 @@ stat_t cm_set_path_control(GCodeState_t *gcode_state, const uint8_t mode) */ stat_t cm_dwell(const float seconds) { - cm->gm.parameter = seconds; + cm->gm.P_word = seconds; mp_dwell(seconds); return (STAT_OK); } @@ -1244,10 +1245,10 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) } cm_set_model_target(target, flags); - ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown - cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state + ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown + cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles - stat_t status = mp_aline(&cm->gm); // send the move to the planner + stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_finalize_move(); // <-- ONLY safe because we don't care about status... @@ -1547,7 +1548,8 @@ static void _exec_program_finalize(float *value, bool *flag) cm_select_plane(cm->default_select_plane); // reset to default arc plane cm_set_distance_mode(cm->default_distance_mode); cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default - spindle_control_immediate(SPINDLE_OFF); // M5 +// toolhead.control_immediate(TOOLHEAD_OFF); // M5 + spindle_control_immediate(SPINDLE_OFF); // M5 coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH);// M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. @@ -1936,7 +1938,8 @@ stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], uint8_t value return(nv_copy_string(nv, (const char *)GET_TEXT_ITEM(msg_array, value))); } -stat_t cm_get_stat(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state()));} +stat_t cm_get_stat(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm1)));} +stat_t cm_get_stat2(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm2)));} stat_t cm_get_macs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_macs, cm_get_machine_state()));} stat_t cm_get_cycs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_cycs, cm_get_cycle_state()));} stat_t cm_get_mots(nvObj_t *nv) { return(_get_msg_helper(nv, msg_mots, cm_get_motion_state()));} diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index c024de86..07fd90cd 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -303,7 +303,7 @@ extern cmToolTable_t tt; /*--- Internal functions and helpers ---*/ // Model state getters and setters -cmCombinedState cm_get_combined_state(void); +cmCombinedState cm_get_combined_state(cmMachine_t *_cm); cmMachineState cm_get_machine_state(void); cmCycleState cm_get_cycle_state(void); cmMotionState cm_get_motion_state(void); @@ -489,6 +489,7 @@ cmAxisType cm_get_axis_type(const nvObj_t *nv); stat_t cm_get_mline(nvObj_t *nv); // get model line number stat_t cm_get_line(nvObj_t *nv); // get active (model or runtime) line number stat_t cm_get_stat(nvObj_t *nv); // get combined machine state as value and string +stat_t cm_get_stat2(nvObj_t *nv); // get combined machine state as value and string stat_t cm_get_macs(nvObj_t *nv); // get raw machine state as value and string stat_t cm_get_cycs(nvObj_t *nv); // get raw cycle state stat_t cm_get_mots(nvObj_t *nv); // get raw motion state diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index d0035306..9163da7f 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -113,25 +113,26 @@ const cfgItem_t cfgArray[] = { { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) - { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _f0, 0, cm_print_line, cm_get_mline,set_ro, (float *)&cs.null, 0 }, // Model line number - { "", "line",_f0, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity - { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool -// { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "stat", _f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "stat2",_f0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "n", _f0, 0, cm_print_line, cm_get_mline,set_ro, (float *)&cs.null, 0 }, // Model line number + { "", "line", _f0, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number + { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity + { "", "feed", _f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate + { "", "macs", _f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state + { "", "cycs", _f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state + { "", "mots", _f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state + { "", "hold", _f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state + { "", "unit", _f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode + { "", "coor", _f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system + { "", "momo", _f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode + { "", "plan", _f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select + { "", "path", _f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode + { "", "dist", _f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode + { "", "admo", _f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode + { "", "frmo", _f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode + { "", "tool", _f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool +// { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0f767602..36e55b55 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 9836116 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 9836116 + 10000000 diff --git a/g2core/gcode.h b/g2core/gcode.h index acb66e0b..c8a5c557 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -218,7 +218,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl float work_offset[AXES]; // offset from the work coordinate system (for reporting only) float feed_rate; // F - normalized to millimeters/minute or in inverse time mode - float parameter; // P - parameter used for dwell time in seconds, G10 coord select... + float P_word; // P - parameter used for dwell time in seconds, G10 coord select... cmFeedRateMode feed_rate_mode; // See cmFeedRateMode for settings cmCanonicalPlane select_plane; // G17,G18,G19 - values to set plane to @@ -241,7 +241,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl } feed_rate = 0.0; - parameter = 0.0; + P_word = 0.0; feed_rate_mode = INVERSE_TIME_MODE; select_plane = CANON_PLANE_XY; From 24109f26cea34b65ad9f15c351209b8496f3e57e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 23 Jan 2017 16:07:40 -0500 Subject: [PATCH 094/283] Working on integrating queue flush in with feedhold actions --- g2core/canonical_machine.cpp | 4 +- g2core/canonical_machine.h | 20 ++-- g2core/controller.cpp | 2 +- g2core/cycle_feedhold.cpp | 184 +++++++++++++++++++---------------- g2core/cycle_probing.cpp | 2 +- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 8 +- g2core/plan_line.cpp | 2 +- g2core/planner.cpp | 15 --- g2core/planner.h | 4 +- 10 files changed, 124 insertions(+), 121 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 02cf307c..ab8a15ac 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -454,7 +454,7 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax if (gcode_state == MODEL) { return (cm->gmx.position[axis]); } - return (mp_get_runtime_absolute_position(axis)); + return (mp_get_runtime_absolute_position(mr, axis)); } /* @@ -954,7 +954,7 @@ static void _exec_offset(float *value, bool *flag) * This is useful for setting origins for homing, probing, and other operations. * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!! + * !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * More specifically, do not call this function if there are any moves in the planner or diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 07fd90cd..3331ba42 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -113,8 +113,9 @@ typedef enum { // feedhold state machine FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero FEEDHOLD_DECEL_END, // end the deceleration - FEEDHOLD_PENDING, // waiting to finalize the deceleration once motion stops - FEEDHOLD_FINALIZING, // switch to secondary planner and perform feedhold actions + FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops + FEEDHOLD_FINAL_ONCE, // enter secondary planner and perform feedhold actions (once) + FEEDHOLD_FINAL_WAIT, // wait for feedhold actions to complete FEEDHOLD_HOLD // holding } cmFeedholdState; @@ -143,7 +144,7 @@ typedef enum { // feed override state machine typedef enum { // queue flush state machine FLUSH_OFF = 0, // no queue flush in effect - FLUSH_REQUESTED, // flush has been requested but not started yet + FLUSH_REQUESTED // flush has been requested but not started yet } cmQueueFlushState; typedef enum { @@ -257,7 +258,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot - bool waiting_for_planner_done; // cm_return_from_hold_context() uses this to tell when secondary planner finished + bool waiting_for_exit_hold; // used by cm_exit_hold_planner() to tell when secondary planner is done bool end_hold_requested; // request restart after feedhold bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) @@ -441,14 +442,11 @@ stat_t cm_feedhold_sequencing_callback(void); // process feedh bool cm_has_hold(void); void cm_start_hold(void); -void cm_end_hold(void); - -stat_t cm_switch_to_hold_context(void); // move to secondary planner for in-hold actions -stat_t cm_return_from_hold_context(void); // return to primary planner -stat_t cm_return_from_hold_callback(void); // main loop callback for synchronization - void cm_queue_flush(void); // flush serial and planner queues with coordinate resets -void cm_end_queue_flush(void); + +stat_t cm_enter_hold_planner(void); // move to secondary planner for in-hold actions +stat_t cm_exit_hold_planner(void); // return to primary planner +stat_t cm_exit_hold_finalize(void); // main loop callback for synchronization // Homing cycles (cycle_homing.cpp) stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2 diff --git a/g2core/controller.cpp b/g2core/controller.cpp index b1dc3abc..5d56f12e 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -162,7 +162,7 @@ static void _controller_HSM() DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines - DISPATCH(cm_return_from_hold_callback()); // return from secondary planner + DISPATCH(cm_exit_hold_finalize()); // finalization for return from secondary planner DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index a4d514df..d31029b1 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -31,6 +31,7 @@ #include "gcode.h" // #3 #include "canonical_machine.h" #include "planner.h" +#include "plan_arc.h" #include "stepper.h" #include "spindle.h" #include "coolant.h" @@ -110,6 +111,25 @@ - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart */ +/*********************************************************************************** + * cm_has_hold() - return true if a hold condition exists (or a pending hold request) + * cm_start_hold() - start a feedhhold external to feedhold request + * + * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) + */ +bool cm_has_hold() +{ + return (cm1.hold_state != FEEDHOLD_OFF); +} + +void cm_start_hold() +{ + if ((cm1.hold_state != FEEDHOLD_REQUESTED) && (mp_has_runnable_buffer(mp))) { // meaning there's something running + cm_set_motion_state(MOTION_HOLD); + cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } +} + /*********************************************************************************** * cm_request_feedhold() * cm_request_end_hold() @@ -119,7 +139,7 @@ void cm_request_feedhold(void) { - // do not generate a feedhold request from the secondary context + // cannot generate a feedhold request from the secondary context if (cm_select != CM_PRIMARY) { return; } @@ -129,7 +149,7 @@ void cm_request_feedhold(void) } } -void cm_request_end_hold(void) // This is usually requested form the secondary context +void cm_request_end_hold(void) // This is usually requested from the secondary context { if (cm1.hold_state != FEEDHOLD_OFF) { cm1.end_hold_requested = true; @@ -138,77 +158,64 @@ void cm_request_end_hold(void) // This is usually requested form the secondary void cm_request_queue_flush() { - // do not generate a queue flush request from the secondary context - if (cm_select != CM_PRIMARY) { - return; - } if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped - - // NOTE: we used to flush the input buffers, but this is handled in xio *prior* to queue flush now + // NOTE: this function used to flush the input buffers, + // but this is handled in xio *prior* to queue flush now } } stat_t cm_feedhold_sequencing_callback() { + // invoking a feedhold is a 2 step process, invoke it, then do the hold moves if (cm1.hold_state == FEEDHOLD_REQUESTED) { - cm_start_hold(); // feed won't run unless the machine is moving + if (mp_has_runnable_buffer(mp)) { // bypass cm_start_hold() to start from here + cm_set_motion_state(MOTION_HOLD); + cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } } - if (cm1.hold_state == FEEDHOLD_FINALIZING) { - cm1.hold_state = FEEDHOLD_HOLD; - cm_switch_to_hold_context(); // perform Z lift, spindle & coolant operations - } - if (cm1.queue_flush_state == FLUSH_REQUESTED) { - cm_queue_flush(); // queue flush won't run until runtime is idle + if (cm1.hold_state == FEEDHOLD_FINAL_ONCE) { + cm_enter_hold_planner(); // perform Z lift, spindle & coolant operations } + + // queue flush won't run until the hold is complete and all (subsequent) motion has stopped + if ((cm1.queue_flush_state == FLUSH_REQUESTED) && + (cm1.hold_state == FEEDHOLD_HOLD) && // only flush once hold is actually holding + (mp_runtime_is_idle())) { // don't flush planner during movement + cm_queue_flush(); + } // queue flush always ends hold, so it drops through + + // end hold always copies end position of the hold back to the primary planner if (cm1.end_hold_requested) { if (cm1.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing - cm_end_hold(); + cm1.end_hold_requested = false; + cm_exit_hold_planner(); } } return (STAT_OK); } /*********************************************************************************** - * cm_has_hold() - return true if a hold condition exists (or a pending hold request) - * cm_start_hold() - start a feedhhold by signalling the exec - * cm_end_hold() - end a feedhold by returning the system to normal operation - */ -bool cm_has_hold() -{ - return (cm1.hold_state != FEEDHOLD_OFF); -} - -void cm_start_hold() -{ - if (mp_has_runnable_buffer(mp)) { //+++++ // meaning there's something running - cm_set_motion_state(MOTION_HOLD); - cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} - -void cm_end_hold() -{ - if (cm1.hold_state == FEEDHOLD_HOLD) { - cm1.end_hold_requested = false; - cm_return_from_hold_context(); - } -} - -/*********************************************************************************** - * cm_switch_to_hold_context() - switch to secondary machine context + * cm_enter_hold_planner() - switch to secondary machine context for feedhold * - * Moving between contexts is only safe when the machine is completely stopped + * Moving between planners is only safe when the machine is completely stopped * either during a feedhold or when idle. + * + * This function assumes that the feedhold sequencing callback has resolved all + * state and timing issues and it's OK to call this now. Do not call this function + * directly. Always use the feedhold sequencing callback. */ -stat_t cm_switch_to_hold_context() +// Callback to run at when the secondary planner moves are finished +static void _enter_hold_finalize(float* vect, bool* flag) { - // Must be in the primary CM and fully stopped in a hold - if ((cm != &cm1) || (cm->hold_state != FEEDHOLD_HOLD)) { - return (STAT_COMMAND_NOT_ACCEPTED); - } + cm1.hold_state = FEEDHOLD_HOLD; +} + +stat_t cm_enter_hold_planner() +{ + cm->hold_state = FEEDHOLD_FINAL_WAIT; // last state before transitioning to HOLD // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner @@ -250,34 +257,38 @@ stat_t cm_switch_to_hold_context() cm_set_distance_mode(stored_distance_mode); } - spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause - coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause + spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause + coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause + mp_queue_command(_enter_hold_finalize, nullptr, nullptr); return (STAT_OK); } /*********************************************************************************** - * cm_return_from_hold_context() - initiate return from secondary context - * cm_return_from_hold_callback() - main loop callback to finsh return once moves are done - * _planner_done_callback() - callback to sync to end of planner operations + * cm_exit_hold_planner() - initiate return from secondary context + * cm_exit_hold_finalize() - main loop callback to finsh return once moves are done + * _planner_done_callback() - callback to sync to end of planner operations * - * Moving between contexts is only safe when the machine is completely stopped + * Moving between planners is only safe when the machine is completely stopped * either during a feedhold or when idle. + * + * The reason the finalization moves are not just done in _exit_hold_finalize + * is that they need to run as main loop functions, not called from the + * planner_exec interrupt level. + * + * This function assumes that the feedhold sequencing callback has resolved all + * state and timing issues and it's OK to call this now. Do not call this function + * directly. Always use the feedhold sequencing callback. */ // Callback to run at when the G30 return move is finished -static void _planner_done_callback(float* vect, bool* flag) +static void _exit_hold_finalize(float* vect, bool* flag) { - cm2.waiting_for_planner_done = false; + cm2.waiting_for_exit_hold = false; } -stat_t cm_return_from_hold_context() // LATER: if value == true return with offset corrections +stat_t cm_exit_hold_planner() // LATER: if value == true return with offset corrections { - // Must be in the secondary CM and fully stopped - if ((cm != &cm2) || (cm->motion_state != MOTION_STOP)) { - return (STAT_COMMAND_NOT_ACCEPTED); - } - // *** While still in secondary machine: spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused @@ -287,39 +298,52 @@ stat_t cm_return_from_hold_context() // LATER: if value == true return with float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move - cm->waiting_for_planner_done = true; // indicates running the final G30 move in the secondary - mp_queue_command(_planner_done_callback, nullptr, nullptr); + cm2.waiting_for_exit_hold = true; // indicates running the final G30 move in the secondary + mp_queue_command(_exit_hold_finalize, nullptr, nullptr); cm_select = CM_SECONDARY_RETURN; return (STAT_OK); // return_to_primary completes in cm_return_callback() after the wait } -stat_t cm_return_from_hold_callback() +stat_t cm_exit_hold_finalize() { if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner return (STAT_NOOP); } - if (cm->waiting_for_planner_done) { // sync to planner move ends (via _return_move_callback) + if (cm2.waiting_for_exit_hold) { // sync to planner move ends (via _return_move_callback) return (STAT_EAGAIN); } + // collect final runtime position from secondary planner + uint8_t axis; + float runtime_position[AXES]; + for (axis = AXIS_X; axis < AXES; axis++) { + runtime_position[axis] = mp_get_runtime_absolute_position(&mr2, axis); + } +// copy_vector(runtime_position, mr2.position); + // return to primary machine cm = &cm1; mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; cm_select = CM_PRIMARY; + // copy final runtime position to primary planner + for (axis = AXIS_X; axis < AXES; axis++) { + cm_set_position(axis, runtime_position[axis]); + } + cm->hold_state = FEEDHOLD_OFF; if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? cm_set_motion_state(MOTION_RUN); cm_cycle_start(); st_request_exec_move(); - sr_request_status_report(SR_REQUEST_IMMEDIATE); } else { cm_set_motion_state(MOTION_STOP); cm_cycle_end(); } + sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); } @@ -361,22 +385,18 @@ stat_t cm_return_from_hold_callback() */ /*********************************************************************************** - * cm_queue_flush() - Flush planner queue and correct model positions + * cm_queue_flush() - Flush primary planner queue + * + * This function assumes that the feedhold sequencing callback has resolved all + * state and timing issues and it's OK to call this now. Do not call this function + * directly. ALways use the feedhold sequencing callback. */ void cm_queue_flush() { - if (mp_runtime_is_idle()) { // can't flush planner during movement - mp_flush_planner(mp); // +++++ Active planner. Potential cleanup - - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions - cm_set_position(axis, mp_get_runtime_absolute_position(axis)); - } - if(cm->hold_state == FEEDHOLD_HOLD) { // end feedhold if we're in one - cm_end_hold(); - } - cm->queue_flush_state = FLUSH_OFF; - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available - } + cm_abort_arc(&cm1); // kill arcs so they don't just create more alines + planner_reset((mpPlanner_t *)cm1.mp); // also resets the mr under the planner + cm1.queue_flush_state = FLUSH_OFF; + cm1.end_hold_requested = true; // queue flush always ends the hold + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } - diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 554e33a3..fcee822e 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -313,7 +313,7 @@ static stat_t _probe_axis_move(const float target[], bool exact_position) { } for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions - cm_set_position(axis, mp_get_runtime_absolute_position(axis)); + cm_set_position(axis, mp_get_runtime_absolute_position(mr, axis)); } // set this BEFORE the motion starts diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 36e55b55..af27d1e0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 9cfc373f..e8f03851 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -533,18 +533,18 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->motion_state == MOTION_HOLD) { // Case (7) - all motion has ceased - if (cm->hold_state >= FEEDHOLD_FINALIZING) { // FEEDHOLD_FINALIZING or FEEDHOLD_HOLD + if (cm->hold_state >= FEEDHOLD_FINAL_ONCE) { // FEEDHOLD_FINAL_ONCE or later return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } // Case (6) - wait for the steppers to stop - if (cm->hold_state == FEEDHOLD_PENDING) { + if (cm->hold_state == FEEDHOLD_STOPPING) { if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { // when homing or probing we don't want to stay in HOLD or execute finalizations cm->hold_state = FEEDHOLD_OFF; } else { - cm->hold_state = FEEDHOLD_FINALIZING; + cm->hold_state = FEEDHOLD_FINAL_ONCE; } mp_zero_segment_velocity(); // for reporting purposes sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -560,7 +560,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr->target, mr->position);// reset length //bf->entry_vmax = 0; // set bp+0 as hold point - cm->hold_state = FEEDHOLD_PENDING; + cm->hold_state = FEEDHOLD_STOPPING; // No point bothering with the rest of this move if homing or probing if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 67f16b90..32ee664b 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -76,7 +76,7 @@ static void _set_bf_diagnostics(mpBuf_t* bf) { void mp_zero_segment_velocity() { mr->segment_velocity = 0; } float mp_get_runtime_velocity(void) { return (mr->segment_velocity); } -float mp_get_runtime_absolute_position(uint8_t axis) { return (mr->position[axis]); } +float mp_get_runtime_absolute_position(mpPlannerRuntime_t *_mr, uint8_t axis) { return (_mr->position[axis]); } void mp_set_runtime_work_offset(float offset[]) { copy_vector(mr->gm.work_offset, offset); } // We have to handle rotation - "rotate" by the transverse of the matrix to got "normal" coordinates diff --git a/g2core/planner.cpp b/g2core/planner.cpp index e7d00b1f..d331b828 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -230,21 +230,6 @@ void mp_halt_runtime() planner_reset(mp); // reset the active planner } -/* - * mp_flush_planner() - flush all moves in the planner and all arcs - * - * Does not affect the move currently running in mr-> - * Does not affect mm or gm model positions - * This function is designed to be called during a hold to reset the planner - * This function should not generally be called; call cm_queue_flush() instead - */ -void mp_flush_planner(mpPlanner_t *_mp) -{ - cm_abort_arc(cm); - planner_reset(_mp); - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to prevent subsequent motion -} - /* * mp_set_planner_position() - set planner position for a single axis * mp_set_runtime_position() - set runtime position for a single axis diff --git a/g2core/planner.h b/g2core/planner.h index 359b1d9a..9a7d8f8a 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -541,7 +541,7 @@ void planner_reset(mpPlanner_t *_mp); stat_t planner_test_assertions(const mpPlanner_t *_mp); void mp_halt_runtime(void); -void mp_flush_planner(mpPlanner_t *_mp); + void mp_set_planner_position(uint8_t axis, const float position); void mp_set_runtime_position(uint8_t axis, const float position); void mp_set_steps_to_runtime_position(void); @@ -590,7 +590,7 @@ bool mp_free_run_buffer(void); //**** plan_line.c functions void mp_zero_segment_velocity(void); // getters and setters... float mp_get_runtime_velocity(void); -float mp_get_runtime_absolute_position(uint8_t axis); +float mp_get_runtime_absolute_position(mpPlannerRuntime_t *_mr, uint8_t axis); float mp_get_runtime_work_position(uint8_t axis); void mp_set_runtime_work_offset(float offset[]); bool mp_get_runtime_busy(void); From 894fa532b45e7cc67fc50b76b9960d627d08e3c2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 24 Jan 2017 09:29:07 -0500 Subject: [PATCH 095/283] Testing queue flush return from feedhold. Passes current tests --- g2core/canonical_machine.cpp | 4 +- g2core/canonical_machine.h | 3 +- g2core/cycle_feedhold.cpp | 71 +++++++++++++++++------------------- g2core/g2core.cppproj | 4 +- 4 files changed, 40 insertions(+), 42 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index ab8a15ac..adae40c7 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -740,8 +740,8 @@ void cm_set_model_target(const float target[], const bool flags[]) static stat_t _finalize_soft_limits(const stat_t status) { - cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // cancel motion - copy_vector(cm->gm.target, cm->gmx.position); // reset model target + cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // cancel motion + copy_vector(cm->gm.target, cm->gmx.position); // reset model target return (cm_alarm(status, "soft_limits")); // throw an alarm } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 3331ba42..2569356b 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -144,7 +144,8 @@ typedef enum { // feed override state machine typedef enum { // queue flush state machine FLUSH_OFF = 0, // no queue flush in effect - FLUSH_REQUESTED // flush has been requested but not started yet + FLUSH_REQUESTED, // flush has been requested but not started yet + FLUSH_WAS_RUN // transient state to note that a queue flush has been run } cmQueueFlushState; typedef enum { diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index d31029b1..4c2258b8 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -134,7 +134,6 @@ void cm_start_hold() * cm_request_feedhold() * cm_request_end_hold() * cm_request_queue_flush() - * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests */ void cm_request_feedhold(void) @@ -166,6 +165,10 @@ void cm_request_queue_flush() } } +/*********************************************************************************** + * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests + */ + stat_t cm_feedhold_sequencing_callback() { // invoking a feedhold is a 2 step process, invoke it, then do the hold moves @@ -186,12 +189,13 @@ stat_t cm_feedhold_sequencing_callback() cm_queue_flush(); } // queue flush always ends hold, so it drops through - // end hold always copies end position of the hold back to the primary planner + // exit_hold runs for both ~ and % feedhold ends if (cm1.end_hold_requested) { - if (cm1.queue_flush_state == FLUSH_OFF) { // either no flush or wait until it's done flushing - cm1.end_hold_requested = false; - cm_exit_hold_planner(); - } + if (cm1.queue_flush_state == FLUSH_REQUESTED) { // possible race condition if flush request + return (STAT_OK); //...was received when this callback was running + } + cm1.end_hold_requested = false; + cm_exit_hold_planner(); } return (STAT_OK); } @@ -224,18 +228,17 @@ stat_t cm_enter_hold_planner() planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer // set parameters in cm, gm and gmx so you can actually use it - cmMachine_t *_cm = &cm2; - _cm->hold_state = FEEDHOLD_OFF; - _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - _cm->gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - _cm->gm.feed_rate = 0; + cm2.hold_state = FEEDHOLD_OFF; + cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + cm2.gm.feed_rate = 0; // clear the target and set the positions to the current hold position - memset(&(_cm->gm.target), 0, sizeof(_cm->gm.target)); - copy_vector(_cm->gm.target_comp, cm->gm.target_comp); // preserve original Kahan compensation - copy_vector(_cm->gmx.position, mr->position); - copy_vector(mp2.position, mr->position); - copy_vector(mr2.position, mr->position); + memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); + copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation + copy_vector(cm2.gmx.position, mr1.position); + copy_vector(mp2.position, mr1.position); + copy_vector(mr2.position, mr1.position); // reassign the globals to the secondary CM cm = &cm2; @@ -247,8 +250,8 @@ stat_t cm_enter_hold_planner() cm_set_g30_position(); cm_set_motion_state(MOTION_STOP); - // optional Z lift - if (fp_NOT_ZERO(cm->feedhold_z_lift)) { + // execute feedhold actions + if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift float stored_distance_mode = cm_get_distance_mode(MODEL); cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); bool flags[] = { 0,0,1,0,0,0 }; @@ -256,7 +259,6 @@ stat_t cm_enter_hold_planner() cm_straight_traverse(target, flags); cm_set_distance_mode(stored_distance_mode); } - spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause mp_queue_command(_enter_hold_finalize, nullptr, nullptr); @@ -289,8 +291,7 @@ static void _exit_hold_finalize(float* vect, bool* flag) stat_t cm_exit_hold_planner() // LATER: if value == true return with offset corrections { - // *** While still in secondary machine: - + // perform end-hold actions --- while still in secondary machine spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused @@ -303,7 +304,7 @@ stat_t cm_exit_hold_planner() // LATER: if value == true return with offset cm_select = CM_SECONDARY_RETURN; return (STAT_OK); - // return_to_primary completes in cm_return_callback() after the wait +// cm_exit_hold_planner() completes in cm_exit_hold_finalize() after the above moves are done } stat_t cm_exit_hold_finalize() @@ -315,25 +316,21 @@ stat_t cm_exit_hold_finalize() return (STAT_EAGAIN); } - // collect final runtime position from secondary planner - uint8_t axis; - float runtime_position[AXES]; - for (axis = AXIS_X; axis < AXES; axis++) { - runtime_position[axis] = mp_get_runtime_absolute_position(&mr2, axis); - } -// copy_vector(runtime_position, mr2.position); - // return to primary machine cm = &cm1; mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; cm_select = CM_PRIMARY; - // copy final runtime position to primary planner - for (axis = AXIS_X; axis < AXES; axis++) { - cm_set_position(axis, runtime_position[axis]); + // if queue flush occurred adjust primary planner positions to runtime positions + if (cm1.queue_flush_state == FLUSH_WAS_RUN) { + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { + cm_set_position(axis, mp_get_runtime_absolute_position(&mr2, axis)); + } + cm1.queue_flush_state = FLUSH_OFF; } + // resume motion from primary planner or end cycle if now moves cm->hold_state = FEEDHOLD_OFF; if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? cm_set_motion_state(MOTION_RUN); @@ -351,8 +348,8 @@ stat_t cm_exit_hold_finalize() * Queue Flush operations * * This one's complicated. See here first: - * https://github.com/synthetos/g2/wiki/Alarm-Processing * https://github.com/synthetos/g2/wiki/Job-Exception-Handling + * https://github.com/synthetos/g2/wiki/Alarm-Processing * * We want to use queue flush for a few different use cases, as per the above wiki pages. * The % behavior implements Exception Handling cases 1 and 2 - Stop a Single Move and @@ -389,14 +386,14 @@ stat_t cm_exit_hold_finalize() * * This function assumes that the feedhold sequencing callback has resolved all * state and timing issues and it's OK to call this now. Do not call this function - * directly. ALways use the feedhold sequencing callback. + * directly. Always use the feedhold sequencing callback. */ void cm_queue_flush() { cm_abort_arc(&cm1); // kill arcs so they don't just create more alines - planner_reset((mpPlanner_t *)cm1.mp); // also resets the mr under the planner - cm1.queue_flush_state = FLUSH_OFF; + planner_reset((mpPlanner_t *)cm1.mp); // reset primary planner. also resets the mr under the planner + cm1.queue_flush_state = FLUSH_WAS_RUN; cm1.end_hold_requested = true; // queue flush always ends the hold qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index af27d1e0..0f767602 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 9836116 SWD @@ -102,7 +102,7 @@ true J41800030015 0x284E0A60 - 10000000 + 9836116 From 78410236d47212d18ea52ddf0c977b6f5fd9a4fc Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 24 Jan 2017 10:04:27 -0500 Subject: [PATCH 096/283] Fixed !% condition --- g2core/cycle_feedhold.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 4c2258b8..7bcbf78e 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -173,29 +173,33 @@ stat_t cm_feedhold_sequencing_callback() { // invoking a feedhold is a 2 step process, invoke it, then do the hold moves if (cm1.hold_state == FEEDHOLD_REQUESTED) { - if (mp_has_runnable_buffer(mp)) { // bypass cm_start_hold() to start from here + if (mp_has_runnable_buffer(mp)) { // bypass cm_start_hold() to start from here cm_set_motion_state(MOTION_HOLD); - cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } if (cm1.hold_state == FEEDHOLD_FINAL_ONCE) { - cm_enter_hold_planner(); // perform Z lift, spindle & coolant operations + cm_enter_hold_planner(); // perform Z lift, spindle & coolant operations } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped if ((cm1.queue_flush_state == FLUSH_REQUESTED) && - (cm1.hold_state == FEEDHOLD_HOLD) && // only flush once hold is actually holding - (mp_runtime_is_idle())) { // don't flush planner during movement + (cm1.hold_state == FEEDHOLD_HOLD) && // only flush once hold is actually holding + (mp_runtime_is_idle())) { // don't flush planner during movement cm_queue_flush(); - } // queue flush always ends hold, so it drops through + } // queue flush always ends hold, so it drops through // exit_hold runs for both ~ and % feedhold ends if (cm1.end_hold_requested) { - if (cm1.queue_flush_state == FLUSH_REQUESTED) { // possible race condition if flush request - return (STAT_OK); //...was received when this callback was running - } - cm1.end_hold_requested = false; - cm_exit_hold_planner(); + + // Flushes must complete before end_hold runs. Trap possible race condition if flush request was + if (cm1.queue_flush_state == FLUSH_REQUESTED) { // ...received when this callback was running + return (STAT_OK); + } + if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold + cm1.end_hold_requested = false; + cm_exit_hold_planner(); + } } return (STAT_OK); } From 482fd7d233c09f8e3a15a80b56989633a8f79887 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 24 Jan 2017 10:44:17 -0500 Subject: [PATCH 097/283] Comments --- g2core/cycle_feedhold.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 7bcbf78e..355198a9 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -167,6 +167,19 @@ void cm_request_queue_flush() /*********************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests + * + * Expected behaviors: (no-hold means machine is not in hold, etc) + * + * (no-cycle) ! No action. Feedhold is not run (nothing to hold!) + * (no-hold) ~ No action. Cannot exit a feedhold that does not exist + * (no-hold) % No action. Queue flush is not honored except during a feedhold + * (in-cycle) ! Start a feedhold + * (in-hold) ~ Wait for feedhold actions to complete, exit feedhold, resume motion + * (in-hold) % Wait for feedhold actions to complete, exit feedhold, do not resume motion + * (in-cycle) !~ Start a feedhold, do enter and exit actions, exit feedhold, resume motion + * (in-cycle) !% Start a feedhold, do enter and exit actions, exit feedhold, do not resume motion + * (in-cycle) !%~ Same as above + * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) */ stat_t cm_feedhold_sequencing_callback() From 2f6f7b5130fd37e1099e439f4ab54aa07bc5d954 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 24 Jan 2017 10:56:38 -0500 Subject: [PATCH 098/283] Changes to cm_start_hold(). Needs testing with homing and probing --- g2core/cycle_feedhold.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 355198a9..cdb45738 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -113,7 +113,7 @@ /*********************************************************************************** * cm_has_hold() - return true if a hold condition exists (or a pending hold request) - * cm_start_hold() - start a feedhhold external to feedhold request + * cm_start_hold() - start a feedhhold external to feedhold request & sequencing * * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) */ @@ -124,9 +124,11 @@ bool cm_has_hold() void cm_start_hold() { - if ((cm1.hold_state != FEEDHOLD_REQUESTED) && (mp_has_runnable_buffer(mp))) { // meaning there's something running +// if ((cm1.hold_state != FEEDHOLD_REQUESTED) && (mp_has_runnable_buffer(mp))) { // meaning there's something running + // Can only request a feedhold if the machine is in motion and there not one is not already in progress + if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { cm_set_motion_state(MOTION_HOLD); - cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } @@ -205,7 +207,7 @@ stat_t cm_feedhold_sequencing_callback() // exit_hold runs for both ~ and % feedhold ends if (cm1.end_hold_requested) { - // Flushes must complete before end_hold runs. Trap possible race condition if flush request was + // Flush must complete before exit_hold runs. Trap possible race condition if flush request was if (cm1.queue_flush_state == FLUSH_REQUESTED) { // ...received when this callback was running return (STAT_OK); } @@ -284,7 +286,7 @@ stat_t cm_enter_hold_planner() } /*********************************************************************************** - * cm_exit_hold_planner() - initiate return from secondary context + * cm_exit_hold_planner() - initiate return from feedhold planner * cm_exit_hold_finalize() - main loop callback to finsh return once moves are done * _planner_done_callback() - callback to sync to end of planner operations * From f13278e72a32928ea8d4df58d5fd230b291c749f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 25 Jan 2017 10:35:23 -0500 Subject: [PATCH 099/283] Corrected arc entry condition that was not properly trapped; more feedhold testing --- g2core/cycle_feedhold.cpp | 4 +++- g2core/error.h | 8 ++++---- g2core/g2core.cppproj | 8 ++++---- g2core/gcode_parser.cpp | 2 +- g2core/plan_arc.cpp | 11 ++++++++++- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index cdb45738..06c570ec 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -341,11 +341,13 @@ stat_t cm_exit_hold_finalize() mr = mp->mr; cm_select = CM_PRIMARY; - // if queue flush occurred adjust primary planner positions to runtime positions + // execute this block if a queue flush was performed + // adjust primary planner positions to runtime positions if (cm1.queue_flush_state == FLUSH_WAS_RUN) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { cm_set_position(axis, mp_get_runtime_absolute_position(&mr2, axis)); } + // TODO: reset motion mode to G80 or G0. Others? cm1.queue_flush_state = FLUSH_OFF; } diff --git a/g2core/error.h b/g2core/error.h index b3c3f68a..4f4024c9 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -249,9 +249,9 @@ char *get_status_message(stat_t status); #define STAT_SPINDLE_SPEED_MAX_EXCEEDED 150 #define STAT_SPINDLE_MUST_BE_OFF 151 #define STAT_SPINDLE_MUST_BE_TURNING 152 // some canned cycles require spindle to be turning when called -#define STAT_ARC_ERROR_RESERVED 153 // RESERVED +#define STAT_ARC_SPECIFICATION_ERROR 153 // generic arc specification error #define STAT_ARC_HAS_IMPOSSIBLE_CENTER_POINT 154 // trap (.05 inch/.5 mm) OR ((.0005 inch/.005mm) AND .1% of radius condition -#define STAT_ARC_SPECIFICATION_ERROR 155 // generic arc specification error +#define STAT_ARC_HAS_ROTARY_AXIS 155 // arc specification includes a rotary axis #define STAT_ARC_AXIS_MISSING_FOR_SELECTED_PLANE 156 // arc is missing axis (axes) required by selected plane #define STAT_ARC_OFFSETS_MISSING_FOR_SELECTED_PLANE 157 // one or both offsets are not specified #define STAT_ARC_RADIUS_OUT_OF_TOLERANCE 158 // WARNING - radius arc is too large - accuracy in question @@ -543,9 +543,9 @@ static const char stat_149[] = "Spindle speed below minimum"; static const char stat_150[] = "Spindle speed exceeded maximum"; static const char stat_151[] = "Spindle must be off for this command"; static const char stat_152[] = "Spindle must be turning for this command"; -static const char stat_153[] = "153"; +static const char stat_153[] = "Arc specification error"; static const char stat_154[] = "Arc specification error - impossible center point"; -static const char stat_155[] = "Arc specification error"; +static const char stat_155[] = "Arc specification error - arc has rotary axis(es)"; static const char stat_156[] = "Arc specification error - missing axis(es)"; static const char stat_157[] = "Arc specification error - missing offset(s)"; //--------------------------------------1--------10--------20--------30--------40--------50--------60-64 diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0f767602..36e55b55 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 9836116 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 9836116 + 10000000 diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 8f8f5fc1..d0bc3cdd 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -724,7 +724,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) * 20. perform motion (G0 to G3, G80-G89) as modified (possibly) by G53 * 21. stop and end (M0, M1, M2, M30, M60) * - * Values in gn are in original units and should not be unit converted prior + * Values in gv are in original units and should not be unit converted prior * to calling the canonical functions (which do the unit conversions) */ diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 49389f29..963db602 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -105,7 +105,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en const cmMotionMode motion_mode) // defined motion mode { // Start setting up the arc and trapping arc specification errors - + // Trap some precursor cases. Since motion mode (MODAL_GROUP_G1) persists from the // previous move it's possible for non-modal commands such as F or P to arrive here // when no motion has actually been specified. It's also possible to run an arc as @@ -127,6 +127,15 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // Some things you might think are errors but are not: // - offset specified for linear axis (i.e. not one of the plane axes). Ignored // - rotary axes are present. Ignored + // - no parameters are specified. This can happen when G2 or G3 motion mode persists but + // a non-arc, non-motion command is entered afterwards, such as M3 or T. Trapped here: + + // Trap if no parameters were specified while in CW or CCW arc motion mode. This is OK + if (!(target_f[AXIS_X] | target_f[AXIS_Y] | target_f[AXIS_Z] | + offset_f[AXIS_X] | offset_f[AXIS_Y] | offset_f[AXIS_Z] | + radius_f | P_word_f)) { + return(STAT_OK); + } // trap missing feed rate if (fp_ZERO(cm->gm.feed_rate)) { From 27b26cfef84e496db57a0b3a25ebbbfdba45a915 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 25 Jan 2017 11:33:18 -0500 Subject: [PATCH 100/283] Passes all tests --- g2core/cycle_feedhold.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 06c570ec..180d6be3 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -347,7 +347,6 @@ stat_t cm_exit_hold_finalize() for (uint8_t axis = AXIS_X; axis < AXES; axis++) { cm_set_position(axis, mp_get_runtime_absolute_position(&mr2, axis)); } - // TODO: reset motion mode to G80 or G0. Others? cm1.queue_flush_state = FLUSH_OFF; } From 5416a5c2c55d08ed76f30aed3175d127b2869ff5 Mon Sep 17 00:00:00 2001 From: Ryan Sturmer Date: Thu, 26 Jan 2017 10:20:37 -0500 Subject: [PATCH 101/283] Add z lift to sbv300 settings --- g2core/settings/settings_shopbot_sbv300.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/g2core/settings/settings_shopbot_sbv300.h b/g2core/settings/settings_shopbot_sbv300.h index 2cf538bb..62c2f77c 100644 --- a/g2core/settings/settings_shopbot_sbv300.h +++ b/g2core/settings/settings_shopbot_sbv300.h @@ -417,3 +417,6 @@ constexpr float H3_DEFAULT_D = 100.0; #define USER_DATA_D1 0 #define USER_DATA_D2 0 #define USER_DATA_D3 0 + +#define FEEDHOLD_Z_LIFT 0.5 + From 7f5888fac5a0b12dceaa8e1360769d12252a9168 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 27 Jan 2017 13:12:48 -0500 Subject: [PATCH 102/283] Fixed root finding problem in feedhold exit velocity calculation --- g2core/boards.mk | 3 +- g2core/config_app.cpp | 2 +- g2core/g2core.cppproj | 4 +- g2core/plan_zoid.cpp | 53 +++++------ g2core/settings/settings_shopbot_sbv300.h | 6 +- g2core/settings/settings_shopbot_test.h | 108 ++++------------------ 6 files changed, 53 insertions(+), 123 deletions(-) diff --git a/g2core/boards.mk b/g2core/boards.mk index f51eca4d..170f37f3 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -67,7 +67,8 @@ ifeq ("$(CONFIG)","TestV9") ifeq ("$(BOARD)","NONE") BOARD=g2v9k endif - SETTINGS_FILE="settings_test.h" +# SETTINGS_FILE="settings_test.h" + SETTINGS_FILE="settings_shopbot_test.h" endif ifeq ("$(CONFIG)","TestQuintic") diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 9163da7f..04811f24 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -628,7 +628,7 @@ const cfgItem_t cfgArray[] = { // General system parameters { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, - { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT}, + { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT }, { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, { "sys","lim", _fipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, { "sys","saf", _fipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 36e55b55..af27d1e0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index e63f27cb..36dedc0b 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -2,8 +2,8 @@ * plan_zoid.cpp - acceleration managed line planning and motion execution - trapezoid planner * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2016 Rob Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -419,51 +419,52 @@ float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t* bf) return fabs(v_1); } - /* * mp_get_decel_velocity() - mp_get_target_velocity but ONLY for deceleration * - * Get "the velocity" that we would end up at if we *decelerated* from v_0, - * over the provided L (length) and J (jerk, provided in the bf structure). + * Get "the velocity" that we would end up at if we *decelerated* from v_0, + * over the provided L (length) and J (jerk, provided in the bf structure). * - * We have to use a root finding solution, since there is actually three possible - * solutions. We can eliminate one quickly, since it's the acceleration case. + * We have to use a root finding solution, since there is actually three possible + * solutions. We can eliminate one quickly, since it's the acceleration case. * - * The other two cases are occasionally the same value, but this is rare. - * Otherwise there is a "high" value and a "low" value. The low value can be - * negative and then eliminated. + * The other two cases are occasionally the same value, but this is rare. + * Otherwise there is a "high" value and a "low" value. The low value can be + * negative and then eliminated. + * + * This function may generate minor errors in target velocity, and should only + * be used to compute feedholds or other cases where exact velocity is not mandatory. */ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) { const float q_recip_2_sqrt_j = bf->q_recip_2_sqrt_j; + float v_1 = 0; // start the guess at zero - float v_1 = 0; // start the guess at zero - bool first_pass = true; // We may invert our guess based on the first pass results. + int i = 0; // limit the iterations + while (i++ < 20) { // If it fails after 20 iterations something's wrong - int i = 0; // limit the iterations - while (i++ < 10) { // If it fails after 10, something's wrong + // l_t is the difference in length between the L provided and the current guessed deceleration length const float sqrt_delta_v_0 = sqrt(v_0 - v_1); - const float l_t = q_recip_2_sqrt_j * (sqrt_delta_v_0 * (v_1 + v_0)) - L; + const float l_t = q_recip_2_sqrt_j * (sqrt_delta_v_0 * (v_1 + v_0)) - L; - if (fabs(l_t) < 0.00001) { + // The return condition allows a minor error in length (in mm). + // Note: This comparison does NOT affect actual lengths or steps, which would be bad. + // The actual lengths traveled must be controlled by the caller. + if (fabs(l_t) < 0.001) { break; } - // For the first pass, we tested velocity 0. - // If velocity 0 yields a l_t > zero, then we need to start searching - // at v_1 instead. (We can't start AT v_1, so we start at v_1 - 0.1.) - if (first_pass && (l_t > 0)) { - v_1 = v_0 - 0.001; - + // For the first pass we tested velocity 0. If velocity 0 yields a l_t > 0, + // then we need to start searching at v_1 instead. + // (We can't start AT v_1, so we start at v_1 - 0.1) + if (i==1 && (l_t > 0)) { + v_1 = v_0 - 0.1; continue; } - - const float v_1x3 = 3 * v_1; + const float v_1x3 = 3 * v_1; const float recip_l_t = (2 * sqrt_delta_v_0) / ((v_0 - v_1x3) * q_recip_2_sqrt_j); - v_1 = v_1 - (l_t * recip_l_t); } - return v_1; } diff --git a/g2core/settings/settings_shopbot_sbv300.h b/g2core/settings/settings_shopbot_sbv300.h index 2cf538bb..357289d5 100644 --- a/g2core/settings/settings_shopbot_sbv300.h +++ b/g2core/settings/settings_shopbot_sbv300.h @@ -1,8 +1,8 @@ /* - * settings_shapeoko375.h - Shopbot Test + * settings_shopbot_sbv300.h - Shopbot sbv300 board * This file is part of the g2core project * - * Copyright (c) 2015 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -154,7 +154,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min #define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits #define X_TRAVEL_MAX (25 * 25.4) // xtm travel between switches or crashes -#define X_JERK_MAX (2 * 25.4) // xjm jerk is multipled by 1,000,000 internally +#define X_JERK_MAX (2 * 25.4) // xjm jerk is multiplied by 1,000,000 internally #define X_JERK_HIGH_SPEED 10000 // xjh //#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable #define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive diff --git a/g2core/settings/settings_shopbot_test.h b/g2core/settings/settings_shopbot_test.h index 76caf26b..dcb28d4a 100644 --- a/g2core/settings/settings_shopbot_test.h +++ b/g2core/settings/settings_shopbot_test.h @@ -1,8 +1,8 @@ /* - * settings_shapeoko375.h - Shopbot Test + * settings_shopbot_test.h - Shopbot Test * This file is part of the g2core project * - * Copyright (c) 2015 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -51,13 +51,15 @@ #define SPINDLE_PAUSE_ON_HOLD true #define SPINDLE_DWELL_TIME 1.0 +#define FEEDHOLD_Z_LIFT (0.5 * 25.4) + #define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high #define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high #define COOLANT_PAUSE_ON_HOLD true // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS @@ -69,14 +71,7 @@ #define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE #define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum #define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -//#define STATUS_REPORT_DEFAULTS "posx","posy","posz","posa","posb","vel","stat","hold","line","coor" -//#define STATUS_REPORT_DEFAULTS -//"posx","posy","posz","posa","posb","vel","stat","macs","cycs","mots","hold","line","coor" -#define STATUS_REPORT_DEFAULTS \ - "posx", "posy", "posz", "posa", "vel", "feed", "stat", "macs", "cycs", "mots", "hold", "in1", "in2", "in3", "in4", \ - "in5", "in6", "in7", "in8", "in9" -// "home","homx","homy","homz" -// "line","vel","feed","stat","macs","cycs","mots","hold","unit", +#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", "vel", "stat", "hold", "line", "coor" // Gcode startup defaults #define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES @@ -106,7 +101,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define M1_MOTOR_MAP AXIS_X // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr -#define M1_MICROSTEPS 16 // 1mi 1,2,4,8 +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8 #define M1_POLARITY 0 // 1po 0=normal, 1=reversed #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled #define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 @@ -114,7 +109,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define M2_MOTOR_MAP AXIS_Y #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV (0.5 * 25.4) -#define M2_MICROSTEPS 16 +#define M2_MICROSTEPS 8 #define M2_POLARITY 0 #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL MOTOR_POWER_LEVEL @@ -122,7 +117,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define M3_MOTOR_MAP AXIS_Z #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV (0.5 * 25.4) -#define M3_MICROSTEPS 16 +#define M3_MICROSTEPS 8 #define M3_POLARITY 0 #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL MOTOR_POWER_LEVEL @@ -130,7 +125,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define M4_MOTOR_MAP AXIS_A #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV (0.5 * 25.4) -#define M4_MICROSTEPS 16 +#define M4_MICROSTEPS 8 #define M4_POLARITY 0 #define M4_POWER_MODE MOTOR_POWER_MODE #define M4_POWER_LEVEL MOTOR_POWER_LEVEL @@ -139,7 +134,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define M5_MOTOR_MAP AXIS_B #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV (0.5 * 25.4) -#define M5_MICROSTEPS 16 +#define M5_MICROSTEPS 8 #define M5_POLARITY 0 #define M5_POWER_MODE MOTOR_POWER_MODE #define M5_POWER_LEVEL MOTOR_POWER_LEVEL @@ -147,7 +142,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define M6_MOTOR_MAP AXIS_C #define M6_STEP_ANGLE 1.8 #define M6_TRAVEL_PER_REV (0.5 * 25.4) -#define M6_MICROSTEPS 16 +#define M6_MICROSTEPS 8 #define M6_POLARITY 0 #define M6_POWER_MODE MOTOR_POWER_MODE #define M6_POWER_LEVEL MOTOR_POWER_LEVEL @@ -160,7 +155,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min #define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits #define X_TRAVEL_MAX (25 * 25.4) // xtm travel between switches or crashes -#define X_JERK_MAX (2 * 25.4) // xjm jerk is multipled by 1,000,000 internally +#define X_JERK_MAX (2 * 25.4) // xjm jerk is multiplied by 1,000,000 internally #define X_JERK_HIGH_SPEED 10000 // xjh #define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable #define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive @@ -272,7 +267,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define DI1_FUNCTION INPUT_FUNCTION_LIMIT // configured as limit switch. Also used for X homing // Xmax -#define DI2_MODE INPUT_MODE_DISABLED // testing disable +#define DI2_MODE INPUT_INACTIVE // testing disable //#define DI2_MODE NORMALLY_CLOSED // configured as limit switch #define DI2_ACTION INPUT_ACTION_FAST_STOP #define DI2_FUNCTION INPUT_FUNCTION_LIMIT @@ -288,7 +283,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define DI4_FUNCTION INPUT_FUNCTION_LIMIT // Zmin -#define DI5_MODE INPUT_ACTIVE_LOW // used for Z probe. Active closes circuit (active LO) +#define DI5_MODE IO_ACTIVE_LOW // used for Z probe. Active closes circuit (active LO) #define DI5_ACTION INPUT_ACTION_NONE #define DI5_FUNCTION INPUT_FUNCTION_NONE @@ -302,12 +297,12 @@ constexpr float H3_DEFAULT_D = 100.0; //#define DI6_FUNCTION INPUT_FUNCTION_LIMIT // Amin -#define DI7_MODE INPUT_ACTIVE_HIGH // interlock happens when NO switch goes HI (opens) -#define DI7_ACTION INPUT_ACTION_STOP // wired as interlock switch +#define DI7_MODE IO_ACTIVE_HIGH // interlock happens when NO switch goes HI (opens) +#define DI7_ACTION INPUT_ACTION_STOP // wired as interlock switch #define DI7_FUNCTION INPUT_FUNCTION_INTERLOCK // Amax -#define DI8_MODE INPUT_ACTIVE_LOW // configured as panic switch, NO +#define DI8_MODE IO_ACTIVE_LOW // configured as panic switch, NO #define DI8_ACTION INPUT_ACTION_PANIC #define DI8_FUNCTION INPUT_FUNCTION_NONE @@ -328,70 +323,3 @@ constexpr float H3_DEFAULT_D = 100.0; #define P1_CCW_PHASE_LO 0.1 #define P1_CCW_PHASE_HI 0.1 #define P1_PWM_PHASE_OFF 0.1 - -// *** DEFAULT COORDINATE SYSTEM OFFSETS *** -// Our convention is: -// - leave G54 in machine coordinates to act as a persistent absolute coordinate system -// - set G55 to be a zero in the middle of the table -// - no action for the others - -#define G54_X_OFFSET 0 // G54 is traditionally set to all zeros -#define G54_Y_OFFSET 0 -#define G54_Z_OFFSET 0 -#define G54_A_OFFSET 0 -#define G54_B_OFFSET 0 -#define G54_C_OFFSET 0 - -#define G55_X_OFFSET 0 -#define G55_Y_OFFSET 0 -#define G55_Z_OFFSET 0 -#define G55_A_OFFSET 0 -#define G55_B_OFFSET 0 -#define G55_C_OFFSET 0 - -#define G56_X_OFFSET 0 -#define G56_Y_OFFSET 0 -#define G56_Z_OFFSET 0 -#define G56_A_OFFSET 0 -#define G56_B_OFFSET 0 -#define G56_C_OFFSET 0 - -#define G57_X_OFFSET 0 -#define G57_Y_OFFSET 0 -#define G57_Z_OFFSET 0 -#define G57_A_OFFSET 0 -#define G57_B_OFFSET 0 -#define G57_C_OFFSET 0 - -#define G58_X_OFFSET 0 -#define G58_Y_OFFSET 0 -#define G58_Z_OFFSET 0 -#define G58_A_OFFSET 0 -#define G58_B_OFFSET 0 -#define G58_C_OFFSET 0 - -#define G59_X_OFFSET 0 -#define G59_Y_OFFSET 0 -#define G59_Z_OFFSET 0 -#define G59_A_OFFSET 0 -#define G59_B_OFFSET 0 -#define G59_C_OFFSET 0 - -/*** User-Defined Data Defaults ***/ - -#define USER_DATA_A0 0 -#define USER_DATA_A1 0 -#define USER_DATA_A2 0 -#define USER_DATA_A3 0 -#define USER_DATA_B0 0 -#define USER_DATA_B1 0 -#define USER_DATA_B2 0 -#define USER_DATA_B3 0 -#define USER_DATA_C0 0 -#define USER_DATA_C1 0 -#define USER_DATA_C2 0 -#define USER_DATA_C3 0 -#define USER_DATA_D0 0 -#define USER_DATA_D1 0 -#define USER_DATA_D2 0 -#define USER_DATA_D3 0 From 12e8c494493892ea4c6e24cb3d6ef2180d739823 Mon Sep 17 00:00:00 2001 From: "alden.hart" Date: Sun, 29 Jan 2017 13:13:02 -0500 Subject: [PATCH 103/283] Added Showboat test CONFIG to AS7 configs; Updated Showboat and Othermill machine settings. --- g2core.atsln | 4 + g2core/boards.mk | 10 +- g2core/g2core.cppproj | 16 +- g2core/settings/settings_othermill_test.h | 531 ++++++++++------------ g2core/settings/settings_shopbot_sbv300.h | 418 +++++++++-------- g2core/settings/settings_shopbot_test.h | 358 ++++++++------- 6 files changed, 636 insertions(+), 701 deletions(-) diff --git a/g2core.atsln b/g2core.atsln index 93cd6ae1..8f2a65a3 100644 --- a/g2core.atsln +++ b/g2core.atsln @@ -18,6 +18,7 @@ Global sbv300|ARM = sbv300|ARM Shapeoko2|ARM = Shapeoko2|ARM shopbotShield|ARM = shopbotShield|ARM + ShopbotTestV9|ARM = ShopbotTestV9|ARM Stub|ARM = Stub|ARM TestQuadratic|ARM = TestQuadratic|ARM TestQuintic|ARM = TestQuintic|ARM @@ -46,6 +47,8 @@ Global {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.Shapeoko2|ARM.Build.0 = Shapeoko2|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.shopbotShield|ARM.ActiveCfg = shopbotShield|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.shopbotShield|ARM.Build.0 = shopbotShield|ARM + {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.ShopbotTestV9|ARM.ActiveCfg = G2v9k|ARM + {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.ShopbotTestV9|ARM.Build.0 = G2v9k|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.Stub|ARM.ActiveCfg = Shapeoko2|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestQuadratic|ARM.ActiveCfg = TestQuadratic|ARM {44EA8FEC-55D7-4149-8A78-A574FC26BF51}.TestQuadratic|ARM.Build.0 = TestQuadratic|ARM @@ -67,6 +70,7 @@ Global {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.sbv300|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.Shapeoko2|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.shopbotShield|ARM.ActiveCfg = Stub|ARM + {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.ShopbotTestV9|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.Stub|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.TestQuadratic|ARM.ActiveCfg = Stub|ARM {D7779B24-5CD6-4A1B-893C-2CAE8CF7A3A0}.TestQuintic|ARM.ActiveCfg = Stub|ARM diff --git a/g2core/boards.mk b/g2core/boards.mk index f51eca4d..dfd5bf7e 100644 --- a/g2core/boards.mk +++ b/g2core/boards.mk @@ -24,7 +24,6 @@ # To choose a CONFIG but apply it to a different BOARD: # make CONFIG=PrintrbotPlus BOARD=g2ref-a - ########## # V9-based configs: @@ -39,7 +38,8 @@ ifeq ("$(CONFIG)","Othermill") ifeq ("$(BOARD)","NONE") BOARD=g2v9k endif - SETTINGS_FILE="settings_othermill.h" +# SETTINGS_FILE="settings_othermill.h" + SETTINGS_FILE="settings_othermill_test.h" endif ifeq ("$(CONFIG)","ProbotixV90") @@ -95,6 +95,12 @@ ifeq ("$(CONFIG)","sbv300") SETTINGS_FILE="settings_shopbot_sbv300.h" endif +ifeq ("$(CONFIG)","ShopbotTestV9") + ifeq ("$(BOARD)","NONE") + BOARD=g2v9k + endif + SETTINGS_FILE="settings_shopbot_test.h" +endif ########## # PrintrBot configs: diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 4e9ca4ea..1963b3aa 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -5,7 +5,7 @@ 7.0 com.Atmel.ARMGCC.CPP {44ea8fec-55d7-4149-8a78-a574fc26bf51} - ATSAM3X8E + ATSAM3X8C none Executable CPP @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800021206 Atmel-ICE True @@ -100,8 +100,8 @@ True true - J41800036434 - 0x285E0A60 + J41800021206 + 0x284E0A60 2000000 @@ -252,8 +252,8 @@ True - BOARD=sbv300 COLOR=0 VERBOSE=1 - clean BOARD=sbv300 + CONFIG=sbv300 COLOR=0 VERBOSE=1 + clean CONFIG=sbv300 Makefile bin\sbv300\ @@ -376,8 +376,8 @@ True - BOARD=g2v9k CONFIG=ShapeokoDualY COLOR=0 VERBOSE=1 - clean BOARD=g2v9k CONFIG=ShapeokoDualY + CONFIG=ShopbotTestV9 COLOR=0 VERBOSE=1 + clean CONFIG=ShopbotTestV9 Makefile bin\G2v9k\ diff --git a/g2core/settings/settings_othermill_test.h b/g2core/settings/settings_othermill_test.h index c61977f7..18a2800d 100644 --- a/g2core/settings/settings_othermill_test.h +++ b/g2core/settings/settings_othermill_test.h @@ -1,5 +1,5 @@ /* - * settings_othermill.h - Other Machine Company Mini Milling Machine + * settings_othermill_test.h - Other Machine Company Mini Milling Machine * This file is part of the g2core project * * This file ("the software") is free software: you can redistribute it and/or modify @@ -28,247 +28,222 @@ /***********************************************************************/ // ***> NOTE: The init message must be a single line with no CRs or LFs -#define INIT_MESSAGE "Initializing configs to OMC OtherMill settings" +#define INIT_MESSAGE "Initializing configs to OMC OtherMill Test settings" //**** GLOBAL / GENERAL SETTINGS ****************************************************** -#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) -#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) -#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on -#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high -#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high -#define SPINDLE_PAUSE_ON_HOLD true -#define SPINDLE_DWELL_TIME 1.5 // after unpausing and turning the spindle on, dwell for 1.5s +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.5 // after unpausing and turning the spindle on, dwell for 1.5s -#define ESC_BOOT_TIME 5000 // how long the ESC takes to boot, in milliseconds -#define ESC_LOCKOUT_TIME \ - 900 // how long the interlock needs to be engaged before killing power... actually 1s, but be conservative +#define ESC_BOOT_TIME 5000 // how long the ESC takes to boot, in milliseconds +#define ESC_LOCKOUT_TIME 900 // how long the interlock needs to be engaged before killing power... actually 1s, but be conservative -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD true - -constexpr float H1_DEFAULT_P = 7.0; -constexpr float H1_DEFAULT_I = 0.2; -constexpr float H1_DEFAULT_D = 100.0; - -constexpr float H2_DEFAULT_P = 7.0; -constexpr float H2_DEFAULT_I = 0.2; -constexpr float H2_DEFAULT_D = 100.0; - -constexpr float H3_DEFAULT_P = 7.0; -constexpr float H3_DEFAULT_I = 0.2; -constexpr float H3_DEFAULT_D = 100.0; +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD true // WARNING: Older Othermill machines use a 15deg can stack for their Z axis. // new machines use a stepper which has the same config as the other axis. -#define HAS_CANSTACK_Z_AXIS 0 -/* -// Switch definitions for interlock & E-stop -#define ENABLE_INTERLOCK_AND_ESTOP -#define INTERLOCK_SWITCH_AXIS AXIS_Y -#define INTERLOCK_SWITCH_POSITION SW_MAX -#define ESTOP_SWITCH_AXIS AXIS_X -#define ESTOP_SWITCH_POSITION SW_MAX -#define PAUSE_DWELL_TIME 1.5 //after unpausing and turning the spindle on, dwell for 1.5s -*/ +//#define HAS_CANSTACK_Z_AXIS 0 // Communications and reporting settings -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! -#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE -#define JSON_VERBOSITY JV_CONFIGS // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE -#define QUEUE_REPORT_VERBOSITY QR_SINGLE +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS -#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum -#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -#define STATUS_REPORT_DEFAULTS \ - "mpox", "mpoy", "mpoz", "ofsx", "ofsy", "ofsz", "g55x", "g55y", "g55z", "unit", "stat", "coor", "momo", "dist", \ - "home", "mots", "plan", "line", "path", "frmo", "prbe", "safe", "spe", "spd", "hold", "macs", "cycs", "sps" +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_CONFIGS // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable +#define STATUS_REPORT_DEFAULTS "mpox", "mpoy", "mpoz", \ + "ofsx", "ofsy", "ofsz", \ + "g55x", "g55y", "g55z", \ + "unit", "stat", "coor", "momo", "dist", \ + "home", "mots", "plan", "line", "path", \ + "frmo", "prbe", "safe", "spe", "spd", \ + "hold", "macs", "cycs", "sps" // Gcode startup defaults -#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES -#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ -#define GCODE_DEFAULT_COORD_SYSTEM G55 // G54, G55, G56, G57, G58 or G59 -#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G55 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS #define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_DISTANCE_MODE // *** motor settings ************************************************************************************ // NOTE: Motor numbers are reversed from TinyGv8 in order to maintain compatibility with wiring harnesses -#define MOTOR_POWER_LEVEL_XY 0.375 // default motor power level 0.00 - 1.00 -#define MOTOR_POWER_LEVEL_XY_IDLE 0.15 -#define MOTOR_POWER_LEVEL_Z 0.375 -#define MOTOR_POWER_LEVEL_Z_IDLE 0.15 -#define MOTOR_POWER_LEVEL_DISABLED 0.05 +#define MOTOR_POWER_LEVEL_XY 0.375 // default motor power level 0.00 - 1.00 +#define MOTOR_POWER_LEVEL_XY_IDLE 0.15 +#define MOTOR_POWER_LEVEL_Z 0.375 +#define MOTOR_POWER_LEVEL_Z_IDLE 0.15 +#define MOTOR_POWER_LEVEL_DISABLED 0.05 -#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 4.8768 // 1tr -#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 -#define M1_POLARITY 1 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h -#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max -#define M1_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 4.8768 // 1tr +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max +#define M1_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M2_MOTOR_MAP AXIS_Y -#define M2_STEP_ANGLE 1.8 -#define M2_TRAVEL_PER_REV 4.8768 -#define M2_MICROSTEPS 8 -#define M2_POLARITY 1 -#define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL MOTOR_POWER_LEVEL_XY -#define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE +#define M2_MOTOR_MAP AXIS_Y +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV 4.8768 +#define M2_MICROSTEPS 8 +#define M2_POLARITY 1 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL MOTOR_POWER_LEVEL_XY +#define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M3_MOTOR_MAP AXIS_Z -#if HAS_CANSTACK_Z_AXIS -#define M3_STEP_ANGLE 15 -#define M3_TRAVEL_PER_REV 1.27254 -#else -#define M3_STEP_ANGLE 1.8 -#define M3_TRAVEL_PER_REV 4.8768 -#endif -#define M3_MICROSTEPS 8 -#define M3_POLARITY 0 -#define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL MOTOR_POWER_LEVEL_Z -#define M3_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_Z_IDLE +#define M3_MOTOR_MAP AXIS_Z +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV 4.8768 +#define M3_MICROSTEPS 8 +#define M3_POLARITY 0 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL MOTOR_POWER_LEVEL_Z +#define M3_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_Z_IDLE -#define M4_MOTOR_MAP AXIS_A -#define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev -#define M4_MICROSTEPS 8 -#define M4_POLARITY 1 -#define M4_POWER_MODE MOTOR_DISABLED -#define M4_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED -#define M4_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED +#define M4_MOTOR_MAP AXIS_A +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M4_MICROSTEPS 8 +#define M4_POLARITY 1 +#define M4_POWER_MODE MOTOR_DISABLED +#define M4_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED +#define M4_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED -#define M5_MOTOR_MAP AXIS_B -#define M5_STEP_ANGLE 1.8 -#define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev -#define M5_MICROSTEPS 8 -#define M5_POLARITY 0 -#define M5_POWER_MODE MOTOR_DISABLED -#define M5_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED -#define M5_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED +#define M5_MOTOR_MAP AXIS_B +#define M5_STEP_ANGLE 1.8 +#define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M5_MICROSTEPS 8 +#define M5_POLARITY 0 +#define M5_POWER_MODE MOTOR_DISABLED +#define M5_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED +#define M5_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED -#define M6_MOTOR_MAP AXIS_C -#define M6_STEP_ANGLE 1.8 -#define M6_TRAVEL_PER_REV 360 // degrees moved per motor rev -#define M6_MICROSTEPS 8 -#define M6_POLARITY 0 -#define M6_POWER_MODE MOTOR_DISABLED -#define M6_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED -#define M6_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED +#define M6_MOTOR_MAP AXIS_C +#define M6_STEP_ANGLE 1.8 +#define M6_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M6_MICROSTEPS 8 +#define M6_POLARITY 0 +#define M6_POWER_MODE MOTOR_DISABLED +#define M6_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED +#define M6_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED // *** axis settings ********************************************************************************** -#define JERK_MAX 500 // 500 million mm/(min^3) -#define JERK_HIGH_SPEED 1000 // 1000 million mm/(min^3) // Jerk during homing needs to stop *fast* -#define LATCH_VELOCITY 25 // reeeeally slow for accuracy +#define JERK_MAX 500 // 500 million mm/(min^3) +#define JERK_HIGH_SPEED 1000 // 1000 million mm/(min^3) // Jerk during homing needs to stop *fast* +#define LATCH_VELOCITY 25 // reeeeally slow for accuracy -#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX 1500 // xvm G0 max velocity in mm/min -#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min -#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits -#define X_TRAVEL_MAX 145.6 // xtr travel between switches or crashes -#define X_JERK_MAX JERK_MAX // xjm -#define X_JERK_HIGH_SPEED JERK_HIGH_SPEED // xjh -#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable -#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive -#define X_SEARCH_VELOCITY (X_FEEDRATE_MAX / 3) // xsv -#define X_LATCH_VELOCITY LATCH_VELOCITY // xlv mm/min -#define X_LATCH_BACKOFF 5 // xlb mm -#define X_ZERO_BACKOFF 0.4 // xzb mm +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX 1500 // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits +#define X_TRAVEL_MAX 145.6 // xtr travel between switches or crashes +#define X_JERK_MAX JERK_MAX // xjm +#define X_JERK_HIGH_SPEED JERK_HIGH_SPEED // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY (X_FEEDRATE_MAX / 3)// xsv +#define X_LATCH_VELOCITY LATCH_VELOCITY // xlv mm/min +#define X_LATCH_BACKOFF 2 // xlb mm +#define X_ZERO_BACKOFF 0.4 // xzb mm -#define Y_AXIS_MODE AXIS_STANDARD -#define Y_VELOCITY_MAX X_VELOCITY_MAX -#define Y_FEEDRATE_MAX Y_VELOCITY_MAX -#define Y_TRAVEL_MIN 0 -#define Y_TRAVEL_MAX 119.1 -#define Y_JERK_MAX JERK_MAX -#define Y_JERK_HIGH_SPEED JERK_HIGH_SPEED -#define Y_HOMING_INPUT 3 -#define Y_HOMING_DIRECTION 0 -#define Y_SEARCH_VELOCITY (Y_FEEDRATE_MAX / 3) -#define Y_LATCH_VELOCITY LATCH_VELOCITY -#define Y_LATCH_BACKOFF 5 -#define Y_ZERO_BACKOFF 0.4 +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX X_VELOCITY_MAX +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX 119.1 +#define Y_JERK_MAX JERK_MAX +#define Y_JERK_HIGH_SPEED JERK_HIGH_SPEED +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIRECTION 0 +#define Y_SEARCH_VELOCITY (Y_FEEDRATE_MAX / 3) +#define Y_LATCH_VELOCITY LATCH_VELOCITY +#define Y_LATCH_BACKOFF 2 +#define Y_ZERO_BACKOFF 0.4 -#define Z_AXIS_MODE AXIS_STANDARD -#if HAS_CANSTACK_Z_AXIS -#define Z_VELOCITY_MAX 1000 -#else -#define Z_VELOCITY_MAX X_VELOCITY_MAX -#endif -#define Z_FEEDRATE_MAX Z_VELOCITY_MAX -#define Z_TRAVEL_MIN -60.1 -#define Z_TRAVEL_MAX 0 -#define Z_JERK_MAX JERK_MAX -#define Z_JERK_HIGH_SPEED JERK_HIGH_SPEED -#define Z_HOMING_INPUT 6 -#define Z_HOMING_DIRECTION 1 -#define Z_SEARCH_VELOCITY (Z_FEEDRATE_MAX / 3) -#define Z_LATCH_VELOCITY LATCH_VELOCITY -#define Z_LATCH_BACKOFF 5 -#define Z_ZERO_BACKOFF 0.4 +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX X_VELOCITY_MAX +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MIN -60.1 +#define Z_TRAVEL_MAX 0 +#define Z_JERK_MAX JERK_MAX +#define Z_JERK_HIGH_SPEED JERK_HIGH_SPEED +#define Z_HOMING_INPUT 6 +#define Z_HOMING_DIRECTION 1 +#define Z_SEARCH_VELOCITY (Z_FEEDRATE_MAX / 3) +#define Z_LATCH_VELOCITY LATCH_VELOCITY +#define Z_LATCH_BACKOFF 2 +#define Z_ZERO_BACKOFF 0.4 // Rotary values are chosen to make the motor react the same as X for testing -#define A_AXIS_MODE AXIS_DISABLED // DISABLED -#define A_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) // set to the same speed as X axis -#define A_FEEDRATE_MAX A_VELOCITY_MAX -#define A_TRAVEL_MIN -1 // min/max the same means infinite, no limit -#define A_TRAVEL_MAX -1 -#define A_JERK_MAX (X_JERK_MAX * (360 / M1_TRAVEL_PER_REV)) -#define A_JERK_HIGH_SPEED A_JERK_MAX -#define A_RADIUS (M1_TRAVEL_PER_REV / (2 * 3.14159628)) -#define A_HOMING_INPUT 0 -#define A_HOMING_DIRECTION 0 -#define A_SEARCH_VELOCITY 600 -#define A_LATCH_VELOCITY 100 -#define A_LATCH_BACKOFF 5 -#define A_ZERO_BACKOFF 2 +#define A_AXIS_MODE AXIS_DISABLED // DISABLED +#define A_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) // set to the same speed as X axis +#define A_FEEDRATE_MAX A_VELOCITY_MAX +#define A_TRAVEL_MIN -1 // min/max the same means infinite, no limit +#define A_TRAVEL_MAX -1 +#define A_JERK_MAX (X_JERK_MAX * (360 / M1_TRAVEL_PER_REV)) +#define A_JERK_HIGH_SPEED A_JERK_MAX +#define A_RADIUS (M1_TRAVEL_PER_REV / (2 * 3.14159628)) +#define A_HOMING_INPUT 0 +#define A_HOMING_DIRECTION 0 +#define A_SEARCH_VELOCITY 600 +#define A_LATCH_VELOCITY 100 +#define A_LATCH_BACKOFF 5 +#define A_ZERO_BACKOFF 2 -#define B_AXIS_MODE AXIS_DISABLED // DISABLED -#define B_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) -#define B_FEEDRATE_MAX B_VELOCITY_MAX -#define B_TRAVEL_MIN -1 -#define B_TRAVEL_MAX -1 -#define B_JERK_MAX (X_JERK_MAX * (360 / M1_TRAVEL_PER_REV)) -#define B_JERK_HIGH_SPEED B_JERK_MAX -#define B_RADIUS (M1_TRAVEL_PER_REV / (2 * 3.14159628)) -#define B_HOMING_INPUT 0 -#define B_HOMING_DIRECTION 0 -#define B_SEARCH_VELOCITY 600 -#define B_LATCH_VELOCITY 100 -#define B_LATCH_BACKOFF 5 -#define B_ZERO_BACKOFF 2 +#define B_AXIS_MODE AXIS_DISABLED // DISABLED +#define B_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MIN -1 +#define B_TRAVEL_MAX -1 +#define B_JERK_MAX (X_JERK_MAX * (360 / M1_TRAVEL_PER_REV)) +#define B_JERK_HIGH_SPEED B_JERK_MAX +#define B_RADIUS (M1_TRAVEL_PER_REV / (2 * 3.14159628)) +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY 600 +#define B_LATCH_VELOCITY 100 +#define B_LATCH_BACKOFF 5 +#define B_ZERO_BACKOFF 2 -#define C_AXIS_MODE AXIS_DISABLED // DISABLED -#define C_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) -#define C_FEEDRATE_MAX C_VELOCITY_MAX -#define C_TRAVEL_MIN -1 -#define C_TRAVEL_MAX -1 -#define C_JERK_MAX (X_JERK_MAX * (360 / M1_TRAVEL_PER_REV)) -#define C_JERK_HIGH_SPEED C_JERK_MAX -#define C_RADIUS (M1_TRAVEL_PER_REV / (2 * 3.14159628)) -#define C_HOMING_INPUT 0 -#define C_HOMING_DIRECTION 0 -#define C_SEARCH_VELOCITY 600 -#define C_LATCH_VELOCITY 100 -#define C_LATCH_BACKOFF 5 -#define C_ZERO_BACKOFF 2 +#define C_AXIS_MODE AXIS_DISABLED // DISABLED +#define C_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) +#define C_FEEDRATE_MAX C_VELOCITY_MAX +#define C_TRAVEL_MIN -1 +#define C_TRAVEL_MAX -1 +#define C_JERK_MAX (X_JERK_MAX * (360 / M1_TRAVEL_PER_REV)) +#define C_JERK_HIGH_SPEED C_JERK_MAX +#define C_RADIUS (M1_TRAVEL_PER_REV / (2 * 3.14159628)) +#define C_HOMING_INPUT 0 +#define C_HOMING_DIRECTION 0 +#define C_SEARCH_VELOCITY 600 +#define C_LATCH_VELOCITY 100 +#define C_LATCH_BACKOFF 5 +#define C_ZERO_BACKOFF 2 //*** Input / output settings *** /* @@ -295,128 +270,80 @@ constexpr float H3_DEFAULT_D = 100.0; */ // Xmin on v9 board // X homing - see X axis setup -#define DI1_MODE NORMALLY_CLOSED -#define DI1_ACTION INPUT_ACTION_NONE -#define DI1_FUNCTION INPUT_FUNCTION_NONE +#define DI1_MODE NORMALLY_CLOSED +#define DI1_ACTION INPUT_ACTION_NONE +#define DI1_FUNCTION INPUT_FUNCTION_NONE // Xmax // External ESTOP -#define DI2_MODE INPUT_ACTIVE_HIGH -#define DI2_ACTION INPUT_ACTION_HALT -#define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN +#define DI2_MODE IO_ACTIVE_HIGH +#define DI2_ACTION INPUT_ACTION_HALT +#define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN // Ymin // Y homing - see Y axis setup -#define DI3_MODE NORMALLY_CLOSED -#define DI3_ACTION INPUT_ACTION_NONE -#define DI3_FUNCTION INPUT_FUNCTION_NONE +#define DI3_MODE NORMALLY_CLOSED +#define DI3_ACTION INPUT_ACTION_NONE +#define DI3_FUNCTION INPUT_FUNCTION_NONE // Ymax // Safety interlock -#define DI4_MODE INPUT_ACTIVE_HIGH -#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) -#define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK +#define DI4_MODE IO_ACTIVE_HIGH +#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) +#define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK // Zmin // Z probe -#define DI5_MODE INPUT_ACTIVE_LOW -#define DI5_ACTION INPUT_ACTION_NONE -#define DI5_FUNCTION INPUT_FUNCTION_NONE +#define DI5_MODE IO_ACTIVE_LOW +#define DI5_ACTION INPUT_ACTION_NONE +#define DI5_FUNCTION INPUT_FUNCTION_NONE // Zmax // Z homing - see Z axis for setup -#define DI6_MODE NORMALLY_CLOSED -#define DI6_ACTION INPUT_ACTION_NONE -#define DI6_FUNCTION INPUT_FUNCTION_NONE +#define DI6_MODE NORMALLY_CLOSED +#define DI6_ACTION INPUT_ACTION_NONE +#define DI6_FUNCTION INPUT_FUNCTION_NONE // Amin // Unused -#define DI7_MODE INPUT_MODE_DISABLED -#define DI7_ACTION INPUT_ACTION_NONE -#define DI7_FUNCTION INPUT_FUNCTION_NONE +#define DI7_MODE IO_MODE_DISABLED +#define DI7_ACTION INPUT_ACTION_NONE +#define DI7_FUNCTION INPUT_FUNCTION_NONE // Amax // Unused -#define DI8_MODE INPUT_MODE_DISABLED -#define DI8_ACTION INPUT_ACTION_NONE -#define DI8_FUNCTION INPUT_FUNCTION_NONE +#define DI8_MODE IO_MODE_DISABLED +#define DI8_ACTION INPUT_ACTION_NONE +#define DI8_FUNCTION INPUT_FUNCTION_NONE // Safety line w/HW timer // Unused -#define DI9_MODE INPUT_MODE_DISABLED -#define DI9_ACTION INPUT_ACTION_NONE -#define DI9_FUNCTION INPUT_FUNCTION_NONE +#define DI9_MODE IO_MODE_DISABLED +#define DI9_ACTION INPUT_ACTION_NONE +#define DI9_FUNCTION INPUT_FUNCTION_NONE // *** PWM SPINDLE CONTROL *** -#define P1_PWM_FREQUENCY 100 // in Hz -#define P1_CW_SPEED_LO 10500 // in RPM (arbitrary units) -#define P1_CW_SPEED_HI 16400 -#define P1_CW_PHASE_LO 0.13 // phase [0..1] -#define P1_CW_PHASE_HI 0.17 -#define P1_CCW_SPEED_LO 0 -#define P1_CCW_SPEED_HI 0 -#define P1_CCW_PHASE_LO 0.1 -#define P1_CCW_PHASE_HI 0.1 -#define P1_PWM_PHASE_OFF 0.1 +#define P1_PWM_FREQUENCY 100 // in Hz +#define P1_CW_SPEED_LO 10500 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 16400 +#define P1_CW_PHASE_LO 0.13 // phase [0..1] +#define P1_CW_PHASE_HI 0.17 +#define P1_CCW_SPEED_LO 0 +#define P1_CCW_SPEED_HI 0 +#define P1_CCW_PHASE_LO 0.1 +#define P1_CCW_PHASE_HI 0.1 +#define P1_PWM_PHASE_OFF 0.1 #define P1_USE_MAPPING_CUBIC -#define P1_MAPPING_CUBIC_X3 2.1225328766717546e-013 -#define P1_MAPPING_CUBIC_X2 -7.2900167282605129e-009 -#define P1_MAPPING_CUBIC_X1 8.5854646785876479e-005 -#define P1_MAPPING_CUBIC_X0 -2.1301489219406905e-001 +#define P1_MAPPING_CUBIC_X3 2.1225328766717546e-013 +#define P1_MAPPING_CUBIC_X2 -7.2900167282605129e-009 +#define P1_MAPPING_CUBIC_X1 8.5854646785876479e-005 +#define P1_MAPPING_CUBIC_X0 -2.1301489219406905e-001 // *** DEFAULT COORDINATE SYSTEM OFFSETS *** +/* +constexpr float H1_DEFAULT_P = 7.0; +constexpr float H1_DEFAULT_I = 0.2; +constexpr float H1_DEFAULT_D = 100.0; -#define G54_X_OFFSET 0 // G54 is traditionally set to all zeros -#define G54_Y_OFFSET 0 -#define G54_Z_OFFSET 0 -#define G54_A_OFFSET 0 -#define G54_B_OFFSET 0 -#define G54_C_OFFSET 0 +constexpr float H2_DEFAULT_P = 7.0; +constexpr float H2_DEFAULT_I = 0.2; +constexpr float H2_DEFAULT_D = 100.0; -#define G55_X_OFFSET 0 // but the again, so is everyting else (at least for start) -#define G55_Y_OFFSET 0 -#define G55_Z_OFFSET 0 -#define G55_A_OFFSET 0 -#define G55_B_OFFSET 0 -#define G55_C_OFFSET 0 // this is where we currently store the tool offset - -#define G56_X_OFFSET 0 -#define G56_Y_OFFSET 0 -#define G56_Z_OFFSET 0 -#define G56_A_OFFSET 0 -#define G56_B_OFFSET 0 -#define G56_C_OFFSET 0 - -#define G57_X_OFFSET 0 -#define G57_Y_OFFSET 0 -#define G57_Z_OFFSET 0 -#define G57_A_OFFSET 0 -#define G57_B_OFFSET 0 -#define G57_C_OFFSET 0 - -#define G58_X_OFFSET 0 -#define G58_Y_OFFSET 0 -#define G58_Z_OFFSET 0 -#define G58_A_OFFSET 0 -#define G58_B_OFFSET 0 -#define G58_C_OFFSET 0 - -#define G59_X_OFFSET 0 -#define G59_Y_OFFSET 0 -#define G59_Z_OFFSET 0 -#define G59_A_OFFSET 0 -#define G59_B_OFFSET 0 -#define G59_C_OFFSET 0 - -/*** User-Defined Data Defaults ***/ - -#define USER_DATA_A0 0 -#define USER_DATA_A1 0 -#define USER_DATA_A2 0 -#define USER_DATA_A3 0 -#define USER_DATA_B0 0 -#define USER_DATA_B1 0 -#define USER_DATA_B2 0 -#define USER_DATA_B3 0 -#define USER_DATA_C0 0 -#define USER_DATA_C1 0 -#define USER_DATA_C2 0 -#define USER_DATA_C3 0 -#define USER_DATA_D0 0 -#define USER_DATA_D1 0 -#define USER_DATA_D2 0 -#define USER_DATA_D3 0 +constexpr float H3_DEFAULT_P = 7.0; +constexpr float H3_DEFAULT_I = 0.2; +constexpr float H3_DEFAULT_D = 100.0; +*/ \ No newline at end of file diff --git a/g2core/settings/settings_shopbot_sbv300.h b/g2core/settings/settings_shopbot_sbv300.h index 2cf538bb..f8e3d8ff 100644 --- a/g2core/settings/settings_shopbot_sbv300.h +++ b/g2core/settings/settings_shopbot_sbv300.h @@ -1,8 +1,8 @@ /* - * settings_shapeoko375.h - Shopbot Test + * settings_shopbot_sbv300.h - Shopbot sbv3000 * This file is part of the g2core project * - * Copyright (c) 2015 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -38,218 +38,193 @@ //**** GLOBAL / GENERAL SETTINGS ****************************************************** -#define JUNCTION_INTEGRATION_TIME (5000 * 25.4) // centripetal acceleration around corners -#define CHORDAL_TOLERANCE 0.001 // chordal accuracy for arc drawing (in mm) +//#define JUNCTION_INTEGRATION_TIME (5000 * 25.4) // centripetal acceleration around corners +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.001 // chordal accuracy for arc drawing (in mm) -#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on -#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high -#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high -#define SPINDLE_PAUSE_ON_HOLD true -#define SPINDLE_DWELL_TIME 1.0 +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.0 -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD true - -// Communications and reporting settings - -#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! - -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS - -#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE -#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE -#define QUEUE_REPORT_VERBOSITY QR_TRIPLE // one of: QR_OFF, QR_SINGLE, QR_TRIPLE - -#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum -#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", "vel", "stat", "hold", "line", "coor" - -// Gcode startup defaults -#define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES -#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ -#define GCODE_DEFAULT_COORD_SYSTEM G55 // G54, G55, G56, G57, G58 or G59 -#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS -#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_DISTANCE_MODE - -constexpr float H1_DEFAULT_P = 7.0; -constexpr float H1_DEFAULT_I = 0.2; -constexpr float H1_DEFAULT_D = 100.0; - -constexpr float H2_DEFAULT_P = 7.0; -constexpr float H2_DEFAULT_I = 0.2; -constexpr float H2_DEFAULT_D = 100.0; - -constexpr float H3_DEFAULT_P = 7.0; -constexpr float H3_DEFAULT_I = 0.2; -constexpr float H3_DEFAULT_D = 100.0; - -// *** motor settings ************************************************************************************ - -#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define MOTOR_POWER_LEVEL 0.375 // default motor power level 0.00 - 1.00 - -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr -#define M1_MICROSTEPS 10 // 1mi 1,2,4,8 -#define M1_POLARITY 0 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled -#define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 - -#define M2_MOTOR_MAP AXIS_Y -#define M2_STEP_ANGLE 1.8 -#define M2_TRAVEL_PER_REV (0.5 * 25.4) -#define M2_MICROSTEPS 10 -#define M2_POLARITY 0 -#define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL MOTOR_POWER_LEVEL - -#define M3_MOTOR_MAP AXIS_Z -#define M3_STEP_ANGLE 1.8 -#define M3_TRAVEL_PER_REV (0.5 * 25.4) -#define M3_MICROSTEPS 10 -#define M3_POLARITY 0 -#define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL MOTOR_POWER_LEVEL - -#define M4_MOTOR_MAP AXIS_A -#define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV (0.5 * 25.4) -#define M4_MICROSTEPS 10 -#define M4_POLARITY 0 -#define M4_POWER_MODE MOTOR_POWER_MODE -#define M4_POWER_LEVEL MOTOR_POWER_LEVEL - -#if (MOTORS >= 5) -#define M5_MOTOR_MAP AXIS_B -#define M5_STEP_ANGLE 1.8 -#define M5_TRAVEL_PER_REV (0.5 * 25.4) -#define M5_MICROSTEPS 10 -#define M5_POLARITY 0 -#define M5_POWER_MODE MOTOR_POWER_MODE -#define M5_POWER_LEVEL MOTOR_POWER_LEVEL - -#define M6_MOTOR_MAP AXIS_C -#define M6_STEP_ANGLE 1.8 -#define M6_TRAVEL_PER_REV (0.5 * 25.4) -#define M6_MICROSTEPS 10 -#define M6_POLARITY 0 -#define M6_POWER_MODE MOTOR_POWER_MODE -#define M6_POWER_LEVEL MOTOR_POWER_LEVEL -#endif +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD true #define MANUAL_FEEDRATE_OVERRIDE_ENABLE false #define MANUAL_FEEDRATE_OVERRIDE_PARAMETER 1.00 + +// Communications and reporting settings + +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! + +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS + +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_CONFIGS // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_TRIPLE // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable +#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", "vel", "hold", "line", "coor", "stat" + +// Gcode startup defaults +#define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G55 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_DISTANCE_MODE + +// *** motor settings ************************************************************************************ + +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_LEVEL 0.375 // default motor power level 0.00 - 1.00 + +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr +#define M1_MICROSTEPS 10 // 1mi 1,2,4,8 +#define M1_POLARITY 0 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 + +#define M2_MOTOR_MAP AXIS_Y +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV (0.5 * 25.4) +#define M2_MICROSTEPS 10 +#define M2_POLARITY 0 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL MOTOR_POWER_LEVEL + +#define M3_MOTOR_MAP AXIS_Z +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV (0.5 * 25.4) +#define M3_MICROSTEPS 10 +#define M3_POLARITY 0 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL MOTOR_POWER_LEVEL + +#define M4_MOTOR_MAP AXIS_A +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV (0.5 * 25.4) +#define M4_MICROSTEPS 10 +#define M4_POLARITY 0 +#define M4_POWER_MODE MOTOR_POWER_MODE +#define M4_POWER_LEVEL MOTOR_POWER_LEVEL + +#if (MOTORS >= 5) +#define M5_MOTOR_MAP AXIS_B +#define M5_STEP_ANGLE 1.8 +#define M5_TRAVEL_PER_REV (0.5 * 25.4) +#define M5_MICROSTEPS 10 +#define M5_POLARITY 0 +#define M5_POWER_MODE MOTOR_POWER_MODE +#define M5_POWER_LEVEL MOTOR_POWER_LEVEL + +#define M6_MOTOR_MAP AXIS_C +#define M6_STEP_ANGLE 1.8 +#define M6_TRAVEL_PER_REV (0.5 * 25.4) +#define M6_MICROSTEPS 10 +#define M6_POLARITY 0 +#define M6_POWER_MODE MOTOR_POWER_MODE +#define M6_POWER_LEVEL MOTOR_POWER_LEVEL +#endif + // *** axis settings ********************************************************************************* -#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX (360 * 25.4) // xvm G0 max velocity in mm/min -#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min -#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits -#define X_TRAVEL_MAX (25 * 25.4) // xtm travel between switches or crashes -#define X_JERK_MAX (2 * 25.4) // xjm jerk is multipled by 1,000,000 internally -#define X_JERK_HIGH_SPEED 10000 // xjh -//#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable -#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive -#define X_SEARCH_VELOCITY (60 * 25.4) // xsv minus means move to minimum switch -#define X_LATCH_VELOCITY (30 * 25.4) // xlv mm/min -#define X_LATCH_BACKOFF (0.125 * 25.4) // xlb mm -#define X_ZERO_BACKOFF (0.375 * 25.4) // xzb mm -#define X_HOMING_INPUT 0 -#define X_HOMING_DIR 0 +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX (360 * 25.4) // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits +#define X_TRAVEL_MAX (25 * 25.4) // xtm travel between switches or crashes +#define X_JERK_MAX (2 * 25.4) // xjm jerk is multiplied by 1,000,000 internally +#define X_JERK_HIGH_SPEED 10000 // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY (60 * 25.4) // xsv minus means move to minimum switch +#define X_LATCH_VELOCITY (30 * 25.4) // xlv mm/min +#define X_LATCH_BACKOFF (0.125 * 25.4) // xlb mm +#define X_ZERO_BACKOFF (0.375 * 25.4) // xzb mm -#define Y_AXIS_MODE AXIS_STANDARD -#define Y_VELOCITY_MAX (360 * 25.4) -#define Y_FEEDRATE_MAX Y_VELOCITY_MAX -#define Y_TRAVEL_MIN 0 -#define Y_TRAVEL_MAX (19 * 25.4) -#define Y_JERK_MAX (2 * 25.4) -#define Y_JERK_HIGH_SPEED 10000 -#define Y_HOMING_INPUT 3 -#define Y_HOMING_DIRECTION 0 -#define Y_SEARCH_VELOCITY (60 * 25.4) -#define Y_LATCH_VELOCITY (30 * 25.4) -#define Y_LATCH_BACKOFF (0.125 * 25.4) -#define Y_ZERO_BACKOFF (0.375 * 25.4) -//#define Y_HOMING_INPUT 0 -#define Y_HOMING_DIR 0 +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX (360 * 25.4) +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX (19 * 25.4) +#define Y_JERK_MAX (2 * 25.4) +#define Y_JERK_HIGH_SPEED 10000 +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIRECTION 0 +#define Y_SEARCH_VELOCITY (60 * 25.4) +#define Y_LATCH_VELOCITY (30 * 25.4) +#define Y_LATCH_BACKOFF (0.125 * 25.4) +#define Y_ZERO_BACKOFF (0.375 * 25.4) +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX (360 * 25.4) +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MAX (6.5 * 25.4) +#define Z_TRAVEL_MIN 0 +#define Z_JERK_MAX (2 * 25.4) +#define Z_JERK_HIGH_SPEED 1000 +#define Z_HOMING_INPUT 6 +#define Z_HOMING_DIRECTION 1 +#define Z_SEARCH_VELOCITY (60 * 25.4) +#define Z_LATCH_VELOCITY (30 * 25.4) +#define Z_LATCH_BACKOFF (0.125 * 25.4) +#define Z_ZERO_BACKOFF (0.375 * 25.4) -#define Z_AXIS_MODE AXIS_STANDARD -#define Z_VELOCITY_MAX (360 * 25.4) -#define Z_FEEDRATE_MAX Z_VELOCITY_MAX -#define Z_TRAVEL_MAX (6.5 * 25.4) -#define Z_TRAVEL_MIN 0 -#define Z_JERK_MAX (2 * 25.4) -#define Z_JERK_HIGH_SPEED 1000 -#define Z_HOMING_INPUT 6 -#define Z_HOMING_DIRECTION 1 -#define Z_SEARCH_VELOCITY (60 * 25.4) -#define Z_LATCH_VELOCITY (30 * 25.4) -#define Z_LATCH_BACKOFF (0.125 * 25.4) -#define Z_ZERO_BACKOFF (0.375 * 25.4) -//#define Z_HOMING_INPUT 0 -#define Z_HOMING_DIR 0 +#define A_AXIS_MODE AXIS_STANDARD +#define A_VELOCITY_MAX (360 * 25.4) +#define A_FEEDRATE_MAX 48000 +#define A_TRAVEL_MIN -1 // degrees +#define A_TRAVEL_MAX -1 // same value means infinite, no limit +#define A_JERK_MAX (2 * 25.4) +#define A_JERK_HIGH_SPEED A_JERK_MAX +#define A_RADIUS 1.0 +#define A_HOMING_INPUT 0 +#define A_HOMING_DIRECTION 0 +#define A_SEARCH_VELOCITY (60 * 25.4) +#define A_LATCH_VELOCITY (30 * 25.4) +#define A_LATCH_BACKOFF (0.125 * 25.4) +#define A_ZERO_BACKOFF (0.375 * 25.4) +#define B_AXIS_MODE AXIS_DISABLED +#define B_VELOCITY_MAX (360 * 25.4) +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MAX -1 +#define B_TRAVEL_MIN -1 +#define B_JERK_MAX (2 * 25.4) +#define B_JERK_HIGH_SPEED B_JERK_MAX +#define B_RADIUS 1 +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY (60 * 25.4) +#define B_LATCH_VELOCITY (30 * 25.4) +#define B_LATCH_BACKOFF (0.125 * 25.4) +#define B_ZERO_BACKOFF (0.375 * 25.4) -#define A_AXIS_MODE AXIS_STANDARD -#define A_VELOCITY_MAX (360 * 25.4) -#define A_FEEDRATE_MAX 48000 -#define A_TRAVEL_MIN -1 // degrees -#define A_TRAVEL_MAX -1 // same value means infinite, no limit -#define A_JERK_MAX (2 * 25.4) -#define A_JERK_HIGH_SPEED A_JERK_MAX -#define A_RADIUS 1.0 -#define A_HOMING_INPUT 0 -#define A_HOMING_DIRECTION 0 -#define A_SEARCH_VELOCITY (60 * 25.4) -#define A_LATCH_VELOCITY (30 * 25.4) -#define A_LATCH_BACKOFF (0.125 * 25.4) -#define A_ZERO_BACKOFF (0.375 * 25.4) -#define A_HOMING_INPUT 0 -#define A_HOMING_DIR 0 - -#define B_AXIS_MODE AXIS_DISABLED -#define B_VELOCITY_MAX (360 * 25.4) -#define B_FEEDRATE_MAX B_VELOCITY_MAX -#define B_TRAVEL_MAX -1 -#define B_TRAVEL_MIN -1 -#define B_JERK_MAX (2 * 25.4) -#define B_JERK_HIGH_SPEED B_JERK_MAX -#define B_RADIUS 1 -#define B_HOMING_INPUT 0 -#define B_HOMING_DIRECTION 0 -#define B_SEARCH_VELOCITY (60 * 25.4) -#define B_LATCH_VELOCITY (30 * 25.4) -#define B_LATCH_BACKOFF (0.125 * 25.4) -#define B_ZERO_BACKOFF (0.375 * 25.4) -#define B_HOMING_INPUT 0 -#define B_HOMING_DIR 0 - - -#define C_AXIS_MODE AXIS_DISABLED -#define C_VELOCITY_MAX (360 * 25.4) -#define C_FEEDRATE_MAX C_VELOCITY_MAX -#define C_TRAVEL_MAX -1 -#define C_TRAVEL_MIN -1 -#define C_JERK_MAX (2 * 25.4) -#define C_JERK_HIGH_SPEED C_JERK_MAX -#define C_RADIUS 1 -#define C_HOMING_INPUT 0 -#define C_HOMING_DIRECTION 0 -#define C_SEARCH_VELOCITY (60 * 25.4) -#define C_LATCH_VELOCITY (30 * 25.4) -#define C_LATCH_BACKOFF (0.125 * 25.4) -#define C_ZERO_BACKOFF (0.375 * 25.4) -#define C_HOMING_INPUT 0 -#define C_HOMING_DIR 0 +#define C_AXIS_MODE AXIS_DISABLED +#define C_VELOCITY_MAX (360 * 25.4) +#define C_FEEDRATE_MAX C_VELOCITY_MAX +#define C_TRAVEL_MAX -1 +#define C_TRAVEL_MIN -1 +#define C_JERK_MAX (2 * 25.4) +#define C_JERK_HIGH_SPEED C_JERK_MAX +#define C_RADIUS 1 +#define C_HOMING_INPUT 0 +#define C_HOMING_DIRECTION 0 +#define C_SEARCH_VELOCITY (60 * 25.4) +#define C_LATCH_VELOCITY (30 * 25.4) +#define C_LATCH_BACKOFF (0.125 * 25.4) +#define C_ZERO_BACKOFF (0.375 * 25.4) //*** Input / output settings *** @@ -316,7 +291,6 @@ constexpr float H3_DEFAULT_D = 100.0; #define DI9_ACTION INPUT_ACTION_NONE #define DI9_FUNCTION INPUT_FUNCTION_NONE - // Extruder1_PWM #define DO1_MODE IO_ACTIVE_HIGH // Extruder2_PWM @@ -340,23 +314,23 @@ constexpr float H3_DEFAULT_D = 100.0; /*** Handle optional modules that may not be in every machine ***/ -#define P1_PWM_FREQUENCY 100 // in Hz -#define P1_CW_SPEED_LO 7900 // in RPM (arbitrary units) -#define P1_CW_SPEED_HI 12800 -#define P1_CW_PHASE_LO 0.13 // phase [0..1] -#define P1_CW_PHASE_HI 0.17 -#define P1_CCW_SPEED_LO 0 -#define P1_CCW_SPEED_HI 0 -#define P1_CCW_PHASE_LO 0.1 -#define P1_CCW_PHASE_HI 0.1 -#define P1_PWM_PHASE_OFF 0.1 +#define P1_PWM_FREQUENCY 100 // in Hz +#define P1_CW_SPEED_LO 7900 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 12800 +#define P1_CW_PHASE_LO 0.13 // phase [0..1] +#define P1_CW_PHASE_HI 0.17 +#define P1_CCW_SPEED_LO 0 +#define P1_CCW_SPEED_HI 0 +#define P1_CCW_PHASE_LO 0.1 +#define P1_CCW_PHASE_HI 0.1 +#define P1_PWM_PHASE_OFF 0.1 // *** DEFAULT COORDINATE SYSTEM OFFSETS *** // Our convention is: // - leave G54 in machine coordinates to act as a persistent absolute coordinate system // - set G55 to be a zero in the middle of the table // - no action for the others - +/* #define G54_X_OFFSET 0 // G54 is traditionally set to all zeros #define G54_Y_OFFSET 0 #define G54_Z_OFFSET 0 @@ -398,9 +372,9 @@ constexpr float H3_DEFAULT_D = 100.0; #define G59_A_OFFSET 0 #define G59_B_OFFSET 0 #define G59_C_OFFSET 0 - +*/ /*** User-Defined Data Defaults ***/ - +/* #define USER_DATA_A0 0 #define USER_DATA_A1 0 #define USER_DATA_A2 0 @@ -417,3 +391,17 @@ constexpr float H3_DEFAULT_D = 100.0; #define USER_DATA_D1 0 #define USER_DATA_D2 0 #define USER_DATA_D3 0 + + +constexpr float H1_DEFAULT_P = 7.0; +constexpr float H1_DEFAULT_I = 0.2; +constexpr float H1_DEFAULT_D = 100.0; + +constexpr float H2_DEFAULT_P = 7.0; +constexpr float H2_DEFAULT_I = 0.2; +constexpr float H2_DEFAULT_D = 100.0; + +constexpr float H3_DEFAULT_P = 7.0; +constexpr float H3_DEFAULT_I = 0.2; +constexpr float H3_DEFAULT_D = 100.0; +*/ \ No newline at end of file diff --git a/g2core/settings/settings_shopbot_test.h b/g2core/settings/settings_shopbot_test.h index 76caf26b..6e74ce6b 100644 --- a/g2core/settings/settings_shopbot_test.h +++ b/g2core/settings/settings_shopbot_test.h @@ -1,8 +1,8 @@ /* - * settings_shapeoko375.h - Shopbot Test + * settings_shopbot_test.h - Shopbot Test * This file is part of the g2core project * - * Copyright (c) 2015 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -39,208 +39,204 @@ //**** GLOBAL / GENERAL SETTINGS ****************************************************** -#define JUNCTION_INTEGRATION_TIME (5000 * 25.4) // cornering - usually between 0.5 and 2.0 (higher is faster) -#define CHORDAL_TOLERANCE 0.001 // chordal accuracy for arc drawing (in mm) +//#define JUNCTION_INTEGRATION_TIME (5000 * 25.4) // cornering - usually between 0.5 and 2.0 (higher is faster) +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.001 // chordal accuracy for arc drawing (in mm) -#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on -#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high -#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high -#define SPINDLE_PAUSE_ON_HOLD true -#define SPINDLE_DWELL_TIME 1.0 +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.0 -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD true +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD true + +#define MANUAL_FEEDRATE_OVERRIDE_ENABLE false +#define MANUAL_FEEDRATE_OVERRIDE_PARAMETER 1.00 // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS -#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE -#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE -#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_VERBOSE // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE #define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE #define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum #define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -//#define STATUS_REPORT_DEFAULTS "posx","posy","posz","posa","posb","vel","stat","hold","line","coor" -//#define STATUS_REPORT_DEFAULTS -//"posx","posy","posz","posa","posb","vel","stat","macs","cycs","mots","hold","line","coor" -#define STATUS_REPORT_DEFAULTS \ - "posx", "posy", "posz", "posa", "vel", "feed", "stat", "macs", "cycs", "mots", "hold", "in1", "in2", "in3", "in4", \ - "in5", "in6", "in7", "in8", "in9" + +//#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", "vel", "hold", "line", "coor", "stat" +#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", \ + "vel", "feed", "stat", "macs", "cycs", "mots", "hold", \ + "in1", "in2", "in3", "in4", "in5", "in6", "in7", "in8", "in9" // "home","homx","homy","homz" // "line","vel","feed","stat","macs","cycs","mots","hold","unit", // Gcode startup defaults -#define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES -#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ -#define GCODE_DEFAULT_COORD_SYSTEM G55 // G54, G55, G56, G57, G58 or G59 -#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS +#define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES +#define GCODE_DEFAULT_PLANE CANON_PLANE_XY // CANON_PLANE_XY, CANON_PLANE_XZ, or CANON_PLANE_YZ +#define GCODE_DEFAULT_COORD_SYSTEM G55 // G54, G55, G56, G57, G58 or G59 +#define GCODE_DEFAULT_PATH_CONTROL PATH_CONTINUOUS #define GCODE_DEFAULT_DISTANCE_MODE ABSOLUTE_DISTANCE_MODE -constexpr float H1_DEFAULT_P = 7.0; -constexpr float H1_DEFAULT_I = 0.2; -constexpr float H1_DEFAULT_D = 100.0; - -constexpr float H2_DEFAULT_P = 7.0; -constexpr float H2_DEFAULT_I = 0.2; -constexpr float H2_DEFAULT_D = 100.0; - -constexpr float H3_DEFAULT_P = 7.0; -constexpr float H3_DEFAULT_I = 0.2; -constexpr float H3_DEFAULT_D = 100.0; // *** motor settings ************************************************************************************ -#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define MOTOR_POWER_LEVEL 0.375 // default motor power level 0.00 - 1.00 +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_LEVEL 0.375 // default motor power level 0.00 - 1.00 -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr -#define M1_MICROSTEPS 16 // 1mi 1,2,4,8 -#define M1_POLARITY 0 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled -#define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 -#define M2_MOTOR_MAP AXIS_Y -#define M2_STEP_ANGLE 1.8 -#define M2_TRAVEL_PER_REV (0.5 * 25.4) -#define M2_MICROSTEPS 16 -#define M2_POLARITY 0 -#define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL MOTOR_POWER_LEVEL -#define M3_MOTOR_MAP AXIS_Z -#define M3_STEP_ANGLE 1.8 -#define M3_TRAVEL_PER_REV (0.5 * 25.4) -#define M3_MICROSTEPS 16 -#define M3_POLARITY 0 -#define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL MOTOR_POWER_LEVEL +#define M2_MOTOR_MAP AXIS_Y +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV (0.5 * 25.4) +#define M2_MICROSTEPS 8 +#define M2_POLARITY 1 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL MOTOR_POWER_LEVEL -#define M4_MOTOR_MAP AXIS_A -#define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV (0.5 * 25.4) -#define M4_MICROSTEPS 16 -#define M4_POLARITY 0 -#define M4_POWER_MODE MOTOR_POWER_MODE -#define M4_POWER_LEVEL MOTOR_POWER_LEVEL +#define M3_MOTOR_MAP AXIS_Z +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV (0.5 * 25.4) +#define M3_MICROSTEPS 8 +#define M3_POLARITY 0 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL MOTOR_POWER_LEVEL + +#define M4_MOTOR_MAP AXIS_A +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV (0.5 * 25.4) +#define M4_MICROSTEPS 8 +#define M4_POLARITY 0 +#define M4_POWER_MODE MOTOR_POWER_MODE +#define M4_POWER_LEVEL MOTOR_POWER_LEVEL #if (MOTORS >= 5) -#define M5_MOTOR_MAP AXIS_B -#define M5_STEP_ANGLE 1.8 -#define M5_TRAVEL_PER_REV (0.5 * 25.4) -#define M5_MICROSTEPS 16 -#define M5_POLARITY 0 -#define M5_POWER_MODE MOTOR_POWER_MODE -#define M5_POWER_LEVEL MOTOR_POWER_LEVEL +#define M5_MOTOR_MAP AXIS_B +#define M5_STEP_ANGLE 1.8 +#define M5_TRAVEL_PER_REV (0.5 * 25.4) +#define M5_MICROSTEPS 8 +#define M5_POLARITY 0 +#define M5_POWER_MODE MOTOR_POWER_MODE +#define M5_POWER_LEVEL MOTOR_POWER_LEVEL -#define M6_MOTOR_MAP AXIS_C -#define M6_STEP_ANGLE 1.8 -#define M6_TRAVEL_PER_REV (0.5 * 25.4) -#define M6_MICROSTEPS 16 -#define M6_POLARITY 0 -#define M6_POWER_MODE MOTOR_POWER_MODE -#define M6_POWER_LEVEL MOTOR_POWER_LEVEL +#define M6_MOTOR_MAP AXIS_C +#define M6_STEP_ANGLE 1.8 +#define M6_TRAVEL_PER_REV (0.5 * 25.4) +#define M6_MICROSTEPS 8 +#define M6_POLARITY 0 +#define M6_POWER_MODE MOTOR_POWER_MODE +#define M6_POWER_LEVEL MOTOR_POWER_LEVEL #endif // *** axis settings ********************************************************************************* -#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX (360 * 25.4) // xvm G0 max velocity in mm/min -#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min -#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits -#define X_TRAVEL_MAX (25 * 25.4) // xtm travel between switches or crashes -#define X_JERK_MAX (2 * 25.4) // xjm jerk is multipled by 1,000,000 internally -#define X_JERK_HIGH_SPEED 10000 // xjh -#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable -#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive -#define X_SEARCH_VELOCITY (60 * 25.4) // xsv minus means move to minimum switch -#define X_LATCH_VELOCITY (30 * 25.4) // xlv mm/min -#define X_LATCH_BACKOFF (0.125 * 25.4) // xlb mm -#define X_ZERO_BACKOFF (0.375 * 25.4) // xzb mm +// Axis values are set to make the Othermachine behave like a smaller Handibot +// Units are not to scale: i.e. G0 X1 travels approx 0.34" instead of 1" -#define Y_AXIS_MODE AXIS_STANDARD -#define Y_VELOCITY_MAX (360 * 25.4) -#define Y_FEEDRATE_MAX Y_VELOCITY_MAX -#define Y_TRAVEL_MIN 0 -#define Y_TRAVEL_MAX (19 * 25.4) -#define Y_JERK_MAX (2 * 25.4) -#define Y_JERK_HIGH_SPEED 10000 -#define Y_HOMING_INPUT 3 -#define Y_HOMING_DIRECTION 0 -#define Y_SEARCH_VELOCITY (60 * 25.4) -#define Y_LATCH_VELOCITY (30 * 25.4) -#define Y_LATCH_BACKOFF (0.125 * 25.4) -#define Y_ZERO_BACKOFF (0.375 * 25.4) +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX (100 * 25.4) // xvm G0 max velocity in mm/min (was 360) +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits +#define X_TRAVEL_MAX (14 * 25.4) // xtm travel between switches or crashes (was 25) +#define X_JERK_MAX (2 * 25.4) // xjm jerk is multiplied by 1,000,000 internally +#define X_JERK_HIGH_SPEED 10000 // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY (60 * 25.4) // xsv minus means move to minimum switch +#define X_LATCH_VELOCITY (30 * 25.4) // xlv mm/min +#define X_LATCH_BACKOFF (0.125 * 25.4) // xlb mm +#define X_ZERO_BACKOFF (0.250 * 25.4) // xzb mm was 0.375 -#define Z_AXIS_MODE AXIS_STANDARD -#define Z_VELOCITY_MAX (360 * 25.4) -#define Z_FEEDRATE_MAX Z_VELOCITY_MAX -#define Z_TRAVEL_MAX (6.5 * 25.4) -#define Z_TRAVEL_MIN 0 -#define Z_JERK_MAX (2 * 25.4) -#define Z_JERK_HIGH_SPEED 1000 -#define Z_HOMING_INPUT 6 -#define Z_HOMING_DIRECTION 1 -#define Z_SEARCH_VELOCITY (60 * 25.4) -#define Z_LATCH_VELOCITY (30 * 25.4) -#define Z_LATCH_BACKOFF (0.125 * 25.4) -#define Z_ZERO_BACKOFF (0.375 * 25.4) +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX (100 * 25.4) // was 360 +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX (11.5 * 25.4) // was 19 +#define Y_JERK_MAX (2 * 25.4) +#define Y_JERK_HIGH_SPEED 10000 +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIRECTION 0 +#define Y_SEARCH_VELOCITY (60 * 25.4) +#define Y_LATCH_VELOCITY (30 * 25.4) +#define Y_LATCH_BACKOFF (0.125 * 25.4) +#define Y_ZERO_BACKOFF (0.250 * 25.4) // was 0.375 -#define A_AXIS_MODE AXIS_STANDARD -#define A_VELOCITY_MAX (360 * 25.4) -#define A_FEEDRATE_MAX 48000 -#define A_TRAVEL_MIN -1 // degrees -#define A_TRAVEL_MAX -1 // same value means infinite, no limit -#define A_JERK_MAX (2 * 25.4) -#define A_JERK_HIGH_SPEED A_JERK_MAX -#define A_RADIUS 1.0 -#define A_HOMING_INPUT 0 -#define A_HOMING_DIRECTION 0 -#define A_SEARCH_VELOCITY (60 * 25.4) -#define A_LATCH_VELOCITY (30 * 25.4) -#define A_LATCH_BACKOFF (0.125 * 25.4) -#define A_ZERO_BACKOFF (0.375 * 25.4) +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX (100 * 25.4) // was 360 +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MAX (6 * 25.4) // was 6.5 +#define Z_TRAVEL_MIN 0 +#define Z_JERK_MAX (2 * 25.4) +#define Z_JERK_HIGH_SPEED 1000 +#define Z_HOMING_INPUT 6 +#define Z_HOMING_DIRECTION 1 +#define Z_SEARCH_VELOCITY (60 * 25.4) +#define Z_LATCH_VELOCITY (30 * 25.4) +#define Z_LATCH_BACKOFF (0.125 * 25.4) +#define Z_ZERO_BACKOFF (0.250 * 25.4) // was 0.375 -#define B_AXIS_MODE AXIS_DISABLED -#define B_VELOCITY_MAX (360 * 25.4) -#define B_FEEDRATE_MAX B_VELOCITY_MAX -#define B_TRAVEL_MAX -1 -#define B_TRAVEL_MIN -1 -#define B_JERK_MAX (2 * 25.4) -#define B_JERK_HIGH_SPEED B_JERK_MAX -#define B_RADIUS 1 -#define B_HOMING_INPUT 0 -#define B_HOMING_DIRECTION 0 -#define B_SEARCH_VELOCITY (60 * 25.4) -#define B_LATCH_VELOCITY (30 * 25.4) -#define B_LATCH_BACKOFF (0.125 * 25.4) -#define B_ZERO_BACKOFF (0.375 * 25.4) +#define A_AXIS_MODE AXIS_STANDARD +#define A_VELOCITY_MAX (360 * 25.4) +#define A_FEEDRATE_MAX 48000 +#define A_TRAVEL_MIN -1 // degrees +#define A_TRAVEL_MAX -1 // same value means infinite, no limit +#define A_JERK_MAX (2 * 25.4) +#define A_JERK_HIGH_SPEED A_JERK_MAX +#define A_RADIUS 1.0 +#define A_HOMING_INPUT 0 +#define A_HOMING_DIRECTION 0 +#define A_SEARCH_VELOCITY (60 * 25.4) +#define A_LATCH_VELOCITY (30 * 25.4) +#define A_LATCH_BACKOFF (0.125 * 25.4) +#define A_ZERO_BACKOFF (0.375 * 25.4) -#define C_AXIS_MODE AXIS_DISABLED -#define C_VELOCITY_MAX (360 * 25.4) -#define C_FEEDRATE_MAX C_VELOCITY_MAX -#define C_TRAVEL_MAX -1 -#define C_TRAVEL_MIN -1 -#define C_JERK_MAX (2 * 25.4) -#define C_JERK_HIGH_SPEED C_JERK_MAX -#define C_RADIUS 1 -#define C_HOMING_INPUT 0 -#define C_HOMING_DIRECTION 0 -#define C_SEARCH_VELOCITY (60 * 25.4) -#define C_LATCH_VELOCITY (30 * 25.4) -#define C_LATCH_BACKOFF (0.125 * 25.4) -#define C_ZERO_BACKOFF (0.375 * 25.4) +#define B_AXIS_MODE AXIS_DISABLED +#define B_VELOCITY_MAX (360 * 25.4) +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MAX -1 +#define B_TRAVEL_MIN -1 +#define B_JERK_MAX (2 * 25.4) +#define B_JERK_HIGH_SPEED B_JERK_MAX +#define B_RADIUS 1 +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY (60 * 25.4) +#define B_LATCH_VELOCITY (30 * 25.4) +#define B_LATCH_BACKOFF (0.125 * 25.4) +#define B_ZERO_BACKOFF (0.375 * 25.4) + +#define C_AXIS_MODE AXIS_DISABLED +#define C_VELOCITY_MAX (360 * 25.4) +#define C_FEEDRATE_MAX C_VELOCITY_MAX +#define C_TRAVEL_MAX -1 +#define C_TRAVEL_MIN -1 +#define C_JERK_MAX (2 * 25.4) +#define C_JERK_HIGH_SPEED C_JERK_MAX +#define C_RADIUS 1 +#define C_HOMING_INPUT 0 +#define C_HOMING_DIRECTION 0 +#define C_SEARCH_VELOCITY (60 * 25.4) +#define C_LATCH_VELOCITY (30 * 25.4) +#define C_LATCH_BACKOFF (0.125 * 25.4) +#define C_ZERO_BACKOFF (0.375 * 25.4) //*** Input / output settings *** /* @@ -272,7 +268,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define DI1_FUNCTION INPUT_FUNCTION_LIMIT // configured as limit switch. Also used for X homing // Xmax -#define DI2_MODE INPUT_MODE_DISABLED // testing disable +#define DI2_MODE IO_MODE_DISABLED // testing disable //#define DI2_MODE NORMALLY_CLOSED // configured as limit switch #define DI2_ACTION INPUT_ACTION_FAST_STOP #define DI2_FUNCTION INPUT_FUNCTION_LIMIT @@ -288,7 +284,7 @@ constexpr float H3_DEFAULT_D = 100.0; #define DI4_FUNCTION INPUT_FUNCTION_LIMIT // Zmin -#define DI5_MODE INPUT_ACTIVE_LOW // used for Z probe. Active closes circuit (active LO) +#define DI5_MODE IO_ACTIVE_LOW // used for Z probe. Active closes circuit (active LO) #define DI5_ACTION INPUT_ACTION_NONE #define DI5_FUNCTION INPUT_FUNCTION_NONE @@ -302,12 +298,12 @@ constexpr float H3_DEFAULT_D = 100.0; //#define DI6_FUNCTION INPUT_FUNCTION_LIMIT // Amin -#define DI7_MODE INPUT_ACTIVE_HIGH // interlock happens when NO switch goes HI (opens) +#define DI7_MODE IO_ACTIVE_HIGH // interlock happens when NO switch goes HI (opens) #define DI7_ACTION INPUT_ACTION_STOP // wired as interlock switch #define DI7_FUNCTION INPUT_FUNCTION_INTERLOCK // Amax -#define DI8_MODE INPUT_ACTIVE_LOW // configured as panic switch, NO +#define DI8_MODE IO_ACTIVE_LOW // configured as panic switch, NO #define DI8_ACTION INPUT_ACTION_PANIC #define DI8_FUNCTION INPUT_FUNCTION_NONE @@ -334,7 +330,7 @@ constexpr float H3_DEFAULT_D = 100.0; // - leave G54 in machine coordinates to act as a persistent absolute coordinate system // - set G55 to be a zero in the middle of the table // - no action for the others - +/* #define G54_X_OFFSET 0 // G54 is traditionally set to all zeros #define G54_Y_OFFSET 0 #define G54_Z_OFFSET 0 @@ -376,9 +372,9 @@ constexpr float H3_DEFAULT_D = 100.0; #define G59_A_OFFSET 0 #define G59_B_OFFSET 0 #define G59_C_OFFSET 0 - +*/ /*** User-Defined Data Defaults ***/ - +/* #define USER_DATA_A0 0 #define USER_DATA_A1 0 #define USER_DATA_A2 0 @@ -395,3 +391,17 @@ constexpr float H3_DEFAULT_D = 100.0; #define USER_DATA_D1 0 #define USER_DATA_D2 0 #define USER_DATA_D3 0 + + +constexpr float H1_DEFAULT_P = 7.0; +constexpr float H1_DEFAULT_I = 0.2; +constexpr float H1_DEFAULT_D = 100.0; + +constexpr float H2_DEFAULT_P = 7.0; +constexpr float H2_DEFAULT_I = 0.2; +constexpr float H2_DEFAULT_D = 100.0; + +constexpr float H3_DEFAULT_P = 7.0; +constexpr float H3_DEFAULT_I = 0.2; +constexpr float H3_DEFAULT_D = 100.0; +*/ \ No newline at end of file From 9867df985845366169acc29a45d5cee273286c06 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 30 Jan 2017 07:15:19 -0500 Subject: [PATCH 104/283] Minor commit --- g2core/g2core.cppproj | 6 +++--- g2core/plan_exec.cpp | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 7fb39b00..36e55b55 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index e8f03851..1c838055 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -578,12 +578,14 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (3a) - already decelerating, continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are if (fp_ZERO(mr->r->exit_velocity)) { +// if (mr->r->exit_velocity < 1)) { cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } - // Case (3b) - currently accelerating - is simply skipped and waited for + // Case (3b) - Currently accelerating - is simply skipped and waited for. + // This is true because to do otherwise the jerk would not have returned to zero. // Small exception, if we *just started* the head, then we're not actually accelerating yet. } else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { mr->entry_velocity = mr->segment_velocity; From 214d0604a819a9e7f6a39477aae2c2aa7daf1c18 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 30 Jan 2017 09:29:41 -0500 Subject: [PATCH 105/283] Handling corner cases in feedhold. Passes regressions --- g2core/plan_exec.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index cd6180bb..3b9c220d 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -532,12 +532,12 @@ stat_t mp_exec_aline(mpBuf_t *bf) // (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) if (cm->motion_state == MOTION_HOLD) { - // Case (7) - all motion has ceased + // Case (7) - All motion has ceased if (cm->hold_state >= FEEDHOLD_FINAL_ONCE) { // FEEDHOLD_FINAL_ONCE or later return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } - // Case (6) - wait for the steppers to stop + // Case (6) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_STOPPING) { if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { @@ -553,7 +553,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) return (STAT_OK); // hold here. No more movement } - // Case (5) - decelerated to zero + // Case (5) - Decelerated to zero // Update the run buffer then force a replan of the whole planner queue if (cm->hold_state == FEEDHOLD_DECEL_END) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move @@ -575,10 +575,9 @@ stat_t mp_exec_aline(mpBuf_t *bf) if ((cm->hold_state == FEEDHOLD_SYNC) || ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { - // Case (3a) - already decelerating, continue the deceleration. + // Case (3a) - Already decelerating, continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are - if (fp_ZERO(mr->r->exit_velocity)) { -// if (mr->r->exit_velocity < 1)) { + if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; @@ -596,21 +595,27 @@ stat_t mp_exec_aline(mpBuf_t *bf) float available_length = get_axis_vector_length(mr->target, mr->position); mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length - if (fp_ZERO(available_length - mr->r->tail_length)) { // (1c) the deceleration time is almost exactly the remaining of the current move + // (1c) The deceleration distance is almost exactly the remaining of the current move. + // This happens mostly when the tail in the move was already planned to zero. + // EPSILON2 deals with floating point rounding errors that might mis-classify this move. + if (fabs(available_length - mr->r->tail_length) < EPSILON2) { cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr->r->tail_length = available_length; mr->r->exit_velocity = 0; - } else if (available_length < mr->r->tail_length) { // (1b) the deceleration has to span multiple moves + // (1b) The deceleration clearly has to span multiple moves + } else if (available_length < mr->r->tail_length) { + mr->r->tail_length = available_length; mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); + if (fp_ZERO(mr->r->exit_velocity)) { // this takes care of an odd case where the move cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; // was previously mis-classified as a CONTINUE move } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } - mr->r->tail_length = available_length; - } else { // (1a)the deceleration will fit into the current move + // (1a) The deceleration will fit easily into the current move + } else { cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr->r->exit_velocity = 0; } From 0c92646984a7f8464adfa97e16c8d93ddbd633aa Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 2 Feb 2017 14:19:16 -0500 Subject: [PATCH 106/283] Fix inches mode Z lift height --- g2core/canonical_machine.h | 3 ++- g2core/cycle_feedhold.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 2569356b..b7f80306 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -42,7 +42,8 @@ #define RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct #define ACTIVE_MODEL cm->am // active model pointer is maintained by cm_set_motion_state() -#define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) +#define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) +#define _to_inches(a) ((cm->gm.units_mode == INCHES) ? (a * 1/MM_PER_INCH) : a) #define DISABLE_SOFT_LIMIT (999999) #define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3 diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 180d6be3..b18e6c1e 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -273,8 +273,8 @@ stat_t cm_enter_hold_planner() if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift float stored_distance_mode = cm_get_distance_mode(MODEL); cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); - bool flags[] = { 0,0,1,0,0,0 }; - float target[] = { 0,0, cm->feedhold_z_lift, 0,0,0 }; + bool flags[] = { 0,0,1,0,0,0 }; + float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode cm_straight_traverse(target, flags); cm_set_distance_mode(stored_distance_mode); } From 7cfcf30c9f75b6d187068119baf288bef7917e92 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 2 Feb 2017 15:57:43 -0500 Subject: [PATCH 107/283] Fix for status report precision - missing status report for final position --- g2core/canonical_machine.h | 4 ++-- g2core/report.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index b7f80306..5ced3e97 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -42,8 +42,8 @@ #define RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct #define ACTIVE_MODEL cm->am // active model pointer is maintained by cm_set_motion_state() -#define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? (a * MM_PER_INCH) : a) -#define _to_inches(a) ((cm->gm.units_mode == INCHES) ? (a * 1/MM_PER_INCH) : a) +#define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? ((float)a * (float)MM_PER_INCH) : (float)a) +#define _to_inches(a) ((cm->gm.units_mode == INCHES) ? ((float)a * (float)(1/MM_PER_INCH)) : (float)a) #define DISABLE_SOFT_LIMIT (999999) #define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3 diff --git a/g2core/report.cpp b/g2core/report.cpp index 27cdfb1d..16da1b7d 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -368,6 +368,7 @@ static uint8_t _populate_filtered_status_report() bool has_data = false; char tmp[TOKEN_LEN+1]; nvObj_t *nv = nv_reset_nv_list(); // sets nv to the start of the body + float precision[8] = { 1, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001 }; nv->valuetype = TYPE_PARENT; // setup the parent object (no need to length check the copy) strcpy(nv->token, sr_str); @@ -381,7 +382,7 @@ static uint8_t _populate_filtered_status_report() nv_get_nvObj(nv); // report values that have changed by more than 0.0001, but always stops and ends - if ((fabs(nv->value - sr.status_report_value[i]) > EPSILON3) || + if ((fabs(nv->value - sr.status_report_value[i]) > precision[cfgArray[nv->index].precision]) || ((nv->index == sr.stat_index) && fp_EQ(nv->value, COMBINED_PROGRAM_STOP)) || ((nv->index == sr.stat_index) && fp_EQ(nv->value, COMBINED_PROGRAM_END))) { From 7bf79288c49e004eda98d00bd3165a3750d1baba Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 3 Feb 2017 06:58:02 -0500 Subject: [PATCH 108/283] Adjusted threshold precision in status report to account for FP rounding errors --- g2core/g2core.cppproj | 4 ++-- g2core/report.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 3e17cbf8..a4704359 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/report.cpp b/g2core/report.cpp index 16da1b7d..293b3539 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -368,7 +368,7 @@ static uint8_t _populate_filtered_status_report() bool has_data = false; char tmp[TOKEN_LEN+1]; nvObj_t *nv = nv_reset_nv_list(); // sets nv to the start of the body - float precision[8] = { 1, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001 }; + float precision[8] = { 0.9, 0.09, 0.009, 0.0009, 0.00009, 0.000009, 0.0000009, 0.00000009 }; nv->valuetype = TYPE_PARENT; // setup the parent object (no need to length check the copy) strcpy(nv->token, sr_str); From c8d8509949f0da56ed5d48717fb9ca61f623f2b0 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 4 Feb 2017 10:48:44 -0500 Subject: [PATCH 109/283] adjusting settings files to agree with flight replayer values --- g2core/persistence.cpp | 16 ++++---- g2core/report.cpp | 3 ++ g2core/settings/settings_shopbot_sbv300.h | 10 +++-- g2core/settings/settings_shopbot_test.h | 49 +++++++++++------------ 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/g2core/persistence.cpp b/g2core/persistence.cpp index 8644d6da..00bd37e6 100644 --- a/g2core/persistence.cpp +++ b/g2core/persistence.cpp @@ -2,7 +2,7 @@ * persistence.cpp - persistence functions * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2017 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -47,7 +47,7 @@ nvmSingleton_t nvm; void persistence_init() { - return; + return; } /* @@ -58,8 +58,8 @@ void persistence_init() stat_t read_persistent_value(nvObj_t *nv) { - nv->value = 0; - return (STAT_OK); + nv->value = 0; + return (STAT_OK); } /* @@ -71,8 +71,8 @@ stat_t read_persistent_value(nvObj_t *nv) stat_t write_persistent_value(nvObj_t *nv) { - if (cm->cycle_state != CYCLE_OFF) { // can't write when machine is moving - return(rpt_exception(STAT_FILE_NOT_OPEN, "write_persistent_value() can't write when machine is in cycle")); - } - return (STAT_OK); +// if (cm->cycle_state != CYCLE_OFF) { // can't write when machine is moving +// return(rpt_exception(STAT_FILE_NOT_OPEN, "write_persistent_value() can't write when machine is in cycle")); +// } + return (STAT_OK); } diff --git a/g2core/report.cpp b/g2core/report.cpp index 293b3539..7a7b24f3 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -368,6 +368,9 @@ static uint8_t _populate_filtered_status_report() bool has_data = false; char tmp[TOKEN_LEN+1]; nvObj_t *nv = nv_reset_nv_list(); // sets nv to the start of the body + + // Set thresholds to detect value changes based on precision for the value. + // Allow for floating point roundoffs, i.e. precision = 2 is 0.01 becomes --> 0.009 float precision[8] = { 0.9, 0.09, 0.009, 0.0009, 0.00009, 0.000009, 0.0000009, 0.00000009 }; nv->valuetype = TYPE_PARENT; // setup the parent object (no need to length check the copy) diff --git a/g2core/settings/settings_shopbot_sbv300.h b/g2core/settings/settings_shopbot_sbv300.h index 75c89a58..2472569f 100644 --- a/g2core/settings/settings_shopbot_sbv300.h +++ b/g2core/settings/settings_shopbot_sbv300.h @@ -38,9 +38,8 @@ //**** GLOBAL / GENERAL SETTINGS ****************************************************** -//#define JUNCTION_INTEGRATION_TIME (5000 * 25.4) // centripetal acceleration around corners -#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) -#define CHORDAL_TOLERANCE 0.001 // chordal accuracy for arc drawing (in mm) +#define JUNCTION_INTEGRATION_TIME 0.8 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.0001 // chordal accuracy for arc drawing (in mm) #define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on #define HARD_LIMIT_ENABLE 1 // 0=off, 1=on @@ -74,7 +73,10 @@ #define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE #define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum #define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", "vel", "hold", "line", "coor", "stat" + +#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", \ + "vel", "stat", "hold", "line", "coor", "unit", \ + "in1", "in2", "in3", "in4", "in5", "in6", "in7", "in8" // Gcode startup defaults #define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES diff --git a/g2core/settings/settings_shopbot_test.h b/g2core/settings/settings_shopbot_test.h index ac7538e8..92cd827f 100644 --- a/g2core/settings/settings_shopbot_test.h +++ b/g2core/settings/settings_shopbot_test.h @@ -39,13 +39,12 @@ //**** GLOBAL / GENERAL SETTINGS ****************************************************** -//#define JUNCTION_INTEGRATION_TIME (5000 * 25.4) // cornering - usually between 0.5 and 2.0 (higher is faster) -#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) -#define CHORDAL_TOLERANCE 0.001 // chordal accuracy for arc drawing (in mm) +#define JUNCTION_INTEGRATION_TIME 0.8 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.0001 // chordal accuracy for arc drawing (in mm) #define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 0 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 0 // 0=off, 1=on #define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high #define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high @@ -72,16 +71,14 @@ #define JSON_VERBOSITY JV_VERBOSE // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE #define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE -#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum -#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds -//#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", "vel", "hold", "line", "coor", "stat" -#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", \ - "vel", "feed", "stat", "macs", "cycs", "mots", "hold", \ - "in1", "in2", "in3", "in4", "in5", "in6", "in7", "in8", "in9" +#define STATUS_REPORT_DEFAULTS "posx", "posy", "posz", "posa", "posb", \ + "vel", "stat", "hold", "line", "coor", "unit", \ + "in1", "in2", "in3", "in4", "in5", "in6", "in7", "in8" // "home","homx","homy","homz" -// "line","vel","feed","stat","macs","cycs","mots","hold","unit", // Gcode startup defaults #define GCODE_DEFAULT_UNITS INCHES // MILLIMETERS or INCHES @@ -122,7 +119,7 @@ #define M4_MOTOR_MAP AXIS_A #define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV (0.5 * 25.4) +#define M4_TRAVEL_PER_REV 48 // was (0.5 * 25.4) Set to agree with sbv300 su = 33.333333 #define M4_MICROSTEPS 8 #define M4_POLARITY 0 #define M4_POWER_MODE MOTOR_POWER_MODE @@ -131,7 +128,7 @@ #if (MOTORS >= 5) #define M5_MOTOR_MAP AXIS_B #define M5_STEP_ANGLE 1.8 -#define M5_TRAVEL_PER_REV (0.5 * 25.4) +#define M5_TRAVEL_PER_REV 48 // (0.5 * 25.4) #define M5_MICROSTEPS 8 #define M5_POLARITY 0 #define M5_POWER_MODE MOTOR_POWER_MODE @@ -139,7 +136,7 @@ #define M6_MOTOR_MAP AXIS_C #define M6_STEP_ANGLE 1.8 -#define M6_TRAVEL_PER_REV (0.5 * 25.4) +#define M6_TRAVEL_PER_REV 48 // (0.5 * 25.4) #define M6_MICROSTEPS 8 #define M6_POLARITY 0 #define M6_POWER_MODE MOTOR_POWER_MODE @@ -151,13 +148,16 @@ // Axis values are set to make the Othermachine behave like a smaller Handibot // Units are not to scale: i.e. G0 X1 travels approx 0.34" instead of 1" +#define LINEAR_JERK_MAX 50 // value set by sbv300 initialization sequence +//#define LINEAR_JERK_MAX 25.4 // test value +#define ROTARY_JERK_MAX 6000 // sbv300 initialization value + #define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values #define X_VELOCITY_MAX (100 * 25.4) // xvm G0 max velocity in mm/min (was 360) #define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min #define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits #define X_TRAVEL_MAX (14 * 25.4) // xtm travel between switches or crashes (was 25) -//#define X_JERK_MAX (2 * 25.4) // xjm jerk is multiplied by 1,000,000 internally -#define X_JERK_MAX (1 * 25.4) // xjm jerk is multiplied by 1,000,000 internally +#define X_JERK_MAX LINEAR_JERK_MAX // xjm #define X_JERK_HIGH_SPEED 10000 // xjh #define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable #define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive @@ -171,8 +171,7 @@ #define Y_FEEDRATE_MAX Y_VELOCITY_MAX #define Y_TRAVEL_MIN 0 #define Y_TRAVEL_MAX (11.5 * 25.4) // was 19 -//#define Y_JERK_MAX (2 * 25.4) -#define Y_JERK_MAX (1 * 25.4) +#define Y_JERK_MAX LINEAR_JERK_MAX #define Y_JERK_HIGH_SPEED 10000 #define Y_HOMING_INPUT 3 #define Y_HOMING_DIRECTION 0 @@ -186,7 +185,7 @@ #define Z_FEEDRATE_MAX Z_VELOCITY_MAX #define Z_TRAVEL_MAX (6 * 25.4) // was 6.5 #define Z_TRAVEL_MIN 0 -#define Z_JERK_MAX (2 * 25.4) +#define Z_JERK_MAX LINEAR_JERK_MAX #define Z_JERK_HIGH_SPEED 1000 #define Z_HOMING_INPUT 6 #define Z_HOMING_DIRECTION 1 @@ -196,11 +195,11 @@ #define Z_ZERO_BACKOFF (0.250 * 25.4) // was 0.375 #define A_AXIS_MODE AXIS_STANDARD -#define A_VELOCITY_MAX (360 * 25.4) +#define A_VELOCITY_MAX (360 * 25.4) // is 15000 in sbv300 #define A_FEEDRATE_MAX 48000 #define A_TRAVEL_MIN -1 // degrees #define A_TRAVEL_MAX -1 // same value means infinite, no limit -#define A_JERK_MAX (2 * 25.4) +#define A_JERK_MAX ROTARY_JERK_MAX #define A_JERK_HIGH_SPEED A_JERK_MAX #define A_RADIUS 1.0 #define A_HOMING_INPUT 0 @@ -215,7 +214,7 @@ #define B_FEEDRATE_MAX B_VELOCITY_MAX #define B_TRAVEL_MAX -1 #define B_TRAVEL_MIN -1 -#define B_JERK_MAX (2 * 25.4) +#define B_JERK_MAX ROTARY_JERK_MAX #define B_JERK_HIGH_SPEED B_JERK_MAX #define B_RADIUS 1 #define B_HOMING_INPUT 0 @@ -230,7 +229,7 @@ #define C_FEEDRATE_MAX C_VELOCITY_MAX #define C_TRAVEL_MAX -1 #define C_TRAVEL_MIN -1 -#define C_JERK_MAX (2 * 25.4) +#define C_JERK_MAX ROTARY_JERK_MAX #define C_JERK_HIGH_SPEED C_JERK_MAX #define C_RADIUS 1 #define C_HOMING_INPUT 0 From d92852a81295b15ce9a66b32bad9c05691b43faa Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 4 Feb 2017 14:33:53 -0500 Subject: [PATCH 110/283] Changes some feedhold state names. Nothing functional --- g2core/canonical_machine.h | 6 +++--- g2core/cycle_feedhold.cpp | 6 +++--- g2core/plan_exec.cpp | 28 ++++++++++++++-------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 5ced3e97..9f491a88 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -114,9 +114,9 @@ typedef enum { // feedhold state machine FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero FEEDHOLD_DECEL_END, // end the deceleration - FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops - FEEDHOLD_FINAL_ONCE, // enter secondary planner and perform feedhold actions (once) - FEEDHOLD_FINAL_WAIT, // wait for feedhold actions to complete + FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops + FEEDHOLD_ACTIONS_START, // enter secondary planner and perform feedhold actions (once) + FEEDHOLD_ACTIONS_WAIT, // wait for feedhold actions to complete FEEDHOLD_HOLD // holding } cmFeedholdState; diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index b18e6c1e..f57dd962 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -193,8 +193,8 @@ stat_t cm_feedhold_sequencing_callback() cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } - if (cm1.hold_state == FEEDHOLD_FINAL_ONCE) { - cm_enter_hold_planner(); // perform Z lift, spindle & coolant operations + if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions + cm_enter_hold_planner(); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped @@ -238,7 +238,7 @@ static void _enter_hold_finalize(float* vect, bool* flag) stat_t cm_enter_hold_planner() { - cm->hold_state = FEEDHOLD_FINAL_WAIT; // last state before transitioning to HOLD + cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // last state before transitioning to HOLD // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 3b9c220d..a082dba5 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -533,40 +533,40 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->motion_state == MOTION_HOLD) { // Case (7) - All motion has ceased - if (cm->hold_state >= FEEDHOLD_FINAL_ONCE) { // FEEDHOLD_FINAL_ONCE or later - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS or later + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } // Case (6) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_STOPPING) { - if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out + if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { // when homing or probing we don't want to stay in HOLD or execute finalizations cm->hold_state = FEEDHOLD_OFF; } else { - cm->hold_state = FEEDHOLD_FINAL_ONCE; + cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions } - mp_zero_segment_velocity(); // for reporting purposes + mp_zero_segment_velocity(); // for reporting purposes sr_request_status_report(SR_REQUEST_IMMEDIATE); - cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE + cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } - return (STAT_OK); // hold here. No more movement + return (STAT_OK); // hold here. No more movement } // Case (5) - Decelerated to zero // Update the run buffer then force a replan of the whole planner queue if (cm->hold_state == FEEDHOLD_DECEL_END) { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr->target, mr->position);// reset length - //bf->entry_vmax = 0; // set bp+0 as hold point + //bf->entry_vmax = 0; // set bp+0 as hold point cm->hold_state = FEEDHOLD_STOPPING; // No point bothering with the rest of this move if homing or probing if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { mp_free_run_buffer(); } - mp_replan_queue(mp_get_r()); // make it replan all the blocks + mp_replan_queue(mp_get_r()); // make it replan all the blocks return (STAT_OK); } @@ -577,7 +577,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (3a) - Already decelerating, continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are - if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero + if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; @@ -608,8 +608,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->tail_length = available_length; mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); - if (fp_ZERO(mr->r->exit_velocity)) { // this takes care of an odd case where the move - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; // was previously mis-classified as a CONTINUE move + if (fp_ZERO(mr->r->exit_velocity)) { // this takes care of an odd case where the move + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO;// was previously mis-classified as a CONTINUE move } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } From b17a5d19634715cbdf3f3742f72782feeee30ab9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 06:48:33 -0500 Subject: [PATCH 111/283] Better isolation of feedhold state --- g2core/canonical_machine.h | 10 ++--- g2core/controller.cpp | 1 - g2core/cycle_feedhold.cpp | 76 ++++++++++++++++++++++---------------- g2core/plan_exec.cpp | 6 +-- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 9f491a88..efad66b7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -108,6 +108,7 @@ typedef enum { } cmMotionState; typedef enum { // feedhold state machine + FEEDHOLD_EXIT = -1, // set when feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet FEEDHOLD_SYNC, // start hold - sync to latest aline segment @@ -117,7 +118,7 @@ typedef enum { // feedhold state machine FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops FEEDHOLD_ACTIONS_START, // enter secondary planner and perform feedhold actions (once) FEEDHOLD_ACTIONS_WAIT, // wait for feedhold actions to complete - FEEDHOLD_HOLD // holding + FEEDHOLD_HOLD // holding (steady state) Must be last state } cmFeedholdState; typedef enum { // applies to cm->homing_state @@ -153,7 +154,6 @@ typedef enum { CM_NOT_INIT = 0, // planners need initialization CM_PRIMARY, // in primary machine/planner CM_SECONDARY, // in secondary machine/planner - CM_SECONDARY_RETURN // in return move from secondary planner } cmMachineSelect; /***************************************************************************** @@ -260,7 +260,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot - bool waiting_for_exit_hold; // used by cm_exit_hold_planner() to tell when secondary planner is done +// bool waiting_for_exit_hold; // used by cm_exit_hold_planner() to tell when secondary planner is done bool end_hold_requested; // request restart after feedhold bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) @@ -446,10 +446,6 @@ bool cm_has_hold(void); void cm_start_hold(void); void cm_queue_flush(void); // flush serial and planner queues with coordinate resets -stat_t cm_enter_hold_planner(void); // move to secondary planner for in-hold actions -stat_t cm_exit_hold_planner(void); // return to primary planner -stat_t cm_exit_hold_finalize(void); // main loop callback for synchronization - // Homing cycles (cycle_homing.cpp) stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2 stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]); // G28.4 diff --git a/g2core/controller.cpp b/g2core/controller.cpp index d1003b8f..4d701bb5 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -162,7 +162,6 @@ static void _controller_HSM() DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines - DISPATCH(cm_exit_hold_finalize()); // finalization for return from secondary planner DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index f57dd962..76d61117 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -37,6 +37,13 @@ #include "coolant.h" #include "util.h" +static stat_t _run_p1_hold_entry_actions(void); +static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); + +static stat_t _run_p1_hold_exit_actions(void); +static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); +static stat_t _finalize_p1_hold_exit(void); + /*********************************************************************************** **** Feedholds ******************************************************************** ***********************************************************************************/ @@ -186,7 +193,7 @@ void cm_request_queue_flush() stat_t cm_feedhold_sequencing_callback() { - // invoking a feedhold is a 2 step process, invoke it, then do the hold moves + // invoking a feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_REQUESTED) { if (mp_has_runnable_buffer(mp)) { // bypass cm_start_hold() to start from here cm_set_motion_state(MOTION_HOLD); @@ -194,7 +201,7 @@ stat_t cm_feedhold_sequencing_callback() } } if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions - cm_enter_hold_planner(); + _run_p1_hold_entry_actions(); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped @@ -213,9 +220,12 @@ stat_t cm_feedhold_sequencing_callback() } if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold cm1.end_hold_requested = false; - cm_exit_hold_planner(); + _run_p1_hold_exit_actions(); // runs once only } } + if (cm1.hold_state == FEEDHOLD_EXIT) { + return(_finalize_p1_hold_exit()); // run multiple times until actions are complete + } return (STAT_OK); } @@ -230,13 +240,17 @@ stat_t cm_feedhold_sequencing_callback() * directly. Always use the feedhold sequencing callback. */ -// Callback to run at when the secondary planner moves are finished -static void _enter_hold_finalize(float* vect, bool* flag) +// Callback to run when the ACTIONS from feedhold in planner 1 are finished. +// This function hits cm1 directly (no pointers) as ACTIONS for a feedhold +// in planner 1 actually run in the secondary planner. Feedholds from planner 2 +// do not run actions, so this function is never called for planner 2 feedholds. +// It's called from an interrupt, so it only sets a flag. +static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD; } -stat_t cm_enter_hold_planner() +static stat_t _run_p1_hold_entry_actions() { cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // last state before transitioning to HOLD @@ -280,15 +294,15 @@ stat_t cm_enter_hold_planner() } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - mp_queue_command(_enter_hold_finalize, nullptr, nullptr); + mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); return (STAT_OK); } /*********************************************************************************** - * cm_exit_hold_planner() - initiate return from feedhold planner - * cm_exit_hold_finalize() - main loop callback to finsh return once moves are done - * _planner_done_callback() - callback to sync to end of planner operations + * _run_p1_hold_exit_actions() - initiate return from feedhold planner + * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations + * _finalize_p1_hold_exit() - callback to finsh return once moves are done * * Moving between planners is only safe when the machine is completely stopped * either during a feedhold or when idle. @@ -302,13 +316,7 @@ stat_t cm_enter_hold_planner() * directly. Always use the feedhold sequencing callback. */ -// Callback to run at when the G30 return move is finished -static void _exit_hold_finalize(float* vect, bool* flag) -{ - cm2.waiting_for_exit_hold = false; -} - -stat_t cm_exit_hold_planner() // LATER: if value == true return with offset corrections +static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return with offset corrections { // perform end-hold actions --- while still in secondary machine spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused @@ -318,24 +326,30 @@ stat_t cm_exit_hold_planner() // LATER: if value == true return with offset float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move - cm2.waiting_for_exit_hold = true; // indicates running the final G30 move in the secondary - mp_queue_command(_exit_hold_finalize, nullptr, nullptr); - cm_select = CM_SECONDARY_RETURN; + // cm2.waiting_for_exit_hold = true; // indicates running the final G30 move in the secondary + mp_queue_command(_sync_to_p1_hold_exit_actions_done, nullptr, nullptr); return (STAT_OK); - -// cm_exit_hold_planner() completes in cm_exit_hold_finalize() after the above moves are done } -stat_t cm_exit_hold_finalize() +// Callback to run at when the G30 return move is finished. This function is +// only ever called by the secondary planner, and only when exiting a feedhold +// from planner 1. It's called from an interrupt, so it only sets a flag. +static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) { - if (cm_select != CM_SECONDARY_RETURN) { // exit if not in secondary planner +// cm2.waiting_for_exit_hold = false; + cm1.hold_state = FEEDHOLD_EXIT; // last state before transitioning out of HOLD +} + +static stat_t _finalize_p1_hold_exit() +{ + if (cm1.hold_state != FEEDHOLD_EXIT) { // skip out if not ready to finalize the exit return (STAT_NOOP); } - if (cm2.waiting_for_exit_hold) { // sync to planner move ends (via _return_move_callback) - return (STAT_EAGAIN); - } +// if (cm2.waiting_for_exit_hold) { // sync to planner move ends (via _return_move_callback) +// return (STAT_EAGAIN); +// } - // return to primary machine + // return to primary planner (p1) cm = &cm1; mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; @@ -350,9 +364,9 @@ stat_t cm_exit_hold_finalize() cm1.queue_flush_state = FLUSH_OFF; } - // resume motion from primary planner or end cycle if now moves - cm->hold_state = FEEDHOLD_OFF; - if (mp_has_runnable_buffer(mp)) { //+++++ Should MP be passed or global? + // resume motion from primary planner or end cycle if no moves in planner + cm1.hold_state = FEEDHOLD_OFF; + if (mp_has_runnable_buffer(&mp1)) { cm_set_motion_state(MOTION_RUN); cm_cycle_start(); st_request_exec_move(); diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index a082dba5..816ce870 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -533,7 +533,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->motion_state == MOTION_HOLD) { // Case (7) - All motion has ceased - if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS or later + // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD + if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } @@ -554,12 +555,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Case (5) - Decelerated to zero - // Update the run buffer then force a replan of the whole planner queue + // Update the run buffer then force a replan of the whole planner queue. Replans from 0 velocity if (cm->hold_state == FEEDHOLD_DECEL_END) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer bf->length = get_axis_vector_length(mr->target, mr->position);// reset length - //bf->entry_vmax = 0; // set bp+0 as hold point cm->hold_state = FEEDHOLD_STOPPING; // No point bothering with the rest of this move if homing or probing From 21cd532f69c7455b884fe7e12b1888d650802e73 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 06:59:33 -0500 Subject: [PATCH 112/283] Cleanup unused variables and comments --- g2core/canonical_machine.h | 1 - g2core/cycle_feedhold.cpp | 62 +++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index efad66b7..102b054e 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -260,7 +260,6 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot -// bool waiting_for_exit_hold; // used by cm_exit_hold_planner() to tell when secondary planner is done bool end_hold_requested; // request restart after feedhold bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 76d61117..3212d146 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -230,29 +230,19 @@ stat_t cm_feedhold_sequencing_callback() } /*********************************************************************************** - * cm_enter_hold_planner() - switch to secondary machine context for feedhold - * - * Moving between planners is only safe when the machine is completely stopped - * either during a feedhold or when idle. + * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold + * _sync_to_p1_hold_entry_actions_done() - final state change occurs here * * This function assumes that the feedhold sequencing callback has resolved all * state and timing issues and it's OK to call this now. Do not call this function * directly. Always use the feedhold sequencing callback. + * + * Moving between planners is only safe when the machine is completely stopped. */ -// Callback to run when the ACTIONS from feedhold in planner 1 are finished. -// This function hits cm1 directly (no pointers) as ACTIONS for a feedhold -// in planner 1 actually run in the secondary planner. Feedholds from planner 2 -// do not run actions, so this function is never called for planner 2 feedholds. -// It's called from an interrupt, so it only sets a flag. -static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_HOLD; -} - static stat_t _run_p1_hold_entry_actions() { - cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // last state before transitioning to HOLD + cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // penultimate state before transitioning to HOLD // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner @@ -295,25 +285,30 @@ static stat_t _run_p1_hold_entry_actions() spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); - return (STAT_OK); } +// Callback to run when the ACTIONS from feedhold in planner 1 are finished. +// This function hits cm1 directly as ACTIONS for a feedhold in planner 1 +// actually run in the secondary planner. Feedholds from planner 2 do not run +// actions, so this function is never called for planner 2 feedholds. +// It's called from an interrupt, so it only sets a flag. +static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD; +} + /*********************************************************************************** * _run_p1_hold_exit_actions() - initiate return from feedhold planner * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations * _finalize_p1_hold_exit() - callback to finsh return once moves are done * - * Moving between planners is only safe when the machine is completely stopped - * either during a feedhold or when idle. - * - * The reason the finalization moves are not just done in _exit_hold_finalize - * is that they need to run as main loop functions, not called from the - * planner_exec interrupt level. - * - * This function assumes that the feedhold sequencing callback has resolved all + * These functions assume that the feedhold sequencing callback has resolved all * state and timing issues and it's OK to call this now. Do not call this function * directly. Always use the feedhold sequencing callback. + * + * The finalization moves are performed in _sync_to_p1_hold_exit_actions_done() because + * the sync runs from an interrupt. Finalization needs to run from the main loop. */ static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return with offset corrections @@ -326,28 +321,25 @@ static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z bool flags[] = { 0,0,0,0,0,0 }; cm_goto_g30_position(target, flags); // initiate a return move - // cm2.waiting_for_exit_hold = true; // indicates running the final G30 move in the secondary mp_queue_command(_sync_to_p1_hold_exit_actions_done, nullptr, nullptr); return (STAT_OK); } -// Callback to run at when the G30 return move is finished. This function is -// only ever called by the secondary planner, and only when exiting a feedhold -// from planner 1. It's called from an interrupt, so it only sets a flag. +// Callback to run when the G30 return move is finished. This function is only ever +// called by the secondary planner, and only when exiting a feedhold from planner 1. +// It's called from an interrupt, so it only sets a flag. + static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) { -// cm2.waiting_for_exit_hold = false; - cm1.hold_state = FEEDHOLD_EXIT; // last state before transitioning out of HOLD + cm1.hold_state = FEEDHOLD_EXIT; // penultimate state before transitioning to FEEDHOLD_OFF } static stat_t _finalize_p1_hold_exit() { - if (cm1.hold_state != FEEDHOLD_EXIT) { // skip out if not ready to finalize the exit - return (STAT_NOOP); + // skip out if not ready to finalize the exit + if (cm1.hold_state != FEEDHOLD_EXIT) { + return (STAT_NOOP); // ??? return (STAT_EAGAIN); } -// if (cm2.waiting_for_exit_hold) { // sync to planner move ends (via _return_move_callback) -// return (STAT_EAGAIN); -// } // return to primary planner (p1) cm = &cm1; From fec6c336121295e17072ed67a9e431f1ebe1abb9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 10:39:28 -0500 Subject: [PATCH 113/283] Work on secondary feedholds --- g2core/alarm.cpp | 8 ++-- g2core/canonical_machine.cpp | 2 - g2core/canonical_machine.h | 14 ++----- g2core/cycle_feedhold.cpp | 76 +++++++++++++++++++++++++++--------- g2core/plan_exec.cpp | 18 +++++---- 5 files changed, 76 insertions(+), 42 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index dbbdfeab..b98e1ff2 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -206,14 +206,14 @@ stat_t cm_shutdown(const stat_t status, const char *msg) spindle_reset(); // stop spindle immediately and set speed to 0 RPM coolant_reset(); // stop coolant immediately temperature_reset(); // turn off heaters and fans - cm_queue_flush(); // flush all queues and reset positions + cm_queue_flush(&cm1); // flush all queues and reset positions for (uint8_t i = 0; i < HOMING_AXES; i++) { // unhome axes and the machine cm->homed[i] = false; } cm->homing_state = HOMING_NOT_HOMED; - cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity + cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity rpt_exception(status, msg); // send exception report return (status); } @@ -239,9 +239,9 @@ stat_t cm_panic(const stat_t status, const char *msg) spindle_reset(); // stop spindle immediately and set speed to 0 RPM coolant_reset(); // stop coolant immediately temperature_reset(); // turn off heaters and fans - cm_queue_flush(); // flush all queues and reset positions + cm_queue_flush(&cm1); // flush all queues and reset positions - cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable rpt_exception(status, msg); // send panic report return (status); } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index b01a00b0..a4fd9334 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -114,7 +114,6 @@ **** CM GLOBALS & STRUCTURE ALLOCATIONS ******************************************* ***********************************************************************************/ -cmMachineSelect cm_select; // CM_PRIMARY, CM_SECONDARY, CM_SECONDARY_RETURN cmMachine_t *cm; // pointer to active canonical machine cmMachine_t cm1; // canonical machine primary machine cmMachine_t cm2; // canonical machine secondary machine @@ -156,7 +155,6 @@ void canonical_machine_inits() cm = &cm1; // set global canonical machine pointer to primary machine mp = &mp1; // set global pointer to the primary planner mr = &mr1; // and primary runtime - cm_select = CM_PRIMARY; } void canonical_machine_init(cmMachine_t *_cm, void *_mp) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 102b054e..ee21aeb8 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -108,6 +108,7 @@ typedef enum { } cmMotionState; typedef enum { // feedhold state machine +// FEEDHOLD_FLUSH = -2, // set when p2 feedhold is ready to flush p2 queue FEEDHOLD_EXIT = -1, // set when feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet @@ -150,12 +151,6 @@ typedef enum { // queue flush state machine FLUSH_WAS_RUN // transient state to note that a queue flush has been run } cmQueueFlushState; -typedef enum { - CM_NOT_INIT = 0, // planners need initialization - CM_PRIMARY, // in primary machine/planner - CM_SECONDARY, // in secondary machine/planner -} cmMachineSelect; - /***************************************************************************** * CANONICAL MACHINE STRUCTURES */ @@ -291,7 +286,6 @@ typedef struct cmToolTable { // struct to keep a global tool tabl /**** Externs - See canonical_machine.cpp for allocation ****/ -extern cmMachineSelect cm_select; // CM_PRIMARY, CM_SECONDARY, CM_SECONDARY_RETURN extern cmMachine_t *cm; // pointer to active canonical machine extern cmMachine_t cm1; // canonical machine primary machine extern cmMachine_t cm2; // canonical machine secondary machine @@ -441,9 +435,9 @@ void cm_request_end_hold(void); void cm_request_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests -bool cm_has_hold(void); -void cm_start_hold(void); -void cm_queue_flush(void); // flush serial and planner queues with coordinate resets +bool cm_has_hold(void); // has hold in primary planner +void cm_start_hold(void); // starts hold in primary planner +void cm_queue_flush(cmMachine_t *_cm); // queue flush in either planner // Homing cycles (cycle_homing.cpp) stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2 diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 3212d146..d294066e 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -143,21 +143,41 @@ void cm_start_hold() * cm_request_feedhold() * cm_request_end_hold() * cm_request_queue_flush() + * + * p1 is the primary planner, p2 is the secondary planner, which is active if the + * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. + * Request_feedhold, request_end_hold, and request_queue_flush are contextual: + * + * request_feedhold: + * - If p1 is not in HOLD & is in motion, request_feedhold requests a p1 hold + * - If p1 is in HOLD & p2 is in motion, request_feedhold requests a p2 hold + * - If both p1 and p2 are in HOLD, request_feedhold is ignored + * + * request_end_hold: + * - If p1 is not in HOLD, request_end_hold is ignored + * - If p1 is in HOLD request_end_hold will end p1 hold & resume motion. + * Pre-defined exit actions (coolant, spindle, Z move) are completed first + * Any executing or pending "in-hold" moves are stopped prior to the exit actions + * + * request_queue_flush: + * - If p1 is not in HOLD, request_queue_flush is ignored + * - If p1 is in HOLD request_queue_flush will end p1 hold & queue flush (stop motion). + * Pre-defined exit actions (coolant, spindle, Z move) are completed first + * Any executing or pending "in-hold" moves are stopped prior to the exit actions */ void cm_request_feedhold(void) { - // cannot generate a feedhold request from the secondary context - if (cm_select != CM_PRIMARY) { - return; - } - // only generate request if not already in a feedhold and the machine is in motion + // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { cm1.hold_state = FEEDHOLD_REQUESTED; + } else + if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { + cm2.hold_state = FEEDHOLD_REQUESTED; } } -void cm_request_end_hold(void) // This is usually requested from the secondary context +void cm_request_end_hold(void) { if (cm1.hold_state != FEEDHOLD_OFF) { cm1.end_hold_requested = true; @@ -166,11 +186,10 @@ void cm_request_end_hold(void) // This is usually requested from the secondary void cm_request_queue_flush() { + // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped - // NOTE: this function used to flush the input buffers, - // but this is handled in xio *prior* to queue flush now } } @@ -193,24 +212,38 @@ void cm_request_queue_flush() stat_t cm_feedhold_sequencing_callback() { - // invoking a feedhold is a 2 step process - get to the stop, then execute the hold actions + // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_REQUESTED) { - if (mp_has_runnable_buffer(mp)) { // bypass cm_start_hold() to start from here + if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here cm_set_motion_state(MOTION_HOLD); - cm->hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions _run_p1_hold_entry_actions(); } + if (cm2.hold_state == FEEDHOLD_REQUESTED) { + if (mp_has_runnable_buffer(&mp2)) { + cm_set_motion_state(MOTION_HOLD); + cm2.hold_state = FEEDHOLD_SYNC; + } + } + // queue flush won't run until the hold is complete and all (subsequent) motion has stopped +/* + if ((cm2.queue_flush_state == FLUSH_REQUESTED) && (mp_runtime_is_idle())) { + cm_queue_flush(&cm2); + return (STAT_OK); + } +*/ if ((cm1.queue_flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && // only flush once hold is actually holding (mp_runtime_is_idle())) { // don't flush planner during movement - cm_queue_flush(); - } // queue flush always ends hold, so it drops through - + cm_queue_flush(&cm1); + cm1.end_hold_requested = true; // p1 queue flush always ends the hold + } + // exit_hold runs for both ~ and % feedhold ends if (cm1.end_hold_requested) { @@ -225,7 +258,7 @@ stat_t cm_feedhold_sequencing_callback() } if (cm1.hold_state == FEEDHOLD_EXIT) { return(_finalize_p1_hold_exit()); // run multiple times until actions are complete - } + } return (STAT_OK); } @@ -267,7 +300,6 @@ static stat_t _run_p1_hold_entry_actions() cm = &cm2; mp = (mpPlanner_t *)cm->mp; // mp is a void pointer mr = mp->mr; - cm_select = CM_SECONDARY; // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 cm_set_g30_position(); @@ -345,7 +377,6 @@ static stat_t _finalize_p1_hold_exit() cm = &cm1; mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; - cm_select = CM_PRIMARY; // execute this block if a queue flush was performed // adjust primary planner positions to runtime positions @@ -408,18 +439,25 @@ static stat_t _finalize_p1_hold_exit() */ /*********************************************************************************** - * cm_queue_flush() - Flush primary planner queue + * cm_queue_flush() - Flush planner queue * * This function assumes that the feedhold sequencing callback has resolved all * state and timing issues and it's OK to call this now. Do not call this function * directly. Always use the feedhold sequencing callback. */ -void cm_queue_flush() +void cm_queue_flush(cmMachine_t *_cm) { + cm_abort_arc(_cm); // kill arcs so they don't just create more alines + planner_reset((mpPlanner_t *)_cm->mp); // reset primary planner. also resets the mr under the planner + _cm->queue_flush_state = FLUSH_WAS_RUN; + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available + +/* cm_abort_arc(&cm1); // kill arcs so they don't just create more alines planner_reset((mpPlanner_t *)cm1.mp); // reset primary planner. also resets the mr under the planner cm1.queue_flush_state = FLUSH_WAS_RUN; cm1.end_hold_requested = true; // queue flush always ends the hold qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available +*/ } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 816ce870..65394f47 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -527,24 +527,28 @@ stat_t mp_exec_aline(mpBuf_t *bf) // (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) // (5) - We have decelerated a block to zero velocity // (6) - We have finished all the runtime work now we have to wait for the steppers to stop - // (7) - The steppers have stopped. No motion should occur. ALlows hold finalization to commence + // (6a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF + // (6b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush + // (6c) - It's a normal feedhold - signal we want the entry action + // (7) - The steppers have stopped. No motion should occur. Allows hold actions to complete // (8) - We are removing the hold state and there is queued motion (handled outside this routine) // (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) if (cm->motion_state == MOTION_HOLD) { // Case (7) - All motion has ceased - // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD - if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } // Case (6) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_STOPPING) { - if (mp_runtime_is_idle()) { // wait for the steppers to actually clear out + if (mp_runtime_is_idle()) { // wait for steppers to actually finish + // when homing or probing don't stay in HOLD or execute entry actions if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - // when homing or probing we don't want to stay in HOLD or execute finalizations cm->hold_state = FEEDHOLD_OFF; - } else { + } else if (cm == &cm2) { // if in p2 hold set up a flush + cm->queue_flush_state = FLUSH_REQUESTED; + } else { cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions } mp_zero_segment_velocity(); // for reporting purposes From 2e911caaee65aac3c1a95ac24d87352e0010132e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 12:43:20 -0500 Subject: [PATCH 114/283] Checkpoint --- g2core/canonical_machine.cpp | 18 +++++++++-- g2core/canonical_machine.h | 9 ++++-- g2core/cycle_feedhold.cpp | 59 ++++++++++++++++-------------------- g2core/cycle_homing.cpp | 2 +- g2core/cycle_probing.cpp | 2 +- g2core/plan_exec.cpp | 3 +- g2core/planner.cpp | 2 +- 7 files changed, 52 insertions(+), 43 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a4fd9334..4fbca969 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -190,7 +190,7 @@ void canonical_machine_reset(cmMachine_t *_cm) _cm->homing_state = HOMING_NOT_HOMED; // reset request flags - _cm->queue_flush_state = FLUSH_OFF; + _cm->flush_state = FLUSH_OFF; _cm->end_hold_requested = false; _cm->limit_requested = 0; // resets switch closures that occurred during initialization _cm->safety_interlock_disengaged = 0; // ditto @@ -947,7 +947,7 @@ static void _exec_offset(float *value, bool *flag) } /* - * cm_set_position() - set the position of a single axis in the model, planner and runtime + * cm_set_position_by_axis() - set the position of a single axis in the model, planner and runtime * * This command sets an axis/axes to a position provided as an argument. * This is useful for setting origins for homing, probing, and other operations. @@ -965,7 +965,7 @@ static void _exec_offset(float *value, bool *flag) * Use cm_get_runtime_busy() to be sure the system is quiescent. */ -void cm_set_position(const uint8_t axis, const float position) +void cm_set_position_by_axis(const uint8_t axis, const float position) { // TODO: Interlock involving runtime_busy test cm->gmx.position[axis] = position; @@ -975,6 +975,18 @@ void cm_set_position(const uint8_t axis, const float position) mp_set_steps_to_runtime_position(); } +/* + * cm_reset_position_to_absolute_position() - set all positions to current absolute position in mr + */ + +void cm_reset_position_to_absolute_position(cmMachine_t *_cm) +{ + mpPlanner_t *_mp = (mpPlanner_t *)_cm->mp; + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { + cm_set_position_by_axis(axis, mp_get_runtime_absolute_position(_mp->mr, axis)); + } +} + /*** G28.3 functions and support *** * * cm_set_absolute_origin() - G28.3 - model, planner and queue to runtime diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index ee21aeb8..c517ff3c 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -149,7 +149,7 @@ typedef enum { // queue flush state machine FLUSH_OFF = 0, // no queue flush in effect FLUSH_REQUESTED, // flush has been requested but not started yet FLUSH_WAS_RUN // transient state to note that a queue flush has been run -} cmQueueFlushState; +} cmFlushState; /***************************************************************************** * CANONICAL MACHINE STRUCTURES @@ -248,7 +248,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmMotionState motion_state; // momo cmFeedholdState hold_state; // hold: feedhold state machine cmOverrideState mfo_state; // feed override state machine - cmQueueFlushState queue_flush_state; // master queue flush state machine + cmFlushState flush_state; // queue flush state machine uint8_t safety_interlock_disengaged; // set non-zero to start interlock processing (value is input number) uint8_t safety_interlock_reengaged; // set non-zero to end interlock processing (value is input number) @@ -365,7 +365,10 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, // G const uint8_t L_word, const bool L_flag, const float offset[], const bool flag[]); -void cm_set_position(const uint8_t axis, const float position); // set absolute position - single axis +void cm_set_position_by_axis(const uint8_t axis, const float position); // set position to abs pos - single axis +void cm_reset_position_to_absolute_position(cmMachine_t *_cm); // set position to abs pos - all axes +//void cm_set_position(const uint8_t axis, const float position); // set absolute position - single axis +//void cm_set_positions(cmMachine_t *_cm); // set absolute position - all axes stat_t cm_set_absolute_origin(const float origin[], bool flag[]); // G28.3 void cm_set_axis_origin(uint8_t axis, const float position); // G28.3 planner callback diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index d294066e..306bb37a 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -187,9 +187,9 @@ void cm_request_end_hold(void) void cm_request_queue_flush() { // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now - if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm1.queue_flush_state == FLUSH_OFF)) { // ...and only once - cm1.queue_flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold + (cm1.flush_state == FLUSH_OFF)) { // ...and only once + cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped } } @@ -214,12 +214,12 @@ stat_t cm_feedhold_sequencing_callback() { // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_REQUESTED) { - if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here + if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here cm_set_motion_state(MOTION_HOLD); - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } - if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions + if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions _run_p1_hold_entry_actions(); } @@ -231,37 +231,37 @@ stat_t cm_feedhold_sequencing_callback() } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped -/* - if ((cm2.queue_flush_state == FLUSH_REQUESTED) && (mp_runtime_is_idle())) { +// if ((cm2.flush_state == FLUSH_REQUESTED) && (mp_runtime_is_idle())) { + if (cm2.flush_state == FLUSH_REQUESTED) { cm_queue_flush(&cm2); return (STAT_OK); } -*/ - if ((cm1.queue_flush_state == FLUSH_REQUESTED) && - (cm1.hold_state == FEEDHOLD_HOLD) && // only flush once hold is actually holding - (mp_runtime_is_idle())) { // don't flush planner during movement + + if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && + (mp_runtime_is_idle())) { // don't flush planner during movement cm_queue_flush(&cm1); - cm1.end_hold_requested = true; // p1 queue flush always ends the hold + cm1.end_hold_requested = true; // p1 queue flush always ends the hold + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } // exit_hold runs for both ~ and % feedhold ends if (cm1.end_hold_requested) { // Flush must complete before exit_hold runs. Trap possible race condition if flush request was - if (cm1.queue_flush_state == FLUSH_REQUESTED) { // ...received when this callback was running + if (cm1.flush_state == FLUSH_REQUESTED) { // ...received when this callback was running return (STAT_OK); } - if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold + if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold cm1.end_hold_requested = false; - _run_p1_hold_exit_actions(); // runs once only + _run_p1_hold_exit_actions(); // runs once only } } if (cm1.hold_state == FEEDHOLD_EXIT) { - return(_finalize_p1_hold_exit()); // run multiple times until actions are complete + return(_finalize_p1_hold_exit()); // run multiple times until actions are complete } return (STAT_OK); } - + /*********************************************************************************** * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here @@ -287,6 +287,7 @@ static stat_t _run_p1_hold_entry_actions() cm2.hold_state = FEEDHOLD_OFF; cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + cm2.flush_state = FLUSH_OFF; cm2.gm.feed_rate = 0; // clear the target and set the positions to the current hold position @@ -380,11 +381,12 @@ static stat_t _finalize_p1_hold_exit() // execute this block if a queue flush was performed // adjust primary planner positions to runtime positions - if (cm1.queue_flush_state == FLUSH_WAS_RUN) { - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - cm_set_position(axis, mp_get_runtime_absolute_position(&mr2, axis)); - } - cm1.queue_flush_state = FLUSH_OFF; + if (cm1.flush_state == FLUSH_WAS_RUN) { + cm_reset_position_to_absolute_position(cm); +// for (uint8_t axis = AXIS_X; axis < AXES; axis++) { +// cm_set_position(axis, mp_get_runtime_absolute_position(&mr2, axis)); +// } + cm1.flush_state = FLUSH_OFF; } // resume motion from primary planner or end cycle if no moves in planner @@ -450,14 +452,5 @@ void cm_queue_flush(cmMachine_t *_cm) { cm_abort_arc(_cm); // kill arcs so they don't just create more alines planner_reset((mpPlanner_t *)_cm->mp); // reset primary planner. also resets the mr under the planner - _cm->queue_flush_state = FLUSH_WAS_RUN; - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available - -/* - cm_abort_arc(&cm1); // kill arcs so they don't just create more alines - planner_reset((mpPlanner_t *)cm1.mp); // reset primary planner. also resets the mr under the planner - cm1.queue_flush_state = FLUSH_WAS_RUN; - cm1.end_hold_requested = true; // queue flush always ends the hold - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available -*/ + _cm->flush_state = FLUSH_WAS_RUN; } diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index adb1b4ba..b041cbc3 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -321,7 +321,7 @@ static stat_t _homing_axis_setpoint_backoff(int8_t axis) // backoff to zero or static stat_t _homing_axis_set_position(int8_t axis) // set axis zero / max and finish up { if (hm.set_coordinates) { - cm_set_position(axis, hm.setpoint); + cm_set_position_by_axis(axis, hm.setpoint); cm->homed[axis] = true; } else { // handle G28.4 cycle - set position to the point of switch closure diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index fcee822e..85833094 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -313,7 +313,7 @@ static stat_t _probe_axis_move(const float target[], bool exact_position) { } for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // set all positions - cm_set_position(axis, mp_get_runtime_absolute_position(mr, axis)); + cm_set_position_by_axis(axis, mp_get_runtime_absolute_position(mr, axis)); } // set this BEFORE the motion starts diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 65394f47..9360c6c1 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -547,7 +547,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { cm->hold_state = FEEDHOLD_OFF; } else if (cm == &cm2) { // if in p2 hold set up a flush - cm->queue_flush_state = FLUSH_REQUESTED; + cm->hold_state = FEEDHOLD_OFF; + cm->flush_state = FLUSH_REQUESTED; } else { cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index d331b828..a7a5877c 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -255,7 +255,7 @@ void mp_halt_runtime() * still close to the starting point. */ -void mp_set_planner_position(uint8_t axis, const float position) { mp->position[axis] = position; } //+++++ +void mp_set_planner_position(uint8_t axis, const float position) { mp->position[axis] = position; } void mp_set_runtime_position(uint8_t axis, const float position) { mr->position[axis] = position; } void mp_set_steps_to_runtime_position() From 6898f86bad1d30f7622fc76e7c1c240f740009cf Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 14:43:32 -0500 Subject: [PATCH 115/283] Checkpoint --- g2core/canonical_machine.cpp | 29 +++++++++++++---------------- g2core/canonical_machine.h | 8 +++----- g2core/cycle_feedhold.cpp | 25 ++++++++++++++----------- g2core/plan_exec.cpp | 4 ++-- 4 files changed, 32 insertions(+), 34 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 4fbca969..d81375dc 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -948,21 +948,22 @@ static void _exec_offset(float *value, bool *flag) /* * cm_set_position_by_axis() - set the position of a single axis in the model, planner and runtime + * cm_reset_position_to_absolute_position() - set all positions to current absolute position in mr * - * This command sets an axis/axes to a position provided as an argument. - * This is useful for setting origins for homing, probing, and other operations. + * This command sets an axis/axes to a position provided as an argument. + * This is useful for setting origins for homing, probing, and other operations. * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !!!!! DO NOT CALL THESE FUNCTIONS WHILE IN A MACHINING CYCLE !!!!! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * - * More specifically, do not call this function if there are any moves in the planner or - * if the runtime is moving. The system must be quiescent or you will introduce positional - * errors. This is true because the planned / running moves have a different reference frame - * than the one you are now going to set. These functions should only be called during - * initialization sequences and during cycles (such as homing cycles) when you know there - * are no more moves in the planner and that all motion has stopped. - * Use cm_get_runtime_busy() to be sure the system is quiescent. + * More specifically, do not call these functions if there are any moves in the planner or + * if the runtime is moving. The system must be quiescent or you will introduce positional + * errors. This is true because the planned / running moves have a different reference frame + * than the one you are now going to set. These functions should only be called during + * initialization sequences and during cycles (such as homing cycles) when you know there + * are no more moves in the planner and that all motion has stopped. + * You can use cm_get_runtime_busy() to be sure the system is quiescent. */ void cm_set_position_by_axis(const uint8_t axis, const float position) @@ -975,10 +976,6 @@ void cm_set_position_by_axis(const uint8_t axis, const float position) mp_set_steps_to_runtime_position(); } -/* - * cm_reset_position_to_absolute_position() - set all positions to current absolute position in mr - */ - void cm_reset_position_to_absolute_position(cmMachine_t *_cm) { mpPlanner_t *_mp = (mpPlanner_t *)_cm->mp; diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index c517ff3c..fc6f7892 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -108,8 +108,7 @@ typedef enum { } cmMotionState; typedef enum { // feedhold state machine -// FEEDHOLD_FLUSH = -2, // set when p2 feedhold is ready to flush p2 queue - FEEDHOLD_EXIT = -1, // set when feedhold is due to exit + FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet FEEDHOLD_SYNC, // start hold - sync to latest aline segment @@ -119,7 +118,8 @@ typedef enum { // feedhold state machine FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops FEEDHOLD_ACTIONS_START, // enter secondary planner and perform feedhold actions (once) FEEDHOLD_ACTIONS_WAIT, // wait for feedhold actions to complete - FEEDHOLD_HOLD // holding (steady state) Must be last state + FEEDHOLD_HOLD, // holding (steady state) Must be last state + FEEDHOLD_P2_EXIT // set when p2 feedhold is finishing } cmFeedholdState; typedef enum { // applies to cm->homing_state @@ -367,8 +367,6 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, // G void cm_set_position_by_axis(const uint8_t axis, const float position); // set position to abs pos - single axis void cm_reset_position_to_absolute_position(cmMachine_t *_cm); // set position to abs pos - all axes -//void cm_set_position(const uint8_t axis, const float position); // set absolute position - single axis -//void cm_set_positions(cmMachine_t *_cm); // set absolute position - all axes stat_t cm_set_absolute_origin(const float origin[], bool flag[]); // G28.3 void cm_set_axis_origin(uint8_t axis, const float position); // G28.3 planner callback diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 306bb37a..46b86644 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -223,20 +223,26 @@ stat_t cm_feedhold_sequencing_callback() _run_p1_hold_entry_actions(); } + // p2 feedhold states - feedhold in feedhold if (cm2.hold_state == FEEDHOLD_REQUESTED) { if (mp_has_runnable_buffer(&mp2)) { cm_set_motion_state(MOTION_HOLD); cm2.hold_state = FEEDHOLD_SYNC; } } - - // queue flush won't run until the hold is complete and all (subsequent) motion has stopped -// if ((cm2.flush_state == FLUSH_REQUESTED) && (mp_runtime_is_idle())) { - if (cm2.flush_state == FLUSH_REQUESTED) { + if (cm2.hold_state == FEEDHOLD_P2_EXIT) { + cm2.hold_state = FEEDHOLD_OFF; +// copy_vector (mr1.position, mr2.position); + cm_reset_position_to_absolute_position(&cm2); // get the absolute position before destroying it +// cm_reset_position_to_absolute_position(&cm1); cm_queue_flush(&cm2); + cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); + sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); } + // queue flush won't run until the hold is complete and all (subsequent) motion has stopped if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && (mp_runtime_is_idle())) { // don't flush planner during movement cm_queue_flush(&cm1); @@ -256,7 +262,7 @@ stat_t cm_feedhold_sequencing_callback() _run_p1_hold_exit_actions(); // runs once only } } - if (cm1.hold_state == FEEDHOLD_EXIT) { + if (cm1.hold_state == FEEDHOLD_P1_EXIT) { return(_finalize_p1_hold_exit()); // run multiple times until actions are complete } return (STAT_OK); @@ -364,13 +370,13 @@ static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) { - cm1.hold_state = FEEDHOLD_EXIT; // penultimate state before transitioning to FEEDHOLD_OFF + cm1.hold_state = FEEDHOLD_P1_EXIT; // penultimate state before transitioning to FEEDHOLD_OFF } static stat_t _finalize_p1_hold_exit() { // skip out if not ready to finalize the exit - if (cm1.hold_state != FEEDHOLD_EXIT) { + if (cm1.hold_state != FEEDHOLD_P1_EXIT) { return (STAT_NOOP); // ??? return (STAT_EAGAIN); } @@ -380,12 +386,9 @@ static stat_t _finalize_p1_hold_exit() mr = mp->mr; // execute this block if a queue flush was performed - // adjust primary planner positions to runtime positions + // adjust p1 planner positions to runtime positions if (cm1.flush_state == FLUSH_WAS_RUN) { cm_reset_position_to_absolute_position(cm); -// for (uint8_t axis = AXIS_X; axis < AXES; axis++) { -// cm_set_position(axis, mp_get_runtime_absolute_position(&mr2, axis)); -// } cm1.flush_state = FLUSH_OFF; } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 9360c6c1..9a5e90e1 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -547,8 +547,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { cm->hold_state = FEEDHOLD_OFF; } else if (cm == &cm2) { // if in p2 hold set up a flush - cm->hold_state = FEEDHOLD_OFF; - cm->flush_state = FLUSH_REQUESTED; +// cm_reset_position_to_absolute_position(&cm2); + cm->hold_state = FEEDHOLD_P2_EXIT; } else { cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions } From bac6163714dd7f28366e37252c779b558e88443d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 17:01:32 -0500 Subject: [PATCH 116/283] Roughing in p2 feedholds --- g2core/cycle_feedhold.cpp | 30 +++++++++++++++++++++--------- g2core/plan_exec.cpp | 1 - 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 46b86644..75cf01d0 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -43,6 +43,7 @@ static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); static stat_t _run_p1_hold_exit_actions(void); static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); static stat_t _finalize_p1_hold_exit(void); +static stat_t _finalize_p2_hold_exit(void); /*********************************************************************************** **** Feedholds ******************************************************************** @@ -231,15 +232,7 @@ stat_t cm_feedhold_sequencing_callback() } } if (cm2.hold_state == FEEDHOLD_P2_EXIT) { - cm2.hold_state = FEEDHOLD_OFF; -// copy_vector (mr1.position, mr2.position); - cm_reset_position_to_absolute_position(&cm2); // get the absolute position before destroying it -// cm_reset_position_to_absolute_position(&cm1); - cm_queue_flush(&cm2); - cm_set_motion_state(MOTION_STOP); - cm_cycle_end(); - sr_request_status_report(SR_REQUEST_IMMEDIATE); - return (STAT_OK); + return(_finalize_p2_hold_exit()); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped @@ -406,6 +399,25 @@ static stat_t _finalize_p1_hold_exit() return (STAT_OK); } +/*********************************************************************************** + * _finalize_p2_hold_exit() + */ + +static stat_t _finalize_p2_hold_exit() +{ + float position[AXES]; + copy_vector(position, mr2.position); // save the final position + cm_queue_flush(&cm2); + copy_vector(mr2.position, position); // restore the final position + cm_reset_position_to_absolute_position(&cm2); // propagate position + + cm2.hold_state = FEEDHOLD_OFF; + cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); + sr_request_status_report(SR_REQUEST_IMMEDIATE); + return (STAT_OK); +} + /*********************************************************************************** * Queue Flush operations * diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 9a5e90e1..a1de3372 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -547,7 +547,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { cm->hold_state = FEEDHOLD_OFF; } else if (cm == &cm2) { // if in p2 hold set up a flush -// cm_reset_position_to_absolute_position(&cm2); cm->hold_state = FEEDHOLD_P2_EXIT; } else { cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions From f36382e04245bf6f22be157263229cc94fec45bf Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 5 Feb 2017 18:39:32 -0500 Subject: [PATCH 117/283] Return move runs through intermediate point - Z plunge is last --- g2core/canonical_machine.cpp | 10 ++++++---- g2core/canonical_machine.h | 12 +++++++----- g2core/cycle_feedhold.cpp | 17 +++++++++-------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index d81375dc..984b7252 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -191,7 +191,7 @@ void canonical_machine_reset(cmMachine_t *_cm) // reset request flags _cm->flush_state = FLUSH_OFF; - _cm->end_hold_requested = false; + _cm->hold_exit_requested = false; _cm->limit_requested = 0; // resets switch closures that occurred during initialization _cm->safety_interlock_disengaged = 0; // ditto _cm->safety_interlock_reengaged = 0; // ditto @@ -708,6 +708,7 @@ void cm_set_model_target(const float target[], const bool flags[]) } else { cm->gm.target[axis] += _to_millimeters(target[axis]); } + cm->return_flags[axis] = true; // used to make a synthetic G28/G30 intermediate move } } // FYI: The ABC loop below relies on the XYZ loop having been run first @@ -722,6 +723,7 @@ void cm_set_model_target(const float target[], const bool flags[]) } else { cm->gm.target[axis] += tmp; } + cm->return_flags[axis] = true; } } @@ -1137,7 +1139,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm target[i] *= INCHES_PER_MM; } } - + // Run the stored position move while (mp_planner_is_full(mp)); // Make sure you have available buffers @@ -1154,7 +1156,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm stat_t cm_set_g28_position(void) { - copy_vector(cm->gmx.g28_position, cm->gmx.position); // in MM and machine coordinates + copy_vector(cm->gmx.g28_position, cm->gmx.position); // in MM and machine coordinates return (STAT_OK); } @@ -1165,7 +1167,7 @@ stat_t cm_goto_g28_position(const float target[], const bool flags[]) stat_t cm_set_g30_position(void) { - copy_vector(cm->gmx.g30_position, cm->gmx.position); // in MM and machine coordinates + copy_vector(cm->gmx.g30_position, cm->gmx.position); // in MM and machine coordinates return (STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index fc6f7892..48d1fdb1 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -241,7 +241,7 @@ typedef struct cmMachine { // struct to manage canonical machin /**** Runtime variables (PRIVATE) ****/ - // Global state variables and requestors + // Global state variables and flags cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleState cycle_state; // cycs @@ -255,19 +255,21 @@ typedef struct cmMachine { // struct to manage canonical machin cmSafetyState safety_interlock_state; // safety interlock state uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot - bool end_hold_requested; // request restart after feedhold - bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) + bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them + bool hold_exit_requested; // request exit from feedhold + bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move cmHomingState homing_state; // home: homing cycle sub-state machine uint8_t homed[AXES]; // individual axis homing flags - cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple) - float probe_results[PROBES_STORED][AXES]; // probing results + cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple) + float probe_results[PROBES_STORED][AXES]; // probing results float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore rotary axes. float rotation_z_offset; // separately handle a z-offset to maintain consistent distance to bed + float jogging_dest; // jogging destination as a relative move from current position /**** Model state structures ****/ diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 75cf01d0..dba2d29c 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -181,7 +181,7 @@ void cm_request_feedhold(void) void cm_request_end_hold(void) { if (cm1.hold_state != FEEDHOLD_OFF) { - cm1.end_hold_requested = true; + cm1.hold_exit_requested = true; } } @@ -239,19 +239,19 @@ stat_t cm_feedhold_sequencing_callback() if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && (mp_runtime_is_idle())) { // don't flush planner during movement cm_queue_flush(&cm1); - cm1.end_hold_requested = true; // p1 queue flush always ends the hold + cm1.hold_exit_requested = true; // p1 queue flush always ends the hold qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } // exit_hold runs for both ~ and % feedhold ends - if (cm1.end_hold_requested) { + if (cm1.hold_exit_requested) { // Flush must complete before exit_hold runs. Trap possible race condition if flush request was if (cm1.flush_state == FLUSH_REQUESTED) { // ...received when this callback was running return (STAT_OK); } if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold - cm1.end_hold_requested = false; + cm1.hold_exit_requested = false; _run_p1_hold_exit_actions(); // runs once only } } @@ -291,6 +291,7 @@ static stat_t _run_p1_hold_entry_actions() // clear the target and set the positions to the current hold position memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); + memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation copy_vector(cm2.gmx.position, mr1.position); copy_vector(mp2.position, mr1.position); @@ -325,6 +326,7 @@ static stat_t _run_p1_hold_entry_actions() // actually run in the secondary planner. Feedholds from planner 2 do not run // actions, so this function is never called for planner 2 feedholds. // It's called from an interrupt, so it only sets a flag. + static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD; @@ -349,10 +351,9 @@ static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused - // perform the G30 move and queue a wait - float target[] = { 0,0,0,0,0,0 }; // LATER: Make this move return through XY, then Z - bool flags[] = { 0,0,0,0,0,0 }; - cm_goto_g30_position(target, flags); // initiate a return move + // do return move though an intermediate point; queue a wait + cm2.return_flags[AXIS_Z] = false; + cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); mp_queue_command(_sync_to_p1_hold_exit_actions_done, nullptr, nullptr); return (STAT_OK); } From 750353c633164d06f3073b276c0a72396137562f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Feb 2017 06:45:59 -0500 Subject: [PATCH 118/283] Testing sending in Gcode using {gc} --- g2core/canonical_machine.cpp | 2 +- g2core/config_app.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 984b7252..6c12154a 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -372,7 +372,7 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ void cm_set_model_linenum(const uint32_t linenum) { - cm->gm.linenum = linenum; // you must first set the model line number, + cm->gm.linenum = linenum; // you must first set the model line number, nv_add_object((const char *)"n"); // then add the line number to the nv list } diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 04811f24..5ecb6325 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -115,7 +115,7 @@ const cfgItem_t cfgArray[] = { // dynamic model attributes for reporting purposes (up front for speed) { "", "stat", _f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state { "", "stat2",_f0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _f0, 0, cm_print_line, cm_get_mline,set_ro, (float *)&cs.null, 0 }, // Model line number + { "", "n", _f0, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null, 0 }, // Model line number { "", "line", _f0, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity { "", "feed", _f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate @@ -658,6 +658,7 @@ const cfgItem_t cfgArray[] = { { "sys","gco", _fipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, { "sys","gpa", _fipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, { "sys","gdi", _fipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, +// { "", "gc2", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // send gcode to secondary planner { "", "gc", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports From 85450a0b928776158cf6cdf436a55a722f6134c7 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Feb 2017 07:19:40 -0500 Subject: [PATCH 119/283] Update for gc2 --- g2core/config_app.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 5ecb6325..5726922a 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -658,7 +658,7 @@ const cfgItem_t cfgArray[] = { { "sys","gco", _fipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, { "sys","gpa", _fipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, { "sys","gdi", _fipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, -// { "", "gc2", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // send gcode to secondary planner + { "", "gc2", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // send gcode to secondary planner { "", "gc", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports From edf2b845b5b1641b56534b4745cd51dc2e3c21ab Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Feb 2017 08:59:13 -0500 Subject: [PATCH 120/283] Added {dw:n} as a way to examine the dwell timer down counter. Useful for testing --- g2core/config_app.cpp | 1 + g2core/g2core.cppproj | 4 ++-- g2core/spindle.cpp | 5 ----- g2core/stepper.cpp | 10 +++++++++- g2core/stepper.h | 1 + 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 5726922a..00590e53 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -669,6 +669,7 @@ const cfgItem_t cfgArray[] = { { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets + { "", "dw", _f0, 0, tx_print_int, st_get_dw, set_nul, (float *)&cs.null, 0 }, // get dwell time remaining { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index a4704359..3e17cbf8 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 35c8db51..2ff03bb8 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -399,11 +399,8 @@ stat_t sp_set_spdp(nvObj_t *nv) { stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.pause_enable)); } stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.pause_enable, 0, 1)); } - stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } -//stat_t sp_get_spdn(nvObj_t *nv) { return(get_float(nv, spindle.spindown_delay)); } -//stat_t sp_set_spdn(nvObj_t *nv) { return(set_float_range(nv, spindle.spindown_delay, 0, SPINDLE_DWELL_MAX)); } stat_t sp_get_spsn(nvObj_t *nv) { return(get_float(nv, spindle.speed_min)); } stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } @@ -435,7 +432,6 @@ const char fmt_spep[] = "[spep] spindle enable polarity%5d [0=active_low,1=activ const char fmt_spdp[] = "[spdp] spindle direction polarity%2d [0=CW_low,1=CW_high]\n"; const char fmt_spph[] = "[spph] spindle pause on hold%7d [0=no,1=pause_on_hold]\n"; const char fmt_spde[] = "[spde] spindle spinup delay%10.1f seconds\n"; -//const char fmt_spdn[] = "[spdn] spindle spindown delay%8.1f seconds\n"; const char fmt_spsn[] = "[spsn] spindle speed min%14.2f rpm\n"; const char fmt_spsm[] = "[spsm] spindle speed max%14.2f rpm\n"; const char fmt_spoe[] = "[spoe] spindle speed override ena%2d [0=disable,1=enable]\n"; @@ -448,7 +444,6 @@ void sp_print_spep(nvObj_t *nv) { text_print(nv, fmt_spep);} // TYPE_INT void sp_print_spdp(nvObj_t *nv) { text_print(nv, fmt_spdp);} // TYPE_INT void sp_print_spph(nvObj_t *nv) { text_print(nv, fmt_spph);} // TYPE_INT void sp_print_spde(nvObj_t *nv) { text_print(nv, fmt_spde);} // TYPE_FLOAT -//void sp_print_spdn(nvObj_t *nv) { text_print(nv, fmt_spdn);} // TYPE_FLOAT void sp_print_spsn(nvObj_t *nv) { text_print(nv, fmt_spsn);} // TYPE_FLOAT void sp_print_spsm(nvObj_t *nv) { text_print(nv, fmt_spsm);} // TYPE_FLOAT void sp_print_spoe(nvObj_t *nv) { text_print(nv, fmt_spoe);} // TYPE INT diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index dfbce1f3..0b7828af 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -607,7 +607,7 @@ static void _load_move() // We now use SysTick events to handle dwells SysTickTimer.registerEvent(&dwell_systick_event); - // handle synchronous commands + // handle synchronous commands } else if (st_pre.block_type == BLOCK_TYPE_COMMAND) { mp_runtime_command(st_pre.bf); @@ -973,6 +973,7 @@ stat_t st_get_pwr(nvObj_t *nv) * st_set_md() - disable motor power * st_set_me() - enable motor power * st_set_md() - disable motor power + * st_get_dw() - get remaining dwell time * * Calling me or md with NULL will enable or disable all motors * Setting a value of 0 will enable or disable all motors @@ -1017,6 +1018,13 @@ stat_t st_set_md(nvObj_t *nv) return (STAT_OK); } +stat_t st_get_dw(nvObj_t *nv) +{ + nv->value = st_run.dwell_ticks_downcount; + nv->valuetype = TYPE_INT; + return (STAT_OK); +} + /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table diff --git a/g2core/stepper.h b/g2core/stepper.h index 0038722d..f3ef06d7 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -601,6 +601,7 @@ stat_t st_get_mt(nvObj_t *nv); stat_t st_set_mt(nvObj_t *nv); stat_t st_set_md(nvObj_t *nv); stat_t st_set_me(nvObj_t *nv); +stat_t st_get_dw(nvObj_t *nv); #ifdef __TEXT_MODE From 17ddf830ff42fa1ed0b24ea766b8a46f249d699a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Feb 2017 15:10:30 -0500 Subject: [PATCH 121/283] Lightened up planner reset to not destroy position values and other data; Corrected coolant and spindle ordering in feedhold exit actions; Added {dw:n} to report progress of dwells; Added RADIUS_MIN value and compile-time and runtime tests for tests for zero radius values. Illegal due to divide by zero --- g2core/canonical_machine.cpp | 4 ++-- g2core/canonical_machine.h | 3 ++- g2core/config_app.cpp | 8 ++++---- g2core/cycle_feedhold.cpp | 2 +- g2core/error.h | 1 - g2core/planner.cpp | 6 ++++-- g2core/settings.h | 17 ++++++++++++++++- g2core/stepper.cpp | 4 +--- 8 files changed, 30 insertions(+), 15 deletions(-) mode change 100755 => 100644 g2core/settings.h diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 6c12154a..2722158f 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -367,7 +367,7 @@ void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool) void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override) { gcode_state->absolute_override = (cmAbsoluteOverride)absolute_override; - cm_set_work_offsets(MODEL); // must reset offsets if you change absolute override +// cm_set_work_offsets(MODEL); // must reset offsets if you change absolute override } void cm_set_model_linenum(const uint32_t linenum) @@ -2082,7 +2082,7 @@ stat_t cm_set_tn(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv)].travel_mi stat_t cm_get_tm(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].travel_max)); } stat_t cm_set_tm(nvObj_t *nv) { return (set_float(nv, cm->a[_axis(nv)].travel_max)); } stat_t cm_get_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].radius)); } -stat_t cm_set_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].radius)); } +stat_t cm_set_ra(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].radius, RADIUS_MIN, 1000000)); } /**** Axis Jerk Primitives * cm_get_axis_jerk() - returns jerk for an axis diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 48d1fdb1..a204d9b6 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -47,8 +47,9 @@ #define DISABLE_SOFT_LIMIT (999999) #define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3 -#define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3 +#define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3 #define PROBES_STORED 3 // we store three probes for coordinate rotation computation +#define RADIUS_MIN (0.0001) // minimum value for ABC radius settings /***************************************************************************** * MACHINE STATE MODEL diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 00590e53..f55aa324 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -669,15 +669,15 @@ const cfgItem_t cfgArray[] = { { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets - { "", "dw", _f0, 0, tx_print_int, st_get_dw, set_nul, (float *)&cs.null, 0 }, // get dwell time remaining + { "", "dw", _f0, 0, tx_print_int, st_get_dw, set_noop, (float *)&cs.null, 0 }, // get dwell time remaining { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state - { "", "clr", _f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" - { "", "tick", _f0,0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic - { "", "tram", _f0,0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes + { "", "clr", _f0, 0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" + { "", "tick",_f0, 0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic + { "", "tram",_f0, 0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index dba2d29c..e4c059d7 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -348,8 +348,8 @@ static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return with offset corrections { // perform end-hold actions --- while still in secondary machine - spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused + spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused // do return move though an intermediate point; queue a wait cm2.return_flags[AXIS_Z] = false; diff --git a/g2core/error.h b/g2core/error.h index 4f4024c9..06884f5d 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -205,7 +205,6 @@ char *get_status_message(stat_t status); #define STAT_MAX_DEPTH_EXCEEDED 115 // JSON exceeded maximum nesting depth #define STAT_VALUE_TYPE_ERROR 116 // JSON value does not agree with variable type -//#define STAT_ERROR_DEVICE_NOT_ACTIVE 117 // Device cannot receive commands at this time #define STAT_INPUT_FROM_MUTED_CHANNEL_ERROR 117 // input from a muted channel was ignored #define STAT_ERROR_118 118 #define STAT_ERROR_119 119 diff --git a/g2core/planner.cpp b/g2core/planner.cpp index a7a5877c..8224af74 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -200,9 +200,11 @@ void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uin _mr->p = &_mr->bf[1]; } -void planner_reset(mpPlanner_t *_mp) +void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR activity, but leave positions alone { - planner_init(_mp, _mp->mr, _mp->q.bf, _mp->q.queue_size); // reset parent planner and linked Q and MR +// planner_init(_mp, _mp->mr, _mp->q.bf, _mp->q.queue_size); // reset parent planner and linked Q and MR +// _mp->mr.block_state == BLOCK_INACTIVE; + _init_planner_queue(_mp, _mp->q.bf, _mp->q.queue_size); } stat_t planner_test_assertions(const mpPlanner_t *_mp) diff --git a/g2core/settings.h b/g2core/settings.h old mode 100755 new mode 100644 index eaa2fb7d..5fd3b12e --- a/g2core/settings.h +++ b/g2core/settings.h @@ -2,7 +2,7 @@ * settings.h - default runtime settings * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -35,6 +35,8 @@ #ifndef SETTINGS_H_ONCE #define SETTINGS_H_ONCE +#include "canonical_machine.h" + /**** MACHINE PROFILES ****************************************************** * * Provide an optional SETTINGS_FILE in the makefile or compiler command line: @@ -54,4 +56,17 @@ // The defaults below generally disable that function #include "settings/settings_default.h" +// compile-time assertions - mostly checking the settings are not impossible + +#define stringify2(a) #a +#define stringify(a) stringify2(a) + +//static_assert ( bool_constexpr , message ) // bool_constexpr must be true or assertion will fail +static_assert ( (A_RADIUS > RADIUS_MIN), "A axis radius must be more than " stringify(RADIUS_MIN) ", but is " stringify(A_RADIUS) ); +static_assert ( (B_RADIUS > RADIUS_MIN), "B axis radius must be more than " stringify(RADIUS_MIN) ", but is " stringify(B_RADIUS) ); +static_assert ( (C_RADIUS > RADIUS_MIN), "C axis radius must be more than " stringify(RADIUS_MIN) ", but is " stringify(C_RADIUS) ); + +#undef stringify +#undef stringify2 + #endif // End of include guard: SETTINGS_H_ONCE diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 0b7828af..9bf39acc 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -603,9 +603,7 @@ static void _load_move() // handle dwells and commands } else if (st_pre.block_type == BLOCK_TYPE_DWELL) { st_run.dwell_ticks_downcount = st_pre.dwell_ticks; - - // We now use SysTick events to handle dwells - SysTickTimer.registerEvent(&dwell_systick_event); + SysTickTimer.registerEvent(&dwell_systick_event); // We now use SysTick events to handle dwells // handle synchronous commands } else if (st_pre.block_type == BLOCK_TYPE_COMMAND) { From aaf39969d4b7829ad44524476e932c8435599c9b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Feb 2017 16:22:43 -0500 Subject: [PATCH 122/283] Experimental commit. May roll this back --- g2core/canonical_machine.cpp | 20 +++++++++++--------- g2core/canonical_machine.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 2722158f..47ca4a98 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -406,15 +406,17 @@ void cm_set_model_linenum(const uint32_t linenum) /* * cm_get_active_coord_offset() - return the currently active coordinate offset for an axis * - * Takes G5x, G92 and absolute override into account to return the active offset for this move + * This function is typically used to evaluate and set offsets, as opposed to cm_get_work_offset() + * which merely returns what's in the work_offset[] array. * - * This function is typically used to evaluate and set offsets, as opposed to cm_get_work_offset() - * which merely returns what's in the work_offset[] array. + * Takes G5x, G92 into account to return the active offset for this move. + * If absolute_override is provided and is ON it will zero offsets for an absolute override move. + * If you don;t want that, just set absolute_override false in the function call. */ -float cm_get_active_coord_offset(const uint8_t axis) +float cm_get_active_coord_offset(const uint8_t axis, const cmAbsoluteOverride absolute_override) { - if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON) { // no offset if in absolute override mode + if (cm->gm.absolute_override == absolute_override) { // no offset if in absolute override mode return (0.0); } float offset = cm->offset[cm->gm.coord_system][axis] + cm->tl_offset[axis]; @@ -437,7 +439,7 @@ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) void cm_set_work_offsets(GCodeState_t *gcode_state) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - gcode_state->work_offset[axis] = cm_get_active_coord_offset(axis); + gcode_state->work_offset[axis] = cm_get_active_coord_offset(axis, (cmAbsoluteOverride)false); } } @@ -466,7 +468,7 @@ float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) float position; if (gcode_state == MODEL) { - position = cm->gmx.position[axis] - cm_get_active_coord_offset(axis); + position = cm->gmx.position[axis] - cm_get_active_coord_offset(axis, (cmAbsoluteOverride)false); } else { position = mp_get_runtime_work_position(axis); } @@ -704,7 +706,7 @@ void cm_set_model_target(const float target[], const bool flags[]) continue; // skip axis if not flagged for update or its disabled } else if ((cm->a[axis].axis_mode == AXIS_STANDARD) || (cm->a[axis].axis_mode == AXIS_INHIBITED)) { if (cm->gm.distance_mode == ABSOLUTE_DISTANCE_MODE) { - cm->gm.target[axis] = cm_get_active_coord_offset(axis) + _to_millimeters(target[axis]); + cm->gm.target[axis] = cm_get_active_coord_offset(axis, cm->gm.absolute_override) + _to_millimeters(target[axis]); } else { cm->gm.target[axis] += _to_millimeters(target[axis]); } @@ -719,7 +721,7 @@ void cm_set_model_target(const float target[], const bool flags[]) tmp = _calc_ABC(axis, target); } if (cm->gm.distance_mode == ABSOLUTE_DISTANCE_MODE) { - cm->gm.target[axis] = tmp + cm_get_active_coord_offset(axis); // sacidu93's fix to Issue #22 + cm->gm.target[axis] = tmp + cm_get_active_coord_offset(axis, cm->gm.absolute_override); // sacidu93's fix to Issue #22 } else { cm->gm.target[axis] += tmp; } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index a204d9b6..c1f26723 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -333,7 +333,7 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ void cm_set_model_linenum(const uint32_t linenum); // Coordinate systems and offsets -float cm_get_active_coord_offset(const uint8_t axis); +float cm_get_active_coord_offset(const uint8_t axis, const cmAbsoluteOverride absolute_override); float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis); void cm_set_work_offsets(GCodeState_t *gcode_state); float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t axis); From e21e583eb09ce9bdf86af56cfec0e9bee8f7e9a9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 7 Feb 2017 06:01:47 -0500 Subject: [PATCH 123/283] Messing with work offset reporting. Passes all g54-offset regression tests --- g2core/canonical_machine.cpp | 16 +++++++++------- g2core/canonical_machine.h | 2 +- g2core/g2core.cppproj | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 47ca4a98..439677a6 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -414,10 +414,12 @@ void cm_set_model_linenum(const uint32_t linenum) * If you don;t want that, just set absolute_override false in the function call. */ -float cm_get_active_coord_offset(const uint8_t axis, const cmAbsoluteOverride absolute_override) +float cm_get_active_coord_offset(const uint8_t axis, const bool use_absolute_override) { - if (cm->gm.absolute_override == absolute_override) { // no offset if in absolute override mode - return (0.0); + if (use_absolute_override) { + if (cm->gm.absolute_override == use_absolute_override) { // no offset if in absolute override mode + return (0.0); + } } float offset = cm->offset[cm->gm.coord_system][axis] + cm->tl_offset[axis]; if (cm->gmx.origin_offset_enable == true) { @@ -439,7 +441,7 @@ float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) void cm_set_work_offsets(GCodeState_t *gcode_state) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - gcode_state->work_offset[axis] = cm_get_active_coord_offset(axis, (cmAbsoluteOverride)false); + gcode_state->work_offset[axis] = cm_get_active_coord_offset(axis, false); } } @@ -468,7 +470,7 @@ float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) float position; if (gcode_state == MODEL) { - position = cm->gmx.position[axis] - cm_get_active_coord_offset(axis, (cmAbsoluteOverride)false); + position = cm->gmx.position[axis] - cm_get_active_coord_offset(axis, false); } else { position = mp_get_runtime_work_position(axis); } @@ -706,7 +708,7 @@ void cm_set_model_target(const float target[], const bool flags[]) continue; // skip axis if not flagged for update or its disabled } else if ((cm->a[axis].axis_mode == AXIS_STANDARD) || (cm->a[axis].axis_mode == AXIS_INHIBITED)) { if (cm->gm.distance_mode == ABSOLUTE_DISTANCE_MODE) { - cm->gm.target[axis] = cm_get_active_coord_offset(axis, cm->gm.absolute_override) + _to_millimeters(target[axis]); + cm->gm.target[axis] = cm_get_active_coord_offset(axis, true) + _to_millimeters(target[axis]); } else { cm->gm.target[axis] += _to_millimeters(target[axis]); } @@ -721,7 +723,7 @@ void cm_set_model_target(const float target[], const bool flags[]) tmp = _calc_ABC(axis, target); } if (cm->gm.distance_mode == ABSOLUTE_DISTANCE_MODE) { - cm->gm.target[axis] = tmp + cm_get_active_coord_offset(axis, cm->gm.absolute_override); // sacidu93's fix to Issue #22 + cm->gm.target[axis] = tmp + cm_get_active_coord_offset(axis, true); // sacidu93's fix to Issue #22 } else { cm->gm.target[axis] += tmp; } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index c1f26723..1cde000a 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -333,7 +333,7 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ void cm_set_model_linenum(const uint32_t linenum); // Coordinate systems and offsets -float cm_get_active_coord_offset(const uint8_t axis, const cmAbsoluteOverride absolute_override); +float cm_get_active_coord_offset(const uint8_t axis, const bool use_absolute_override); float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis); void cm_set_work_offsets(GCodeState_t *gcode_state); float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t axis); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 3e17cbf8..a4704359 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 From e592ce1339e486352191d244aa036310a6791485 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 8 Feb 2017 13:22:49 -0500 Subject: [PATCH 124/283] Checkpoint. Passes G28 and G53 tests --- g2core/canonical_machine.cpp | 28 +++++++++++++++++----------- g2core/canonical_machine.h | 2 +- g2core/cycle_probing.cpp | 1 + g2core/g2core.cppproj | 4 ++-- g2core/gcode.h | 7 ++++--- g2core/gcode_parser.cpp | 6 +++--- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 439677a6..397a313d 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -367,7 +367,7 @@ void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool) void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override) { gcode_state->absolute_override = (cmAbsoluteOverride)absolute_override; -// cm_set_work_offsets(MODEL); // must reset offsets if you change absolute override + cm_set_work_offsets(MODEL); // must reset offsets if you change absolute override } void cm_set_model_linenum(const uint32_t linenum) @@ -410,16 +410,22 @@ void cm_set_model_linenum(const uint32_t linenum) * which merely returns what's in the work_offset[] array. * * Takes G5x, G92 into account to return the active offset for this move. - * If absolute_override is provided and is ON it will zero offsets for an absolute override move. - * If you don;t want that, just set absolute_override false in the function call. + * + * Absolute Override is the Gcode G53 convention to allow one and only one Gcode block + * to be run in absolute coordinates, regardless of coordinate offsets, G92 offsets, and + * tool offsets. If absolute_override is set to ABSOLUTE_OVERRIDE_ON_AND_DISPLAY this + * function will return 0.0 for the offset value. This bit is here to support G28 and G30 + * return moves and other moves that run in absolute override mode but may want position + * to be reported using all current offsets (work offsets), versus an explicit G53 move that + * should be displayed in absolute coordinates. */ -float cm_get_active_coord_offset(const uint8_t axis, const bool use_absolute_override) +float cm_get_active_coord_offset(const uint8_t axis, const bool absolute) { - if (use_absolute_override) { - if (cm->gm.absolute_override == use_absolute_override) { // no offset if in absolute override mode - return (0.0); - } + // if absolute override is on and is to be displayed with no offsets: +// if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_AND_DISPLAY) { + if (absolute & (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON)) { + return (0.0); } float offset = cm->offset[cm->gm.coord_system][axis] + cm->tl_offset[axis]; if (cm->gmx.origin_offset_enable == true) { @@ -823,7 +829,7 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode) * during the Gcode cycle. The persist flag is used to persist offsets once the cycle * has ended. You can also use $g54x - $g59c config functions to change offsets. * - * It also does not reset the work_offsets which may be accomplished by calling + * It also does not reset the work offsets which may be accomplished by calling * cm_set_work_offsets() immediately afterwards. */ @@ -934,6 +940,7 @@ stat_t cm_cancel_tl_offset() stat_t cm_set_coord_system(const uint8_t coord_system) // set coordinate system sync'd with planner { cm->gm.coord_system = (cmCoordSystem)coord_system; + cm_set_work_offsets(MODEL); // must reset offsets if you change coordinate system //++++++ float value[] = { (float)coord_system }; mp_queue_command(_exec_offset, value, nullptr); @@ -949,7 +956,6 @@ static void _exec_offset(float *value, bool *flag) (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); } mp_set_runtime_work_offset(offsets); - cm_set_work_offsets(MODEL); // set work offsets in the Gcode model } /* @@ -1138,7 +1144,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm // If G20 adjust stored position (always in mm) to inches so traverse will be correct float target[AXES]; // make a local stored position as it may be modified copy_vector(target, stored_position); - if (cm->gm.units_mode == INCHES) { + if (cm->gm.units_mode == INCHES) { for (uint8_t i=0; igm.units_mode = stored_units_mode; cm->gm.distance_mode = stored_distance_mode; + cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_OFF); // ++++ } // the last two arguments are ignored anyway diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index a4704359..3e17cbf8 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/gcode.h b/g2core/gcode.h index c8a5c557..ddee1be2 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -119,8 +119,9 @@ typedef enum { #define COORD_SYSTEM_MAX G59 // set this manually to the last one typedef enum { - ABSOLUTE_OVERRIDE_OFF = 0,// G53 enabled - ABSOLUTE_OVERRIDE_ON + ABSOLUTE_OVERRIDE_OFF = 0, // G53 disabled + ABSOLUTE_OVERRIDE_ON, // G53 enabled for movement + ABSOLUTE_OVERRIDE_ON_AND_DISPLAY // G53 enabled for movement and display } cmAbsoluteOverride; typedef enum { // G Modal Group 13 @@ -215,7 +216,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl float target[AXES]; // XYZABC where the move should go float target_comp[AXES]; // summation compensation (Kahan) overflow value - float work_offset[AXES]; // offset from the work coordinate system (for reporting only) + float work_offset[AXES]; // work offsets from the machine coordinate system (for reporting only) float feed_rate; // F - normalized to millimeters/minute or in inverse time mode float P_word; // P - parameter used for dwell time in seconds, G10 coord select... diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index d0bc3cdd..bc33f9e8 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -580,7 +580,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) break; } case 49: SET_NON_MODAL (next_action, NEXT_ACTION_CANCEL_TL_OFFSET); - case 53: SET_NON_MODAL (absolute_override, true); + case 53: SET_NON_MODAL (absolute_override, ABSOLUTE_OVERRIDE_ON_AND_DISPLAY); case 54: SET_MODAL (MODAL_GROUP_G12, coord_system, G54); case 55: SET_MODAL (MODAL_GROUP_G12, coord_system, G55); case 56: SET_MODAL (MODAL_GROUP_G12, coord_system, G56); @@ -826,7 +826,7 @@ static stat_t _execute_gcode_block(char *active_comment) // case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 case NEXT_ACTION_DEFAULT: { - cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override + cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override & display as absolute switch (gv.motion_mode) { case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gv.motion_mode; break;} // G80 case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gv.target, gf.target); break;} // G0 @@ -842,7 +842,7 @@ static stat_t _execute_gcode_block(char *active_comment) } default: break; } - cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_OFF); // un-set absolute override once the move is planned + cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_OFF); // un-set absolute override once the move is planned } } From 2325c1119e107af57ea7c65231aec979912e51ac Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 8 Feb 2017 16:04:33 -0500 Subject: [PATCH 125/283] Removed some cruft --- g2core/config_app.cpp | 22 ---------------------- g2core/gcode_parser.cpp | 29 ----------------------------- 2 files changed, 51 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 1de99a55..4466b65d 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -113,28 +113,6 @@ const cfgItem_t cfgArray[] = { { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) -/*<<<<<<< HEAD - { "", "stat", _f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "stat2",_f0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _f0, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null, 0 }, // Model line number - { "", "line", _f0, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity - { "", "feed", _f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs", _f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs", _f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots", _f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold", _f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit", _f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor", _f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo", _f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan", _f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path", _f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist", _f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo", _f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo", _f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool", _f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool -// { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled -=======*/ { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state // { "", "stat2",_f0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_noop, (float *)&cs.null, 0 },// Model line number diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index a06e337f..8fab3c1d 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -797,35 +797,6 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_set_arc_distance_mode, arc_distance_mode); // G90.1, G91.1 //--> set retract mode goes here -/*<<<<<<< HEAD - switch (gv.next_action) { - case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 - case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gv.target, gf.target); break;} // G30 - - case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gv.target, gf.target); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gv.target, gf.target); break;} // G28.3 - case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(gv.target, gf.target); break;} // G28.4 - - case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gv.target, gf.target, true, true); break;} // G38.2 - case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gv.target, gf.target, false, true); break;} // G38.3 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gv.target, gf.target, true, false); break;} // G38.4 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gv.target, gf.target, false, false); break;}// G38.5 - - case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gv.P_word, gf.P_word, - gv.L_word, gf.L_word, - gv.target, gf.target); break;} - - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gv.target, gf.target); break;}// G92 - case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 - case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 - case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 - - case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 - case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 -// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 -=======*/ switch (gv.next_action) { case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 From 7c34374c654f7278f1a1c2da34ab9d59147039f4 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 9 Feb 2017 08:35:22 -0500 Subject: [PATCH 126/283] Reset coordinate displays in cycle finalization --- g2core/canonical_machine.cpp | 1 + g2core/config_app.cpp | 40 +++++++++++------------ g2core/settings/settings_othermill_test.h | 20 ------------ 3 files changed, 21 insertions(+), 40 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0e095c8e..f8280a23 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1580,6 +1580,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_reset_overrides(); // reset feedrate the spindle overrides temperature_reset(); // turn off all heaters and fans } + cm_set_work_offsets(MODEL); // reset work offsets for display porpoises sr_request_status_report(SR_REQUEST_IMMEDIATE); // request a final and full status report (not filtered) } diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 4466b65d..1be4d7bc 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -113,26 +113,26 @@ const cfgItem_t cfgArray[] = { { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) - { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state -// { "", "stat2",_f0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_noop, (float *)&cs.null, 0 },// Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity - { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool - { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "stat2",_f0,0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null, 0 }, // Model line number + { "", "line",_fi, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number + { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity + { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate + { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state + { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state + { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state + { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state + { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode + { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system + { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode + { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select + { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode + { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode + { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode + { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode + { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool + { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs diff --git a/g2core/settings/settings_othermill_test.h b/g2core/settings/settings_othermill_test.h index 2e4a89de..077b2357 100644 --- a/g2core/settings/settings_othermill_test.h +++ b/g2core/settings/settings_othermill_test.h @@ -328,23 +328,3 @@ #define P1_MAPPING_CUBIC_X2 -7.2900167282605129e-009 #define P1_MAPPING_CUBIC_X1 8.5854646785876479e-005 #define P1_MAPPING_CUBIC_X0 -2.1301489219406905e-001 - -/*** User-Defined Data Defaults ***/ -/* -#define USER_DATA_A0 0 -#define USER_DATA_A1 0 -#define USER_DATA_A2 0 -#define USER_DATA_A3 0 -#define USER_DATA_B0 0 -#define USER_DATA_B1 0 -#define USER_DATA_B2 0 -#define USER_DATA_B3 0 -#define USER_DATA_C0 0 -#define USER_DATA_C1 0 -#define USER_DATA_C2 0 -#define USER_DATA_C3 0 -#define USER_DATA_D0 0 -#define USER_DATA_D1 0 -#define USER_DATA_D2 0 -#define USER_DATA_D3 0 -*/ \ No newline at end of file From 544caa8b2f018e8b4068c1035e9eea67d0f51a00 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 9 Feb 2017 09:35:01 -0500 Subject: [PATCH 127/283] setting.h updated --- g2core/config_app.cpp | 1 - g2core/settings/settings_default.h | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 1be4d7bc..dff499ae 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -658,7 +658,6 @@ const cfgItem_t cfgArray[] = { { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, - //{ "sp","spdn", _fip, 2, sp_print_spdn, sp_get_spdn, sp_set_spdn, (float *)&cs.null, SPINDLE_SPINDOWN_DELAY }, { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 5806a35d..c33132e7 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -101,10 +101,6 @@ #define SPINDLE_SPINUP_DELAY 0 // {spde: #endif -#ifndef SPINDLE_SPINDOWN_DELAY -#define SPINDLE_SPINDOWN_DELAY 0 // {spdn: -#endif - #ifndef SPINDLE_DWELL_MAX #define SPINDLE_DWELL_MAX 10000000.0 // maximum allowable dwell time. May be overridden in settings files #endif @@ -129,6 +125,10 @@ #define COOLANT_PAUSE_ON_HOLD true // {coph: #endif +#ifndef FEEDHOLD_Z_LIFT +#define FEEDHOLD_Z_LIFT 0 // {zl: mm to lift Z on feedhold +#endif + #ifndef PROBE_REPORT_ENABLE #define PROBE_REPORT_ENABLE true // {prbr: #endif From 5c13dbca9f1b53323342afd0f94487bb3820c948 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 9 Feb 2017 12:45:26 -0500 Subject: [PATCH 128/283] Cleaned up offset handling in advance of fixing a bug in G53 move display --- g2core/board/gquadratic/hardware.cpp | 2 +- g2core/canonical_machine.cpp | 181 ++++++++++++++------------- g2core/canonical_machine.h | 14 +-- g2core/config_app.cpp | 78 +++--------- g2core/gcode.h | 4 +- g2core/plan_arc.cpp | 34 ++--- g2core/plan_line.cpp | 16 +-- g2core/planner.h | 4 +- g2core/settings/settings_default.h | 5 - 9 files changed, 144 insertions(+), 194 deletions(-) diff --git a/g2core/board/gquadratic/hardware.cpp b/g2core/board/gquadratic/hardware.cpp index f1e3fe50..febd5e3d 100644 --- a/g2core/board/gquadratic/hardware.cpp +++ b/g2core/board/gquadratic/hardware.cpp @@ -92,7 +92,7 @@ void hardware_init() stat_t hardware_periodic() { - float x_pos = cm_get_work_position(ACTIVE_MODEL, AXIS_X); + float x_pos = cm_get_display_position(ACTIVE_MODEL, AXIS_X); if (fabs(LEDs::old_x_pos - x_pos) > 0.01) { LEDs::old_x_pos = x_pos; diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f8280a23..8d371ffe 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -368,7 +368,7 @@ void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool) void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override) { gcode_state->absolute_override = (cmAbsoluteOverride)absolute_override; - cm_set_work_offsets(MODEL); // must reset offsets if you change absolute override + cm_set_display_offsets(MODEL); // must reset offsets if you change absolute override } void cm_set_model_linenum(const uint32_t linenum) @@ -384,72 +384,100 @@ void cm_set_model_linenum(const uint32_t linenum) * These functions are not part of the NIST defined functions ***********************************************************************************/ /* + * cm_get_combined_offset() - return the combined offsets for an axis (G53-G59, G92, Tools) + * cm_get_display_offset() - return the current display offset from pecified Gcode model + * cm_set_display_offsets() - capture combined offsets from the model into absolute values in the active Gcode dynamic model + * * Notes on Coordinate System and Offset functions * * All positional information in the canonical machine is kept as absolute coords and in - * canonical units (mm). The offsets are only used to translate in and out of canonical form - * during interpretation and response. + * canonical units (mm, mm/min). The offsets are only used to translate in and out of + * canonical form during incoming processing, and for displays in responses. * * Managing the coordinate systems & offsets is somewhat complicated. The following affect offsets: - * - coordinate system selected. 1-9 correspond to G54-G59 - * - absolute override: forces current move to be interpreted in machine coordinates: G53 (system 0) + * - coordinate system selected. 1-6 correspond to G54-G59 * - G92 offsets are added "on top of" the coord system offsets -- if origin_offset_enable == true - * - G28 and G30 moves; these are run in absolute coordinates + * - tool offsets are also accounted for * - * The offsets themselves are considered static, are kept in cm, and are supposed to be persistent. + * Position displays {pos:n} are always in work coordinates aka using 'display' offsets + * - position displays are assembled by applying all active offsets to the current machine position + * - an absolute override forces current move to be interpreted in machine coordinates: G53 (system 0) + * - G53 is an explicit absolute override requested by the program, so displays in absolute coords + * - G28 and G30 moves are run in absolute coordinates but display using current offsets + * - Probing also has a very short move that behaves this way * - * To reduce complexity and data load the following is done: - * - Full data for coordinates/offsets is only accessible by the canonical machine, not the downstream - * - A fully resolved set of coord and G92 offsets, with per-move exceptions can be captured as "work_offsets" - * - The core gcode context (gm) only knows about the active coord system and the work offsets - */ - -/* - * cm_get_active_coord_offset() - return the currently active coordinate offset for an axis + * The offsets themselves are "the truth". These are: + * - cm.coord_offset[coord][axis] coordinate offsets for G53-G59, by axis - persistent + * - cm.tool_offset[axis] offsets for currently selected and active tool - persistent + * - cm.gmx.origin_offset[axis] G92 origin offset. Not persistent * - * This function is typically used to evaluate and set offsets, as opposed to cm_get_work_offset() - * which merely returns what's in the work_offset[] array. + * - cm_get_combined_offset() puts the above together to provide a combined, active offset. + * G92 offsets are only included if it is active * - * Takes G5x, G92 into account to return the active offset for this move. - * - * Absolute Override is the Gcode G53 convention to allow one and only one Gcode block + * Display offsets + * - cm_set_display_offsets() writes combined offsets to cm.gm.display_offset[] + * *** This is for display purposes only and should not be used to set positions *** + * - cm_set_display_offsets() should be called every time underlying data would cause a change + * - cm_set_display_offsets() takes absolute override display rules into account + * - Use cm_get_display_offset() to return the display offset value + */ +/* Absolute Override is the Gcode G53 convention to allow one and only one Gcode block * to be run in absolute coordinates, regardless of coordinate offsets, G92 offsets, and - * tool offsets. If absolute_override is set to ABSOLUTE_OVERRIDE_ON_AND_DISPLAY this - * function will return 0.0 for the offset value. This bit is here to support G28 and G30 + * tool offsets. If absolute_override is set to ABSOLUTE_OVERRIDE_ON_AND_DISPLAY the display + * values will be set to 0.0 for the offset value. This bit is here to support G28 and G30 * return moves and other moves that run in absolute override mode but may want position * to be reported using all current offsets (work offsets), versus an explicit G53 move that * should be displayed in absolute coordinates. */ - -float cm_get_active_coord_offset(const uint8_t axis, const bool absolute) + +float cm_get_combined_offset(const uint8_t axis) { - // if absolute override is on and is to be displayed with no offsets: -// if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_AND_DISPLAY) { - if (absolute & (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON)) { - return (0.0); - } - float offset = cm->offset[cm->gm.coord_system][axis] + cm->tl_offset[axis]; + float offset = cm->coord_offset[cm->gm.coord_system][axis] + cm->tool_offset[axis]; if (cm->gmx.origin_offset_enable == true) { - offset += cm->gmx.origin_offset[axis]; // includes G5x and G92 components + offset += cm->gmx.origin_offset[axis]; } return (offset); +} + +float cm_get_display_offset(const GCodeState_t *gcode_state, const uint8_t axis) +{ + return (gcode_state->display_offset[axis]); +} + +void cm_set_display_offsets(GCodeState_t *gcode_state) +{ + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { + + // if absolute override is on and position is to be displayed with no offsets + if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_AND_DISPLAY) { + gcode_state->display_offset[axis] = 0; + } else { + gcode_state->display_offset[axis] = cm_get_combined_offset(axis); + } + } } /* - * cm_get_work_offset() - return a coord offset from the active Gcode dynamic model - * cm_set_work_offsets() - capture coord offsets from the model into absolute values in the active Gcode dynamic model + * cm_get_display_position() - return position in external form from the active Gcode dynamic model + * + * ... that means in prevailing units (mm/inch) and with all offsets applied */ -float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis) +float cm_get_display_position(const GCodeState_t *gcode_state, const uint8_t axis) { - return (gcode_state->work_offset[axis]); -} + float position; -void cm_set_work_offsets(GCodeState_t *gcode_state) -{ - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - gcode_state->work_offset[axis] = cm_get_active_coord_offset(axis, false); + if (gcode_state == MODEL) { + position = cm->gmx.position[axis] - cm_get_display_offset(MODEL, axis); + } else { + position = mp_get_runtime_display_position(axis); } + if (axis <= AXIS_Z) { + if (gcode_state->units_mode == INCHES) { + position /= MM_PER_INCH; + } + } + return (position); } /* @@ -466,29 +494,6 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax return (mp_get_runtime_absolute_position(mr, axis)); } -/* - * cm_get_work_position() - return work position in external form from the active Gcode dynamic model - * - * ... that means in prevailing units (mm/inch) and with all offsets applied - */ - -float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis) -{ - float position; - - if (gcode_state == MODEL) { - position = cm->gmx.position[axis] - cm_get_active_coord_offset(axis, false); - } else { - position = mp_get_runtime_work_position(axis); - } - if (axis <= AXIS_Z) { - if (gcode_state->units_mode == INCHES) { - position /= MM_PER_INCH; - } - } - return (position); -} - /*********************************************************************************** **** CRITICAL HELPERS ************************************************************* *********************************************************************************** @@ -533,7 +538,7 @@ stat_t cm_deferred_write_callback() for (uint8_t j=0; joffset[i][j]; + nv.value = cm->coord_offset[i][j]; nv_persist(&nv); // Note: only writes values that have changed } } @@ -715,7 +720,7 @@ void cm_set_model_target(const float target[], const bool flags[]) continue; // skip axis if not flagged for update or its disabled } else if ((cm->a[axis].axis_mode == AXIS_STANDARD) || (cm->a[axis].axis_mode == AXIS_INHIBITED)) { if (cm->gm.distance_mode == ABSOLUTE_DISTANCE_MODE) { - cm->gm.target[axis] = cm_get_active_coord_offset(axis, true) + _to_millimeters(target[axis]); + cm->gm.target[axis] = cm_get_combined_offset(axis) + _to_millimeters(target[axis]); } else { cm->gm.target[axis] += _to_millimeters(target[axis]); } @@ -730,7 +735,7 @@ void cm_set_model_target(const float target[], const bool flags[]) tmp = _calc_ABC(axis, target); } if (cm->gm.distance_mode == ABSOLUTE_DISTANCE_MODE) { - cm->gm.target[axis] = tmp + cm_get_active_coord_offset(axis, true); // sacidu93's fix to Issue #22 + cm->gm.target[axis] = tmp + cm_get_combined_offset(axis); // sacidu93's fix to Issue #22 } else { cm->gm.target[axis] += tmp; } @@ -835,7 +840,7 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode) * has ended. You can also use $g54x - $g59c config functions to change offsets. * * It also does not reset the work offsets which may be accomplished by calling - * cm_set_work_offsets() immediately afterwards. + * cm_set_display_offsets() immediately afterwards. */ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, @@ -855,12 +860,12 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { if (L_word == 2) { - cm->offset[P_word][axis] = _to_millimeters(offset[axis]); + cm->coord_offset[P_word][axis] = _to_millimeters(offset[axis]); } else { // Should L20 take into account G92 offsets? - cm->offset[P_word][axis] = cm->gmx.position[axis] - + cm->coord_offset[P_word][axis] = cm->gmx.position[axis] - _to_millimeters(offset[axis]) - - cm->tl_offset[axis]; + cm->tool_offset[axis]; } // persist offsets once machining cycle is over cm->deferred_write_flag = true; @@ -880,7 +885,7 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, // L10 should also take into account G92 offset tt.tt_offset[P_word][axis] = cm->gmx.position[axis] - _to_millimeters(offset[axis]) - - cm->offset[cm->gm.coord_system][axis] - + cm->coord_offset[cm->gm.coord_system][axis] - (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); } // persist offsets once machining cycle is over @@ -920,11 +925,11 @@ stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool appl } if (apply_additional) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - cm->tl_offset[axis] += tt.tt_offset[tool][axis]; + cm->tool_offset[axis] += tt.tt_offset[tool][axis]; } } else { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - cm->tl_offset[axis] = tt.tt_offset[tool][axis]; + cm->tool_offset[axis] = tt.tt_offset[tool][axis]; } } float value[] = { (float)cm->gm.coord_system }; // pass coordinate system in value[0] element @@ -935,7 +940,7 @@ stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool appl stat_t cm_cancel_tl_offset() { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - cm->tl_offset[axis] = 0; + cm->tool_offset[axis] = 0; } float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); @@ -945,7 +950,7 @@ stat_t cm_cancel_tl_offset() stat_t cm_set_coord_system(const uint8_t coord_system) // set coordinate system sync'd with planner { cm->gm.coord_system = (cmCoordSystem)coord_system; - cm_set_work_offsets(MODEL); // must reset offsets if you change coordinate system //++++++ + cm_set_display_offsets(MODEL); // must reset display offsets if you change coordinate system float value[] = { (float)coord_system }; mp_queue_command(_exec_offset, value, nullptr); @@ -957,10 +962,10 @@ static void _exec_offset(float *value, bool *flag) uint8_t coord_system = ((uint8_t)value[0]); // coordinate system is passed in value[0] element float offsets[AXES]; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - offsets[axis] = cm->offset[coord_system][axis] + cm->tl_offset[axis] + + offsets[axis] = cm->coord_offset[coord_system][axis] + cm->tool_offset[axis] + (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); } - mp_set_runtime_work_offset(offsets); + mp_set_runtime_display_offset(offsets); } /* @@ -1060,8 +1065,8 @@ stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { cm->gmx.origin_offset[axis] = cm->gmx.position[axis] - - cm->offset[cm->gm.coord_system][axis] - - cm->tl_offset[axis] - + cm->coord_offset[cm->gm.coord_system][axis] - + cm->tool_offset[axis] - _to_millimeters(offset[axis]); } } @@ -1116,7 +1121,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) cm_set_model_target(target, flags); ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown - cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state + cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm->gm); // send the move to the planner @@ -1270,7 +1275,7 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) cm_set_model_target(target, flags); ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown - cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to the state + cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm->gm); // send the move to the planner @@ -1580,7 +1585,7 @@ static void _exec_program_finalize(float *value, bool *flag) cm_reset_overrides(); // reset feedrate the spindle overrides temperature_reset(); // turn off all heaters and fans } - cm_set_work_offsets(MODEL); // reset work offsets for display porpoises + cm_set_display_offsets(MODEL); // reset work offsets for display porpoises sr_request_status_report(SR_REQUEST_IMMEDIATE); // request a final and full status report (not filtered) } @@ -1999,9 +2004,9 @@ stat_t cm_get_vel(nvObj_t *nv) } stat_t cm_get_feed(nvObj_t *nv) { return (get_float(nv, cm_get_feed_rate(ACTIVE_MODEL))); } -stat_t cm_get_pos(nvObj_t *nv) { return (get_float(nv, cm_get_work_position(ACTIVE_MODEL, _axis(nv)))); } +stat_t cm_get_pos(nvObj_t *nv) { return (get_float(nv, cm_get_display_position(ACTIVE_MODEL, _axis(nv)))); } stat_t cm_get_mpo(nvObj_t *nv) { return (get_float(nv, cm_get_absolute_position(ACTIVE_MODEL, _axis(nv)))); } -stat_t cm_get_ofs(nvObj_t *nv) { return (get_float(nv, cm_get_work_offset(ACTIVE_MODEL, _axis(nv)))); } +stat_t cm_get_ofs(nvObj_t *nv) { return (get_float(nv, cm_get_display_offset(ACTIVE_MODEL, _axis(nv)))); } stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state())); } stat_t cm_set_home(nvObj_t *nv) { return (set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } @@ -2010,8 +2015,8 @@ stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv)])); } stat_t cm_get_prob(nvObj_t *nv) { return(_get_msg_helper(nv, msg_probe, cm_get_probe_state())); } stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_axis(nv)])); } -stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->offset[_coord(nv)][_axis(nv)])); } -stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->offset[_coord(nv)][_axis(nv)])); } +stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } +stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv)])); } stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv)])); } @@ -2029,8 +2034,8 @@ static uint8_t _tool(nvObj_t *nv) return (atoi(&nv->token[2])); // ttNNx is all in the token } -stat_t cm_get_tof(nvObj_t *nv) { return (get_float(nv, cm->tl_offset[_axis(nv)])); } -stat_t cm_set_tof(nvObj_t *nv) { return (set_float(nv, cm->tl_offset[_axis(nv)])); } +stat_t cm_get_tof(nvObj_t *nv) { return (get_float(nv, cm->tool_offset[_axis(nv)])); } +stat_t cm_set_tof(nvObj_t *nv) { return (set_float(nv, cm->tool_offset[_axis(nv)])); } stat_t cm_get_tt(nvObj_t *nv) { diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index a951728c..0440a6eb 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -187,7 +187,7 @@ typedef struct cmArc { // planner and runtime variables for uint8_t run_state; // runtime state machine sequence float position[AXES]; // accumulating runtime position - float offset[3]; // arc IJK offsets + float ijk_offset[3]; // arc IJK offsets float length; // length of line or helix in mm float radius; // Raw R value, or computed via offsets @@ -227,8 +227,8 @@ typedef struct cmMachine { // struct to manage canonical machin bool safety_interlock_enable; // true to enable safety interlock system // Coordinate systems and offsets - float offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 - float tl_offset[AXES]; // current tool length offset + float coord_offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 + float tool_offset[AXES]; // current tool offset // Axis settings cfgAxis_t a[AXES]; @@ -334,11 +334,11 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ void cm_set_model_linenum(const uint32_t linenum); // Coordinate systems and offsets -float cm_get_active_coord_offset(const uint8_t axis, const bool absolute); -float cm_get_work_offset(const GCodeState_t *gcode_state, const uint8_t axis); -void cm_set_work_offsets(GCodeState_t *gcode_state); +float cm_get_combined_offset(const uint8_t axis); +float cm_get_display_offset(const GCodeState_t *gcode_state, const uint8_t axis); +void cm_set_display_offsets(GCodeState_t *gcode_state); +float cm_get_display_position(const GCodeState_t *gcode_state, const uint8_t axis); float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t axis); -float cm_get_work_position(const GCodeState_t *gcode_state, const uint8_t axis); // Critical helpers void cm_update_model_position_from_runtime(void); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index dff499ae..f9f3d420 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -160,20 +160,20 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsc",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed + { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group + { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Y homed + { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Z homed + { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // A homed + { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // B homed + { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed - { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state - { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results - { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results - { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results - { "prb","prba",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // A probe results - { "prb","prbb",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // B probe results - { "prb","prbc",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // C probe results + { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state + { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results + { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results + { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results + { "prb","prba",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // A probe results + { "prb","prbb",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // B probe results + { "prb","prbc",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // C probe results { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in X axis { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Y axis @@ -182,58 +182,8 @@ const cfgItem_t cfgArray[] = { { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in B axis { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in C axis - { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts + { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, -/*======= - { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position - - { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position - - { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset - { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset - { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Z work offset - { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // A work offset - { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset - { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset - - { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_01,(float *)&cm.homing_state, 0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_X], false }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_Y], false }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_Z], false }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_A], false }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_B], false }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_C], false }, // C homed - - { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_ro, (float *)&cm.probe_state[0], 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_X], 0 }, - { "prb","prby",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_Y], 0 }, - { "prb","prbz",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_Z], 0 }, - { "prb","prba",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_A], 0 }, - { "prb","prbb",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_B], 0 }, - { "prb","prbc",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_C], 0 }, - { "prb","prbr",_f0, 0, tx_print_nul, cm_get_prbr, cm_get_prbr, nullptr, 0 }, // enable probe report. Init in cm_init - - { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm.jogging_dest, 0}, - { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm.jogging_dest, 0}, - { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jogz, (float *)&cm.jogging_dest, 0}, - { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_joga, (float *)&cm.jogging_dest, 0}, -// { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jogb, (float *)&cm.jogging_dest, 0}, -// { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jogc, (float *)&cm.jogging_dest, 0}, - - { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts - { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, ->>>>>>> refs/heads/dev-237-probing-improvements -*/ #if (MOTORS > 2) { "pwr","pwr3",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, #endif diff --git a/g2core/gcode.h b/g2core/gcode.h index ddee1be2..048355c3 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -216,7 +216,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl float target[AXES]; // XYZABC where the move should go float target_comp[AXES]; // summation compensation (Kahan) overflow value - float work_offset[AXES]; // work offsets from the machine coordinate system (for reporting only) + float display_offset[AXES]; // work offsets from the machine coordinate system (for reporting only) float feed_rate; // F - normalized to millimeters/minute or in inverse time mode float P_word; // P - parameter used for dwell time in seconds, G10 coord select... @@ -238,7 +238,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl for (uint8_t i = 0; i< AXES; i++) { target[i] = 0.0; - work_offset[i] = 0.0; + display_offset[i] = 0.0; } feed_rate = 0.0; diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 8c651b03..4a61ea31 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -216,24 +216,24 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en // *** now get down to the rest of the work setting up the arc for execution *** cm->gm.motion_mode = motion_mode; - cm_set_work_offsets(&cm->gm); // capture the fully resolved offsets to gm + cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to gm memcpy(&(cm->arc.gm), &cm->gm, sizeof(GCodeState_t)); // copy GCode context to arc singleton - some will be overwritten to run segments copy_vector(cm->arc.position, cm->gmx.position); // set initial arc position from gcode model // setup offsets - cm->arc.offset[OFS_I] = _to_millimeters(offset[OFS_I]); // copy offsets with conversion to canonical form (mm) - cm->arc.offset[OFS_J] = _to_millimeters(offset[OFS_J]); - cm->arc.offset[OFS_K] = _to_millimeters(offset[OFS_K]); + cm->arc.ijk_offset[OFS_I] = _to_millimeters(offset[OFS_I]); // copy offsets with conversion to canonical form (mm) + cm->arc.ijk_offset[OFS_J] = _to_millimeters(offset[OFS_J]); + cm->arc.ijk_offset[OFS_K] = _to_millimeters(offset[OFS_K]); if (cm->arc.gm.arc_distance_mode == ABSOLUTE_DISTANCE_MODE) { // adjust offsets if in absolute mode - cm->arc.offset[OFS_I] -= cm->arc.position[AXIS_X]; - cm->arc.offset[OFS_J] -= cm->arc.position[AXIS_Y]; - cm->arc.offset[OFS_K] -= cm->arc.position[AXIS_Z]; + cm->arc.ijk_offset[OFS_I] -= cm->arc.position[AXIS_X]; + cm->arc.ijk_offset[OFS_J] -= cm->arc.position[AXIS_Y]; + cm->arc.ijk_offset[OFS_K] -= cm->arc.position[AXIS_Z]; } - if ((fp_ZERO(cm->arc.offset[OFS_I])) && // it's an error if no offsets are provided - (fp_ZERO(cm->arc.offset[OFS_J])) && - (fp_ZERO(cm->arc.offset[OFS_K]))) { + if ((fp_ZERO(cm->arc.ijk_offset[OFS_I])) && // it's an error if no offsets are provided + (fp_ZERO(cm->arc.ijk_offset[OFS_J])) && + (fp_ZERO(cm->arc.ijk_offset[OFS_K]))) { return (cm_alarm(STAT_ARC_OFFSETS_MISSING_FOR_SELECTED_PLANE, "arc offsets missing or zero")); } @@ -278,7 +278,7 @@ static stat_t _compute_arc(const bool radius_f) if (radius_f) { // indicates a radius arc _compute_arc_offsets_from_radius(); } else { // compute start radius - cm->arc.radius = hypotf(-cm->arc.offset[cm->arc.plane_axis_0], -cm->arc.offset[cm->arc.plane_axis_1]); + cm->arc.radius = hypotf(-cm->arc.ijk_offset[cm->arc.plane_axis_0], -cm->arc.ijk_offset[cm->arc.plane_axis_1]); } // Test arc specification for correctness according to: @@ -290,11 +290,11 @@ static stat_t _compute_arc(const bool radius_f) // Compute end radius from the center of circle (offsets) to target endpoint float end_0 = cm->arc.gm.target[cm->arc.plane_axis_0] - cm->arc.position[cm->arc.plane_axis_0] - - cm->arc.offset[cm->arc.plane_axis_0]; + cm->arc.ijk_offset[cm->arc.plane_axis_0]; float end_1 = cm->arc.gm.target[cm->arc.plane_axis_1] - cm->arc.position[cm->arc.plane_axis_1] - - cm->arc.offset[cm->arc.plane_axis_1]; + cm->arc.ijk_offset[cm->arc.plane_axis_1]; float err = fabs(hypotf(end_0, end_1) - cm->arc.radius); // end radius - start radius if ((err > ARC_RADIUS_ERROR_MAX) || @@ -305,7 +305,7 @@ static stat_t _compute_arc(const bool radius_f) // Compute the angular travel // Calculate the theta angle of the current position (theta is also needed for calculating center point) // Note: gcc atan2 reverses args, i.e.: atan2(Y,X) - cm->arc.theta = atan2(-cm->arc.offset[cm->arc.plane_axis_0], -cm->arc.offset[cm->arc.plane_axis_1]); + cm->arc.theta = atan2(-cm->arc.ijk_offset[cm->arc.plane_axis_0], -cm->arc.ijk_offset[cm->arc.plane_axis_1]); // Compute angular travel if not a full circle arc if (!cm->arc.full_circle) { @@ -470,9 +470,9 @@ static void _compute_arc_offsets_from_radius() } // Complete the operation by calculating the actual center of the arc - cm->arc.offset[cm->arc.plane_axis_0] = (x-(y*h_x2_div_d))/2; - cm->arc.offset[cm->arc.plane_axis_1] = (y+(x*h_x2_div_d))/2; - cm->arc.offset[cm->arc.linear_axis] = 0; + cm->arc.ijk_offset[cm->arc.plane_axis_0] = (x-(y*h_x2_div_d))/2; + cm->arc.ijk_offset[cm->arc.plane_axis_1] = (y+(x*h_x2_div_d))/2; + cm->arc.ijk_offset[cm->arc.linear_axis] = 0; } /* diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index b242761a..82be21d5 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -69,18 +69,18 @@ static void _set_bf_diagnostics(mpBuf_t* bf) { * mp_zero_segment_velocity() - correct velocity in last segment for reporting purposes * mp_get_runtime_velocity() - returns current velocity (aggregate) * mp_get_runtime_machine_position() - returns current axis position in machine coordinates - * mp_set_runtime_work_offset() - set offsets in the MR struct - * mp_get_runtime_work_position() - returns current axis position in work coordinates + * mp_set_runtime_display_offset() - set combined display offsets in the MR struct + * mp_get_runtime_display_position() - returns current axis position in work display coordinates * that were in effect at move planning time */ void mp_zero_segment_velocity() { mr->segment_velocity = 0; } float mp_get_runtime_velocity(void) { return (mr->segment_velocity); } float mp_get_runtime_absolute_position(mpPlannerRuntime_t *_mr, uint8_t axis) { return (_mr->position[axis]); } -void mp_set_runtime_work_offset(float offset[]) { copy_vector(mr->gm.work_offset, offset); } +void mp_set_runtime_display_offset(float offset[]) { copy_vector(mr->gm.display_offset, offset); } // We have to handle rotation - "rotate" by the transverse of the matrix to got "normal" coordinates -float mp_get_runtime_work_position(uint8_t axis) { +float mp_get_runtime_display_position(uint8_t axis) { // Shorthand: // target_rotated[0] = a x_1 + b x_2 + c x_3 // target_rotated[1] = a y_1 + b y_2 + c y_3 @@ -88,16 +88,16 @@ float mp_get_runtime_work_position(uint8_t axis) { if (axis == AXIS_X) { return mr->position[0] * cm->rotation_matrix[0][0] + mr->position[1] * cm->rotation_matrix[1][0] + - mr->position[2] * cm->rotation_matrix[2][0] - mr->gm.work_offset[0]; + mr->position[2] * cm->rotation_matrix[2][0] - mr->gm.display_offset[0]; } else if (axis == AXIS_Y) { return mr->position[0] * cm->rotation_matrix[0][1] + mr->position[1] * cm->rotation_matrix[1][1] + - mr->position[2] * cm->rotation_matrix[2][1] - mr->gm.work_offset[1]; + mr->position[2] * cm->rotation_matrix[2][1] - mr->gm.display_offset[1]; } else if (axis == AXIS_Z) { return mr->position[0] * cm->rotation_matrix[0][2] + mr->position[1] * cm->rotation_matrix[1][2] + - mr->position[2] * cm->rotation_matrix[2][2] - cm->rotation_z_offset - mr->gm.work_offset[2]; + mr->position[2] * cm->rotation_matrix[2][2] - cm->rotation_z_offset - mr->gm.display_offset[2]; } else { // ABC, UVW, we don't rotate them - return (mr->position[axis] - mr->gm.work_offset[axis]); + return (mr->position[axis] - mr->gm.display_offset[axis]); } } diff --git a/g2core/planner.h b/g2core/planner.h index 9a7d8f8a..1d7b4c68 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -591,8 +591,8 @@ bool mp_free_run_buffer(void); void mp_zero_segment_velocity(void); // getters and setters... float mp_get_runtime_velocity(void); float mp_get_runtime_absolute_position(mpPlannerRuntime_t *_mr, uint8_t axis); -float mp_get_runtime_work_position(uint8_t axis); -void mp_set_runtime_work_offset(float offset[]); +float mp_get_runtime_display_position(uint8_t axis); +void mp_set_runtime_display_offset(float offset[]); bool mp_get_runtime_busy(void); bool mp_runtime_is_idle(void); diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index c33132e7..7ef5eafe 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -133,11 +133,6 @@ #define PROBE_REPORT_ENABLE true // {prbr: #endif -/* - * The following is to fix an issue where feedrate override was being defined in some users - * settings files but not others. This would otherwise cause an undefined compile error. - * -*/ #ifndef MANUAL_FEEDRATE_OVERRIDE_ENABLE #define MANUAL_FEEDRATE_OVERRIDE_ENABLE false #endif From 28bc3326746b1b5f91931e4fcb54ebc2746080df Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 9 Feb 2017 13:02:23 -0500 Subject: [PATCH 129/283] Fixed bug where G53 was not moving and displaying correctly --- g2core/canonical_machine.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8d371ffe..fac873e2 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -432,6 +432,9 @@ void cm_set_model_linenum(const uint32_t linenum) float cm_get_combined_offset(const uint8_t axis) { + if (cm->gm.absolute_override >= ABSOLUTE_OVERRIDE_ON) { + return (0); + } float offset = cm->coord_offset[cm->gm.coord_system][axis] + cm->tool_offset[axis]; if (cm->gmx.origin_offset_enable == true) { offset += cm->gmx.origin_offset[axis]; @@ -451,10 +454,17 @@ void cm_set_display_offsets(GCodeState_t *gcode_state) // if absolute override is on and position is to be displayed with no offsets if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_AND_DISPLAY) { gcode_state->display_offset[axis] = 0; - } else { - gcode_state->display_offset[axis] = cm_get_combined_offset(axis); + } + + // if position is to be displayed with currently active offsets + else { + gcode_state->display_offset[axis] = cm->coord_offset[cm->gm.coord_system][axis] + + cm->tool_offset[axis]; + if (cm->gmx.origin_offset_enable == true) { + gcode_state->display_offset[axis] += cm->gmx.origin_offset[axis]; + } } - } + } } /* From e9b6492dbf318dedcccbeb9133c1a506e36d457c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 9 Feb 2017 13:45:58 -0500 Subject: [PATCH 130/283] Minor commit --- g2core/canonical_machine.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index fac873e2..b7b78512 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -368,7 +368,7 @@ void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool) void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override) { gcode_state->absolute_override = (cmAbsoluteOverride)absolute_override; - cm_set_display_offsets(MODEL); // must reset offsets if you change absolute override + cm_set_display_offsets(MODEL); // must reset offsets if you change absolute override } void cm_set_model_linenum(const uint32_t linenum) @@ -451,12 +451,12 @@ void cm_set_display_offsets(GCodeState_t *gcode_state) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - // if absolute override is on and position is to be displayed with no offsets + // if absolute override is on for G53 so position should be displayed with no offsets if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_AND_DISPLAY) { gcode_state->display_offset[axis] = 0; } - // if position is to be displayed with currently active offsets + // all other cases: position should be displayed with currently active offsets else { gcode_state->display_offset[axis] = cm->coord_offset[cm->gm.coord_system][axis] + cm->tool_offset[axis]; @@ -864,8 +864,7 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, if ((L_word == 2) || (L_word == 20)) { // coordinate system offset command if ((P_word < G54) || (P_word > COORD_SYSTEM_MAX)) { - // you can't set G53 - return (STAT_P_WORD_IS_INVALID); + return (STAT_P_WORD_IS_INVALID); // you can't set G53 } for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { @@ -877,29 +876,25 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, _to_millimeters(offset[axis]) - cm->tool_offset[axis]; } - // persist offsets once machining cycle is over - cm->deferred_write_flag = true; + cm->deferred_write_flag = true; // persist offsets once machining cycle is over } } } else if ((L_word == 1) || (L_word == 10)) { - // tool table offset command. L11 not supported atm. - if ((P_word < 1) || (P_word > TOOLS)) { + if ((P_word < 1) || (P_word > TOOLS)) { // tool table offset command. L11 not supported atm. return (STAT_P_WORD_IS_INVALID); } for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { if (L_word == 1) { tt.tt_offset[P_word][axis] = _to_millimeters(offset[axis]); - } else { - // L10 should also take into account G92 offset + } else { // L10 should also take into account G92 offset tt.tt_offset[P_word][axis] = cm->gmx.position[axis] - _to_millimeters(offset[axis]) - cm->coord_offset[cm->gm.coord_system][axis] - (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); } - // persist offsets once machining cycle is over - cm->deferred_write_flag = true; + cm->deferred_write_flag = true; // persist offsets once machining cycle is over } } } @@ -1128,7 +1123,6 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { return(STAT_OK); } - cm_set_model_target(target, flags); ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to the state @@ -1341,6 +1335,7 @@ stat_t cm_change_tool(const uint8_t tool_change) static void _exec_change_tool(float *value, bool *flag) { cm->gm.tool = (uint8_t)value[0]; + // TODO - change tool offsets and update display offsets } /*********************************************************************************** @@ -1595,7 +1590,6 @@ static void _exec_program_finalize(float *value, bool *flag) cm_reset_overrides(); // reset feedrate the spindle overrides temperature_reset(); // turn off all heaters and fans } - cm_set_display_offsets(MODEL); // reset work offsets for display porpoises sr_request_status_report(SR_REQUEST_IMMEDIATE); // request a final and full status report (not filtered) } From e7fb4cd6723ab57012e73f73b411e74b6687cd31 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 13 Feb 2017 13:41:23 -0500 Subject: [PATCH 131/283] Fixed reversed move coming out of hold-flush. Look in planner.cpp / planner_reset() for fix.; removed some legacy +++++ comments --- g2core/canonical_machine.cpp | 2 +- g2core/controller.cpp | 4 ++-- g2core/cycle_homing.cpp | 2 +- g2core/gpio.cpp | 3 +-- g2core/plan_arc.cpp | 2 +- g2core/plan_exec.cpp | 4 ++-- g2core/plan_line.cpp | 8 ++++---- g2core/plan_zoid.cpp | 6 +++--- g2core/planner.cpp | 36 +++++++++++++++++------------------- g2core/planner.h | 8 ++++---- g2core/report.cpp | 6 +++--- 11 files changed, 39 insertions(+), 42 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index b7b78512..e9e017fb 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -573,7 +573,7 @@ stat_t cm_set_tram(nvObj_t *nv) // if passed false/0, we will clear the rotation matrix if (!do_set) { - canonical_machine_reset_rotation(cm); //++++++ + canonical_machine_reset_rotation(cm); return (STAT_OK); } diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 4d701bb5..5d6df1c3 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -201,7 +201,7 @@ static stat_t _dispatch_command() { if (cs.controller_state != CONTROLLER_PAUSED) { devflags_t flags = DEV_IS_BOTH | DEV_IS_MUTED; // expressly state we'll handle muted devices - if ((!mp_planner_is_full(mp)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { //+++++ + if ((!mp_planner_is_full(mp)) && (cs.bufp = xio_readline(flags, cs.linelen)) != NULL) { _dispatch_kernel(flags); } } @@ -377,7 +377,7 @@ static stat_t _sync_to_tx_buffer() static stat_t _sync_to_planner() { - if (mp_planner_is_full(mp)) { // allow up to N planner buffers for this line //+++++ + if (mp_planner_is_full(mp)) { // allow up to N planner buffers for this line return (STAT_EAGAIN); } return (STAT_OK); diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index b041cbc3..b0521b32 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -174,7 +174,7 @@ stat_t cm_homing_cycle_start(const float axes[], const bool flags[]) { hm.set_coordinates = true; // clear rotation matrix - canonical_machine_reset_rotation(cm); //+++++ cleanup + canonical_machine_reset_rotation(cm); hm.axis = -1; // set to retrieve initial axis hm.func = _homing_axis_start; // bind initial processing function diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index ad45527a..d8f6a14e 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -210,8 +210,7 @@ struct ioDigitalInputExt { cm->safety_interlock_reengaged = ext_pin_number; } } - - sr_request_status_report(SR_REQUEST_TIMED); //+++++ Put this one back in. + sr_request_status_report(SR_REQUEST_TIMED); }; }; diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 4a61ea31..013b3a05 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -72,7 +72,7 @@ stat_t cm_arc_callback(cmMachine_t *_cm) if (_cm->arc.run_state == BLOCK_INACTIVE) { return (STAT_NOOP); } - if (mp_planner_is_full(mp)) { //+++++ + if (mp_planner_is_full(mp)) { return (STAT_EAGAIN); } _cm->arc.theta += _cm->arc.segment_theta; diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index a1de3372..55f1f7c8 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -36,7 +36,7 @@ #include "report.h" #include "util.h" #include "spindle.h" -#include "xio.h" //+++++DIAGNOSTIC +#include "xio.h" // DIAGNOSTIC // execute routines (NB: These are all called from the LO interrupt) static stat_t _exec_aline_head(mpBuf_t *bf); // passing bf because body might need it, and it might call body @@ -494,7 +494,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) } else { // Uh oh! We have a move that's all body, and is still too short!! - // while (1); // ++++ RG For now, we'll consider this impossible. + // while (1); // RG: For now, we'll consider this impossible. cs.exec_aline_assertion_failure = true; return (STAT_EXEC_ALINE_ASSERTION_FAILURE); } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 82be21d5..6f889353 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -55,12 +55,12 @@ static void _calculate_jerk(mpBuf_t* bf); static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const float axis_square[]); static void _calculate_junction_vmax(mpBuf_t* bf); -//+++++DIAGNOSTICS +// DIAGNOSTICS #pragma GCC optimize("O0") // this pragma is required to force the planner to actually set these unused values //#pragma GCC reset_options static void _set_bf_diagnostics(mpBuf_t* bf) { bf->linenum = bf->gm.linenum; -// UPDATE_BF_DIAGNOSTICS(bf); //+++++ +// UPDATE_BF_DIAGNOSTICS(bf); } #pragma GCC reset_options @@ -222,7 +222,7 @@ stat_t mp_aline(GCodeState_t* gm_in) } _calculate_jerk(bf); // compute bf->jerk values _calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax - _set_bf_diagnostics(bf); //+++++DIAGNOSTIC + _set_bf_diagnostics(bf); // DIAGNOSTIC // Note: these next lines must remain in exact order. Position must update before committing the buffer. copy_vector(mp->position, bf->gm.target); // set the planner position @@ -263,7 +263,7 @@ void mp_plan_block_list() bf = _plan_block(bf); // returns next block to plan planned_something = true; - mp->p = bf; //+++++ DIAGNOSTIC - this is not needed but is set here for debugging purposes + mp->p = bf; // DIAGNOSTIC - this is not needed but is set here for debugging purposes } if (mp->planner_state > PLANNER_STARTUP) { if (planned_something && (cm->hold_state != FEEDHOLD_HOLD)) { diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 36dedc0b..f61df292 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -32,7 +32,7 @@ #include "report.h" #include "util.h" -//+++++ DIAGNOSTICS +// DIAGNOSTICS //#if IN_DEBUGGER < 1 #define LOG_RETURN(msg) // LOG_RETURN with no action (production) @@ -60,7 +60,7 @@ } #endif -//+++++ END DIAGNOSTICS +// END DIAGNOSTICS /* local functions */ @@ -116,7 +116,7 @@ static float _get_meet_velocity(const float v_0, void _zoid_exit(mpBuf_t* bf, zoidExitPoint exit_point) { - //+++++ DIAGNOSTIC + // DIAGNOSTIC // bf->zoid_exit = exit_point; if (mp_runtime_is_idle()) { // normally the runtime keeps this value fresh // bf->time_in_plan_ms += bf->block_time_ms; diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 8224af74..38e2fc74 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -62,7 +62,7 @@ #include "report.h" #include "util.h" #include "json_parser.h" -#include "xio.h" //+++++ DIAGNOSTIC - only needed if xio_writeline() direct prints are used +#include "xio.h" // DIAGNOSTIC - only needed if xio_writeline() direct prints are used // Allocate planner structures @@ -193,18 +193,17 @@ void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uin memset(_mr, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status _mr->magic_start = MAGICNUM; // mr assertions _mr->magic_end = MAGICNUM; - - _mr->bf[0].nx = &_mr->bf[1]; // Handle the two "stub blocks" in the runtime structure. + + _mr->bf[0].nx = &_mr->bf[1]; // Handle the two "stub blocks" in the runtime structure _mr->bf[1].nx = &_mr->bf[0]; _mr->r = &_mr->bf[0]; _mr->p = &_mr->bf[1]; } -void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR activity, but leave positions alone +void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR activity, but leave positions alone { -// planner_init(_mp, _mp->mr, _mp->q.bf, _mp->q.queue_size); // reset parent planner and linked Q and MR -// _mp->mr.block_state == BLOCK_INACTIVE; _init_planner_queue(_mp, _mp->q.bf, _mp->q.queue_size); + _mp->mr->block_state = BLOCK_INACTIVE; // this resets the MR structure without actually wiping it } stat_t planner_test_assertions(const mpPlanner_t *_mp) @@ -528,8 +527,7 @@ bool mp_is_phat_city_time() stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state -// if ((mp_get_planner_buffers(mp) == PLANNER_BUFFER_POOL_SIZE) && //+++++ // detect and set IDLE state - if ((mp_get_planner_buffers(mp) == mp->q.queue_size) && //+++++ // detect and set IDLE state + if ((mp_get_planner_buffers(mp) == mp->q.queue_size) && // detect and set IDLE state (cm->motion_state == MOTION_STOP) && (cm->hold_state == FEEDHOLD_OFF)) { mp->planner_state = PLANNER_IDLE; @@ -547,11 +545,11 @@ stat_t mp_planner_callback() // Process a planner request or timeout if (mp->planner_state == PLANNER_IDLE) { - mp->p = mp_get_r(); //+++++ // initialize planner pointer to run buffer + mp->p = mp_get_r(); // initialize planner pointer to run buffer mp->planner_state = PLANNER_STARTUP; } if (mp->planner_state == PLANNER_STARTUP) { - if (!mp_planner_is_full(mp) && !_timed_out) { //+++++ + if (!mp_planner_is_full(mp) && !_timed_out) { return (STAT_OK); // remain in STARTUP } mp->planner_state = PLANNER_PRIMING; @@ -574,7 +572,7 @@ void mp_replan_queue(mpBuf_t *bf) } else { // If it's not "planned" then it's either PREPPED or earlier. break; // We don't need to adjust it. } - } while ((bf = mp_get_next_buffer(bf)) != mp_get_r()); //+++++ + } while ((bf = mp_get_next_buffer(bf)) != mp_get_r()); mp->request_planning = true; } @@ -641,20 +639,20 @@ void mp_end_traverse_override(const float ramp_time) void mp_planner_time_accounting() { - mpBuf_t *bf = mp_get_r(); //+++++ // start with run buffer + mpBuf_t *bf = mp_get_r(); // start with run buffer // check the run buffer to see if anything is running. Might not be if (bf->buffer_state != MP_BUFFER_RUNNING) { // this is not an error condition return; } - mp->plannable_time = 0; //UPDATE_BF_MS(bf); //+++++ - while ((bf = bf->nx) != mp_get_r()) { //+++++ + mp->plannable_time = 0; //UPDATE_BF_MS(bf); // DIAGNOSTIC + while ((bf = bf->nx) != mp_get_r()) { if (bf->buffer_state == MP_BUFFER_EMPTY || bf->plannable == true) { break; } mp->plannable_time += bf->block_time; } - UPDATE_MP_DIAGNOSTICS //+++++ + UPDATE_MP_DIAGNOSTICS // DIAGNOSTIC } /**** PLANNER BUFFER PRIMITIVES ************************************************************ @@ -745,8 +743,8 @@ mpBuf_t * mp_get_prev_buffer(const mpBuf_t *bf) { return (bf->pv); } mpBuf_t * mp_get_next_buffer(const mpBuf_t *bf) { return (bf->nx); } */ -mpBuf_t * mp_get_w() { return (mp->q.w); } //++++ should this be a DI function? -mpBuf_t * mp_get_r() { return (mp->q.r); } //+++++ ditto +mpBuf_t * mp_get_w() { return (mp->q.w); } +mpBuf_t * mp_get_r() { return (mp->q.r); } mpBuf_t * mp_get_write_buffer() // get & clear a buffer { @@ -754,7 +752,7 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state == MP_BUFFER_EMPTY) { - _clear_buffer(q->w); // ++++RG this is redundant, it was just cleared in mp_free_run_buffer + _clear_buffer(q->w); // RG: this is redundant, it was just cleared in mp_free_run_buffer q->w->buffer_state = MP_BUFFER_INITIALIZING; q->buffers_available--; return (mp_get_w()); @@ -828,7 +826,7 @@ bool mp_free_run_buffer() // EMPTY current run buffer & advance to the mpBuf_t *r_now = q->r; // save this pointer is to avoid a race condition when clearing the buffer - _audit_buffers(); // ++++diagnostic audit for buffer chain integrity (only runs in DEBUG mode) + _audit_buffers(); // DIAGNOSTIC audit for buffer chain integrity (only runs in DEBUG mode) q->r = q->r->nx; // advance to next run buffer first, _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) diff --git a/g2core/planner.h b/g2core/planner.h index 1d7b4c68..1fd94b46 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -309,19 +309,19 @@ typedef struct mpBuffer { // *** CAUTION *** These two pointers are not reset by _clear_buffer() struct mpBuffer *pv; // static pointer to previous buffer struct mpBuffer *nx; // static pointer to next buffer - uint8_t buffer_number; //+++++ DIAGNOSTIC for easier debugging + uint8_t buffer_number; // DIAGNOSTIC for easier debugging stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function cm_exec_t cm_func; // callback to canonical machine execution function - //+++++ DIAGNOSTICS for easier debugging + // DIAGNOSTICS for easier debugging... uint32_t linenum; // mirror of bf->gm.linenum int iterations; float block_time_ms; float plannable_time_ms; // time in planner float plannable_length; // length in planner uint8_t meet_iterations; // iterations needed in _get_meet_velocity - //+++++ to here + //...to here bufferState buffer_state; // used to manage queuing/dequeuing blockType block_type; // used to dispatch to run routine @@ -480,7 +480,7 @@ typedef struct mpPlannerRuntime { // persistent runtime variables typedef struct mpPlanner { // common variables for a planner context magic_t magic_start; // magic number to test memory integrity - //+++++ DIAGNOSTICS + // DIAGNOSTICS float run_time_remaining_ms; float plannable_time_ms; diff --git a/g2core/report.cpp b/g2core/report.cpp index 7a7b24f3..89076606 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -2,7 +2,7 @@ * report.cpp - Status reports and other reporting functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -487,7 +487,7 @@ void qr_init_queue_report() void qr_request_queue_report(int8_t buffers) { // get buffer depth and added/removed count - qr.buffers_available = mp_get_planner_buffers(mp); //+++++ + qr.buffers_available = mp_get_planner_buffers(mp); if (buffers > 0) { qr.buffers_added += buffers; } else { @@ -571,7 +571,7 @@ stat_t qr_queue_report_callback() // called by controller dispatcher */ stat_t qr_get(nvObj_t *nv) { - nv->value = (float)mp_get_planner_buffers(mp); //+++++ // ensure that manually requested QR count is always up to date + nv->value = (float)mp_get_planner_buffers(mp); // ensure that manually requested QR count is always up to date nv->valuetype = TYPE_INT; return (STAT_OK); } From 22737fd75fa775f2267d257b7f2ee6252afd0fe4 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 15 Feb 2017 13:20:10 -0500 Subject: [PATCH 132/283] =?UTF-8?q?Optimistically,=20Issue=20#33=20is=20fi?= =?UTF-8?q?xed.=20Still=20has=20a=20whole=20lot=20of=20diagnostics=20enabl?= =?UTF-8?q?ed=20that=20would=20blow=20up=20the=20JSON=20parser,=20and=20it?= =?UTF-8?q?=20has=20not=20been=20well=20tested=20yet.=20So=20don=E2=80=99t?= =?UTF-8?q?=20use=20this.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/canonical_machine.cpp | 4 ++- g2core/canonical_machine.h | 3 +- g2core/controller.cpp | 11 +++--- g2core/cycle_feedhold.cpp | 33 ++++++++++++++--- g2core/gcode_parser.cpp | 16 ++++----- g2core/plan_line.cpp | 11 +++--- g2core/plan_zoid.cpp | 14 +++----- g2core/planner.cpp | 28 +++++++++++---- g2core/planner.h | 53 +++++++++++++++++++++++++--- g2core/settings/settings_makeblock.h | 14 ++++---- g2core/util.cpp | 21 +++++++++++ g2core/util.h | 3 ++ 12 files changed, 159 insertions(+), 52 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index e9e017fb..0a3b7ce5 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -833,6 +833,7 @@ stat_t cm_set_units_mode(const uint8_t mode) stat_t cm_set_distance_mode(const uint8_t mode) { cm->gm.distance_mode = (cmDistanceMode)mode; // 0 = absolute mode, 1 = incremental + LAGER_cm("set distance mode"); return (STAT_OK); } @@ -1273,7 +1274,8 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) } cm->gm.motion_mode = MOTION_MODE_STRAIGHT_FEED; - if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { + if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | + flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { return(STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 0440a6eb..3caf0d54 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -439,9 +439,10 @@ stat_t cm_json_wait(char *json_string); // M102 // Feedhold and related functions (cycle_feedhold.cpp) void cm_request_feedhold(void); -void cm_request_end_hold(void); +void cm_request_exit_hold(void); void cm_request_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests +stat_t cm_feedhold_command_blocker(void); bool cm_has_hold(void); // has hold in primary planner void cm_start_hold(void); // starts hold in primary planner diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 5d6df1c3..4ab3c705 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -166,7 +166,8 @@ static void _controller_HSM() DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle - +// DISPATCH(cm_feedhold_command_blocker()); // blocks new commands from arriving while in feedhold + //----- command readers and parsers --------------------------------------------------// DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue @@ -237,7 +238,7 @@ static void _dispatch_kernel(const devflags_t flags) // trap single character commands if (*cs.bufp == '!') { cm_request_feedhold(); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } - else if (*cs.bufp == '~') { cm_request_end_hold(); } + else if (*cs.bufp == '~') { cm_request_exit_hold(); } else if (*cs.bufp == EOT) { cm_alarm(STAT_KILL_JOB, "EOT Received"); } else if (*cs.bufp == ENQ) { controller_request_enquiry(); } else if (*cs.bufp == CAN) { hw_hard_reset(); } // reset immediately @@ -440,10 +441,8 @@ static stat_t _interlock_handler(void) // interlock restored if ((cm->safety_interlock_reengaged != 0) && (mp_runtime_is_idle())) { cm->safety_interlock_reengaged = 0; - cm->safety_interlock_state = SAFETY_INTERLOCK_ENGAGED; // interlock restored - // restart spindle with dwell - cm_request_end_hold(); // use cm_request_end_hold() instead of just ending - // restart coolant + cm->safety_interlock_state = SAFETY_INTERLOCK_ENGAGED; // interlock restored + cm_request_exit_hold(); // use cm_request_exit_hold() instead of just ending } } return(STAT_OK); diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index e4c059d7..692cf6e3 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -36,6 +36,7 @@ #include "spindle.h" #include "coolant.h" #include "util.h" +#include "xio.h" // DIAGNOSTIC static stat_t _run_p1_hold_entry_actions(void); static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); @@ -142,7 +143,7 @@ void cm_start_hold() /*********************************************************************************** * cm_request_feedhold() - * cm_request_end_hold() + * cm_request_exit_hold() * cm_request_queue_flush() * * p1 is the primary planner, p2 is the secondary planner, which is active if the @@ -167,30 +168,34 @@ void cm_start_hold() * Any executing or pending "in-hold" moves are stopped prior to the exit actions */ -void cm_request_feedhold(void) +void cm_request_feedhold(void) // ! { // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { cm1.hold_state = FEEDHOLD_REQUESTED; + LAGER("p1 request feedhold"); } else if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { cm2.hold_state = FEEDHOLD_REQUESTED; + LAGER("p2 - request feedhold"); } } -void cm_request_end_hold(void) +void cm_request_exit_hold(void) // ~ { if (cm1.hold_state != FEEDHOLD_OFF) { cm1.hold_exit_requested = true; + LAGER_cm("request exit hold"); } } -void cm_request_queue_flush() +void cm_request_queue_flush() // % { // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm1.flush_state == FLUSH_OFF)) { // ...and only once cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + LAGER_cm("request queue flush"); } } @@ -211,33 +216,47 @@ void cm_request_queue_flush() * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) */ +stat_t cm_feedhold_command_blocker() +{ + if (cm1.hold_state != FEEDHOLD_OFF) { + return (STAT_EAGAIN); + } + return (STAT_OK); +} + stat_t cm_feedhold_sequencing_callback() { // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_REQUESTED) { if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here + LAGER("p1 start feedhold"); cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions + LAGER("p1 start enter hold actions"); _run_p1_hold_entry_actions(); + LAGER("p1 complete enter hold actions"); } // p2 feedhold states - feedhold in feedhold if (cm2.hold_state == FEEDHOLD_REQUESTED) { if (mp_has_runnable_buffer(&mp2)) { + LAGER("p2 start feedhold"); cm_set_motion_state(MOTION_HOLD); cm2.hold_state = FEEDHOLD_SYNC; } } if (cm2.hold_state == FEEDHOLD_P2_EXIT) { + LAGER("p2 exit feedhold"); return(_finalize_p2_hold_exit()); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && (mp_runtime_is_idle())) { // don't flush planner during movement + LAGER("p1 queue flush"); cm_queue_flush(&cm1); cm1.hold_exit_requested = true; // p1 queue flush always ends the hold qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available @@ -251,11 +270,14 @@ stat_t cm_feedhold_sequencing_callback() return (STAT_OK); } if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold + LAGER("p1 start exit hold actions"); cm1.hold_exit_requested = false; _run_p1_hold_exit_actions(); // runs once only + LAGER("p1 complete exit hold actions"); } } if (cm1.hold_state == FEEDHOLD_P1_EXIT) { + LAGER("p1 finalize hold"); return(_finalize_p1_hold_exit()); // run multiple times until actions are complete } return (STAT_OK); @@ -317,6 +339,8 @@ static stat_t _run_p1_hold_entry_actions() } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause + + LAGER_cm("mp_queue_command entry actions done"); mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); return (STAT_OK); } @@ -330,6 +354,7 @@ static stat_t _run_p1_hold_entry_actions() static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD; + LAGER("p1 hold_state = FEEDHOLD_HOLD"); } /*********************************************************************************** diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 8fab3c1d..bddcadae 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -821,24 +821,24 @@ static stat_t _execute_gcode_block(char *active_comment) case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 - case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 - case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 -// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 + case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 + case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 +// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 case NEXT_ACTION_DEFAULT: { cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override & display as absolute switch (gv.motion_mode) { - case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gv.motion_mode; break;} // G80 + case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gv.motion_mode; break;} // G80 case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gv.target, gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target); break;} // G1 - case MOTION_MODE_CW_ARC: // G2 - case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gv.target, gf.target, // G3 + case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target); break;} // G1 + case MOTION_MODE_CW_ARC: // G2 + case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gv.target, gf.target, // G3 gv.arc_offset, gf.arc_offset, gv.arc_radius, gf.arc_radius, gv.P_word, gf.P_word, gp.modals[MODAL_GROUP_G1], gv.motion_mode); - break; + break; } default: break; } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 6f889353..9d8dd7fe 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -55,14 +55,15 @@ static void _calculate_jerk(mpBuf_t* bf); static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const float axis_square[]); static void _calculate_junction_vmax(mpBuf_t* bf); -// DIAGNOSTICS +#ifdef __PLANNER_DIAGNOSTICS #pragma GCC optimize("O0") // this pragma is required to force the planner to actually set these unused values -//#pragma GCC reset_options static void _set_bf_diagnostics(mpBuf_t* bf) { - bf->linenum = bf->gm.linenum; -// UPDATE_BF_DIAGNOSTICS(bf); + UPDATE_BF_DIAGNOSTICS(bf); } #pragma GCC reset_options +#else +static void _set_bf_diagnostics(mpBuf_t* bf) {} +#endif /* Runtime-specific setters and getters * @@ -324,7 +325,7 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) for (; bf->plannable || (braking_velocity < bf->exit_velocity); bf = bf->pv) { // Timings from *here* - bf->iterations++; + INC_PLANNER_ITERATIONS // DIAGNOSTIC bf->plannable = bf->plannable && !optimal; // Don't accidentally enable plannable! // Let's be mindful that forward planning may change exit_vmax, and our exit velocity may be lowered diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index f61df292..943b4216 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -116,15 +116,15 @@ static float _get_meet_velocity(const float v_0, void _zoid_exit(mpBuf_t* bf, zoidExitPoint exit_point) { - // DIAGNOSTIC +#ifdef __PLANNER_DIAGNOSTICS // bf->zoid_exit = exit_point; if (mp_runtime_is_idle()) { // normally the runtime keeps this value fresh - // bf->time_in_plan_ms += bf->block_time_ms; +// bf->time_in_plan_ms += bf->block_time_ms; bf->plannable_time_ms += bf->block_time_ms; } +#endif } - // Hint will be one of these from back-planning: COMMAND_BLOCK, PERFECT_DECELERATION, PERFECT_CRUISE, // MIXED_DECELERATION, ASYMMETRIC_BUMP // We are incorporating both the forward planning and ramp-planning into one function, since we use the same data. @@ -501,9 +501,7 @@ static float _get_meet_velocity(const float v_0, block->head_length = L / 2.0; block->body_length = 0; block->tail_length = L - block->head_length; - - bf->meet_iterations = -1; - + SET_PLANNER_ITERATIONS(-1); // DIAGNOSTIC return v_1; } @@ -587,8 +585,6 @@ static float _get_meet_velocity(const float v_0, v_1 = v_1 - (l_c * recip_l_d); } - - bf->meet_iterations = i; - + SET_MEET_ITERATIONS(i); // DIAGNOSTIC return v_1; } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 38e2fc74..a706cb94 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -202,8 +202,13 @@ void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uin void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR activity, but leave positions alone { + // selectively reset mpPlanner and mpPlannerRuntime w/o actually wiping them + _mp->reset(); + _mp->mr->reset(); +// _mp->mr->block_state = BLOCK_INACTIVE; // this resets the MR structure without actually wiping it + + // completely reset the planner queue _init_planner_queue(_mp, _mp->q.bf, _mp->q.queue_size); - _mp->mr->block_state = BLOCK_INACTIVE; // this resets the MR structure without actually wiping it } stat_t planner_test_assertions(const mpPlanner_t *_mp) @@ -490,7 +495,7 @@ bool mp_is_phat_city_time() return ((mp->plannable_time <= 0.0) || (PHAT_CITY_TIME < mp->plannable_time)); } -/* +/*********************************************************************************** * mp_planner_callback() * * mp_planner_callback()'s job is to invoke backward planning intelligently. @@ -508,7 +513,8 @@ bool mp_is_phat_city_time() * * - _plan_block() is the backward planning function for a single buffer. * - * - Just-in-time forward planning is performed by mp_plan_move() in the plan_exec.cpp runtime executive + * - Just-in-time forward planning is performed by mp_plan_move() in the + * plan_exec.cpp runtime executive * * Some Items to note: * @@ -528,8 +534,8 @@ stat_t mp_planner_callback() { // Test if the planner has transitioned to an IDLE state if ((mp_get_planner_buffers(mp) == mp->q.queue_size) && // detect and set IDLE state - (cm->motion_state == MOTION_STOP) && - (cm->hold_state == FEEDHOLD_OFF)) { + (cm->motion_state == MOTION_STOP) && (cm->hold_state == FEEDHOLD_OFF)) { + if (mp->planner_state != PLANNER_IDLE) { LAGER_cm("Planner entering IDLE state");} mp->planner_state = PLANNER_IDLE; return (STAT_OK); } @@ -537,6 +543,7 @@ stat_t mp_planner_callback() bool _timed_out = mp->block_timeout.isPast(); if (_timed_out) { mp->block_timeout.clear(); // timer is set on commit_write_buffer() + LAGER_cm("Blocks timed out"); } if (!mp->request_planning && !_timed_out) { // Exit if no request or timeout @@ -547,12 +554,14 @@ stat_t mp_planner_callback() if (mp->planner_state == PLANNER_IDLE) { mp->p = mp_get_r(); // initialize planner pointer to run buffer mp->planner_state = PLANNER_STARTUP; + LAGER_cm("Planner entering STARTUP state"); } if (mp->planner_state == PLANNER_STARTUP) { if (!mp_planner_is_full(mp) && !_timed_out) { return (STAT_OK); // remain in STARTUP } mp->planner_state = PLANNER_PRIMING; + LAGER_cm("Planner entering PRIMING state"); } mp_plan_block_list(); return (STAT_OK); @@ -798,8 +807,15 @@ void mp_commit_write_buffer(const blockType block_type) q->w->plannable = true; // enable block for planning mp->request_planning = true; q->w = q->w->nx; // advance write buffer pointer - mp->block_timeout.set(BLOCK_TIMEOUT_MS); // reset the block timer + mp->block_timeout.set(BLOCK_TIMEOUT_MS);// reset the block timer qr_request_queue_report(+1); // request QR and add to "added buffers" count + + char msg[64]; + sprintf(msg, "commit buffer:%d block state:%d timeout.isPast:%d", + q->w->buffer_number, + q->w->block_state, + mp->block_timeout.isPast()); + LAGER_cm(msg); } // Note: mp_get_run_buffer() is only called by mp_exec_move(), which is inside an interrupt diff --git a/g2core/planner.h b/g2core/planner.h index 1fd94b46..f6dbf389 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -288,10 +288,30 @@ typedef enum { /* Diagnostics */ -//#define ASCII_ART(s) xio_writeline(s) +//#define __PLANNER_DIAGNOSTICS // comment this out to drop diagnostics + +#ifdef __PLANNER_DIAGNOSTICS +#define ASCII_ART(s) xio_writeline(s) + +#define UPDATE_BF_DIAGNOSTICS(bf) { bf->linenum = bf->gm.linenum; \ + bf->block_time_ms = bf->block_time*60000; \ + bf->plannable_time_ms = bf->plannable_time*60000; } + +#define UPDATE_MP_DIAGNOSTICS { mp->plannable_time_ms = mp->plannable_time*60000; } +#define SET_PLANNER_ITERATIONS(i) { bf->iterations = i; } +#define INC_PLANNER_ITERATIONS { bf->iterations++; } +#define SET_MEET_ITERATIONS(i) { bf->meet_iterations = i; } +#define INC_MEET_ITERATIONS { bf->meet_iterations++; } + +#else #define ASCII_ART(s) -//#define UPDATE_BF_DIAGNOSTICS(bf) { bf->block_time_ms = bf->block_time*60000; bf->plannable_time_ms = bf->plannable_time*60000; } -#define UPDATE_MP_DIAGNOSTICS { mp->plannable_time_ms = mp->plannable_time*60000; } +#define UPDATE_BF_DIAGNOSTICS +#define UPDATE_MP_DIAGNOSTICS +#define SET_PLANNER_ITERATIONS(i) +#define INC_PLANNER_ITERATIONS +#define SET_MEET_ITERATIONS(i) +#define INC_MEET_ITERATIONS +#endif /* * Planner structures @@ -314,14 +334,14 @@ typedef struct mpBuffer { stat_t (*bf_func)(struct mpBuffer *bf); // callback to buffer exec function cm_exec_t cm_func; // callback to canonical machine execution function - // DIAGNOSTICS for easier debugging... +#ifdef __PLANNER_DIAGNOSTICS uint32_t linenum; // mirror of bf->gm.linenum int iterations; float block_time_ms; float plannable_time_ms; // time in planner float plannable_length; // length in planner uint8_t meet_iterations; // iterations needed in _get_meet_velocity - //...to here +#endif bufferState buffer_state; // used to manage queuing/dequeuing blockType block_type; // used to dispatch to run routine @@ -367,12 +387,14 @@ typedef struct mpBuffer { bf_func = nullptr; cm_func = nullptr; +#ifdef __PLANNER_DIAGNOSTICS linenum = 0; iterations = 0; block_time_ms = 0; plannable_time_ms = 0; plannable_length = 0; meet_iterations = 0; +#endif buffer_state = MP_BUFFER_EMPTY; block_type = BLOCK_TYPE_NULL; @@ -473,6 +495,14 @@ typedef struct mpPlannerRuntime { // persistent runtime variables GCodeState_t gm; // gcode model state currently executing magic_t magic_end; + + // resets mpPlannerRuntime structure without actually wiping it + void reset() { + block_state = BLOCK_INACTIVE; + section = SECTION_HEAD; + section_state = SECTION_OFF; + } + } mpPlannerRuntime_t; //**** Master Planner Structure *** @@ -515,6 +545,19 @@ typedef struct mpPlanner { // common variables for a planner contex mpPlannerQueue_t q; // embed a planner buffer queue manager magic_t magic_end; + + // clears mpPlanner structure but leaves position alone + void reset() { + run_time_remaining = 0; + plannable_time = 0; + planner_state = PLANNER_IDLE; + request_planning = false; + backplanning = false; + mfo_active = false; + ramp_active = false; + entry_changed = false; + block_timeout.clear(); + } } mpPlanner_t; // Reference global scope structures diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index cb29244d..f74830d1 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -59,15 +59,15 @@ #define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE -#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE -#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_OFF // one of: QR_OFF, QR_SINGLE, QR_TRIPLE -#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum -#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable #define STATUS_REPORT_DEFAULTS "line","stat","posx","posy","posz",\ "vel", "unit","feed","coor","momo",\ diff --git a/g2core/util.cpp b/g2core/util.cpp index 03091239..d00421b3 100644 --- a/g2core/util.cpp +++ b/g2core/util.cpp @@ -33,6 +33,9 @@ #include "g2core.h" #include "util.h" +#include "canonical_machine.h" // for LAGERs +#include "xio.h" // for LAGERs + bool FLAGS_NONE[AXES] = { false, false, false, false, false, false }; bool FLAGS_ONE[AXES] = { true, false, false, false, false, false }; @@ -40,6 +43,24 @@ bool FLAGS_ALL[AXES] = { true, true, true, true, true, true }; //*** debug utilities *** +void LAGER(const char * msg) +{ + char message[64]; + sprintf(message, "%lu: %s\n", SysTickTimer_getValue(), msg); + xio_writeline(message); +} + +void LAGER_cm(const char * msg) +{ + char message[64]; + if (cm == &cm1) { + sprintf(message, "%lu: p1 %s\n", SysTickTimer_getValue(), msg); + } else { + sprintf(message, "%lu: p2 %s\n", SysTickTimer_getValue(), msg); + } + xio_writeline(message); +} + /**** Vector utilities **** * copy_vector() - copy vector of arbitrary length * vector_equal() - test if vectors are equal diff --git a/g2core/util.h b/g2core/util.h index e9afc1ff..d8907f5b 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -65,6 +65,9 @@ inline void _debug_trap(const char *reason) { } #pragma GCC reset_options +void LAGER(const char * msg); +void LAGER_cm(const char * msg); + //*** vector utilities *** extern float vector[AXES]; // vector of axes for passing to subroutines From 04857ced4815afdb3aa35542fb74a3d4a4df76a9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 15 Feb 2017 13:36:57 -0500 Subject: [PATCH 133/283] Removed diagnostics and rested with original replay file. Should be ready for use. --- g2core/canonical_machine.cpp | 1 - g2core/cycle_feedhold.cpp | 46 +++++++++++------------------------- g2core/planner.cpp | 12 ---------- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0a3b7ce5..8c7e8a17 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -833,7 +833,6 @@ stat_t cm_set_units_mode(const uint8_t mode) stat_t cm_set_distance_mode(const uint8_t mode) { cm->gm.distance_mode = (cmDistanceMode)mode; // 0 = absolute mode, 1 = incremental - LAGER_cm("set distance mode"); return (STAT_OK); } diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 692cf6e3..9f016da2 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -36,7 +36,7 @@ #include "spindle.h" #include "coolant.h" #include "util.h" -#include "xio.h" // DIAGNOSTIC +//#include "xio.h" // DIAGNOSTIC static stat_t _run_p1_hold_entry_actions(void); static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); @@ -133,7 +133,6 @@ bool cm_has_hold() void cm_start_hold() { -// if ((cm1.hold_state != FEEDHOLD_REQUESTED) && (mp_has_runnable_buffer(mp))) { // meaning there's something running // Can only request a feedhold if the machine is in motion and there not one is not already in progress if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { cm_set_motion_state(MOTION_HOLD); @@ -173,11 +172,9 @@ void cm_request_feedhold(void) // ! // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { cm1.hold_state = FEEDHOLD_REQUESTED; - LAGER("p1 request feedhold"); } else if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { cm2.hold_state = FEEDHOLD_REQUESTED; - LAGER("p2 - request feedhold"); } } @@ -185,7 +182,6 @@ void cm_request_exit_hold(void) // ~ { if (cm1.hold_state != FEEDHOLD_OFF) { cm1.hold_exit_requested = true; - LAGER_cm("request exit hold"); } } @@ -195,7 +191,6 @@ void cm_request_queue_flush() // % if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm1.flush_state == FLUSH_OFF)) { // ...and only once cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped - LAGER_cm("request queue flush"); } } @@ -229,36 +224,30 @@ stat_t cm_feedhold_sequencing_callback() // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_REQUESTED) { if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here - LAGER("p1 start feedhold"); cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions - LAGER("p1 start enter hold actions"); _run_p1_hold_entry_actions(); - LAGER("p1 complete enter hold actions"); } // p2 feedhold states - feedhold in feedhold if (cm2.hold_state == FEEDHOLD_REQUESTED) { if (mp_has_runnable_buffer(&mp2)) { - LAGER("p2 start feedhold"); cm_set_motion_state(MOTION_HOLD); cm2.hold_state = FEEDHOLD_SYNC; } } if (cm2.hold_state == FEEDHOLD_P2_EXIT) { - LAGER("p2 exit feedhold"); return(_finalize_p2_hold_exit()); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && (mp_runtime_is_idle())) { // don't flush planner during movement - LAGER("p1 queue flush"); cm_queue_flush(&cm1); - cm1.hold_exit_requested = true; // p1 queue flush always ends the hold + cm1.hold_exit_requested = true; // p1 queue flush always ends the hold qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } @@ -270,21 +259,18 @@ stat_t cm_feedhold_sequencing_callback() return (STAT_OK); } if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold - LAGER("p1 start exit hold actions"); cm1.hold_exit_requested = false; _run_p1_hold_exit_actions(); // runs once only - LAGER("p1 complete exit hold actions"); } } if (cm1.hold_state == FEEDHOLD_P1_EXIT) { - LAGER("p1 finalize hold"); return(_finalize_p1_hold_exit()); // run multiple times until actions are complete } return (STAT_OK); } /*********************************************************************************** - * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold + * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here * * This function assumes that the feedhold sequencing callback has resolved all @@ -292,7 +278,17 @@ stat_t cm_feedhold_sequencing_callback() * directly. Always use the feedhold sequencing callback. * * Moving between planners is only safe when the machine is completely stopped. + * + * _sync_to_p1_hold_entry_actions_done() is a callback to run when the ACTIONS from + * feedhold in p1 are finished. This function hits cm1 directly as ACTIONS for a + * feedhold in p1 actually run in the secondary planner (p2). Feedholds from p2 do + * not run actions, so this function is never called for p2 feedholds. It's called + * from an interrupt, so it only sets a flag. */ +static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD; +} static stat_t _run_p1_hold_entry_actions() { @@ -338,25 +334,11 @@ static stat_t _run_p1_hold_entry_actions() cm_set_distance_mode(stored_distance_mode); } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause - coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - - LAGER_cm("mp_queue_command entry actions done"); + coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); return (STAT_OK); } -// Callback to run when the ACTIONS from feedhold in planner 1 are finished. -// This function hits cm1 directly as ACTIONS for a feedhold in planner 1 -// actually run in the secondary planner. Feedholds from planner 2 do not run -// actions, so this function is never called for planner 2 feedholds. -// It's called from an interrupt, so it only sets a flag. - -static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_HOLD; - LAGER("p1 hold_state = FEEDHOLD_HOLD"); -} - /*********************************************************************************** * _run_p1_hold_exit_actions() - initiate return from feedhold planner * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations diff --git a/g2core/planner.cpp b/g2core/planner.cpp index a706cb94..4a8a087f 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -535,7 +535,6 @@ stat_t mp_planner_callback() // Test if the planner has transitioned to an IDLE state if ((mp_get_planner_buffers(mp) == mp->q.queue_size) && // detect and set IDLE state (cm->motion_state == MOTION_STOP) && (cm->hold_state == FEEDHOLD_OFF)) { - if (mp->planner_state != PLANNER_IDLE) { LAGER_cm("Planner entering IDLE state");} mp->planner_state = PLANNER_IDLE; return (STAT_OK); } @@ -543,7 +542,6 @@ stat_t mp_planner_callback() bool _timed_out = mp->block_timeout.isPast(); if (_timed_out) { mp->block_timeout.clear(); // timer is set on commit_write_buffer() - LAGER_cm("Blocks timed out"); } if (!mp->request_planning && !_timed_out) { // Exit if no request or timeout @@ -554,14 +552,12 @@ stat_t mp_planner_callback() if (mp->planner_state == PLANNER_IDLE) { mp->p = mp_get_r(); // initialize planner pointer to run buffer mp->planner_state = PLANNER_STARTUP; - LAGER_cm("Planner entering STARTUP state"); } if (mp->planner_state == PLANNER_STARTUP) { if (!mp_planner_is_full(mp) && !_timed_out) { return (STAT_OK); // remain in STARTUP } mp->planner_state = PLANNER_PRIMING; - LAGER_cm("Planner entering PRIMING state"); } mp_plan_block_list(); return (STAT_OK); @@ -809,13 +805,6 @@ void mp_commit_write_buffer(const blockType block_type) q->w = q->w->nx; // advance write buffer pointer mp->block_timeout.set(BLOCK_TIMEOUT_MS);// reset the block timer qr_request_queue_report(+1); // request QR and add to "added buffers" count - - char msg[64]; - sprintf(msg, "commit buffer:%d block state:%d timeout.isPast:%d", - q->w->buffer_number, - q->w->block_state, - mp->block_timeout.isPast()); - LAGER_cm(msg); } // Note: mp_get_run_buffer() is only called by mp_exec_move(), which is inside an interrupt @@ -837,7 +826,6 @@ mpBuf_t * mp_get_run_buffer() // Clearing and advancing must be done atomically as other interrupts may be using the run buffer bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { -// mpQueue_t *q = &mb.q[mb.active_q]; mpPlannerQueue_t *q = &(mp->q); mpBuf_t *r_now = q->r; // save this pointer is to avoid a race condition when clearing the buffer From 6ebf0ebd3a84f41813638dcd7c5018625c1b8d44 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 16 Feb 2017 05:17:03 -0500 Subject: [PATCH 134/283] Minor commit --- g2core/g2core.cppproj | 4 ++-- g2core/gpio.cpp | 2 +- g2core/settings/settings_makeblock.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 3e17cbf8..a4704359 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index d8f6a14e..b55e706c 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -633,7 +633,7 @@ stat_t io_get_output(nvObj_t *nv) } /* - * io_set_output() - return input state given an nv object + * io_set_output() - return output state given an nv object */ stat_t io_set_output(nvObj_t *nv) { diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index f74830d1..5ed74901 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -57,7 +57,7 @@ // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE From cfd199025537d3c1ed34ea75e950384365cca996 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 17 Feb 2017 08:25:20 -0500 Subject: [PATCH 135/283] =?UTF-8?q?Improvements=20to=20feedhold=20status?= =?UTF-8?q?=20reporting.=20Cannot=20tell=20if=20it=E2=80=99s=20completely?= =?UTF-8?q?=20fixed=20yet=20w/o=20more=20testing,=20although=20it=20passes?= =?UTF-8?q?=20repeated=20regression=20tests;=20Changed=20the=20name=20of?= =?UTF-8?q?=20planner=20test=20assertions=20in=20prep=20for=20folding=20th?= =?UTF-8?q?ese=20in=20as=20object=20methods.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/controller.cpp | 6 +++--- g2core/cycle_feedhold.cpp | 3 ++- g2core/planner.cpp | 21 ++++++++------------- g2core/planner.h | 2 +- g2core/spindle.h | 4 ++-- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 4ab3c705..3ff80073 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -471,12 +471,12 @@ static stat_t _test_assertions() stat_t _test_system_assertions() { // these functions will panic if an assertion fails - _test_assertions(); // controller assertions (local) + _test_assertions(); // controller assertions (local) config_test_assertions(); canonical_machine_test_assertions(&cm1); canonical_machine_test_assertions(&cm2); - planner_test_assertions(&mp1); - planner_test_assertions(&mp2); + planner_assert(&mp1); + planner_assert(&mp2); stepper_test_assertions(); encoder_test_assertions(); xio_test_assertions(); diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 9f016da2..4fbaf081 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -288,6 +288,7 @@ stat_t cm_feedhold_sequencing_callback() static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD; + sr_request_status_report(SR_REQUEST_IMMEDIATE); } static stat_t _run_p1_hold_entry_actions() @@ -372,6 +373,7 @@ static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_P1_EXIT; // penultimate state before transitioning to FEEDHOLD_OFF + sr_request_status_report(SR_REQUEST_IMMEDIATE); } static stat_t _finalize_p1_hold_exit() @@ -403,7 +405,6 @@ static stat_t _finalize_p1_hold_exit() cm_set_motion_state(MOTION_STOP); cm_cycle_end(); } - sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 042242c9..f3dce327 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -141,9 +141,9 @@ static stat_t _exec_command(mpBuf_t *bf); static stat_t _exec_json_wait(mpBuf_t *bf); /* - * planner_init() - * planner_reset() - * planner_test_assertions() - test assertions, PANIC if violation exists + * planner_init() - initialize MP, MR and planner queue buffers + * planner_reset() - selective reset MP and MR structures + * planner_assert() - test planner assertions, PANIC if violation exists */ // initialize a planner queue @@ -205,19 +205,14 @@ void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR act // selectively reset mpPlanner and mpPlannerRuntime w/o actually wiping them _mp->reset(); _mp->mr->reset(); -// _mp->mr->block_state = BLOCK_INACTIVE; // this resets the MR structure without actually wiping it - - // completely reset the planner queue - _init_planner_queue(_mp, _mp->q.bf, _mp->q.queue_size); + _init_planner_queue(_mp, _mp->q.bf, _mp->q.queue_size); // reset planner buffers } -stat_t planner_test_assertions(const mpPlanner_t *_mp) +stat_t planner_assert(const mpPlanner_t *_mp) { - if ( - (BAD_MAGIC(_mp->magic_start)) || (BAD_MAGIC(_mp->magic_end)) || - (BAD_MAGIC(_mp->mr->magic_start)) || (BAD_MAGIC(_mp->mr->magic_end)) - ) { - return (cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_test_assertions()")); + if ((BAD_MAGIC(_mp->magic_start)) || (BAD_MAGIC(_mp->magic_end)) || + (BAD_MAGIC(_mp->mr->magic_start)) || (BAD_MAGIC(_mp->mr->magic_end))) { + return (cm_panic(STAT_PLANNER_ASSERTION_FAILURE, "planner_assert()")); } for (uint8_t i=0; i < _mp->q.queue_size; i++) { if ((_mp->q.bf[i].nx == nullptr) || (_mp->q.bf[i].pv == nullptr)) { diff --git a/g2core/planner.h b/g2core/planner.h index f6dbf389..ea447fb9 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -581,7 +581,7 @@ extern mpBuf_t mp2_queue[SECONDARY_QUEUE_SIZE]; // storage allocation for second void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uint8_t queue_size); void planner_reset(mpPlanner_t *_mp); -stat_t planner_test_assertions(const mpPlanner_t *_mp); +stat_t planner_assert(const mpPlanner_t *_mp); void mp_halt_runtime(void); diff --git a/g2core/spindle.h b/g2core/spindle.h index 0ce83eef..3b019fb8 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -50,8 +50,8 @@ typedef enum { // how spindle controls are presented by the Gco SPINDLE_OFF = 0, // M5 SPINDLE_CW = 1, // M3 and store CW to spindle.direction SPINDLE_CCW = 2, // M4 and store CCW to spsindle.direction - SPINDLE_PAUSE, // request PAUSE and store PAUSED state to spindle.state - SPINDLE_RESUME, // request RESUME and revert spindle.state to CW, CCW + SPINDLE_PAUSE = 3, // request PAUSE and store PAUSED state to spindle.state + SPINDLE_RESUME = 4, // request RESUME and revert spindle.state to CW, CCW SPINDLE_NOP, // no operation SPINDLE_REV // operation to reverse spindle direction } spControl; From ad106ca7f39dfe438a68434df7cdb41614447f29 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Feb 2017 10:21:13 -0500 Subject: [PATCH 136/283] Changes to mp_forward_plan() and _plan_commands() to properly report cases where commands are planned multiple times, and return correct status code. Also required changes to Feedhold Case (5, continued) in mp_exec_aline(); Change IN_DEBUGGER cases; Changes to MIN_SEGMENT_MS and related definitions --- g2core/g2core.cppproj | 4 +-- g2core/plan_exec.cpp | 62 ++++++++++++++++++++++++++----------------- g2core/plan_zoid.cpp | 4 +-- g2core/planner.cpp | 4 +-- g2core/planner.h | 9 ++++--- g2core/util.h | 2 +- 6 files changed, 48 insertions(+), 37 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 57a1fc79..a4704359 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800019454 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 2cc0a55e..49ba19c9 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -149,13 +149,14 @@ static void _init_forward_diffs(float v_0, float v_1); * (Note: all COMMAND(s) in j. should be in PLANNED state) */ -static mpBuf_t *_plan_commands(mpBuf_t *bf) // plan or skip commands; return bf past last command +static mpBuf_t *_plan_commands(mpBuf_t *bf, bool &planned) // plan or skip commands; return bf past last command { + planned = false; + // must test for buffer state first as the buffer is only "safe" once it's >= PREPPED while ((bf->buffer_state >= MP_BUFFER_PREPPED) && (bf->block_type >= BLOCK_TYPE_COMMAND)) { - if (bf->buffer_state != MP_BUFFER_PLANNED) { // skip already planned buffers - bf->buffer_state = MP_BUFFER_PLANNED; // "planning" is just setting the state (for now) - } + bf->buffer_state = MP_BUFFER_PLANNED; // "planning" is just setting the state (for now) + planned = true; bf = bf->nx; } return (bf); @@ -179,7 +180,7 @@ static stat_t _plan_move(mpBuf_t *bf, float entry_velocity) // diagnostic traps -#if IN_DEBUGGER == 1 +#ifdef IN_DEBUGGER if (block->exit_velocity > block->cruise_velocity) { __asm__("BKPT"); // exit > cruise after calculate_block } @@ -216,9 +217,12 @@ stat_t mp_forward_plan() } // bf points to command; start cases 1f, 1g, 1h, 1i, 1j, 1k, 2c, 2d, 2e, 2h, 2i, 2j + bool planned_something = false; + if (bf->block_type != BLOCK_TYPE_ALINE) { // meaning it's a COMMAND - bf = _plan_commands(bf); // plan commands or skip past already planned commands - // bf now points to the first non-command buffer past the command(s) + bf = _plan_commands(bf, planned_something); // plan commands or skip past already planned commands + + // Note: bf now points to the first non-command buffer past the command(s) if ((bf->block_type == BLOCK_TYPE_ALINE) && (bf->buffer_state > MP_BUFFER_PREPPED )) { // case 1i entry_velocity = mr->r->exit_velocity; // set entry_velocity for Note 1a } @@ -228,12 +232,11 @@ stat_t mp_forward_plan() // process move if (bf->block_type == BLOCK_TYPE_ALINE) { // do cases 1a - 1e; finish cases 1f - 1k if (bf->buffer_state == MP_BUFFER_PREPPED) {// do 1a; finish 1f, 1j, 2d, 2i - return (_plan_move(bf, entry_velocity)); - } else { - return (STAT_NOOP); // do 1b, 1c, 1d, 1e; finish 1g, 1h, 1j, 1k, 2e, 2j + _plan_move(bf, entry_velocity); + planned_something = true; } } - return (STAT_OK); // report that we planned something... + return (planned_something ? STAT_OK : STAT_NOOP); } /************************************************************************* @@ -265,7 +268,7 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) { -#if IN_DEBUGGER == 1 +#ifdef IN_DEBUGGER __asm__("BKPT"); // mp_exec_move() buffer is not prepped #endif // IMPORTANT: We can't rpt_exception from here! @@ -280,7 +283,7 @@ stat_t mp_exec_move() if (bf->buffer_state == MP_BUFFER_PREPPED) { if (cm->motion_state == MOTION_RUN) { -#if IN_DEBUGGER == 1 +#ifdef IN_DEBUGGER // __asm__("BKPT"); // we are running but don't have a block planned #endif } @@ -558,7 +561,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) return (STAT_OK); // hold here. No more movement } - // Case (5) - Decelerated to zero + // Case (5) - Decelerated to zero. See also Feedhold Case (5, continued), toward end of mp_exec_aline() // Update the run buffer then force a replan of the whole planner queue. Replans from 0 velocity if (cm->hold_state == FEEDHOLD_DECEL_END) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move @@ -640,26 +643,35 @@ stat_t mp_exec_aline(mpBuf_t *bf) else if (mr->section == SECTION_TAIL) { status = _exec_aline_tail(bf);} else { return(cm_panic(STAT_INTERNAL_ERROR, "exec_aline()"));} // never supposed to get here - // We can't use the if/else block above, since the head may call body, and body call tail, so we wait till after - if ((mr->section == SECTION_TAIL) // Once we're in the tail, we can't plan the block anymore - || ((mr->section == SECTION_BODY) && (mr->segment_count < 3))) { // or are too close to the end of the body - + // Conditionally set the move to be unplannable. We can't use the if/else block above, + // since the head may call a body or a tail, and a body call tail, so we wait till after. + // + // Conditions are: + // - Allow 3 segments: 1 segment isn't enough, because there's one running as we execute, + // so it has to be the next one. There's a slight possibility we'll miss that, since we + // didn't necessarily start at the beginning, so three. + // - If it's a head/tail move and we've started the head we can't replan it anyway as + // the head can't be interrupted, and the tail is already as sharp as it can be (or there'd be a body) + // - ...so if you are in a body mark the body unplannable if we are too close to its end. + if ((mr->section == SECTION_TAIL) || ((mr->section == SECTION_BODY) && (mr->segment_count < 3))) { bf->plannable = false; } - // Feedhold Case (5): Look for the end of the deceleration to go into HOLD state - if ((cm->hold_state == FEEDHOLD_DECEL_TO_ZERO) && (status == STAT_OK)) { - cm->hold_state = FEEDHOLD_DECEL_END; - bf->block_state = BLOCK_INITIAL_ACTION; // reset bf so it can restart the rest of the move + // Feedhold Case (5, continued): Look for the end of the deceleration to go into HOLD state + if (cm->hold_state == FEEDHOLD_DECEL_TO_ZERO) { + if ((status == STAT_OK) || (status == STAT_NOOP)) { + cm->hold_state = FEEDHOLD_DECEL_END; + bf->block_state = BLOCK_INITIAL_ACTION; // reset bf so it can restart the rest of the move + } } // There are 4 things that can happen here depending on return conditions: - // status bf->block_state Description - // ----------- -------------- ---------------------------------------- + // status bf->block_state Description + // ----------- -------------- ---------------------------------------- // STAT_EAGAIN mr buffer has more segments to run // STAT_OK BLOCK_ACTIVE mr and bf buffers are done // STAT_OK BLOCK_INITIAL_ACTION mr done; bf must be run again (it's been reused) - // There is no fourth thing. Nobody expects the Spanish Inquisition + // STAT_NOOP treated as a STAT_OK if (status == STAT_EAGAIN) { sr_request_status_report(SR_REQUEST_TIMED); // continue reporting mr buffer diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 943b4216..7deecd09 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -34,7 +34,7 @@ // DIAGNOSTICS -//#if IN_DEBUGGER < 1 +//#ifndef IN_DEBUGGER #define LOG_RETURN(msg) // LOG_RETURN with no action (production) //#else //#include "xio.h" @@ -50,7 +50,7 @@ //#define LOG_RETURN(msg) { _logger(msg, bf); } //#endif -#if IN_DEBUGGER < 1 +#ifndef IN_DEBUGGER #define TRAP_ZERO(t,m) #else #define TRAP_ZERO(t, m) \ diff --git a/g2core/planner.cpp b/g2core/planner.cpp index f3dce327..42ecc046 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -821,12 +821,10 @@ mpBuf_t * mp_get_run_buffer() // Clearing and advancing must be done atomically as other interrupts may be using the run buffer bool mp_free_run_buffer() // EMPTY current run buffer & advance to the next { - mpPlannerQueue_t *q = &(mp->q); - + mpPlannerQueue_t *q = &(mp->q); mpBuf_t *r_now = q->r; // save this pointer is to avoid a race condition when clearing the buffer _audit_buffers(); // DIAGNOSTIC audit for buffer chain integrity (only runs in DEBUG mode) - q->r = q->r->nx; // advance to next run buffer first, _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) q->buffers_available++; diff --git a/g2core/planner.h b/g2core/planner.h index ea447fb9..8602140f 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -250,9 +250,12 @@ typedef enum { #define JUNCTION_INTEGRATION_MIN (0.05) // JT minimum allowable setting #define JUNCTION_INTEGRATION_MAX (5.00) // JT maximum allowable setting +#ifndef MIN_SEGMENT_MS // boards can override this value in hardware.h #define MIN_SEGMENT_MS ((float)0.75) // minimum segment milliseconds -#define NOM_SEGMENT_MS ((float)1.5) // nominal segment ms (at LEAST MIN_SEGMENT_MS * 2) -#define MIN_BLOCK_MS ((float)1.5) // minimum block (whole move) milliseconds +#endif +#define NOM_SEGMENT_MS ((float)MIN_SEGMENT_MS * 2) // nominal segment ms (at LEAST MIN_SEGMENT_MS * 2) +#define MIN_BLOCK_MS ((float)MIN_SEGMENT_MS * 2) // minimum block (whole move) milliseconds + #define BLOCK_TIMEOUT_MS ((float)30.0) // MS before deciding there are no new blocks arriving #define PHAT_CITY_MS ((float)100.0) // if you have at least this much time in the planner @@ -395,7 +398,6 @@ typedef struct mpBuffer { plannable_length = 0; meet_iterations = 0; #endif - buffer_state = MP_BUFFER_EMPTY; block_type = BLOCK_TYPE_NULL; block_state = BLOCK_INACTIVE; @@ -405,7 +407,6 @@ typedef struct mpBuffer { unit[i] = 0; axis_flags[i] = 0; } - plannable = false; length = 0.0; block_time = 0.0; diff --git a/g2core/util.h b/g2core/util.h index d8907f5b..75471031 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -59,7 +59,7 @@ inline void _debug_trap(const char *reason) { // We might be able to put a print here, but it MIGHT interrupt other output // and might be deep in an ISR, so we had better just _NOP() and hope for the best. __NOP(); -#if IN_DEBUGGER == 1 +#ifdef IN_DEBUGGER __asm__("BKPT"); #endif } From 225bacfd5d8ba77ea901038ec090f0bb5a04d5d8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Feb 2017 12:53:19 -0500 Subject: [PATCH 137/283] Fixed stall issue for Issue #34 --- g2core/plan_exec.cpp | 66 +++++++++++++++++++------------------------- g2core/planner.h | 1 + 2 files changed, 30 insertions(+), 37 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 49ba19c9..1a940486 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -62,7 +62,6 @@ static void _init_forward_diffs(float v_0, float v_1); * See also: Planner Overview notes in planner.h * * It examines the currently running buffer and its adjacent buffers to: - * * - Stop the system from re-planning or planning something that's not prepped * - Plan the next available ALINE (movement) block past the COMMAND blocks * - Skip past/ or pre-plan COMMAND blocks while labeling them as PLANNED @@ -149,38 +148,25 @@ static void _init_forward_diffs(float v_0, float v_1); * (Note: all COMMAND(s) in j. should be in PLANNED state) */ -static mpBuf_t *_plan_commands(mpBuf_t *bf, bool &planned) // plan or skip commands; return bf past last command +// _plan_aline() - mp_forward_plan() helper +// +// Calculate ramps for the current planning block and the next PREPPED buffer +// The PREPPED buffer will be set to PLANNED later... +// +// Pass in the bf buffer that will "link" with the planned block +// The block and the buffer are implicitly linked for exec_aline() +// +// Note that that can only be one PLANNED move at a time. +// This is to help sync mr->p to point to the next planned mr->bf +// mr->p is only advanced in mp_exec_aline(), after mp.r = mr->p. +// This code aligns the buffers and the blocks for exec_aline(). + +static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) { - planned = false; - - // must test for buffer state first as the buffer is only "safe" once it's >= PREPPED - while ((bf->buffer_state >= MP_BUFFER_PREPPED) && (bf->block_type >= BLOCK_TYPE_COMMAND)) { - bf->buffer_state = MP_BUFFER_PLANNED; // "planning" is just setting the state (for now) - planned = true; - bf = bf->nx; - } - return (bf); -} - -static stat_t _plan_move(mpBuf_t *bf, float entry_velocity) -{ - // Calculate ramps for the current planning block and the next PREPPED buffer - // The PREPPED buffer will be set to PLANNED later... - // - // Pass in the bf buffer that will "link" with the planned block - // The block and the buffer are implicitly linked for exec_aline() - // - // Note that that can only be one PLANNED move at a time. - // This is to help sync mr->p to point to the next planned mr->bf - // mr->p is only advanced in mp_exec_aline(), after mp.r = mr->p. - // This code aligns the buffers and the blocks for exec_aline(). - mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) - // diagnostic traps - -#ifdef IN_DEBUGGER +#ifdef IN_DEBUGGER // DIAGNOSTIC if (block->exit_velocity > block->cruise_velocity) { __asm__("BKPT"); // exit > cruise after calculate_block } @@ -216,12 +202,17 @@ stat_t mp_forward_plan() entry_velocity = mr->entry_velocity; // set Note 2 entry velocity (command cases) } - // bf points to command; start cases 1f, 1g, 1h, 1i, 1j, 1k, 2c, 2d, 2e, 2h, 2i, 2j + // bf points to a command block; start cases 1f, 1g, 1h, 1i, 1j, 1k, 2c, 2d, 2e, 2h, 2i, 2j bool planned_something = false; if (bf->block_type != BLOCK_TYPE_ALINE) { // meaning it's a COMMAND - bf = _plan_commands(bf, planned_something); // plan commands or skip past already planned commands - + while (bf->block_type >= BLOCK_TYPE_COMMAND) { + if (bf->buffer_state == MP_BUFFER_PREPPED) { + bf->buffer_state = MP_BUFFER_PLANNED;// "planning" is just setting the state (for now) + planned_something = true; + } + bf = bf->nx; + } // Note: bf now points to the first non-command buffer past the command(s) if ((bf->block_type == BLOCK_TYPE_ALINE) && (bf->buffer_state > MP_BUFFER_PREPPED )) { // case 1i entry_velocity = mr->r->exit_velocity; // set entry_velocity for Note 1a @@ -232,7 +223,7 @@ stat_t mp_forward_plan() // process move if (bf->block_type == BLOCK_TYPE_ALINE) { // do cases 1a - 1e; finish cases 1f - 1k if (bf->buffer_state == MP_BUFFER_PREPPED) {// do 1a; finish 1f, 1j, 2d, 2i - _plan_move(bf, entry_velocity); + _plan_aline(bf, entry_velocity); planned_something = true; } } @@ -301,11 +292,12 @@ stat_t mp_exec_move() mp_planner_time_accounting(); } + // Go ahead and *ask* for a forward planning of the next move. + // This won't call mp_plan_move until we leave this function + // (and have called mp_exec_aline via bf->bf_func). + // This also allows mp_exec_aline to advance mr->p first. if (bf->nx->buffer_state >= MP_BUFFER_PREPPED) { - // We go ahead and *ask* for a forward planning of the next move. - // This won't call mp_plan_move until we leave this function - // (and have called mp_exec_aline via bf->bf_func). - // This also allows mp_exec_aline to advance mr->p first. +// if (bf->nx->buffer_state == MP_BUFFER_PREPPED) { st_request_forward_plan(); } diff --git a/g2core/planner.h b/g2core/planner.h index 8602140f..88ee107c 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -182,6 +182,7 @@ typedef enum { // bf->block_type values BLOCK_TYPE_NULL = 0, // MUST=0 null move - does a no-op BLOCK_TYPE_ALINE = 1, // MUST=1 acceleration planned line BLOCK_TYPE_COMMAND = 2, // MUST=2 general command + // All other non-move commands are > BLOCK_TYPE_COMMAND BLOCK_TYPE_DWELL, // Gcode dwell BLOCK_TYPE_JSON_WAIT, // JSON wait command BLOCK_TYPE_TOOL, // T command (T, not M6 tool change) From f31acbb45bdd33fcf9029e40586e015ed7217b6a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Feb 2017 06:34:28 -0500 Subject: [PATCH 138/283] handling cases with very short moves --- g2core/canonical_machine.cpp | 50 +++++++++++++++++++----------------- g2core/canonical_machine.h | 3 +-- g2core/controller.cpp | 5 ++-- g2core/plan_arc.cpp | 2 +- g2core/plan_zoid.cpp | 5 +++- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8c7e8a17..329837c8 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -510,11 +510,9 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax * Core functions supporting the canonical machining functions * These functions are not part of the NIST defined functions ***********************************************************************************/ + /* - * cm_finalize_move() - perform final operations for a traverse or feed - * cm_update_model_position_from_runtime() - set endpoint position from final runtime position - * - * These routines set the point position in the gcode model. + * cm_update_model_position() - set gmx endpoint position for a traverse, feed or arc * * Note: As far as the canonical machine is concerned the final position of a Gcode block (move) * is achieved as soon as the move is planned and the move target becomes the new model position. @@ -522,14 +520,9 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax * execution, and the real tool position is still close to the starting point. */ -void cm_finalize_move() +void cm_update_model_position() { - copy_vector(cm->gmx.position, cm->gm.target); // update model position -} - -void cm_update_model_position_from_runtime() -{ - copy_vector(cm->gmx.position, mr->gm.target); + copy_vector(cm->gmx.position, cm->gm.target); // would be mr->gm.target if from runtime } /* @@ -1128,12 +1121,18 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm->gm); // send the move to the planner + cm_update_model_position(); // update gmx.position to ready for next incoming move - cm_finalize_move(); - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //applies to currently active machine - cm_cycle_end(); - return (STAT_OK); +// if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //mp applies to currently active planner +// cm_cycle_end(); +// return (STAT_OK); +// } + if (status == STAT_MINIMUM_LENGTH_MOVE) { + if (!mp_has_runnable_buffer(mp)) { // handle condition where zero-length move is last or only move + cm_cycle_end(); // ...otherwise cycle will not end properly + } + status = STAT_OK; } return (status); } @@ -1273,8 +1272,8 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) } cm->gm.motion_mode = MOTION_MODE_STRAIGHT_FEED; - if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | - flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { + // it's legal for a G1 to have no axis words but we don't want to process it + if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { return(STAT_OK); } @@ -1283,12 +1282,17 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to the state cm_cycle_start(); // required for homing & other cycles stat_t status = mp_aline(&cm->gm); // send the move to the planner + cm_update_model_position(); // <-- ONLY safe because we don't care about status... - cm_finalize_move(); // <-- ONLY safe because we don't care about status... - - if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { - cm_cycle_end(); - return (STAT_OK); +// if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //mp applies to currently active planner +// cm_cycle_end(); +// return (STAT_OK); +// } + if (status == STAT_MINIMUM_LENGTH_MOVE) { + if (!mp_has_runnable_buffer(mp)) { // handle condition where zero-length move is last or only move + cm_cycle_end(); // ...otherwise cycle will not end properly + } + status = STAT_OK; } return (status); } @@ -1605,7 +1609,7 @@ void cm_cycle_start() void cm_cycle_end() { - if(cm->cycle_state == CYCLE_MACHINING) { + if (cm->cycle_state == CYCLE_MACHINING) { float value[] = { (float)MACHINE_PROGRAM_STOP }; _exec_program_finalize(value, nullptr); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 3caf0d54..8522d83f 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -341,8 +341,7 @@ float cm_get_display_position(const GCodeState_t *gcode_state, const uint8_t axi float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t axis); // Critical helpers -void cm_update_model_position_from_runtime(void); -void cm_finalize_move(void); +void cm_update_model_position(void); stat_t cm_deferred_write_callback(void); void cm_set_model_target(const float target[], const bool flag[]); bool cm_get_soft_limits(void); diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 3ff80073..923a7994 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -166,8 +166,9 @@ static void _controller_HSM() DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle -// DISPATCH(cm_feedhold_command_blocker()); // blocks new commands from arriving while in feedhold - +// DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner + DISPATCH(cm_feedhold_command_blocker()); // blocks new Gcode from arriving while in feedhold + //----- command readers and parsers --------------------------------------------------// DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 013b3a05..775bbe83 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -250,7 +250,7 @@ stat_t cm_arc_feed(const float target[], const bool target_f[], // target en cm_cycle_start(); // if not already started cm->arc.run_state = BLOCK_ACTIVE; // enable arc to be run from the callback - cm_finalize_move(); + cm_update_model_position(); return (STAT_OK); } diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 7deecd09..9d37d039 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -325,7 +325,10 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent // Rate-limited asymmetric cases (3) // compute meet velocity to see if the cruise velocity rises above the entry and/or exit velocities block->cruise_velocity = _get_meet_velocity(entry_velocity, block->exit_velocity, bf->length, bf, block); - TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case"); +// TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case"); + if (fp_ZERO(block->cruise_velocity)) { + __asm__("BKPT"); + } // We now store the head/tail lengths we computed in _get_meet_velocity. // treat as a full up and down (head and tail) From 61704e9eb30b515549b7b2e7e500425fd33c9600 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Feb 2017 10:29:13 -0500 Subject: [PATCH 139/283] Experimental changes to plan_zoid to trap small-move errors; cleaned up mp_calculate_ramps() exit logging --- g2core/plan_exec.cpp | 2 +- g2core/plan_zoid.cpp | 108 +++++++++++++++++++------------------------ g2core/planner.h | 4 +- 3 files changed, 51 insertions(+), 63 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 1a940486..f99f2fab 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -163,7 +163,7 @@ static void _init_forward_diffs(float v_0, float v_1); static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) { - mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you + mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) #ifdef IN_DEBUGGER // DIAGNOSTIC diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 9d37d039..d4ef6091 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -31,13 +31,21 @@ #include "planner.h" #include "report.h" #include "util.h" +#include "xio.h" // only need for DIAGNOSTICS // DIAGNOSTICS -//#ifndef IN_DEBUGGER -#define LOG_RETURN(msg) // LOG_RETURN with no action (production) -//#else -//#include "xio.h" +stat_t _exit_logger(mpBuf_t* bf, const char *msg) +{ + #ifdef __PLANNER_DIAGNOSTICS + if (mp_runtime_is_idle()) { // normally the runtime keeps this value fresh +// bf->time_in_plan_ms += bf->block_time_ms; + bf->plannable_time_ms += bf->block_time_ms;\ + } + #endif + + #ifdef IN_DEBUGGER +// insert logger functions here //static char logbuf[128]; //static void _logger(const char *msg, const mpBuf_t *bf) // LOG_RETURN with full state dump //{ @@ -47,8 +55,10 @@ // bf->pv->exit_velocity, bf->cruise_velocity, bf->exit_velocity); // xio_writeline(logbuf); //} -//#define LOG_RETURN(msg) { _logger(msg, bf); } -//#endif + #endif + + return (STAT_OK); +} #ifndef IN_DEBUGGER #define TRAP_ZERO(t,m) @@ -114,31 +124,20 @@ static float _get_meet_velocity(const float v_0, * */ -void _zoid_exit(mpBuf_t* bf, zoidExitPoint exit_point) -{ -#ifdef __PLANNER_DIAGNOSTICS - // bf->zoid_exit = exit_point; - if (mp_runtime_is_idle()) { // normally the runtime keeps this value fresh -// bf->time_in_plan_ms += bf->block_time_ms; - bf->plannable_time_ms += bf->block_time_ms; - } -#endif -} - // Hint will be one of these from back-planning: COMMAND_BLOCK, PERFECT_DECELERATION, PERFECT_CRUISE, // MIXED_DECELERATION, ASYMMETRIC_BUMP // We are incorporating both the forward planning and ramp-planning into one function, since we use the same data. -void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float entry_velocity) +stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float entry_velocity) { // *** Skip non-move commands *** if (bf->block_type == BLOCK_TYPE_COMMAND) { bf->hint = COMMAND_BLOCK; - return; + return (STAT_NOOP); // NOOP status is informative, not actionable } TRAP_ZERO(bf->length, "zoid() got L=0"); //+++++ Move this outside of zoid TRAP_ZERO(bf->cruise_velocity, "zoid() got Vc=0"); // move this outside - // Timing from *here* + // Timings from *here* // initialize parameters to know values block->head_time = 0; @@ -152,8 +151,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->cruise_velocity = min(bf->cruise_velocity, bf->cruise_vmax); block->exit_velocity = min(bf->exit_velocity, bf->exit_vmax); - - // We *might* do this exact computation later, so cache the value. + // We *might* do this exact computation later, so cache the value float test_velocity = 0; bool test_velocity_valid = false; // record if we have a validly cached value @@ -173,29 +171,25 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->body_length = bf->length; block->body_time = block->body_length / block->cruise_velocity; bf->block_time = block->body_time; - - LOG_RETURN("1c"); - return (_zoid_exit(bf, ZOID_EXIT_1c)); - } else { - // we need to degrade the hint to MIXED_ACCELERATION + return (_exit_logger(bf, "1c")); + } + else { // degrade the hint to MIXED_ACCELERATION bf->hint = MIXED_ACCELERATION; } } - // Quick test to ensure we haven't violated the hint - if (entry_velocity > block->exit_velocity) { - // We're in a deceleration. - if (mp->entry_changed) { - // If entry_changed, then entry_velocity is lower than the hints expect. - // A deceleration will never become an acceleration (post-hinting). - // If it is marked as MIXED_DECELERATION, it means the entry was CRUISE_VMAX. - // If it is marked as PERFECT_DECELERATION, it means the entry was as <= CRUISE_VMAX, - // but as high as possible. - // So, this move is and was a DECELERATION, meaning it *could* achieve the previous (higher) - // entry safely, it will likely get a head section, so we will now degrade the hint to an - // ASYMMETRIC_BUMP. + if (entry_velocity > block->exit_velocity) { // Means this is a deceleration + // If entry_changed then entry_velocity is lower than the hints expect + // A deceleration will never become an acceleration (post-hinting) + // If it is marked as MIXED_DECELERATION, it means the entry was CRUISE_VMAX + // If it is marked as PERFECT_DECELERATION, it means the entry was as <= CRUISE_VMAX, + // but as high as possible + // So, this move is and was a DECELERATION, meaning it *could* achieve the previous (higher) + // entry safely, it will likely get a head section, so we will now degrade the hint to an + // ASYMMETRIC_BUMP + if (mp->entry_changed) { bf->hint = ASYMMETRIC_BUMP; } @@ -209,8 +203,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->body_time = block->body_length / block->cruise_velocity; block->tail_time = block->tail_length * 2 / (block->exit_velocity + block->cruise_velocity); bf->block_time = block->body_time + block->tail_time; - LOG_RETURN("2d"); - return (_zoid_exit(bf, ZOID_EXIT_2d)); + return (_exit_logger(bf, "2d")); } // PERFECT_DECELERATION (1d) single tail segment (deltaV == delta_vmax) @@ -220,19 +213,16 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->cruise_velocity = entry_velocity; block->tail_time = block->tail_length * 2 / (block->exit_velocity + block->cruise_velocity); bf->block_time = block->tail_time; - LOG_RETURN("1d"); - return (_zoid_exit(bf, ZOID_EXIT_1d)); + return (_exit_logger(bf, "1d")); } - // Reset entry_changed. We won't likely be changing the next block's entry velocity. mp->entry_changed = false; - // Since we are not generally decelerating, this is effectively all of forward planning that we need. } else { - // Note that the hints from back-planning are ignored in this section, since back-planing can only predict decel - // and cruise. + // Note that the hints from back-planning are ignored in this section, since back-planing can only + // predict decelerations and cruises float accel_velocity; if (test_velocity_valid) { @@ -256,9 +246,9 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->cruise_velocity = block->exit_velocity; block->head_time = (block->head_length * 2.0) / (entry_velocity + block->cruise_velocity); bf->block_time = block->head_time; - LOG_RETURN("1a"); - return (_zoid_exit(bf, ZOID_EXIT_1a)); - } else { // it's hit the cusp + return (_exit_logger(bf, "1a")); + } + else { // it's hit the cusp mp->entry_changed = false; // we are NOT changing the next block's entry velocity @@ -281,8 +271,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->head_time = (block->head_length * 2.0) / (entry_velocity + block->cruise_velocity); block->body_time = block->body_length / block->cruise_velocity; bf->block_time = block->head_time + block->body_time; - LOG_RETURN("2a"); - return (_zoid_exit(bf, ZOID_EXIT_2a)); + return (_exit_logger(bf, "2a")); } } } @@ -314,9 +303,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent bf->block_time = block->head_time + block->body_time + block->tail_time; bf->hint = ASYMMETRIC_BUMP; - - LOG_RETURN("2c"); - return (_zoid_exit(bf, ZOID_EXIT_2c)); + return (_exit_logger(bf, "2c")); } // *** Rate-Limited-Fit cases (3) *** @@ -327,7 +314,9 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->cruise_velocity = _get_meet_velocity(entry_velocity, block->exit_velocity, bf->length, bf, block); // TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case"); if (fp_ZERO(block->cruise_velocity)) { - __asm__("BKPT"); + return (STAT_MINIMUM_LENGTH_MOVE); // This error case needs to be recovered upstream +// rpt_exception(STAT_MINIMUM_LENGTH_MOVE, "mp_calculate_ramps() case (3)"); +// __asm__("BKPT"); } // We now store the head/tail lengths we computed in _get_meet_velocity. @@ -347,12 +336,9 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent block->tail_time = (block->tail_length * 2.0) / (block->exit_velocity + block->cruise_velocity); } bf->block_time = block->head_time + block->body_time + block->tail_time; - - LOG_RETURN("3c"); - return (_zoid_exit(bf, ZOID_EXIT_3c)); // 550us worst case + return (_exit_logger(bf, "3c")); // 550us worst case } - /**** Planner helpers **** * * mp_get_target_length() - find accel/decel length from delta V and jerk @@ -372,7 +358,7 @@ void mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float ent */ // Just calling this tl_constant. It's full name is: -// static const float tl_constant = 1.201405707067378; // sqrt(5)/( sqrt(2)pow(3,4) ) +// static const float tl_constant = 1.201405707067378; // sqrt(5)/( sqrt(2)pow(3,4) ) float mp_get_target_length(const float v_0, const float v_1, const mpBuf_t* bf) { diff --git a/g2core/planner.h b/g2core/planner.h index 88ee107c..e90db105 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -226,6 +226,7 @@ typedef enum { // code blocks for planning and trapezoid ge ASYMMETRIC_BUMP, // (Ve != Vx) < Vc } blockHint; +/* typedef enum { ZOID_EXIT_NULL = 0, ZOID_EXIT_1a, @@ -240,6 +241,7 @@ typedef enum { ZOID_EXIT_3d2, ZOID_EXIT_3a2 } zoidExitPoint; +*/ /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ @@ -646,7 +648,7 @@ void mp_plan_block_list(void); void mp_plan_block_forward(mpBuf_t *bf); //**** plan_zoid.c functions -void mp_calculate_ramps(mpBlockRuntimeBuf_t *block, mpBuf_t *bf, const float entry_velocity); +stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t *block, mpBuf_t *bf, const float entry_velocity); float mp_get_target_length(const float v_0, const float v_1, const mpBuf_t *bf); float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t *bf); // acceleration ONLY float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t *bf); // deceleration ONLY From d67dc6540e3bc3e57ba7e1077b4167f324d12392 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Feb 2017 16:59:20 -0500 Subject: [PATCH 140/283] More testing. Passes regressions; adjusted minimum line test to 0.00002 mm (up from 0.00001) --- g2core/controller.cpp | 1 - g2core/plan_exec.cpp | 18 +++++++++--------- g2core/plan_line.cpp | 3 ++- g2core/plan_zoid.cpp | 11 ++++++----- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 923a7994..3d853648 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -166,7 +166,6 @@ static void _controller_HSM() DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle -// DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(cm_feedhold_command_blocker()); // blocks new Gcode from arriving while in feedhold //----- command readers and parsers --------------------------------------------------// diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index f99f2fab..377a7ad3 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -913,8 +913,8 @@ static stat_t _exec_aline_head(mpBuf_t *bf) /********************************************************************************************* * _exec_aline_body() * - * The body is broken into little segments even though it is a straight line so that - * feed holds can happen in the middle of a line with a minimum of latency + * The body is broken into little segments even though it is a straight line + * so that feed holds can happen in the middle of a line with minimum latency */ static stat_t _exec_aline_body(mpBuf_t *bf) { @@ -935,11 +935,11 @@ static stat_t _exec_aline_body(mpBuf_t *bf) } mr->section = SECTION_BODY; - mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works + mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done if (fp_ZERO(mr->r->tail_length)) { - return(STAT_OK); // ends the move + return(STAT_OK); // ends the move } mr->section = SECTION_TAIL; mr->section_state = SECTION_NEW; @@ -954,16 +954,16 @@ static stat_t _exec_aline_body(mpBuf_t *bf) static stat_t _exec_aline_tail(mpBuf_t *bf) { bool first_pass = false; - if (mr->section_state == SECTION_NEW) { // INITIALIZATION + if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; // Mark the block as unplannable bf->plannable = false; - if (fp_ZERO(mr->r->tail_length)) { return(STAT_OK);} // end the move + if (fp_ZERO(mr->r->tail_length)) { return(STAT_OK);} // end the move mr->segments = ceil(uSec(mr->r->tail_time) / NOM_SEGMENT_USEC);// # of segments for the section mr->segment_count = (uint32_t)mr->segments; - mr->segment_time = mr->r->tail_time / mr->segments; // time to advance for each segment + mr->segment_time = mr->r->tail_time / mr->segments; // time to advance for each segment if (mr->segment_count == 1) { mr->segment_velocity = mr->r->tail_length / mr->segment_time; @@ -972,8 +972,8 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) } if (mr->segment_time < MIN_SEGMENT_TIME) { _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); - return(STAT_OK); // exit without advancing position, say we're done - // return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position + return(STAT_OK); // exit without advancing position, say we're done + // return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position } mr->section = SECTION_TAIL; mr->section_state = SECTION_RUNNING; diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 9d8dd7fe..99ad3328 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -198,7 +198,8 @@ stat_t mp_aline(GCodeState_t* gm_in) length = sqrt(length_square); // exit if the move has zero movement. At all. - if (fp_ZERO(length)) { +// if (fp_ZERO(length)) { + if (length < 0.00002) { // this value is 2x EPSILON and prevents trap failures in _plan_aline() sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL return (STAT_MINIMUM_LENGTH_MOVE); // STAT_MINIMUM_LENGTH_MOVE needed to end cycle } diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index d4ef6091..2a6cc99a 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -312,13 +312,14 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e // Rate-limited asymmetric cases (3) // compute meet velocity to see if the cruise velocity rises above the entry and/or exit velocities block->cruise_velocity = _get_meet_velocity(entry_velocity, block->exit_velocity, bf->length, bf, block); -// TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case"); +#if (0) + TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case"); +#else if (fp_ZERO(block->cruise_velocity)) { - return (STAT_MINIMUM_LENGTH_MOVE); // This error case needs to be recovered upstream -// rpt_exception(STAT_MINIMUM_LENGTH_MOVE, "mp_calculate_ramps() case (3)"); -// __asm__("BKPT"); +// return (STAT_MINIMUM_LENGTH_MOVE); // This error case needs to be recovered upstream + __asm__("BKPT"); } - +#endif // We now store the head/tail lengths we computed in _get_meet_velocity. // treat as a full up and down (head and tail) bf->hint = ASYMMETRIC_BUMP; From 5810eda2391b3b7f62bc1919bd5b78a18a2d1429 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Feb 2017 06:13:08 -0500 Subject: [PATCH 141/283] Work on debug and diagnostics --- g2core/Makefile | 19 +++++---- g2core/alarm.cpp | 2 +- g2core/g2core.cppproj | 2 +- g2core/main.cpp | 10 +++-- g2core/plan_exec.cpp | 28 +++++-------- g2core/plan_line.cpp | 4 +- g2core/plan_zoid.cpp | 67 ++++++++++++------------------- g2core/planner.cpp | 2 +- g2core/planner.h | 19 +-------- g2core/stepper.cpp | 18 ++------- g2core/util.h | 93 ++++++++++++++++++++++++++++++++++--------- g2core/xio.cpp | 12 +++--- 12 files changed, 144 insertions(+), 132 deletions(-) mode change 100755 => 100644 g2core/Makefile mode change 100755 => 100644 g2core/xio.cpp diff --git a/g2core/Makefile b/g2core/Makefile old mode 100755 new mode 100644 index e4928c15..94aa4a1f --- a/g2core/Makefile +++ b/g2core/Makefile @@ -52,14 +52,17 @@ NEEDS_PRINTF_FLOAT=1 # Now invoke the Motate compile system include $(MOTATE_PATH)/Motate.mk -ifeq ($(DEBUG),1) - DEVICE_DEFINES += DEBUG=1 -endif -ifeq ($(DEBUG),2) - DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1 -endif -ifeq ($(DEBUG),3) - DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1 DEBUG_SEMIHOSTING=1 +ifeq ($(DEBUG),0) + DEVICE_DEFINES += DEBUG=0 IN_DEBUGGER=0 +endif +ifeq ($(DEBUG),1) + DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=0 +endif +ifeq ($(DEBUG),2) + DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1 endif +#ifeq ($(DEBUG),3) +# DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1 DEBUG_SEMIHOSTING=1 +#endif # *** EOF *** diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index b98e1ff2..5b3c0856 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -230,7 +230,7 @@ stat_t cm_shutdown(const stat_t status, const char *msg) stat_t cm_panic(const stat_t status, const char *msg) { - _debug_trap(msg); + __debug_trap(msg); if (cm->machine_state == MACHINE_PANIC) { // only do this once return (STAT_OK); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index a4704359..b67c56bb 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -1177,7 +1177,7 @@ bin\Makeblock-v9\ True - CONFIG=Makeblock COLOR=0 VERBOSE=1 + CONFIG=Makeblock COLOR=0 VERBOSE=1 DEBUG=2 clean CONFIG=Makeblock Makefile diff --git a/g2core/main.cpp b/g2core/main.cpp index 5ea91111..f3ff45aa 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -50,17 +50,19 @@ stat_t status_code; // allocate a variable for the ritorno macro -/************* System Globals For Diagnostics ****************/ +/************* System Globals For Debugging and Diagnostics ****************/ +// See also: util.h for debugging and diagnostics // Using motate pins for profiling -// see https://github.com/synthetos/g2/wiki/Using-Pin-Changes-for-Timing-(and-light-debugging) +// Usage: https://github.com/synthetos/g2/wiki/Using-Pin-Changes-for-Timing-(and-light-debugging) using namespace Motate; OutputPin debug_pin1; OutputPin debug_pin2; OutputPin debug_pin3; -//OutputPin debug_pin4; +OutputPin debug_pin4; +// or these to disable the pin //OutputPin<-1> debug_pin1; //OutputPin<-1> debug_pin2; //OutputPin<-1> debug_pin3; @@ -72,7 +74,7 @@ using namespace Motate; extern OutputPin debug_pin1; extern OutputPin debug_pin2; extern OutputPin debug_pin3; -//extern OutputPin debug_pin4; +extern OutputPin debug_pin4; //extern OutputPin<-1> debug_pin1; //extern OutputPin<-1> debug_pin2; diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 377a7ad3..a2a53804 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -166,14 +166,11 @@ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) -#ifdef IN_DEBUGGER // DIAGNOSTIC - if (block->exit_velocity > block->cruise_velocity) { - __asm__("BKPT"); // exit > cruise after calculate_block - } - if (block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001) { - __asm__("BKPT"); // zero or negative length block - } -#endif + __debug_trap_if_true((block->exit_velocity > block->cruise_velocity), + "_plan_line() exit velocity > cruise velocity after calculate_ramps()"); + + __debug_trap_if_true((block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001), + "_plan_line() zero or negative length block after calculate_ramps()"); bf->buffer_state = MP_BUFFER_PLANNED; //...here bf->plannable = false; @@ -259,10 +256,7 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) { -#ifdef IN_DEBUGGER - __asm__("BKPT"); // mp_exec_move() buffer is not prepped -#endif - // IMPORTANT: We can't rpt_exception from here! + __debug_trap("mp_exec_move() buffer is not prepped"); // IMPORTANT: can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); } @@ -274,9 +268,7 @@ stat_t mp_exec_move() if (bf->buffer_state == MP_BUFFER_PREPPED) { if (cm->motion_state == MOTION_RUN) { -#ifdef IN_DEBUGGER -// __asm__("BKPT"); // we are running but don't have a block planned -#endif + __debug_trap("mp_exec_move() don't have a block planned"); // IMPORTANT: can't rpt_exception from here! } // We need to have it planned. We don't want to do this here, as it // might already be happening in a lower interrupt. @@ -885,7 +877,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) _init_forward_diffs(mr->entry_velocity, mr->r->cruise_velocity); // <-- sets inital segment_velocity } if (mr->segment_time < MIN_SEGMENT_TIME) { - _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); + __debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); return(STAT_OK); // exit without advancing position, say we're done } mr->section = SECTION_HEAD; @@ -930,7 +922,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf) mr->segment_velocity = mr->r->cruise_velocity; mr->segment_count = (uint32_t)mr->segments; if (mr->segment_time < MIN_SEGMENT_TIME) { - _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); + __debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); return(STAT_OK); // exit without advancing position, say we're done } @@ -971,7 +963,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) _init_forward_diffs(mr->r->cruise_velocity, mr->r->exit_velocity); // <-- sets inital segment_velocity } if (mr->segment_time < MIN_SEGMENT_TIME) { - _debug_trap("mr->segment_time < MIN_SEGMENT_TIME"); + __debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); return(STAT_OK); // exit without advancing position, say we're done // return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 99ad3328..c9e3ca32 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -36,7 +36,6 @@ #include "util.h" #include "spindle.h" #include "settings.h" - #include "xio.h" // using Motate::Timeout; @@ -55,7 +54,9 @@ static void _calculate_jerk(mpBuf_t* bf); static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const float axis_square[]); static void _calculate_junction_vmax(mpBuf_t* bf); + #ifdef __PLANNER_DIAGNOSTICS +#pragma GCC push_options #pragma GCC optimize("O0") // this pragma is required to force the planner to actually set these unused values static void _set_bf_diagnostics(mpBuf_t* bf) { UPDATE_BF_DIAGNOSTICS(bf); @@ -65,6 +66,7 @@ static void _set_bf_diagnostics(mpBuf_t* bf) { static void _set_bf_diagnostics(mpBuf_t* bf) {} #endif + /* Runtime-specific setters and getters * * mp_zero_segment_velocity() - correct velocity in last segment for reporting purposes diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 2a6cc99a..a91562cf 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -31,11 +31,11 @@ #include "planner.h" #include "report.h" #include "util.h" -#include "xio.h" // only need for DIAGNOSTICS +//#include "xio.h" // only need for_ramp_exit_logger // DIAGNOSTICS -stat_t _exit_logger(mpBuf_t* bf, const char *msg) +stat_t _ramp_exit_logger(mpBuf_t* bf, const char *msg) { #ifdef __PLANNER_DIAGNOSTICS if (mp_runtime_is_idle()) { // normally the runtime keeps this value fresh @@ -44,32 +44,23 @@ stat_t _exit_logger(mpBuf_t* bf, const char *msg) } #endif - #ifdef IN_DEBUGGER -// insert logger functions here -//static char logbuf[128]; -//static void _logger(const char *msg, const mpBuf_t *bf) // LOG_RETURN with full state dump -//{ -// sprintf(logbuf, "[%2d] %s (%d) mt:%5.2f, L:%1.3f [%1.3f, %1.3f, %1.3f] V:[%1.2f, %1.2f, %1.2f]\n", -// bf->buffer_number, msg, bf->hint, (bf->block_time * 60000), -// bf->length, bf->head_length, bf->body_length, bf->tail_length, -// bf->pv->exit_velocity, bf->cruise_velocity, bf->exit_velocity); -// xio_writeline(logbuf); -//} - #endif +/* insert logger functions here if needed: + // LOG_RETURN with full state dump + #if IN_DEBUGGER == 1 + + static char logbuf[128]; + + sprintf(logbuf, "[%2d] %s (%d) mt:%5.2f, L:%1.3f [%1.3f, %1.3f, %1.3f] V:[%1.2f, %1.2f, %1.2f]\n", + bf->buffer_number, msg, bf->hint, (bf->block_time * 60000), + bf->length, bf->head_length, bf->body_length, bf->tail_length, + bf->pv->exit_velocity, bf->cruise_velocity, bf->exit_velocity); + xio_writeline(logbuf); + #endif +*/ return (STAT_OK); } -#ifndef IN_DEBUGGER -#define TRAP_ZERO(t,m) -#else -#define TRAP_ZERO(t, m) \ - if (fp_ZERO(t)) { \ - rpt_exception(STAT_MINIMUM_LENGTH_MOVE, m); \ - _debug_trap(m); \ - } -#endif - // END DIAGNOSTICS /* local functions */ @@ -134,8 +125,8 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e bf->hint = COMMAND_BLOCK; return (STAT_NOOP); // NOOP status is informative, not actionable } - TRAP_ZERO(bf->length, "zoid() got L=0"); //+++++ Move this outside of zoid - TRAP_ZERO(bf->cruise_velocity, "zoid() got Vc=0"); // move this outside + __debug_trap_if_zero(bf->length, "mp_calculate_ramps() - got L=0"); + __debug_trap_if_zero(bf->cruise_velocity, "mp_calculate_ramps() - got Vc=0"); // Timings from *here* @@ -171,7 +162,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->body_length = bf->length; block->body_time = block->body_length / block->cruise_velocity; bf->block_time = block->body_time; - return (_exit_logger(bf, "1c")); + return (_ramp_exit_logger(bf, "1c")); } else { // degrade the hint to MIXED_ACCELERATION bf->hint = MIXED_ACCELERATION; @@ -203,7 +194,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->body_time = block->body_length / block->cruise_velocity; block->tail_time = block->tail_length * 2 / (block->exit_velocity + block->cruise_velocity); bf->block_time = block->body_time + block->tail_time; - return (_exit_logger(bf, "2d")); + return (_ramp_exit_logger(bf, "2d")); } // PERFECT_DECELERATION (1d) single tail segment (deltaV == delta_vmax) @@ -213,7 +204,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->cruise_velocity = entry_velocity; block->tail_time = block->tail_length * 2 / (block->exit_velocity + block->cruise_velocity); bf->block_time = block->tail_time; - return (_exit_logger(bf, "1d")); + return (_ramp_exit_logger(bf, "1d")); } // Reset entry_changed. We won't likely be changing the next block's entry velocity. @@ -246,7 +237,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->cruise_velocity = block->exit_velocity; block->head_time = (block->head_length * 2.0) / (entry_velocity + block->cruise_velocity); bf->block_time = block->head_time; - return (_exit_logger(bf, "1a")); + return (_ramp_exit_logger(bf, "1a")); } else { // it's hit the cusp @@ -271,7 +262,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->head_time = (block->head_length * 2.0) / (entry_velocity + block->cruise_velocity); block->body_time = block->body_length / block->cruise_velocity; bf->block_time = block->head_time + block->body_time; - return (_exit_logger(bf, "2a")); + return (_ramp_exit_logger(bf, "2a")); } } } @@ -303,7 +294,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e bf->block_time = block->head_time + block->body_time + block->tail_time; bf->hint = ASYMMETRIC_BUMP; - return (_exit_logger(bf, "2c")); + return (_ramp_exit_logger(bf, "2c")); } // *** Rate-Limited-Fit cases (3) *** @@ -312,14 +303,8 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e // Rate-limited asymmetric cases (3) // compute meet velocity to see if the cruise velocity rises above the entry and/or exit velocities block->cruise_velocity = _get_meet_velocity(entry_velocity, block->exit_velocity, bf->length, bf, block); -#if (0) - TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case"); -#else - if (fp_ZERO(block->cruise_velocity)) { -// return (STAT_MINIMUM_LENGTH_MOVE); // This error case needs to be recovered upstream - __asm__("BKPT"); - } -#endif + __debug_trap_if_zero(block->cruise_velocity, "mp_calculate_ramps() Vc=0 asymmetric HT case"); + // We now store the head/tail lengths we computed in _get_meet_velocity. // treat as a full up and down (head and tail) bf->hint = ASYMMETRIC_BUMP; @@ -337,7 +322,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->tail_time = (block->tail_length * 2.0) / (block->exit_velocity + block->cruise_velocity); } bf->block_time = block->head_time + block->body_time + block->tail_time; - return (_exit_logger(bf, "3c")); // 550us worst case + return (_ramp_exit_logger(bf, "3c")); // 550us worst case } /**** Planner helpers **** diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 42ecc046..be0e5bef 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -62,7 +62,7 @@ #include "report.h" #include "util.h" #include "json_parser.h" -#include "xio.h" // DIAGNOSTIC - only needed if xio_writeline() direct prints are used +#include "xio.h" // Allocate planner structures diff --git a/g2core/planner.h b/g2core/planner.h index e90db105..606c2785 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -226,23 +226,6 @@ typedef enum { // code blocks for planning and trapezoid ge ASYMMETRIC_BUMP, // (Ve != Vx) < Vc } blockHint; -/* -typedef enum { - ZOID_EXIT_NULL = 0, - ZOID_EXIT_1a, - ZOID_EXIT_1c, - ZOID_EXIT_1d, - ZOID_EXIT_2a, - ZOID_EXIT_2c, - ZOID_EXIT_2d, - ZOID_EXIT_3c, - ZOID_EXIT_3s, - ZOID_EXIT_3s2, - ZOID_EXIT_3d2, - ZOID_EXIT_3a2 -} zoidExitPoint; -*/ - /*** Most of these factors are the result of a lot of tweaking. Change with caution.***/ #define PLANNER_QUEUE_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255 @@ -292,7 +275,7 @@ typedef enum { #define Veq2_lo 1.0 #define VELOCITY_ROUGHLY_EQ(v0,v1) ( (v0 > Vthr2) ? fabs(v0-v1) < Veq2_hi : fabs(v0-v1) < Veq2_lo ) -/* Diagnostics */ +/* Planner Diagnostics */ //#define __PLANNER_DIAGNOSTICS // comment this out to drop diagnostics diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index d8777402..870072d0 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -44,18 +44,9 @@ #include "MotateDebug.h" -/* Note: stepper_debug statements removed 1/16/17 in SHA eb0905ccae03c04f99e6f471cbe029002f0324c6. See earlier commits to recover -// Unless debugging, this should always read "#if 0 && ..." -// DON'T COMMIT with anything else! -// -#if 0 && (IN_DEBUGGER == 1) -template -void stepper_debug(const char (&str)[len]) { Motate::debug.write(str); }; -#else -template -void stepper_debug(const char (&str)[len]) { ; }; -#endif -*/ +/* Note: stepper_debug statements removed 1/16/17 in SHA eb0905ccae03c04f99e6f471cbe029002f0324c6. + * See earlier commits to recover + */ /**** Allocate structures ****/ @@ -67,9 +58,6 @@ static stRunSingleton_t st_run; static void _load_move(void); -// handy macro -//#define _f_to_period(f) (uint16_t)((float)F_CPU / (float)f) - /**** Setup motate ****/ using namespace Motate; diff --git a/g2core/util.h b/g2core/util.h index 75471031..1c4913e7 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -50,24 +50,6 @@ using Motate::SysTickTimer; /****** Global Scope Variables and Functions ******/ -//*** debug utilities *** - -#pragma GCC push_options -#pragma GCC optimize ("O0") -//#pragma GCC reset_options -inline void _debug_trap(const char *reason) { - // We might be able to put a print here, but it MIGHT interrupt other output - // and might be deep in an ISR, so we had better just _NOP() and hope for the best. - __NOP(); -#ifdef IN_DEBUGGER - __asm__("BKPT"); -#endif -} -#pragma GCC reset_options - -void LAGER(const char * msg); -void LAGER_cm(const char * msg); - //*** vector utilities *** extern float vector[AXES]; // vector of axes for passing to subroutines @@ -178,4 +160,79 @@ inline T avg(const T a,const T b) {return (a+b)/2; } // return count_>1 ? (hold=*t, *t=*(t+(count_-1)), *(t+(count_-1))=hold), c_strreverse(t+1, count_-2), count_ : count_; //} +/*** Debug and DIAGNOSTICS *** + * + * This section collects debug and DIAGNOSTIC functions used by the project. + * + * The debug levels are set in the build line and may be one of: + * - debug is off, IN_DEBUGGER == 0 (See Makefile for the logic) + * DEBUG=0 - debug is off, IN_DEBUGGER == 0 + * DEBUG=1 - debug is on, IN_DEBUGGER == 0 + * DEBUG=2 - debug is on, IN_DEBUGGER == 1. Requires HW debugger to be connected + * DEBUG=3 - debug is on, IN_DEBUGGER == 1. Requires HW debugger and Semihosting to be enabled and running in the debugger + * + * These settings are applied in the Makefile. + * In addition, MotateDebug.h contains the bulk of the Semihosting definitions + * + * The *reason value is provided as it will be shown in the __asm__("BKPT") backtrace, + * or on the __NOP() if a breakpoint is set + * + * Try to use the functions provided below for debug statements to keep the code clean. If these + * are insufficient you can bracket diagnostics like so to enable then for any non-zero debug level: + * + #if IN_DEBUGGER == 1 + if (block->exit_velocity > block->cruise_velocity) { + __asm__("BKPT"); // exit > cruise after calculate_block + } + #endif + * + * ...or add a new debug functions to the ones below + */ + +/* + * _debug_trap() - trap unconditionally + * _debug_trap_if_zero() - trap if floating point value is zero + * _debug_trap_if_true() - trap if condition is true + * + * The 'reason' value will display in GDB (but maybe not in AS7), and can also be passed + * to a downstream logger if these are introduced into the function. + * + * Note that it may be possible to print or generate exceptions in _debug_trap(), but + * it MIGHT interrupt other output, or might have been called deep in an ISR, + * so we had better just _NOP() and hope for the best. + */ +#pragma GCC push_options +#pragma GCC optimize ("O0") + +inline void __debug_trap(const char *reason) { + __NOP(); +#if IN_DEBUGGER == 1 + __asm__("BKPT"); +#endif +} + +inline void __debug_trap_if_zero(float value, const char *reason) { + if (fp_ZERO(value)) { + __NOP(); +#if IN_DEBUGGER == 1 + __asm__("BKPT"); +#endif + } +} + +inline void __debug_trap_if_true(bool condition, const char *reason) { + if (condition) { + __NOP(); +#if IN_DEBUGGER == 1 + __asm__("BKPT"); +#endif + } +} + +#pragma GCC reset_options + +void LAGER(const char * msg); +void LAGER_cm(const char * msg); + + #endif // End of include guard: UTIL_H_ONCE diff --git a/g2core/xio.cpp b/g2core/xio.cpp old mode 100755 new mode 100644 index 8068a421..d67fc25d --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -600,7 +600,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { char c = _data[_scan_offset]; if (c == 0) { - _debug_trap("scan ran into NULL"); + __debug_trap("_scanBuffer() scan ran into NULL"); flush(); // consider the connection and all data trashed return false; } @@ -624,7 +624,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { ends_line = true; // _at_start_of_line is already true, this is not the first. } } - // prevent going furnther if we are ignoring + // prevent going further if we are ignoring else if (_ignore_until_next_line) { // don't do anything @@ -747,14 +747,14 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // Either way, _scan_offset is one past the end, so we don't care which. if (_data[_line_start_offset] == 0) { - _debug_trap("read ran into NULL"); + __debug_trap("readline() read ran into NULL"); } // scan past any leftover CR or LF from the previous line while ((_data[_line_start_offset] == '\n') || (_data[_line_start_offset] == '\r')) { _line_start_offset = (_line_start_offset+1)&(_size-1); if (_scan_offset == _line_start_offset) { - _debug_trap("read ran into scan (1)"); + __debug_trap("readline() read ran into scan (1)"); } } @@ -802,7 +802,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (_data[_read_offset] == 0) { - _debug_trap("read ran into NULL"); + __debug_trap("readline() read ran into NULL"); } // scan past any leftover CR or LF from the previous line @@ -810,7 +810,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { while ((c == '\n') || (c == '\r')) { _read_offset = (_read_offset+1)&(_size-1); if (_scan_offset == _read_offset) { - _debug_trap("read ran into scan (2)"); + __debug_trap("readline() read ran into scan (2)"); } // this also counts as the beginning of a line _skip_sections.skip(_read_offset); From 5363980d9f0bc73ae8ca6510431d003a7ecf69ad Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Feb 2017 10:50:34 -0500 Subject: [PATCH 142/283] =?UTF-8?q?Fixed=20some=20naming=20on=20the=20debu?= =?UTF-8?q?g=20traps;=20changed=20detection=20threshold=20for=20=E2=80=9Cz?= =?UTF-8?q?ero=20length=20moves=E2=80=9D=20from=201/100=20micron=20to=201/?= =?UTF-8?q?10th=20micron?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/alarm.cpp | 2 +- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 27 +++++++++++++-------------- g2core/plan_line.cpp | 4 ++-- g2core/plan_zoid.cpp | 6 +++--- g2core/util.h | 14 +++++++------- g2core/xio.cpp | 10 +++++----- 7 files changed, 33 insertions(+), 34 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 5b3c0856..e2da88a4 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -230,7 +230,7 @@ stat_t cm_shutdown(const stat_t status, const char *msg) stat_t cm_panic(const stat_t status, const char *msg) { - __debug_trap(msg); + debug_trap(msg); if (cm->machine_state == MACHINE_PANIC) { // only do this once return (STAT_OK); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b67c56bb..fd10f7b0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index a2a53804..ca52d61a 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -166,10 +166,10 @@ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) - __debug_trap_if_true((block->exit_velocity > block->cruise_velocity), + debug_trap_if_true((block->exit_velocity > block->cruise_velocity), "_plan_line() exit velocity > cruise velocity after calculate_ramps()"); - __debug_trap_if_true((block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001), + debug_trap_if_true((block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001), "_plan_line() zero or negative length block after calculate_ramps()"); bf->buffer_state = MP_BUFFER_PLANNED; //...here @@ -256,28 +256,28 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) { - __debug_trap("mp_exec_move() buffer is not prepped"); // IMPORTANT: can't rpt_exception from here! + debug_trap("mp_exec_move() buffer is not prepped. Starvation"); // IMPORTANT: can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); } - if (bf->nx->buffer_state < MP_BUFFER_PREPPED) { + if ((bf->nx->buffer_state < MP_BUFFER_PREPPED) && (bf->nx->buffer_state > MP_BUFFER_EMPTY)) { // This detects buffer starvation, but also can be a single-line "jog" or command // rpt_exception(42, "mp_exec_move() next buffer is empty"); // ^^^ CAUSES A CRASH. We can't rpt_exception from here! + debug_trap("mp_exec_move() no buffer prepped - starvation"); } if (bf->buffer_state == MP_BUFFER_PREPPED) { - if (cm->motion_state == MOTION_RUN) { - __debug_trap("mp_exec_move() don't have a block planned"); // IMPORTANT: can't rpt_exception from here! - } - // We need to have it planned. We don't want to do this here, as it - // might already be happening in a lower interrupt. + debug_trap_if_true((cm->motion_state == MOTION_RUN), "mp_exec_move() buffer prepped but not planned"); + // IMPORTANT: can't rpt_exception from here! + // We need to have it planned. We don't want to do this here, + // as it might already be happening in a lower interrupt. st_request_forward_plan(); return (STAT_NOOP); } if (bf->buffer_state == MP_BUFFER_PLANNED) { - bf->buffer_state = MP_BUFFER_RUNNING; // must precede mp_planner_time_acccounting() + bf->buffer_state = MP_BUFFER_RUNNING; // must precede mp_planner_time_acccounting() } else { return (STAT_NOOP); } @@ -289,7 +289,6 @@ stat_t mp_exec_move() // (and have called mp_exec_aline via bf->bf_func). // This also allows mp_exec_aline to advance mr->p first. if (bf->nx->buffer_state >= MP_BUFFER_PREPPED) { -// if (bf->nx->buffer_state == MP_BUFFER_PREPPED) { st_request_forward_plan(); } @@ -877,7 +876,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) _init_forward_diffs(mr->entry_velocity, mr->r->cruise_velocity); // <-- sets inital segment_velocity } if (mr->segment_time < MIN_SEGMENT_TIME) { - __debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); + debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); return(STAT_OK); // exit without advancing position, say we're done } mr->section = SECTION_HEAD; @@ -922,7 +921,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf) mr->segment_velocity = mr->r->cruise_velocity; mr->segment_count = (uint32_t)mr->segments; if (mr->segment_time < MIN_SEGMENT_TIME) { - __debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); + debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); return(STAT_OK); // exit without advancing position, say we're done } @@ -963,7 +962,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) _init_forward_diffs(mr->r->cruise_velocity, mr->r->exit_velocity); // <-- sets inital segment_velocity } if (mr->segment_time < MIN_SEGMENT_TIME) { - __debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); + debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); return(STAT_OK); // exit without advancing position, say we're done // return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index c9e3ca32..40deeef0 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -200,8 +200,8 @@ stat_t mp_aline(GCodeState_t* gm_in) length = sqrt(length_square); // exit if the move has zero movement. At all. -// if (fp_ZERO(length)) { - if (length < 0.00002) { // this value is 2x EPSILON and prevents trap failures in _plan_aline() +// if (length < 0.00002) { // this value is 2x EPSILON and prevents trap failures in _plan_aline() + if (length < 0.0001) { // this value is 0.1 microns. Prevents planner trap failures sr_request_status_report(SR_REQUEST_TIMED_FULL); // Was SR_REQUEST_IMMEDIATE_FULL return (STAT_MINIMUM_LENGTH_MOVE); // STAT_MINIMUM_LENGTH_MOVE needed to end cycle } diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index a91562cf..bbff69e0 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -125,8 +125,8 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e bf->hint = COMMAND_BLOCK; return (STAT_NOOP); // NOOP status is informative, not actionable } - __debug_trap_if_zero(bf->length, "mp_calculate_ramps() - got L=0"); - __debug_trap_if_zero(bf->cruise_velocity, "mp_calculate_ramps() - got Vc=0"); + debug_trap_if_zero(bf->length, "mp_calculate_ramps() - got L=0"); + debug_trap_if_zero(bf->cruise_velocity, "mp_calculate_ramps() - got Vc=0"); // Timings from *here* @@ -303,7 +303,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e // Rate-limited asymmetric cases (3) // compute meet velocity to see if the cruise velocity rises above the entry and/or exit velocities block->cruise_velocity = _get_meet_velocity(entry_velocity, block->exit_velocity, bf->length, bf, block); - __debug_trap_if_zero(block->cruise_velocity, "mp_calculate_ramps() Vc=0 asymmetric HT case"); + debug_trap_if_zero(block->cruise_velocity, "mp_calculate_ramps() Vc=0 asymmetric HT case"); // We now store the head/tail lengths we computed in _get_meet_velocity. // treat as a full up and down (head and tail) diff --git a/g2core/util.h b/g2core/util.h index 1c4913e7..d5d5aa9b 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -190,28 +190,28 @@ inline T avg(const T a,const T b) {return (a+b)/2; } */ /* - * _debug_trap() - trap unconditionally - * _debug_trap_if_zero() - trap if floating point value is zero - * _debug_trap_if_true() - trap if condition is true + * debug_trap() - trap unconditionally + * debug_trap_if_zero() - trap if floating point value is zero + * debug_trap_if_true() - trap if condition is true * * The 'reason' value will display in GDB (but maybe not in AS7), and can also be passed * to a downstream logger if these are introduced into the function. * - * Note that it may be possible to print or generate exceptions in _debug_trap(), but + * Note that it may be possible to print or generate exceptions in debug_trap(), but * it MIGHT interrupt other output, or might have been called deep in an ISR, * so we had better just _NOP() and hope for the best. */ #pragma GCC push_options #pragma GCC optimize ("O0") -inline void __debug_trap(const char *reason) { +inline void debug_trap(const char *reason) { __NOP(); #if IN_DEBUGGER == 1 __asm__("BKPT"); #endif } -inline void __debug_trap_if_zero(float value, const char *reason) { +inline void debug_trap_if_zero(float value, const char *reason) { if (fp_ZERO(value)) { __NOP(); #if IN_DEBUGGER == 1 @@ -220,7 +220,7 @@ inline void __debug_trap_if_zero(float value, const char *reason) { } } -inline void __debug_trap_if_true(bool condition, const char *reason) { +inline void debug_trap_if_true(bool condition, const char *reason) { if (condition) { __NOP(); #if IN_DEBUGGER == 1 diff --git a/g2core/xio.cpp b/g2core/xio.cpp index d67fc25d..3993150e 100644 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -600,7 +600,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { char c = _data[_scan_offset]; if (c == 0) { - __debug_trap("_scanBuffer() scan ran into NULL"); + debug_trap("_scanBuffer() scan ran into NULL"); flush(); // consider the connection and all data trashed return false; } @@ -747,14 +747,14 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // Either way, _scan_offset is one past the end, so we don't care which. if (_data[_line_start_offset] == 0) { - __debug_trap("readline() read ran into NULL"); + debug_trap("readline() read ran into NULL"); } // scan past any leftover CR or LF from the previous line while ((_data[_line_start_offset] == '\n') || (_data[_line_start_offset] == '\r')) { _line_start_offset = (_line_start_offset+1)&(_size-1); if (_scan_offset == _line_start_offset) { - __debug_trap("readline() read ran into scan (1)"); + debug_trap("readline() read ran into scan (1)"); } } @@ -802,7 +802,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { if (_data[_read_offset] == 0) { - __debug_trap("readline() read ran into NULL"); + debug_trap("readline() read ran into NULL"); } // scan past any leftover CR or LF from the previous line @@ -810,7 +810,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { while ((c == '\n') || (c == '\r')) { _read_offset = (_read_offset+1)&(_size-1); if (_scan_offset == _read_offset) { - __debug_trap("readline() read ran into scan (2)"); + debug_trap("readline() read ran into scan (2)"); } // this also counts as the beginning of a line _skip_sections.skip(_read_offset); From ffd387b61e6c8f0e54bc88c6754de117f4346b43 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 21 Feb 2017 17:13:32 -0500 Subject: [PATCH 143/283] Fixed Y bump problem in double-weirdness.txt --- g2core/cycle_feedhold.cpp | 11 +++--- g2core/g2core.cppproj | 8 ++--- g2core/plan_exec.cpp | 72 +++++++++++++++++++++++---------------- g2core/util.h | 10 +++--- 4 files changed, 57 insertions(+), 44 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 4fbaf081..83681881 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -295,6 +295,8 @@ static stat_t _run_p1_hold_entry_actions() { cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // penultimate state before transitioning to HOLD + debug_trap_if_true(st_runtime_isbusy(), "_run_p1_hold_entry_actions() - runtime is busy"); + // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner memcpy(&cm2, &cm1, sizeof(cmMachine_t)); @@ -326,16 +328,15 @@ static stat_t _run_p1_hold_entry_actions() cm_set_motion_state(MOTION_STOP); // execute feedhold actions - if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift - float stored_distance_mode = cm_get_distance_mode(MODEL); + if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); bool flags[] = { 0,0,1,0,0,0 }; float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode cm_straight_traverse(target, flags); - cm_set_distance_mode(stored_distance_mode); + cm_set_distance_mode(cm1.gm.distance_mode); // restore distance mode to p1 setting } - spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause - coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause + spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause + coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); return (STAT_OK); } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index fd10f7b0..f1ace99b 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 10000000 + 2000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 10000000 + 2000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index ca52d61a..aaaca620 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -400,12 +400,27 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Initialize all new blocks, regardless of normal or feedhold operation if (mr->block_state == BLOCK_INACTIVE) { - // Zero length moves (and other too-short moves) should have already been removed... - // ...so the following code is no longer needed. + // ASSERTIONS + + // Zero length moves (and other too-short moves) should have already been removed earlier // But let's still alert the condition should it ever occur - if (fp_ZERO(bf->length)) { // ...looks for an actual zero here - rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, "mp_exec_aline() zero length move"); - } +// if (fp_ZERO(bf->length)) { // ...looks for an actual zero here +// rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, "mp_exec_aline() zero length move"); +// } + debug_trap_if_zero(bf->length, "mp_exec_aline() zero length move"); + + // Equalities that must be true for this to work: + // entry velocity <= cruise velocity && + // exit velocity <= cruise velocity + // + // Even if the move is head or tail only, cruise velocity needs to be valid. + // This is because a "head" is *always* entry->cruise, and a "tail" is *always* cruise->exit, + // even if there are no other sections in the move. (This is a significant time savings.) + debug_trap_if_true((mr->entry_velocity > mr->r->cruise_velocity), + "mp_exec_aline() mr->entry_velocity > mr->r->cruise_velocity"); + + debug_trap_if_true((mr->r->exit_velocity > mr->r->cruise_velocity), + "mp_exec_aline() mr->exit_velocity > mr->r->cruise_velocity"); // Start a new move by setting up the runtime singleton (mr) memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state @@ -415,20 +430,14 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->section = SECTION_HEAD; mr->section_state = SECTION_NEW; - // This is the only place in the system where mr->r and mr->p are allowed to be changed + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // !!! THIS IS THE ONLY PLACE WHERE mr->r AND mr->p ARE ALLOWED TO BE CHANGED !!! + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Swap P and R blocks mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block - // Equalities that must be true for this to work: - // entry velocity <= cruise velocity && - // cruise velocity >= exit velocity - // - // Even if the move is head or tail only, cruise velocity needs to be valid. - // This is because a "head" is *always* entry->cruise, and a "tail" is *always* cruise->exit, - // even if there are not other sections in the move. (This is a significant time savings.) - - // Here we will check to make sure that the sections are longer than MIN_SEGMENT_TIME - + // Check to make sure no sections are less than MIN_SEGMENT_TIME & adjust if necessary if ((!fp_ZERO(mr->r->head_length)) && (mr->r->head_time < MIN_SEGMENT_TIME)) { // head_time !== body_time // We have to compute the new body time addition. @@ -529,6 +538,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (6) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish + // finalize position and velocity + copy_vector(mr->position, mr->gm.target); // update position from target + bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEsT + mp_zero_segment_velocity(); // for reporting purposes + // when homing or probing don't stay in HOLD or execute entry actions if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { cm->hold_state = FEEDHOLD_OFF; @@ -537,7 +551,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) } else { cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions } - mp_zero_segment_velocity(); // for reporting purposes + sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } @@ -549,7 +563,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->hold_state == FEEDHOLD_DECEL_END) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - bf->length = get_axis_vector_length(mr->target, mr->position);// reset length cm->hold_state = FEEDHOLD_STOPPING; // No point bothering with the rest of this move if homing or probing @@ -859,15 +872,15 @@ static void _init_forward_diffs(const float v_0, const float v_1) static stat_t _exec_aline_head(mpBuf_t *bf) { bool first_pass = false; - if (mr->section_state == SECTION_NEW) { // INITIALIZATION + if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; if (fp_ZERO(mr->r->head_length)) { mr->section = SECTION_BODY; - return(_exec_aline_body(bf)); // skip ahead to the body generator + return(_exec_aline_body(bf)); // skip ahead to the body generator } mr->segments = ceil(uSec(mr->r->head_time) / NOM_SEGMENT_USEC);// # of segments for the section mr->segment_count = (uint32_t)mr->segments; - mr->segment_time = mr->r->head_time / mr->segments; // time to advance for each segment + mr->segment_time = mr->r->head_time / mr->segments; // time to advance for each segment if (mr->segment_count == 1) { // We will only have one segment, simply average the velocities @@ -1016,8 +1029,8 @@ static stat_t _exec_aline_segment() copy_vector(mr->gm.target, mr->waypoint[mr->section]); } else { float segment_length = mr->segment_velocity * mr->segment_time; - // see https://en.wikipedia.org/wiki/Kahan_summation_algorithm - // for the summation compensation description + // See https://en.wikipedia.org/wiki/Kahan_summation_algorithm + // for the summation compensation description for (uint8_t a=0; aunit[a] * segment_length) - mr->gm.target_comp[a]; float target = mr->position[a] + to_add; @@ -1032,16 +1045,15 @@ static stat_t _exec_aline_segment() // Bucket-brigade the old target down the chain before getting the new target from kinematics // // NB: The direct manipulation of steps to compute travel_steps only works for Cartesian kinematics. - // Other kinematics may require transforming travel distance as opposed to simply subtracting steps. - + // Other kinematics may require transforming travel distance as opposed to simply subtracting steps. for (uint8_t m=0; mcommanded_steps[m] = mr->position_steps[m]; // previous segment's position, delayed by 1 segment - mr->position_steps[m] = mr->target_steps[m]; // previous segment's target becomes position - mr->encoder_steps[m] = en_read_encoder(m); // get current encoder position (time aligns to commanded_steps) + mr->commanded_steps[m] = mr->position_steps[m]; // previous segment's position, delayed by 1 segment + mr->position_steps[m] = mr->target_steps[m]; // previous segment's target becomes position + mr->encoder_steps[m] = en_read_encoder(m); // get current encoder position (time aligns to commanded_steps) mr->following_error[m] = mr->encoder_steps[m] - mr->commanded_steps[m]; } - kn_inverse_kinematics(mr->gm.target, mr->target_steps); // now determine the target steps... + kn_inverse_kinematics(mr->gm.target, mr->target_steps); // now determine the target steps... for (uint8_t m=0; mtarget_steps[m] - mr->position_steps[m]; } @@ -1054,7 +1066,7 @@ static stat_t _exec_aline_segment() // Call the stepper prep function ritorno(st_prep_line(travel_steps, mr->following_error, mr->segment_time)); - copy_vector(mr->position, mr->gm.target); // update position from target + copy_vector(mr->position, mr->gm.target); // update position from target if (mr->segment_count == 0) { return (STAT_OK); // this section has run all its segments } diff --git a/g2core/util.h b/g2core/util.h index d5d5aa9b..b69b7c7e 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -205,28 +205,28 @@ inline T avg(const T a,const T b) {return (a+b)/2; } #pragma GCC optimize ("O0") inline void debug_trap(const char *reason) { - __NOP(); #if IN_DEBUGGER == 1 + __NOP(); __asm__("BKPT"); #endif } inline void debug_trap_if_zero(float value, const char *reason) { +#if IN_DEBUGGER == 1 if (fp_ZERO(value)) { __NOP(); -#if IN_DEBUGGER == 1 __asm__("BKPT"); + } #endif - } } inline void debug_trap_if_true(bool condition, const char *reason) { +#if IN_DEBUGGER == 1 if (condition) { __NOP(); -#if IN_DEBUGGER == 1 __asm__("BKPT"); + } #endif - } } #pragma GCC reset_options From ac00174800920221ee083020133dc5909e2335ea Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 21 Feb 2017 17:35:00 -0500 Subject: [PATCH 144/283] Commit new motto --- Motate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Motate b/Motate index c1ffc728..222de41d 160000 --- a/Motate +++ b/Motate @@ -1 +1 @@ -Subproject commit c1ffc728bd23bc224e371af22c3aa7dad10fec94 +Subproject commit 222de41d509543859265bbb41e5e7fc8e0e44ff6 From 526fbcc30fd3a9c1b229f192b971c50503276f9c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 22 Feb 2017 13:38:35 -0500 Subject: [PATCH 145/283] Modifications to mp_exec_aline(). Still has tool farts. Working on that. --- g2core/canonical_machine.cpp | 11 +---- g2core/canonical_machine.h | 2 +- g2core/cycle_feedhold.cpp | 2 +- g2core/g2core.cppproj | 8 ++-- g2core/plan_exec.cpp | 92 ++++++++++++++++++++---------------- g2core/plan_line.cpp | 10 ++-- g2core/plan_zoid.cpp | 24 ++++++++-- 7 files changed, 82 insertions(+), 67 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 329837c8..8ddd1bb5 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1123,11 +1123,6 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_update_model_position(); // update gmx.position to ready for next incoming move - -// if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //mp applies to currently active planner -// cm_cycle_end(); -// return (STAT_OK); -// } if (status == STAT_MINIMUM_LENGTH_MOVE) { if (!mp_has_runnable_buffer(mp)) { // handle condition where zero-length move is last or only move cm_cycle_end(); // ...otherwise cycle will not end properly @@ -1284,10 +1279,6 @@ stat_t cm_straight_feed(const float target[], const bool flags[]) stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_update_model_position(); // <-- ONLY safe because we don't care about status... -// if (status == STAT_MINIMUM_LENGTH_MOVE && !mp_has_runnable_buffer(mp)) { //mp applies to currently active planner -// cm_cycle_end(); -// return (STAT_OK); -// } if (status == STAT_MINIMUM_LENGTH_MOVE) { if (!mp_has_runnable_buffer(mp)) { // handle condition where zero-length move is last or only move cm_cycle_end(); // ...otherwise cycle will not end properly @@ -1564,7 +1555,7 @@ stat_t cm_tro_control(const float P_word, const bool P_flag) // M50.1 static void _exec_program_finalize(float *value, bool *flag) { cmMachineState machine_state = (cmMachineState)value[0]; - cm_set_motion_state(MOTION_STOP); + cm_set_motion_state(MOTION_STOP); // also changes active model back to MODEL // Allow update in the alarm state, to accommodate queue flush (RAS) if ((cm->cycle_state == CYCLE_MACHINING || cm->cycle_state == CYCLE_OFF) && diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 8522d83f..2bd36292 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -115,7 +115,7 @@ typedef enum { // feedhold state machine FEEDHOLD_SYNC, // start hold - sync to latest aline segment FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero - FEEDHOLD_DECEL_END, // end the deceleration + FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops FEEDHOLD_ACTIONS_START, // enter secondary planner and perform feedhold actions (once) FEEDHOLD_ACTIONS_WAIT, // wait for feedhold actions to complete diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 83681881..190c62e8 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -325,7 +325,7 @@ static stat_t _run_p1_hold_entry_actions() // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 cm_set_g30_position(); - cm_set_motion_state(MOTION_STOP); + cm_set_motion_state(MOTION_STOP); // sets cm2 active model to MODEL // execute feedhold actions if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index f1ace99b..fd10f7b0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800036434 + J41800030015 0x284E0A60 - 2000000 + 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index aaaca620..a5eb8ffa 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -294,13 +294,13 @@ stat_t mp_exec_move() // Manage motion state transitions if ((cm->motion_state != MOTION_RUN) && (cm->motion_state != MOTION_HOLD)) { - cm_set_motion_state(MOTION_RUN); + cm_set_motion_state(MOTION_RUN); // also sets active model to RUNTIME } } if (bf->bf_func == NULL) { return(cm_panic(STAT_INTERNAL_ERROR, "mp_exec_move()")); // never supposed to get here } - return (bf->bf_func(bf)); // run the move callback in the planner buffer + return (bf->bf_func(bf)); // run the move callback in the planner buffer } /*************************************************************************/ @@ -404,9 +404,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Zero length moves (and other too-short moves) should have already been removed earlier // But let's still alert the condition should it ever occur -// if (fp_ZERO(bf->length)) { // ...looks for an actual zero here -// rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, "mp_exec_aline() zero length move"); -// } debug_trap_if_zero(bf->length, "mp_exec_aline() zero length move"); // Equalities that must be true for this to work: @@ -425,10 +422,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Start a new move by setting up the runtime singleton (mr) memcpy(&mr->gm, &(bf->gm), sizeof(GCodeState_t)); // copy in the gcode model state bf->block_state = BLOCK_ACTIVE; // note that this buffer is running - // note the planner doesn't look at block_state - mr->block_state = BLOCK_INITIAL_ACTION; - mr->section = SECTION_HEAD; - mr->section_state = SECTION_NEW; + mr->block_state = BLOCK_INITIAL_ACTION; // note the planner doesn't look at block_state // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!! THIS IS THE ONLY PLACE WHERE mr->r AND mr->p ARE ALLOWED TO BE CHANGED !!! @@ -437,6 +431,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block + // Check to make sure no sections are less than MIN_SEGMENT_TIME & adjust if necessary if ((!fp_ZERO(mr->r->head_length)) && (mr->r->head_time < MIN_SEGMENT_TIME)) { // head_time !== body_time @@ -495,10 +490,21 @@ stat_t mp_exec_aline(mpBuf_t *bf) } } + // transfer move parameters from planner buffer to the runtime copy_vector(mr->unit, bf->unit); - copy_vector(mr->target, bf->gm.target); // save the final target of the move + copy_vector(mr->target, bf->gm.target); copy_vector(mr->axis_flags, bf->axis_flags); + // characterize the move for starting section - head/body/tail + mr->section_state = SECTION_NEW; + mr->section = SECTION_HEAD; + if (fp_ZERO(mr->r->head_length)) { + mr->section = SECTION_BODY; + if (fp_ZERO(mr->r->body_length)) { + mr->section = SECTION_TAIL; + } + } + // generate the way points for position correction at section ends for (uint8_t axis=0; axiswaypoint[SECTION_HEAD][axis] = mr->position[axis] + mr->unit[axis] * mr->r->head_length; @@ -540,7 +546,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish // finalize position and velocity copy_vector(mr->position, mr->gm.target); // update position from target - bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEsT + bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS mp_zero_segment_velocity(); // for reporting purposes // when homing or probing don't stay in HOLD or execute entry actions @@ -560,7 +566,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Case (5) - Decelerated to zero. See also Feedhold Case (5, continued), toward end of mp_exec_aline() // Update the run buffer then force a replan of the whole planner queue. Replans from 0 velocity - if (cm->hold_state == FEEDHOLD_DECEL_END) { + if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer cm->hold_state = FEEDHOLD_STOPPING; @@ -579,7 +585,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { // Case (3a) - Already decelerating, continue the deceleration. - if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are + if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; } else { @@ -595,6 +601,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->section_state = SECTION_NEW; mr->r->head_length = 0; mr->r->body_length = 0; + mr->r->head_time = 0; // +++++ can this be taken out? + mr->r->body_time = 0; // +++++ ditto float available_length = get_axis_vector_length(mr->target, mr->position); mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length @@ -606,7 +614,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->tail_length = available_length; mr->r->exit_velocity = 0; - // (1b) The deceleration clearly has to span multiple moves + // (1b) The deceleration has to span multiple moves } else if (available_length < mr->r->tail_length) { mr->r->tail_length = available_length; mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); @@ -617,12 +625,13 @@ stat_t mp_exec_aline(mpBuf_t *bf) cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } - // (1a) The deceleration will fit easily into the current move - } else { + // (1a) The deceleration will fit into the current move + } else { cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr->r->exit_velocity = 0; } mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); + bf->block_time = mr->r->tail_time; } } } @@ -656,7 +665,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Case (5, continued): Look for the end of the deceleration to go into HOLD state if (cm->hold_state == FEEDHOLD_DECEL_TO_ZERO) { if ((status == STAT_OK) || (status == STAT_NOOP)) { - cm->hold_state = FEEDHOLD_DECEL_END; + cm->hold_state = FEEDHOLD_DECEL_COMPLETE; bf->block_state = BLOCK_INITIAL_ACTION; // reset bf so it can restart the rest of the move } } @@ -872,15 +881,15 @@ static void _init_forward_diffs(const float v_0, const float v_1) static stat_t _exec_aline_head(mpBuf_t *bf) { bool first_pass = false; - if (mr->section_state == SECTION_NEW) { // INITIALIZATION + if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; if (fp_ZERO(mr->r->head_length)) { mr->section = SECTION_BODY; - return(_exec_aline_body(bf)); // skip ahead to the body generator + return(_exec_aline_body(bf)); // skip ahead to the body generator } mr->segments = ceil(uSec(mr->r->head_time) / NOM_SEGMENT_USEC);// # of segments for the section mr->segment_count = (uint32_t)mr->segments; - mr->segment_time = mr->r->head_time / mr->segments; // time to advance for each segment + mr->segment_time = mr->r->head_time / mr->segments; // time to advance for each segment if (mr->segment_count == 1) { // We will only have one segment, simply average the velocities @@ -890,22 +899,22 @@ static stat_t _exec_aline_head(mpBuf_t *bf) } if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); - return(STAT_OK); // exit without advancing position, say we're done + return(STAT_OK); // exit without advancing position, say we're done } - mr->section = SECTION_HEAD; + mr->section = SECTION_HEAD; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { mr->segment_velocity += mr->forward_diff_5; } - if (_exec_aline_segment() == STAT_OK) { // set up for second half + if (_exec_aline_segment() == STAT_OK) { // set up for second half if ((fp_ZERO(mr->r->body_length)) && (fp_ZERO(mr->r->tail_length))) { - return(STAT_OK); // ends the move + return(STAT_OK); // ends the move } - - mr->section = SECTION_BODY; + mr->section = SECTION_BODY; // advance to body mr->section_state = SECTION_NEW; - } else if (!first_pass) { + } + else if (!first_pass) { mr->forward_diff_5 += mr->forward_diff_4; mr->forward_diff_4 += mr->forward_diff_3; mr->forward_diff_3 += mr->forward_diff_2; @@ -925,9 +934,8 @@ static stat_t _exec_aline_body(mpBuf_t *bf) if (mr->section_state == SECTION_NEW) { if (fp_ZERO(mr->r->body_length)) { mr->section = SECTION_TAIL; - return(_exec_aline_tail(bf)); // skip ahead to tail periods + return(_exec_aline_tail(bf)); // skip ahead to tail generator } - float body_time = mr->r->body_time; mr->segments = ceil(uSec(body_time) / NOM_SEGMENT_USEC); mr->segment_time = body_time / mr->segments; @@ -938,14 +946,14 @@ static stat_t _exec_aline_body(mpBuf_t *bf) return(STAT_OK); // exit without advancing position, say we're done } - mr->section = SECTION_BODY; + mr->section = SECTION_BODY; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done if (fp_ZERO(mr->r->tail_length)) { return(STAT_OK); // ends the move } - mr->section = SECTION_TAIL; + mr->section = SECTION_TAIL; // advance to tail mr->section_state = SECTION_NEW; } return(STAT_EAGAIN); @@ -960,34 +968,34 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) bool first_pass = false; if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; + bf->plannable = false; // Mark the block as unplannable - // Mark the block as unplannable - bf->plannable = false; - - if (fp_ZERO(mr->r->tail_length)) { return(STAT_OK);} // end the move + if (fp_ZERO(mr->r->tail_length)) { // end the move + return(STAT_OK); + } mr->segments = ceil(uSec(mr->r->tail_time) / NOM_SEGMENT_USEC);// # of segments for the section mr->segment_count = (uint32_t)mr->segments; - mr->segment_time = mr->r->tail_time / mr->segments; // time to advance for each segment + mr->segment_time = mr->r->tail_time / mr->segments; // time to advance for each segment if (mr->segment_count == 1) { mr->segment_velocity = mr->r->tail_length / mr->segment_time; } else { - _init_forward_diffs(mr->r->cruise_velocity, mr->r->exit_velocity); // <-- sets inital segment_velocity + _init_forward_diffs(mr->r->cruise_velocity, mr->r->exit_velocity); // sets initial segment_velocity } if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); - return(STAT_OK); // exit without advancing position, say we're done - // return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position + return(STAT_OK); // exit without advancing position, say we're done } - mr->section = SECTION_TAIL; + mr->section = SECTION_TAIL; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { mr->segment_velocity += mr->forward_diff_5; } if (_exec_aline_segment() == STAT_OK) { - return(STAT_OK); // STAT_OK completes the move - } else if (!first_pass) { + return(STAT_OK); // STAT_OK completes the move + } + else if (!first_pass) { mr->forward_diff_5 += mr->forward_diff_4; mr->forward_diff_4 += mr->forward_diff_3; mr->forward_diff_3 += mr->forward_diff_2; diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 40deeef0..7958b0b3 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -655,7 +655,7 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa /* * _calculate_junction_vmax() - Giseburt's Algorithm ;-) * - * WARNING: This description is out of date and needs updated. + * WARNING: This description is out of date and needs to be updated. * * Computes the maximum allowable junction speed by finding the velocity that will not * violate the jerk value of any axis. @@ -664,14 +664,14 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa * of the corner, at the point from vector a to vector b. The unit vectors of those two * moves are provided as the current block (a_unit) and previous block (b_unit). * - * Delta[i] = (b_unit[i] - a_unit[i]) (1) + * Delta[i] = (b_unit[i] - a_unit[i]) (1) * * We take, axis by axis, the difference in "unit velocity" to get a vector that * represents the direction of acceleration - which may be the opposite direction * as that of the "a" vector to achieve deceleration. To get the actual acceleration, * we use the corner velocity (what we intend to calculate) as the magnitude. * - * Acceleration[i] = UnitAccel[i] * Velocity[i] (2) + * Acceleration[i] = UnitAccel[i] * Velocity[i] (2) * * Since we need the jerk value, which is defined as the "rate of change of acceleration, * that is, the derivative of acceleration with respect to time" (Wikipedia), we need to @@ -679,14 +679,14 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa * physics. That will give us the time over which to "apply" the change of acceleration * in order to get a physically realistic jerk. The yields a fairly simple formula: * - * Jerk[i] = Acceleration[i] / Time (3) + * Jerk[i] = Acceleration[i] / Time (3) * * Now that we can compute the jerk for a given corner, we need to know the maximum * velocity that we can take the corner without violating that jerk for any axis. * Let's incorporate formula (2) into formula (3), and solve for Velocity, using * the known max Jerk and UnitAccel for this corner: * - * Velocity[i] = (Jerk[i] * Time) / UnitAccel[i] (4) + * Velocity[i] = (Jerk[i] * Time) / UnitAccel[i] (4) * * We then compute (4) for each axis, and use the smallest (most limited) result or * vmax, whichever is smaller. diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index bbff69e0..866322f2 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -139,11 +139,16 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e block->body_length = 0; block->tail_length = 0; - block->cruise_velocity = min(bf->cruise_velocity, bf->cruise_vmax); + // these conditions should have been met earlier, but if they are not trap and correct them + debug_trap_if_true((bf->exit_velocity > bf->exit_vmax), "mp_calculate_ramps() - Vexit > Vexit_max"); block->exit_velocity = min(bf->exit_velocity, bf->exit_vmax); + // +++++ THIS WILL NEED TO CHANGE TO SUPPORT OVERRIDES +// debug_trap_if_true((bf->cruise_velocity, bf->cruise_vmax), "mp_calculate_ramps() - Vcruise > Vcruise_max"); + block->cruise_velocity = min(bf->cruise_velocity, bf->cruise_vmax); + // We *might* do this exact computation later, so cache the value - float test_velocity = 0; + float test_velocity = 0; bool test_velocity_valid = false; // record if we have a validly cached value // *** Perfect-Fit Cases (1) *** Cases where curve fitting has already been done @@ -397,7 +402,7 @@ float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t* bf) /* * mp_get_decel_velocity() - mp_get_target_velocity but ONLY for deceleration * - * Get "the velocity" that we would end up at if we *decelerated* from v_0, + * Get the velocity that we would end up at if we decelerated from v_0, * over the provided L (length) and J (jerk, provided in the bf structure). * * We have to use a root finding solution, since there is actually three possible @@ -409,6 +414,9 @@ float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t* bf) * * This function may generate minor errors in target velocity, and should only * be used to compute feedholds or other cases where exact velocity is not mandatory. + * + * This function can fail if the length is too short to get a good answer. + * Failures return (float)-1.0 Negative velocities should never be returned. */ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) @@ -426,7 +434,7 @@ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) // The return condition allows a minor error in length (in mm). // Note: This comparison does NOT affect actual lengths or steps, which would be bad. // The actual lengths traveled must be controlled by the caller. - if (fabs(l_t) < 0.001) { + if (fabs(l_t) < 0.001) { break; } // For the first pass we tested velocity 0. If velocity 0 yields a l_t > 0, @@ -439,10 +447,18 @@ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) const float v_1x3 = 3 * v_1; const float recip_l_t = (2 * sqrt_delta_v_0) / ((v_0 - v_1x3) * q_recip_2_sqrt_j); v_1 = v_1 - (l_t * recip_l_t); + + // hack for cases where there is no solution because the length is so short + if (v_1 > v_0) { +// return (-1.0); // cannot decelerate. Return an error + return (v_0); // cannot decelerate. Return entry velocity + } } return v_1; } +//Is there a way to derive the average slope of a deceleration given the starting velocity, length and jerk? We don't need the + /* * _get_meet_velocity() - find intersection velocity * From 9b751888f0a32dd0d11f18251cb5f19bc3cad906 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 22 Feb 2017 14:56:03 -0500 Subject: [PATCH 146/283] Simplified feedhole cases 1a - 1c prior to remaining work --- g2core/canonical_machine.h | 2 +- g2core/plan_exec.cpp | 62 +++++++++++++++++--------------------- g2core/plan_line.cpp | 3 +- g2core/plan_zoid.cpp | 4 +-- 4 files changed, 33 insertions(+), 38 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 2bd36292..e5e2978f 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -116,7 +116,7 @@ typedef enum { // feedhold state machine FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed - FEEDHOLD_STOPPING, // waiting to complete deceleration once planner motion stops + FEEDHOLD_MOTORS_STOPPING, // waiting to complete deceleration once planner motion stops FEEDHOLD_ACTIONS_START, // enter secondary planner and perform feedhold actions (once) FEEDHOLD_ACTIONS_WAIT, // wait for feedhold actions to complete FEEDHOLD_HOLD, // holding (steady state) Must be last state diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index a5eb8ffa..e9d6e60f 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -519,12 +519,13 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): // (1) - We have a block midway through normal execution and a new feedhold request // (1a) - The deceleration will fit in the length remaining in the running block (mr) - // (1b) - The deceleration will not fit in the running block - // (1c) - 1a, except the remaining length would be zero or EPSILON close to zero (unlikely) + // (1b) - 1a, except the remaining length would be zero or EPSILON2 close to zero (unlikely) + // (1c) - The deceleration will not fit in the running block // (2) - We have a new block and a new feedhold request that arrived at EXACTLY the same time (unlikely, but handled) // (3) - We are in the middle of a block // (3a) - The block is currently accelerating (we wait for the body to start) - // (3b) - The block is currently in the tail (we wait until the end of the block) + // (3b) - The block is in a body (or has not yet started the head) - start deceleration + // (3c) - The block is currently in the tail (we wait until the end of the block) // (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) // (5) - We have decelerated a block to zero velocity // (6) - We have finished all the runtime work now we have to wait for the steppers to stop @@ -542,7 +543,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Case (6) - Wait for the steppers to stop - if (cm->hold_state == FEEDHOLD_STOPPING) { + if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish // finalize position and velocity copy_vector(mr->position, mr->gm.target); // update position from target @@ -565,11 +566,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Case (5) - Decelerated to zero. See also Feedhold Case (5, continued), toward end of mp_exec_aline() - // Update the run buffer then force a replan of the whole planner queue. Replans from 0 velocity + // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - cm->hold_state = FEEDHOLD_STOPPING; + cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop // No point bothering with the rest of this move if homing or probing if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { @@ -579,12 +580,12 @@ stat_t mp_exec_aline(mpBuf_t *bf) return (STAT_OK); } - // Cases (1a, 1b), Case (2), Case (4) + // Cases (1a, 1b, 1c), Case (2), Case (4) // Build a tail-only move from here. Decelerate as fast as possible in the space we have. if ((cm->hold_state == FEEDHOLD_SYNC) || ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { - // Case (3a) - Already decelerating, continue the deceleration. + // Case (3c) - Already decelerating (in a tail), continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; @@ -592,46 +593,39 @@ stat_t mp_exec_aline(mpBuf_t *bf) cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } - // Case (3b) - Currently accelerating - is simply skipped and waited for. + // Case (3a) - Currently accelerating (in a head), skip and waited for body or tail // This is true because to do otherwise the jerk would not have returned to zero. // Small exception, if we *just started* the head, then we're not actually accelerating yet. + + // Case (3b) - Block is in a body, or about to start a new head. Turn it into a new tail. } else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { - mr->entry_velocity = mr->segment_velocity; mr->section = SECTION_TAIL; mr->section_state = SECTION_NEW; + mr->entry_velocity = mr->segment_velocity; mr->r->head_length = 0; mr->r->body_length = 0; - mr->r->head_time = 0; // +++++ can this be taken out? - mr->r->body_time = 0; // +++++ ditto - float available_length = get_axis_vector_length(mr->target, mr->position); + mr->r->head_time = 0; + mr->r->body_time = 0; mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length - + // (1c) The deceleration distance is almost exactly the remaining of the current move. // This happens mostly when the tail in the move was already planned to zero. // EPSILON2 deals with floating point rounding errors that might mis-classify this move. - if (fabs(available_length - mr->r->tail_length) < EPSILON2) { - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - mr->r->tail_length = available_length; - mr->r->exit_velocity = 0; + float available_length = get_axis_vector_length(mr->target, mr->position); - // (1b) The deceleration has to span multiple moves - } else if (available_length < mr->r->tail_length) { + if ((available_length + EPSILON2 - mr->r->tail_length) < 0) { // it will fit + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; + mr->r->exit_velocity = 0; + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); +// bf->block_time = mr->r->tail_time; + } + else { + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr->r->tail_length = available_length; mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); - - if (fp_ZERO(mr->r->exit_velocity)) { // this takes care of an odd case where the move - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO;// was previously mis-classified as a CONTINUE move - } else { - cm->hold_state = FEEDHOLD_DECEL_CONTINUE; - } - - // (1a) The deceleration will fit into the current move - } else { - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - mr->r->exit_velocity = 0; - } - mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); - bf->block_time = mr->r->tail_time; + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); +// bf->block_time = mr->r->tail_time; + } } } } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 7958b0b3..a1509cd9 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -704,7 +704,8 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa static void _calculate_junction_vmax(mpBuf_t* bf) { // If we change cruise_vmax, we'll need to recompute junction_vmax, if we do this: - float velocity = min(bf->cruise_vmax, bf->nx->cruise_vmax); // start with our maximum possible velocity +// float velocity = min(bf->cruise_vmax, bf->nx->cruise_vmax); // start with our maximum possible velocity + float velocity = 8675309; // cmAxes jerk_axis = AXIS_X; // a diagnostic in case you want to find the limiting axis diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 866322f2..d85c6641 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -450,8 +450,8 @@ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) // hack for cases where there is no solution because the length is so short if (v_1 > v_0) { -// return (-1.0); // cannot decelerate. Return an error - return (v_0); // cannot decelerate. Return entry velocity + return (-1.0); // cannot decelerate. Return an error +// return (v_0); // cannot decelerate. Return entry velocity } } return v_1; From 12c2138103e2534e747227af032b9d95f45f775b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 22 Feb 2017 15:19:25 -0500 Subject: [PATCH 147/283] FIFY --- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 15 ++++++++------- g2core/plan_zoid.cpp | 3 ++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index fd10f7b0..0f364b26 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 2000000 SWD @@ -102,7 +102,7 @@ true J41800030015 0x284E0A60 - 10000000 + 2000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index e9d6e60f..0e04c66a 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -608,23 +608,24 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->r->body_time = 0; mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length - // (1c) The deceleration distance is almost exactly the remaining of the current move. - // This happens mostly when the tail in the move was already planned to zero. - // EPSILON2 deals with floating point rounding errors that might mis-classify this move. + // (1a, 1b) The deceleration distance either fits in the available length (1a) or fits + // exactly or close enough (to EPSILON2) (1b). Case 1b happens when the tail in the move + // was already planned to zero. This is also case (2). EPSILON2 deals with floating point + // rounding errors that can mis-classify this case. float available_length = get_axis_vector_length(mr->target, mr->position); - if ((available_length + EPSILON2 - mr->r->tail_length) < 0) { // it will fit + if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { // it will fit cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr->r->exit_velocity = 0; mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); -// bf->block_time = mr->r->tail_time; + bf->block_time = mr->r->tail_time; } else { - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; + cm->hold_state = FEEDHOLD_DECEL_CONTINUE; mr->r->tail_length = available_length; mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); -// bf->block_time = mr->r->tail_time; + bf->block_time = mr->r->tail_time; } } } diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index d85c6641..18f5ef9a 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -447,12 +447,13 @@ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) const float v_1x3 = 3 * v_1; const float recip_l_t = (2 * sqrt_delta_v_0) / ((v_0 - v_1x3) * q_recip_2_sqrt_j); v_1 = v_1 - (l_t * recip_l_t); - +/* // hack for cases where there is no solution because the length is so short if (v_1 > v_0) { return (-1.0); // cannot decelerate. Return an error // return (v_0); // cannot decelerate. Return entry velocity } +*/ } return v_1; } From c04d6932f7ac3f56b82d64acd02c39d764b59e24 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 22 Feb 2017 17:15:53 -0500 Subject: [PATCH 148/283] Solves both issues in double-weirdness --- g2core/g2core.cppproj | 8 +- g2core/plan_exec.cpp | 270 +++++++++++++++++++++++------------------- g2core/planner.h | 1 + 3 files changed, 154 insertions(+), 125 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0f364b26..b67c56bb 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 2000000 + 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 0e04c66a..71d5929c 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -43,6 +43,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf); // passing bf because body might ne static stat_t _exec_aline_body(mpBuf_t *bf); // passing bf so that body can extend itself if the exit velocity rises. static stat_t _exec_aline_tail(mpBuf_t *bf); static stat_t _exec_aline_segment(void); +static stat_t _exec_feedhold_processing(mpBuf_t *bf); static void _init_forward_diffs(float v_0, float v_1); @@ -393,6 +394,8 @@ stat_t mp_exec_move() stat_t mp_exec_aline(mpBuf_t *bf) { + stat_t status; + if (bf->block_state == BLOCK_INACTIVE) { return (STAT_NOOP); } @@ -428,6 +431,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // !!! THIS IS THE ONLY PLACE WHERE mr->r AND mr->p ARE ALLOWED TO BE CHANGED !!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Swap P and R blocks + mr->previous_exit_velocity = mr->r->exit_velocity; mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block @@ -514,133 +518,23 @@ stat_t mp_exec_aline(mpBuf_t *bf) } // Feed Override Processing - We need to handle the following cases (listed in rough sequence order): - // (1) - We've received a feed override request in the middle of a cycle // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): - // (1) - We have a block midway through normal execution and a new feedhold request - // (1a) - The deceleration will fit in the length remaining in the running block (mr) - // (1b) - 1a, except the remaining length would be zero or EPSILON2 close to zero (unlikely) - // (1c) - The deceleration will not fit in the running block - // (2) - We have a new block and a new feedhold request that arrived at EXACTLY the same time (unlikely, but handled) - // (3) - We are in the middle of a block - // (3a) - The block is currently accelerating (we wait for the body to start) - // (3b) - The block is in a body (or has not yet started the head) - start deceleration - // (3c) - The block is currently in the tail (we wait until the end of the block) - // (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) - // (5) - We have decelerated a block to zero velocity - // (6) - We have finished all the runtime work now we have to wait for the steppers to stop - // (6a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF - // (6b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush - // (6c) - It's a normal feedhold - signal we want the entry action - // (7) - The steppers have stopped. No motion should occur. Allows hold actions to complete - // (8) - We are removing the hold state and there is queued motion (handled outside this routine) - // (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) - if (cm->motion_state == MOTION_HOLD) { - // Case (7) - All motion has ceased - if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement - } - - // Case (6) - Wait for the steppers to stop - if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { - if (mp_runtime_is_idle()) { // wait for steppers to actually finish - // finalize position and velocity - copy_vector(mr->position, mr->gm.target); // update position from target - bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS - mp_zero_segment_velocity(); // for reporting purposes - - // when homing or probing don't stay in HOLD or execute entry actions - if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - cm->hold_state = FEEDHOLD_OFF; - } else if (cm == &cm2) { // if in p2 hold set up a flush - cm->hold_state = FEEDHOLD_P2_EXIT; - } else { - cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions - } - - sr_request_status_report(SR_REQUEST_IMMEDIATE); - cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE - } - return (STAT_OK); // hold here. No more movement - } - - // Case (5) - Decelerated to zero. See also Feedhold Case (5, continued), toward end of mp_exec_aline() - // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity - if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop - - // No point bothering with the rest of this move if homing or probing - if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - mp_free_run_buffer(); - } - mp_replan_queue(mp_get_r()); // make it replan all the blocks - return (STAT_OK); - } - - // Cases (1a, 1b, 1c), Case (2), Case (4) - // Build a tail-only move from here. Decelerate as fast as possible in the space we have. - if ((cm->hold_state == FEEDHOLD_SYNC) || - ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { - - // Case (3c) - Already decelerating (in a tail), continue the deceleration. - if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are - if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - } else { - cm->hold_state = FEEDHOLD_DECEL_CONTINUE; - } - - // Case (3a) - Currently accelerating (in a head), skip and waited for body or tail - // This is true because to do otherwise the jerk would not have returned to zero. - // Small exception, if we *just started* the head, then we're not actually accelerating yet. - - // Case (3b) - Block is in a body, or about to start a new head. Turn it into a new tail. - } else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { - mr->section = SECTION_TAIL; - mr->section_state = SECTION_NEW; - mr->entry_velocity = mr->segment_velocity; - mr->r->head_length = 0; - mr->r->body_length = 0; - mr->r->head_time = 0; - mr->r->body_time = 0; - mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length - - // (1a, 1b) The deceleration distance either fits in the available length (1a) or fits - // exactly or close enough (to EPSILON2) (1b). Case 1b happens when the tail in the move - // was already planned to zero. This is also case (2). EPSILON2 deals with floating point - // rounding errors that can mis-classify this case. - float available_length = get_axis_vector_length(mr->target, mr->position); - - if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { // it will fit - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - mr->r->exit_velocity = 0; - mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); - bf->block_time = mr->r->tail_time; - } - else { - cm->hold_state = FEEDHOLD_DECEL_CONTINUE; - mr->r->tail_length = available_length; - mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); - mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); - bf->block_time = mr->r->tail_time; - } - } + if ((status = _exec_feedhold_processing(bf)) != STAT_EAGAIN) { + return (status); } } - // End Feedhold Processing mr->block_state = BLOCK_ACTIVE; // NB: from this point on the contents of the bf buffer do not affect execution //**** main dispatcher to process segments *** - stat_t status = STAT_OK; - if (mr->section == SECTION_HEAD) { status = _exec_aline_head(bf);} - else if (mr->section == SECTION_BODY) { status = _exec_aline_body(bf);} - else if (mr->section == SECTION_TAIL) { status = _exec_aline_tail(bf);} + status = STAT_OK; + if (mr->section == SECTION_HEAD) { status = _exec_aline_head(bf); } + else if (mr->section == SECTION_BODY) { status = _exec_aline_body(bf); } + else if (mr->section == SECTION_TAIL) { status = _exec_aline_tail(bf); } else { return(cm_panic(STAT_INTERNAL_ERROR, "exec_aline()"));} // never supposed to get here // Conditionally set the move to be unplannable. We can't use the if/else block above, @@ -878,7 +772,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) bool first_pass = false; if (mr->section_state == SECTION_NEW) { // INITIALIZATION first_pass = true; - if (fp_ZERO(mr->r->head_length)) { + if (fp_ZERO(mr->r->head_length)) { // Needed here as feedhold may have changed the block mr->section = SECTION_BODY; return(_exec_aline_body(bf)); // skip ahead to the body generator } @@ -890,7 +784,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) // We will only have one segment, simply average the velocities mr->segment_velocity = mr->r->head_length / mr->segment_time; } else { - _init_forward_diffs(mr->entry_velocity, mr->r->cruise_velocity); // <-- sets inital segment_velocity + _init_forward_diffs(mr->entry_velocity, mr->r->cruise_velocity); // sets initial segment_velocity } if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); @@ -927,7 +821,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) static stat_t _exec_aline_body(mpBuf_t *bf) { if (mr->section_state == SECTION_NEW) { - if (fp_ZERO(mr->r->body_length)) { + if (fp_ZERO(mr->r->body_length)) { // Needed here as feedhold may have changed the block mr->section = SECTION_TAIL; return(_exec_aline_tail(bf)); // skip ahead to tail generator } @@ -965,8 +859,8 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) first_pass = true; bf->plannable = false; // Mark the block as unplannable - if (fp_ZERO(mr->r->tail_length)) { // end the move - return(STAT_OK); + if (fp_ZERO(mr->r->tail_length)) { // Needed here as feedhold may have changed the block + return(STAT_OK); // end the move } mr->segments = ceil(uSec(mr->r->tail_time) / NOM_SEGMENT_USEC);// # of segments for the section mr->segment_count = (uint32_t)mr->segments; @@ -1075,3 +969,137 @@ static stat_t _exec_aline_segment() } return (STAT_EAGAIN); // this section still has more segments to run } + + +/********************************************************************************************* + * _exec_feedhold_processing() - + +// Feedhold Processing - We need to handle the following cases (listed in rough sequence order): +// (1) - We have a block midway through normal execution and a new feedhold request +// (1a) - The deceleration will fit in the length remaining in the running block (mr) +// (1b) - 1a, except the remaining length would be zero or EPSILON2 close to zero (unlikely) +// (1c) - The deceleration will not fit in the running block +// (2) - We have a new block and a new feedhold request that arrived at EXACTLY the same time (unlikely, but handled) +// (3) - We are in the middle of a block +// (3a) - The block is currently accelerating (we wait for the body to start) +// (3b) - The block is in a body (or has not yet started the head) - start deceleration +// (3c) - The block is currently in the tail (we wait until the end of the block) +// (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) +// (5) - We have decelerated a block to zero velocity +// (6) - We have finished all the runtime work now we have to wait for the steppers to stop +// (6a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF +// (6b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush +// (6c) - It's a normal feedhold - signal we want the entry action +// (7) - The steppers have stopped. No motion should occur. Allows hold actions to complete +// (8) - We are removing the hold state and there is queued motion (handled outside this routine) +// (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) + +* STAT_OK stops move execution +* STAT_NOOP stops move execution and prevents the next move from loading. Should only be used on an inactive block +* STAT_EAGAIN continues execution of mp_exec_aline() +*/ + +static stat_t _exec_feedhold_processing(mpBuf_t *bf) +{ + if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + } + + // Case (6) - Wait for the steppers to stop + if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { + if (mp_runtime_is_idle()) { // wait for steppers to actually finish + // finalize position and velocity + copy_vector(mr->position, mr->gm.target); // update position from target + bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS + mp_zero_segment_velocity(); // for reporting purposes + + // when homing or probing don't stay in HOLD or execute entry actions + if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { + cm->hold_state = FEEDHOLD_OFF; + } else if (cm == &cm2) { // if in p2 hold set up a flush + cm->hold_state = FEEDHOLD_P2_EXIT; + } else { + cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions + } + + sr_request_status_report(SR_REQUEST_IMMEDIATE); + cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE + } + return (STAT_OK); // hold here. No more movement + } + + // Case (5) - Decelerated to zero. See also Feedhold Case (5, continued), toward end of mp_exec_aline() + // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity + if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop + + // No point bothering with the rest of this move if homing or probing + if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { + mp_free_run_buffer(); + } + mp_replan_queue(mp_get_r()); // make it replan all the blocks + return (STAT_OK); + } + + // Cases (1a, 1b, 1c), Case (2), Case (4) + // Build a tail-only move from here. Decelerate as fast as possible in the space we have. + if ((cm->hold_state == FEEDHOLD_SYNC) || + ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { + + // Case (3c) - Already decelerating (in a tail), continue the deceleration. + if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are + if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; + } else { + cm->hold_state = FEEDHOLD_DECEL_CONTINUE; + } + return (STAT_EAGAIN); + } + + // Case (3a) - Currently accelerating (in a head), skip and waited for body or tail + // This is true because to do otherwise the jerk would not have returned to zero. + // Small exception, if we *just started* the head, then we're not actually accelerating yet. + if ((mr->section == SECTION_HEAD) && (mr->section_state != SECTION_NEW)) { + return (STAT_EAGAIN); + } + + // Case (3b) - Block is in a body, or about to start a new head. Turn it into a new tail. + // else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { + + // In the new head case plan deceleration move (tail) starting at the at the entry velocity + if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { + mr->section = SECTION_TAIL; + mr->section_state = SECTION_NEW; + mr->entry_velocity = mr->segment_velocity; + mr->r->cruise_velocity = mr->entry_velocity; // cruise velocity must be set even if there's no body + mr->r->head_length = 0; + mr->r->body_length = 0; + mr->r->head_time = 0; + mr->r->body_time = 0; + mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length + + // (1a, 1b) The deceleration distance either fits in the available length (1a) or fits + // exactly or close enough (to EPSILON2) (1b). Case 1b happens when the tail in the move + // was already planned to zero. This is also case (2). EPSILON2 deals with floating point + // rounding errors that can mis-classify this case. + float available_length = get_axis_vector_length(mr->target, mr->position); + + if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { // it will fit + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; + mr->r->exit_velocity = 0; + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); + bf->block_time = mr->r->tail_time; + } + else { + cm->hold_state = FEEDHOLD_DECEL_CONTINUE; + mr->r->tail_length = available_length; + mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); + bf->block_time = mr->r->tail_time; + } + } + } + return (STAT_EAGAIN); +} diff --git a/g2core/planner.h b/g2core/planner.h index 606c2785..c637d947 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -467,6 +467,7 @@ typedef struct mpPlannerRuntime { // persistent runtime variables mpBlockRuntimeBuf_t bf[2]; // buffer holding the two blocks float entry_velocity; // entry values for the currently running block + float previous_exit_velocity; float segments; // number of segments in line (also used by arc generation) uint32_t segment_count; // count of running segments From 3bbda127c48c63a989507ed788b70783628914b8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 23 Feb 2017 06:27:23 -0500 Subject: [PATCH 149/283] Checkpoint - working on planner refit cases --- g2core/g2core.cppproj | 6 +- g2core/plan_exec.cpp | 170 ++++++++++++++++++++---------------------- g2core/plan_zoid.cpp | 3 +- g2core/planner.h | 2 +- 4 files changed, 84 insertions(+), 97 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b67c56bb..eef20ce4 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 2000000 SWD @@ -102,7 +102,7 @@ true J41800036434 0x284E0A60 - 10000000 + 2000000 @@ -376,7 +376,7 @@ True - CONFIG=ShopbotTestV9 COLOR=0 VERBOSE=1 + CONFIG=ShopbotTestV9 COLOR=0 VERBOSE=1 DEBUG=2 clean CONFIG=ShopbotTestV9 Makefile bin\G2v9k\ diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 71d5929c..ec5f69c3 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -431,25 +431,23 @@ stat_t mp_exec_aline(mpBuf_t *bf) // !!! THIS IS THE ONLY PLACE WHERE mr->r AND mr->p ARE ALLOWED TO BE CHANGED !!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Swap P and R blocks - mr->previous_exit_velocity = mr->r->exit_velocity; + mr->previous_exit_velocity = mr->r->exit_velocity; // +++++ DIAGNOSTIC mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block // Check to make sure no sections are less than MIN_SEGMENT_TIME & adjust if necessary - if ((!fp_ZERO(mr->r->head_length)) && (mr->r->head_time < MIN_SEGMENT_TIME)) { - // head_time !== body_time - // We have to compute the new body time addition. + if ((mr->r->head_length > 0) && (mr->r->head_time < MIN_SEGMENT_TIME)) { + // Compute the new body time. head_time !== body_time mr->r->body_length += mr->r->head_length; - mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; + mr->r->body_time = mr->r->body_length / mr->r->cruise_velocity; mr->r->head_length = 0; mr->r->head_time = 0; } - if ((!fp_ZERO(mr->r->tail_length)) && (mr->r->tail_time < MIN_SEGMENT_TIME)) { - // tail_time !== body_time - // We have to compute the new body time addition. + if ((mr->r->tail_length > 0) && (mr->r->tail_time < MIN_SEGMENT_TIME)) { + // Compute the new body time. tail_time !== body_time mr->r->body_length += mr->r->tail_length; - mr->r->body_time = mr->r->body_length/mr->r->cruise_velocity; + mr->r->body_time = mr->r->body_length / mr->r->cruise_velocity; mr->r->tail_length = 0; mr->r->tail_time = 0; } @@ -458,37 +456,32 @@ stat_t mp_exec_aline(mpBuf_t *bf) // If the body is still too "short" (brief) we *might* be able to add it to a head or tail. // If there's still a head or a tail, we will add the body to whichever there is, maybe both. // We saved it for last since it's the most expensive. - if ((!fp_ZERO(mr->r->body_length)) && (mr->r->body_time < MIN_SEGMENT_TIME)) { + if ((mr->r->body_length > 0) && (mr->r->body_time < MIN_SEGMENT_TIME)) { // We'll add the time to either the head or the tail or split it if (mr->r->tail_length > 0) { - if (mr->r->head_length > 0) { - // We'll split the body to the head and tail - float body_split = mr->r->body_length/2.0; + if (mr->r->head_length > 0) { // Split the body to the head and tail + mr->r->head_length += mr->r->body_length * 0.5; + mr->r->tail_length += mr->r->body_length * 0.5; // let the compiler optimize out one of these * + mr->r->head_time = (2.0 * mr->r->head_length) / (mr->entry_velocity + mr->r->cruise_velocity); + mr->r->tail_time = (2.0 * mr->r->tail_length) / (mr->r->cruise_velocity + mr->r->exit_velocity); mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->head_length += body_split; - mr->r->tail_length += body_split; - mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); - mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); - } else { - // We'll put it all in the tail + } else { // Put it all in the tail mr->r->tail_length += mr->r->body_length; + mr->r->tail_time = (2.0 * mr->r->tail_length) / (mr->r->cruise_velocity + mr->r->exit_velocity); mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->tail_time = (2.0 * mr->r->tail_length)/(mr->r->cruise_velocity + mr->r->exit_velocity); } } - else if (mr->r->head_length > 0) { - // We'll put it all in the head + else if (mr->r->head_length > 0) { // Put it all in the head mr->r->head_length += mr->r->body_length; + mr->r->head_time = (2.0 * mr->r->head_length) / (mr->entry_velocity + mr->r->cruise_velocity); mr->r->body_length = 0; mr->r->body_time = 0; - mr->r->head_time = (2.0 * mr->r->head_length)/(mr->entry_velocity + mr->r->cruise_velocity); } - else { - // Uh oh! We have a move that's all body, and is still too short!! - // while (1); // RG: For now, we'll consider this impossible. + else { // Uh oh! We have a move that's all body, and is still too short!! + debug_trap("mp_exec_aline() - found a move that is too short"); cs.exec_aline_assertion_failure = true; return (STAT_EXEC_ALINE_ASSERTION_FAILURE); } @@ -521,8 +514,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->motion_state == MOTION_HOLD) { - if ((status = _exec_feedhold_processing(bf)) != STAT_EAGAIN) { - return (status); + if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + } + if (_exec_feedhold_processing(bf) == STAT_OK) { // anything but STAT_OK will continue processing the exec + return (STAT_OK); } } @@ -973,38 +969,33 @@ static stat_t _exec_aline_segment() /********************************************************************************************* * _exec_feedhold_processing() - - -// Feedhold Processing - We need to handle the following cases (listed in rough sequence order): -// (1) - We have a block midway through normal execution and a new feedhold request -// (1a) - The deceleration will fit in the length remaining in the running block (mr) -// (1b) - 1a, except the remaining length would be zero or EPSILON2 close to zero (unlikely) -// (1c) - The deceleration will not fit in the running block -// (2) - We have a new block and a new feedhold request that arrived at EXACTLY the same time (unlikely, but handled) -// (3) - We are in the middle of a block -// (3a) - The block is currently accelerating (we wait for the body to start) -// (3b) - The block is in a body (or has not yet started the head) - start deceleration -// (3c) - The block is currently in the tail (we wait until the end of the block) -// (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) -// (5) - We have decelerated a block to zero velocity -// (6) - We have finished all the runtime work now we have to wait for the steppers to stop -// (6a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF -// (6b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush -// (6c) - It's a normal feedhold - signal we want the entry action -// (7) - The steppers have stopped. No motion should occur. Allows hold actions to complete -// (8) - We are removing the hold state and there is queued motion (handled outside this routine) -// (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) - -* STAT_OK stops move execution -* STAT_NOOP stops move execution and prevents the next move from loading. Should only be used on an inactive block -* STAT_EAGAIN continues execution of mp_exec_aline() -*/ + * + * Feedhold Processing - We need to handle the following cases (listed in rough sequence order): + * (1) - We have a block midway through normal execution and a new feedhold request + * (1a) - The deceleration will fit in the length remaining in the running block (mr) + * (1b) - 1a, except the remaining length would be zero or EPSILON2 close to zero (unlikely) + * (1c) - The deceleration will not fit in the running block + * (2) - We have a new block and a new feedhold request that arrived at EXACTLY the same time (unlikely, but handled) + * (3) - We are in the middle of a block + * (3a) - The block is currently accelerating (we wait for the body to start) + * (3b) - The block is in a body (or has not yet started the head) - start deceleration + * (3c) - The block is currently in the tail (we wait until the end of the block) + * (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) + * (5) - We have decelerated a block to zero velocity + * (6) - We have finished all the runtime work now we have to wait for the steppers to stop + * (6a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF + * (6b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush + * (6c) - It's a normal feedhold - signal we want the entry action + * (7) - The steppers have stopped. No motion should occur. Allows hold actions to complete + * (8) - We are removing the hold state and there is queued motion (handled outside this routine) + * (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) + * + * Returning STAT_OK stops move execution + * Returning STAT_EAGAIN continues execution of mp_exec_aline() + */ static stat_t _exec_feedhold_processing(mpBuf_t *bf) -{ - if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement - } - +{ // Case (6) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish @@ -1043,10 +1034,10 @@ static stat_t _exec_feedhold_processing(mpBuf_t *bf) return (STAT_OK); } - // Cases (1a, 1b, 1c), Case (2), Case (4) - // Build a tail-only move from here. Decelerate as fast as possible in the space we have. + // Cases (3), (1a, 1b, 1c), Case (2), Case (4) + // Build a tail-only move from here. Decelerate as fast as possible in the space available. if ((cm->hold_state == FEEDHOLD_SYNC) || - ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { + ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { // Case (3c) - Already decelerating (in a tail), continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are @@ -1066,39 +1057,36 @@ static stat_t _exec_feedhold_processing(mpBuf_t *bf) } // Case (3b) - Block is in a body, or about to start a new head. Turn it into a new tail. - // else if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { - // In the new head case plan deceleration move (tail) starting at the at the entry velocity - if ((mr->section != SECTION_HEAD) || (mr->section_state == SECTION_NEW)) { - mr->section = SECTION_TAIL; - mr->section_state = SECTION_NEW; - mr->entry_velocity = mr->segment_velocity; - mr->r->cruise_velocity = mr->entry_velocity; // cruise velocity must be set even if there's no body - mr->r->head_length = 0; - mr->r->body_length = 0; - mr->r->head_time = 0; - mr->r->body_time = 0; - mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length + mr->section = SECTION_TAIL; + mr->section_state = SECTION_NEW; + mr->entry_velocity = mr->segment_velocity; +// mr->entry_velocity = mr->previous_exit_velocity; // ++++ COMPARISON + mr->r->cruise_velocity = mr->entry_velocity; // cruise velocity must be set even if there's no body + mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length + mr->r->head_length = 0; + mr->r->body_length = 0; + mr->r->head_time = 0; + mr->r->body_time = 0; - // (1a, 1b) The deceleration distance either fits in the available length (1a) or fits - // exactly or close enough (to EPSILON2) (1b). Case 1b happens when the tail in the move - // was already planned to zero. This is also case (2). EPSILON2 deals with floating point - // rounding errors that can mis-classify this case. - float available_length = get_axis_vector_length(mr->target, mr->position); + // (1a, 1b) The deceleration distance either fits in the available length (1a) or fits + // exactly or close enough (to EPSILON2) (1b). Case 1b happens when the tail in the move + // was already planned to zero. This is also case (2). EPSILON2 deals with floating point + // rounding errors that can mis-classify this case. + float available_length = get_axis_vector_length(mr->target, mr->position); - if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { // it will fit - cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; - mr->r->exit_velocity = 0; - mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); - bf->block_time = mr->r->tail_time; - } - else { - cm->hold_state = FEEDHOLD_DECEL_CONTINUE; - mr->r->tail_length = available_length; - mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); - mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); - bf->block_time = mr->r->tail_time; - } + if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { // it will fit + cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; + mr->r->exit_velocity = 0; + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); + bf->block_time = mr->r->tail_time; + } + else { + cm->hold_state = FEEDHOLD_DECEL_CONTINUE; + mr->r->tail_length = available_length; + mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); + bf->block_time = mr->r->tail_time; } } return (STAT_EAGAIN); diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 18f5ef9a..d85c6641 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -447,13 +447,12 @@ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) const float v_1x3 = 3 * v_1; const float recip_l_t = (2 * sqrt_delta_v_0) / ((v_0 - v_1x3) * q_recip_2_sqrt_j); v_1 = v_1 - (l_t * recip_l_t); -/* + // hack for cases where there is no solution because the length is so short if (v_1 > v_0) { return (-1.0); // cannot decelerate. Return an error // return (v_0); // cannot decelerate. Return entry velocity } -*/ } return v_1; } diff --git a/g2core/planner.h b/g2core/planner.h index c637d947..6711cfcf 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -467,7 +467,7 @@ typedef struct mpPlannerRuntime { // persistent runtime variables mpBlockRuntimeBuf_t bf[2]; // buffer holding the two blocks float entry_velocity; // entry values for the currently running block - float previous_exit_velocity; + float previous_exit_velocity; // +++++ DIAGNOSTIC float segments; // number of segments in line (also used by arc generation) uint32_t segment_count; // count of running segments From ea7586253f5d4beab55056c08705f41cf2d7f001 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 23 Feb 2017 08:25:32 -0500 Subject: [PATCH 150/283] Breakout block normalization into a helper; Added handler for mp_get_decel_velocity() failure case; Added normalizer to feedhold block manipulation; Re-wrote the feedhold cases to be clearer; General cleanup. --- g2core/g2core.cppproj | 8 +- g2core/plan_exec.cpp | 267 +++++++++++++++++++++++------------------- g2core/plan_zoid.cpp | 3 +- g2core/planner.h | 1 - 4 files changed, 154 insertions(+), 125 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index eef20ce4..bb1cf7a0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800036434 + J41800030015 0x284E0A60 - 2000000 + 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index ec5f69c3..73173b45 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -43,7 +43,8 @@ static stat_t _exec_aline_head(mpBuf_t *bf); // passing bf because body might ne static stat_t _exec_aline_body(mpBuf_t *bf); // passing bf so that body can extend itself if the exit velocity rises. static stat_t _exec_aline_tail(mpBuf_t *bf); static stat_t _exec_aline_segment(void); -static stat_t _exec_feedhold_processing(mpBuf_t *bf); +static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b); +static stat_t _exec_aline_feedhold_processing(mpBuf_t *bf); static void _init_forward_diffs(float v_0, float v_1); @@ -394,8 +395,6 @@ stat_t mp_exec_move() stat_t mp_exec_aline(mpBuf_t *bf) { - stat_t status; - if (bf->block_state == BLOCK_INACTIVE) { return (STAT_NOOP); } @@ -404,16 +403,15 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (mr->block_state == BLOCK_INACTIVE) { // ASSERTIONS - // Zero length moves (and other too-short moves) should have already been removed earlier // But let's still alert the condition should it ever occur debug_trap_if_zero(bf->length, "mp_exec_aline() zero length move"); - // Equalities that must be true for this to work: - // entry velocity <= cruise velocity && - // exit velocity <= cruise velocity + // These equalities in the assertions must be true for this to work: + // entry_velocity <= cruise_velocity + // exit_velocity <= cruise_velocity // - // Even if the move is head or tail only, cruise velocity needs to be valid. + // NB: Even if the move is head or tail only, cruise velocity needs to be valid. // This is because a "head" is *always* entry->cruise, and a "tail" is *always* cruise->exit, // even if there are no other sections in the move. (This is a significant time savings.) debug_trap_if_true((mr->entry_velocity > mr->r->cruise_velocity), @@ -431,61 +429,11 @@ stat_t mp_exec_aline(mpBuf_t *bf) // !!! THIS IS THE ONLY PLACE WHERE mr->r AND mr->p ARE ALLOWED TO BE CHANGED !!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Swap P and R blocks - mr->previous_exit_velocity = mr->r->exit_velocity; // +++++ DIAGNOSTIC mr->r = mr->p; // we are now going to run the planning block mr->p = mr->p->nx; // re-use the old running block as the new planning block - - + // Check to make sure no sections are less than MIN_SEGMENT_TIME & adjust if necessary - if ((mr->r->head_length > 0) && (mr->r->head_time < MIN_SEGMENT_TIME)) { - // Compute the new body time. head_time !== body_time - mr->r->body_length += mr->r->head_length; - mr->r->body_time = mr->r->body_length / mr->r->cruise_velocity; - mr->r->head_length = 0; - mr->r->head_time = 0; - } - if ((mr->r->tail_length > 0) && (mr->r->tail_time < MIN_SEGMENT_TIME)) { - // Compute the new body time. tail_time !== body_time - mr->r->body_length += mr->r->tail_length; - mr->r->body_time = mr->r->body_length / mr->r->cruise_velocity; - mr->r->tail_length = 0; - mr->r->tail_time = 0; - } - - // At this point, we've already possibly merged head and/or tail into the body. - // If the body is still too "short" (brief) we *might* be able to add it to a head or tail. - // If there's still a head or a tail, we will add the body to whichever there is, maybe both. - // We saved it for last since it's the most expensive. - if ((mr->r->body_length > 0) && (mr->r->body_time < MIN_SEGMENT_TIME)) { - - // We'll add the time to either the head or the tail or split it - if (mr->r->tail_length > 0) { - if (mr->r->head_length > 0) { // Split the body to the head and tail - mr->r->head_length += mr->r->body_length * 0.5; - mr->r->tail_length += mr->r->body_length * 0.5; // let the compiler optimize out one of these * - mr->r->head_time = (2.0 * mr->r->head_length) / (mr->entry_velocity + mr->r->cruise_velocity); - mr->r->tail_time = (2.0 * mr->r->tail_length) / (mr->r->cruise_velocity + mr->r->exit_velocity); - mr->r->body_length = 0; - mr->r->body_time = 0; - } else { // Put it all in the tail - mr->r->tail_length += mr->r->body_length; - mr->r->tail_time = (2.0 * mr->r->tail_length) / (mr->r->cruise_velocity + mr->r->exit_velocity); - mr->r->body_length = 0; - mr->r->body_time = 0; - } - } - else if (mr->r->head_length > 0) { // Put it all in the head - mr->r->head_length += mr->r->body_length; - mr->r->head_time = (2.0 * mr->r->head_length) / (mr->entry_velocity + mr->r->cruise_velocity); - mr->r->body_length = 0; - mr->r->body_time = 0; - } - else { // Uh oh! We have a move that's all body, and is still too short!! - debug_trap("mp_exec_aline() - found a move that is too short"); - cs.exec_aline_assertion_failure = true; - return (STAT_EXEC_ALINE_ASSERTION_FAILURE); - } - } + _exec_aline_normalize_block(mr->r); // transfer move parameters from planner buffer to the runtime copy_vector(mr->unit, bf->unit); @@ -514,11 +462,12 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->motion_state == MOTION_HOLD) { - if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT or FEEDHOLD HOLD + // if FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT + if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } - if (_exec_feedhold_processing(bf) == STAT_OK) { // anything but STAT_OK will continue processing the exec - return (STAT_OK); + if (_exec_aline_feedhold_processing(bf) == STAT_OK) { + return (STAT_OK); // STAT_OK terminates aline execution for this move } } @@ -527,7 +476,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // NB: from this point on the contents of the bf buffer do not affect execution //**** main dispatcher to process segments *** - status = STAT_OK; + stat_t status = STAT_OK; if (mr->section == SECTION_HEAD) { status = _exec_aline_head(bf); } else if (mr->section == SECTION_BODY) { status = _exec_aline_body(bf); } else if (mr->section == SECTION_TAIL) { status = _exec_aline_tail(bf); } @@ -547,7 +496,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) bf->plannable = false; } - // Feedhold Case (5, continued): Look for the end of the deceleration to go into HOLD state + // Feedhold Case (3b): Look for the end of the deceleration to transition HOLD states + // This code sets states used by _exec_feedhold_processing() helper. if (cm->hold_state == FEEDHOLD_DECEL_TO_ZERO) { if ((status == STAT_OK) || (status == STAT_NOOP)) { cm->hold_state = FEEDHOLD_DECEL_COMPLETE; @@ -742,9 +692,9 @@ static void _init_forward_diffs(const float v_0, const float v_1) mr->forward_diff_5 = const1*Ah_5 + 5.0*Bh_4 + const2*Ch_3; mr->forward_diff_4 = const3*Ah_5 + 29.0*Bh_4 + 9.0*Ch_3; - mr->forward_diff_3 = 255.0*Ah_5 + 48.0*Bh_4 + 6.0*Ch_3; - mr->forward_diff_2 = 300.0*Ah_5 + 24.0*Bh_4; - mr->forward_diff_1 = 120.0*Ah_5; + mr->forward_diff_3 = 255.0*Ah_5 + 48.0*Bh_4 + 6.0*Ch_3; + mr->forward_diff_2 = 300.0*Ah_5 + 24.0*Bh_4; + mr->forward_diff_1 = 120.0*Ah_5; // Calculate the initial velocity by calculating V(h/2) const float half_h = h * 0.5; // h/2 @@ -784,7 +734,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) } if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); - return(STAT_OK); // exit without advancing position, say we're done + return (STAT_OK); // exit without advancing position, say we're done } mr->section = SECTION_HEAD; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; @@ -794,7 +744,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) if (_exec_aline_segment() == STAT_OK) { // set up for second half if ((fp_ZERO(mr->r->body_length)) && (fp_ZERO(mr->r->tail_length))) { - return(STAT_OK); // ends the move + return (STAT_OK); // ends the move } mr->section = SECTION_BODY; // advance to body mr->section_state = SECTION_NEW; @@ -805,7 +755,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) mr->forward_diff_3 += mr->forward_diff_2; mr->forward_diff_2 += mr->forward_diff_1; } - return(STAT_EAGAIN); + return (STAT_EAGAIN); } /********************************************************************************************* @@ -828,7 +778,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf) mr->segment_count = (uint32_t)mr->segments; if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); - return(STAT_OK); // exit without advancing position, say we're done + return (STAT_OK); // exit without advancing position, say we're done } mr->section = SECTION_BODY; // +++++ Redundant??? @@ -836,12 +786,12 @@ static stat_t _exec_aline_body(mpBuf_t *bf) } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done if (fp_ZERO(mr->r->tail_length)) { - return(STAT_OK); // ends the move + return (STAT_OK); // ends the move } mr->section = SECTION_TAIL; // advance to tail mr->section_state = SECTION_NEW; } - return(STAT_EAGAIN); + return (STAT_EAGAIN); } /********************************************************************************************* @@ -869,7 +819,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) } if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); - return(STAT_OK); // exit without advancing position, say we're done + return (STAT_OK); // exit without advancing position, say we're done } mr->section = SECTION_TAIL; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; @@ -878,7 +828,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) } if (_exec_aline_segment() == STAT_OK) { - return(STAT_OK); // STAT_OK completes the move + return (STAT_OK); // STAT_OK completes the move } else if (!first_pass) { mr->forward_diff_5 += mr->forward_diff_4; @@ -886,7 +836,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) mr->forward_diff_3 += mr->forward_diff_2; mr->forward_diff_2 += mr->forward_diff_1; } - return(STAT_EAGAIN); + return (STAT_EAGAIN); } /********************************************************************************************* @@ -966,37 +916,103 @@ static stat_t _exec_aline_segment() return (STAT_EAGAIN); // this section still has more segments to run } - /********************************************************************************************* - * _exec_feedhold_processing() - + * _exec_aline_normalize_block() - re-organize block to eliminate minimum time segments * - * Feedhold Processing - We need to handle the following cases (listed in rough sequence order): - * (1) - We have a block midway through normal execution and a new feedhold request - * (1a) - The deceleration will fit in the length remaining in the running block (mr) - * (1b) - 1a, except the remaining length would be zero or EPSILON2 close to zero (unlikely) - * (1c) - The deceleration will not fit in the running block - * (2) - We have a new block and a new feedhold request that arrived at EXACTLY the same time (unlikely, but handled) - * (3) - We are in the middle of a block - * (3a) - The block is currently accelerating (we wait for the body to start) - * (3b) - The block is in a body (or has not yet started the head) - start deceleration - * (3c) - The block is currently in the tail (we wait until the end of the block) - * (4) - We have decelerated a block to some velocity > zero (needs continuation in next block) - * (5) - We have decelerated a block to zero velocity - * (6) - We have finished all the runtime work now we have to wait for the steppers to stop - * (6a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF - * (6b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush - * (6c) - It's a normal feedhold - signal we want the entry action - * (7) - The steppers have stopped. No motion should occur. Allows hold actions to complete - * (8) - We are removing the hold state and there is queued motion (handled outside this routine) - * (9) - We are removing the hold state and there is no queued motion (also handled outside this routine) - * - * Returning STAT_OK stops move execution - * Returning STAT_EAGAIN continues execution of mp_exec_aline() + * Check to make sure no sections are less than MIN_SEGMENT_TIME & adjust if necessary */ -static stat_t _exec_feedhold_processing(mpBuf_t *bf) +static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) { - // Case (6) - Wait for the steppers to stop + + if ((b->head_length > 0) && (b->head_time < MIN_SEGMENT_TIME)) { + // Compute the new body time. head_time !== body_time + b->body_length += b->head_length; + b->body_time = b->body_length / b->cruise_velocity; + b->head_length = 0; + b->head_time = 0; + } + if ((b->tail_length > 0) && (b->tail_time < MIN_SEGMENT_TIME)) { + // Compute the new body time. tail_time !== body_time + b->body_length += b->tail_length; + b->body_time = b->body_length / b->cruise_velocity; + b->tail_length = 0; + b->tail_time = 0; + } + + // At this point, we've already possibly merged head and/or tail into the body. + // If the body is still too "short" (brief) we *might* be able to add it to a head or tail. + // If there's still a head or a tail, we will add the body to whichever there is, maybe both. + // We saved it for last since it's the most expensive. + if ((b->body_length > 0) && (b->body_time < MIN_SEGMENT_TIME)) { + + // We'll add the time to either the head or the tail or split it + if (b->tail_length > 0) { + if (b->head_length > 0) { // Split the body to the head and tail + b->head_length += b->body_length * 0.5; + b->tail_length += b->body_length * 0.5; // let the compiler optimize out one of these * + b->head_time = (2.0 * b->head_length) / (mr->entry_velocity + b->cruise_velocity); + b->tail_time = (2.0 * b->tail_length) / (b->cruise_velocity + b->exit_velocity); + b->body_length = 0; + b->body_time = 0; + } else { // Put it all in the tail + b->tail_length += b->body_length; + b->tail_time = (2.0 * b->tail_length) / (b->cruise_velocity + b->exit_velocity); + b->body_length = 0; + b->body_time = 0; + } + } + else if (b->head_length > 0) { // Put it all in the head + b->head_length += b->body_length; + b->head_time = (2.0 * b->head_length) / (mr->entry_velocity + b->cruise_velocity); + b->body_length = 0; + b->body_time = 0; + } + else { // Uh oh! We have a move that's all body, and is still too short!! + debug_trap("_exec_aline_normalize_block() - found a move that is too short"); + } + } +} + +/********************************************************************************************* + * _exec_aline_feedhold_processing() - feedhold helper for mp_exec_aline() + * + * This function performs the bulk of the feedhold state machine processing from within + * mp_exec_aline(). There is also a little chunk labeled "Feedhold Case (3-continued)". + * Feedhold processing mostly manages the deceleration phase into the hold, and sets + * state variables used in cycle_feedhold.cpp + * + * Returning STAT_OK ends the move. (i.e. returns STAT_OK from mp_exec_aline()) + * Returning STAT_EAGAIN allows mp_exec_aline() to continue execution + * + * Feedhold Processing - We need to handle the following cases (listed in rough sequence order): + * (1) - Feedhold arrives while we are in the middle executing of a block + * (1a) - The block is currently accelerating - wait for the end of acceleration + * (1b) - The block is in a body - start deceleration + * (1b1) - The deceleration fits into the current block + * (1b2) - The deceleration does not fit and needs to continue in the next block + * (1c) - The block is in a head, but has not started execution yet - start deceleration + * (1c1) - The deceleration fits into the current block + * (1c2) - The deceleration does not fit and needs to continue in the next block + * (1d) - The block is currently in the tail - wait until the end of the block + * (1e) - We have a new block and a new feedhold request that arrived at EXACTLY the same time + * (unlikely, but handled as 1c). + * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block + * (3) - The block has decelerated to zero velocity + * (3a) - The end of deceleration is detected (inline in mp_exec_aline()) + * (3b) - The end of deceleration is signeled and transitioned + * (4) - We have finished all the runtime work now we have to wait for the motors to stop + * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF + * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush + * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute + * (5) - The steppers have stopped. No motion should occur. Allows hold actions to complete + * (6) - Removing the hold state and there is queued motion - see cycle_feedhold.cpp + * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp + */ + +static stat_t _exec_aline_feedhold_processing(mpBuf_t *bf) +{ + // Case (4) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish // finalize position and velocity @@ -1019,7 +1035,7 @@ static stat_t _exec_feedhold_processing(mpBuf_t *bf) return (STAT_OK); // hold here. No more movement } - // Case (5) - Decelerated to zero. See also Feedhold Case (5, continued), toward end of mp_exec_aline() + // Case (3b) - Decelerated to zero. See also Feedhold Case (3a) in mp_exec_aline() // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move @@ -1031,15 +1047,15 @@ static stat_t _exec_feedhold_processing(mpBuf_t *bf) mp_free_run_buffer(); } mp_replan_queue(mp_get_r()); // make it replan all the blocks - return (STAT_OK); + return (STAT_OK); // stop mp_exec_aline() from further execution } - // Cases (3), (1a, 1b, 1c), Case (2), Case (4) + // Cases (1x), Case (2) // Build a tail-only move from here. Decelerate as fast as possible in the space available. if ((cm->hold_state == FEEDHOLD_SYNC) || ((cm->hold_state == FEEDHOLD_DECEL_CONTINUE) && (mr->block_state == BLOCK_INITIAL_ACTION))) { - // Case (3c) - Already decelerating (in a tail), continue the deceleration. + // Case (1d) - Already decelerating (in a tail), continue the deceleration. if (mr->section == SECTION_TAIL) { // if already in a tail don't decelerate. You already are if (mr->r->exit_velocity < EPSILON2) { // allow near-zero velocities to be treated as zero cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; @@ -1049,19 +1065,18 @@ static stat_t _exec_feedhold_processing(mpBuf_t *bf) return (STAT_EAGAIN); } - // Case (3a) - Currently accelerating (in a head), skip and waited for body or tail + // Case (1a) - Currently accelerating (in a head), skip and waited for body or tail // This is true because to do otherwise the jerk would not have returned to zero. // Small exception, if we *just started* the head, then we're not actually accelerating yet. if ((mr->section == SECTION_HEAD) && (mr->section_state != SECTION_NEW)) { return (STAT_EAGAIN); } - // Case (3b) - Block is in a body, or about to start a new head. Turn it into a new tail. - // In the new head case plan deceleration move (tail) starting at the at the entry velocity + // Case (1b, 1c) - Block is in a body or about to start a new head. Turn it into a new tail. + // In the new_head case plan deceleration move (tail) starting at the at the entry velocity mr->section = SECTION_TAIL; mr->section_state = SECTION_NEW; mr->entry_velocity = mr->segment_velocity; -// mr->entry_velocity = mr->previous_exit_velocity; // ++++ COMPARISON mr->r->cruise_velocity = mr->entry_velocity; // cruise velocity must be set even if there's no body mr->r->tail_length = mp_get_target_length(0, mr->r->cruise_velocity, bf); // braking length mr->r->head_length = 0; @@ -1069,25 +1084,41 @@ static stat_t _exec_feedhold_processing(mpBuf_t *bf) mr->r->head_time = 0; mr->r->body_time = 0; - // (1a, 1b) The deceleration distance either fits in the available length (1a) or fits - // exactly or close enough (to EPSILON2) (1b). Case 1b happens when the tail in the move - // was already planned to zero. This is also case (2). EPSILON2 deals with floating point - // rounding errors that can mis-classify this case. + // The deceleration distance either fits in the available length or fits exactly or close + // enough (to EPSILON2) (1e). Case 1e happens frequently when the tail in the move was + // already planned to zero. EPSILON2 deals with floating point rounding errors that can + // mis-classify this case. EPSILON2 is 0.0001, which is 0.1 microns in length. float available_length = get_axis_vector_length(mr->target, mr->position); - if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { // it will fit + // Cases (1b1, 1c1) deceleration will fit in the block + if ((available_length + EPSILON2 - mr->r->tail_length) > 0) { cm->hold_state = FEEDHOLD_DECEL_TO_ZERO; mr->r->exit_velocity = 0; mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); bf->block_time = mr->r->tail_time; } + // Cases (1b2, 1c2) deceleration will not fit in the block else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; mr->r->tail_length = available_length; mr->r->exit_velocity = mp_get_decel_velocity(mr->r->cruise_velocity, mr->r->tail_length, bf); - mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); - bf->block_time = mr->r->tail_time; + if (mr->r->exit_velocity >= 0) { + mr->r->tail_time = mr->r->tail_length*2 / (mr->r->exit_velocity + mr->r->cruise_velocity); + bf->block_time = mr->r->tail_time; + } + // The following branch is rarely if ever taken. It's possible for the deceleration calculation + // to return an error if the length is too short and other conditions exist. In that case + // make the block into a cruise (body) and push the deceleration to the next block. + else { + mr->section = SECTION_BODY; + mr->r->exit_velocity = mr->r->cruise_velocity; // both should be @ mr->segment_velocity + mr->r->body_length = available_length; + mr->r->body_time = mr->r->body_length / mr->r->cruise_velocity; + mr->r->tail_length = 0; + mr->r->tail_time = 0; + } } + _exec_aline_normalize_block(mr->r); } return (STAT_EAGAIN); } diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index d85c6641..fc90178d 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -448,10 +448,9 @@ float mp_get_decel_velocity(const float v_0, const float L, const mpBuf_t* bf) const float recip_l_t = (2 * sqrt_delta_v_0) / ((v_0 - v_1x3) * q_recip_2_sqrt_j); v_1 = v_1 - (l_t * recip_l_t); - // hack for cases where there is no solution because the length is so short + // In some extreme cases there is no solution because the length is too short if (v_1 > v_0) { return (-1.0); // cannot decelerate. Return an error -// return (v_0); // cannot decelerate. Return entry velocity } } return v_1; diff --git a/g2core/planner.h b/g2core/planner.h index 6711cfcf..606c2785 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -467,7 +467,6 @@ typedef struct mpPlannerRuntime { // persistent runtime variables mpBlockRuntimeBuf_t bf[2]; // buffer holding the two blocks float entry_velocity; // entry values for the currently running block - float previous_exit_velocity; // +++++ DIAGNOSTIC float segments; // number of segments in line (also used by arc generation) uint32_t segment_count; // count of running segments From fcaad6b52452f07f6af69c3b5f759cb59436c3fc Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 24 Feb 2017 15:53:43 -0500 Subject: [PATCH 151/283] Mostly comments --- g2core/cycle_feedhold.cpp | 127 +++++++++++++++++--------------------- g2core/plan_exec.cpp | 32 ++-------- g2core/planner.cpp | 7 ++- 3 files changed, 64 insertions(+), 102 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 190c62e8..3add8523 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -50,100 +50,74 @@ static stat_t _finalize_p2_hold_exit(void); **** Feedholds ******************************************************************** ***********************************************************************************/ /* - * Feedholds, queue flushes and end_holds are all related and are in this file. - * Feedholds are implemented as a state machine (cmFeedholdState) that runs in the - * planner (plan_exec.cpp, see Feedhold Processing around line 500) and in this file. + * Feedholds, queue flushes and end_holds are all related and are performed in this + * file and in plan_exec.cpp. Feedholds are implemented as a state machine + * (cmFeedholdState) that runs in these files. * - * Feedholds also use the dual planner (secondary context, or hold context) where a - * new canonical machine and planner are spun up and entered when a feedhold is initiated. - * This allows (almost) all of the machine operations to be accessible during a feedhold. + * There are 2 planners: p1 (primary planner) and p2 (secondary planner). A feedhold + * received while in p1 stops motion in p1 and transitions to p2, where entry actions + * like Z lift, spindle and coolant pause occur. While in p2 (almost) all machine + * operations are available. * - * Feedholds are initiated and ended by a series of request flags (requests). - * The request functions set flags or change state to "REQUESTED". - * The sequencing callback interprets the flags as so: - * - A feedhold request received during motion should be honored - * - A feedhold request received during a feedhold should be ignored - * - A feedhold request received during a motion stop should be ignored + * A feedhold received while in p2 (a feedhold within a feedhold - very Inception) + * stops motion in p2 and flushes the p2 planner. Control remains in p2. * - * - A queue flush request should only be honored while in a feedhold - * - Said queue flush request received during a feedhold should be deferred until - * the feedhold enters a HOLD state (i.e. until deceleration is complete and motors stop). - * - A queue flush request received during a motion stop should be honored + * A feedhold exit request (~) received while in either p1 or p2 will execute the + * feedhold exit actions: + * - Resume coolant (if paused) + * - Resume spindle (if paseud) with spinup delay + * - Move back to starting location in XY, then plunge in Z + * Motion will resume in p1 after the exit actions complete * - * - An end_hold (cycle start) request should only be honored while in a feedhold - * - Said end_hold request received during a feedhold should be deferred until the - * feedhold enters a HOLD state (i.e. until deceleration is complete). - * If a queue flush request is also present the queue flush should be done first + * A feedhold flush request (%) received while in either p1 or p2 will execute the + * exit actions, flush the p1 and p2 queues, then stop motion at the hold point. */ -/* Below the request level, feedholds work like this: - * - The hold is initiated by calling cm_start_hold(). cm->hold_state is set to - * FEEDHOLD_SYNC, motion_state is set to MOTION_HOLD, and the spindle is turned off - * (if it it on). The remainder of feedhold - * processing occurs in plan_exec.c in the mp_exec_aline() function. +/* + * Feedhold Processing - Performs the following cases (listed in rough sequence order): + * (0) - Feedhold request arrives or cm_start_hold() * - * - MOTION_HOLD and FEEDHOLD_SYNC tells mp_exec_aline() to begin feedhold processing - * after the current move segment is finished (< 5 ms later). (Cases handled by - * feedhold processing are listed in plan_exec.c). + * Control transfers to plan_exec.cpp feedhold functions: * - * - FEEDHOLD_SYNC causes the current move in mr to be replanned into a deceleration. - * If the distance remaining in the executing move is sufficient for a full deceleration - * then motion will stop in the current block. Otherwise the deceleration phase - * will extend across as many blocks necessary until one will stop. + * (1) - Feedhold arrives while we are in the middle executing of a block + * (1a) - The block is currently accelerating - wait for the end of acceleration + * (1b) - The block is in a head, but has not started execution yet - start deceleration + * (1b1) - The deceleration fits into the current block + * (1b2) - The deceleration does not fit and needs to continue in the next block + * (1c) - The block is in a body - start deceleration + * (1c1) - The deceleration fits into the current block + * (1c2) - The deceleration does not fit and needs to continue in the next block + * (1d) - The block is currently in the tail - wait until the end of the block + * (1e) - We have a new block and a new feedhold request that arrived at EXACTLY the same time + * (unlikely, but handled as 1b). + * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block + * (3) - The block has decelerated to zero velocity + * (3a) - The end of deceleration is detected (inline in mp_exec_aline()) + * (3b) - The end of deceleration is signeled and transitioned + * (4) - We have finished all the runtime work now we have to wait for the motors to stop + * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF + * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush + * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute + * (5) - The steppers have stopped. No motion should occur. Allows hold actions to complete * - * - Once deceleration is complete hold state transitions to FEEDHOLD_FINALIZING and - * the distance remaining in the bf last block is replanned up from zero velocity. - * The move in the bf block is NOT released (unlike normal operation), as it will - * be used again to restart from hold. + * Control transfers back to cycle_feedhold.cpp feedhold functions: * - * - When cm_end_hold() is called it releases the hold, restarts the move and restarts - * the spindle if the spindle is active. - */ - -/* With the addition of the secondary CM, feedhold state management gets tricky. - What you see below is a temporary solution until we decide the general solution. - - The general solution causes a feedhold from the primary context to switch - into the secondary context to perform feedhold actions. When in the secondary - context an additional feedhold will perform the usual STOP operation, but - will remain in the secondary context, and therefore not perform any feedhold - actions (lifts, spindle, etc.). This is needed to support homing and probing - operations from within the secondary context. - - Oddities of the general solution: - - Should we allow a feedhold to be performed if the tool is not moving? - Right now we don't, but with the secondary context this might be useful - - What you see here is a Q&D to only allow feedholds from the primary context. - It has the following limitations: - - Feedhold requests are only honored form the primary context - - Queue flush requests are only honored form the primary context - - Machine alarm state is not (yet) taken into account in feedhold sequencing and restart + * (6) - Removing the hold state and there is queued motion - see cycle_feedhold.cpp + * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp */ /*********************************************************************************** * cm_has_hold() - return true if a hold condition exists (or a pending hold request) - * cm_start_hold() - start a feedhhold external to feedhold request & sequencing - * - * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) */ bool cm_has_hold() { return (cm1.hold_state != FEEDHOLD_OFF); } -void cm_start_hold() -{ - // Can only request a feedhold if the machine is in motion and there not one is not already in progress - if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { - cm_set_motion_state(MOTION_HOLD); - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} - /*********************************************************************************** * cm_request_feedhold() * cm_request_exit_hold() * cm_request_queue_flush() + * cm_start_hold() - start a feedhhold external to feedhold request & sequencing * * p1 is the primary planner, p2 is the secondary planner, which is active if the * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. @@ -165,6 +139,8 @@ void cm_start_hold() * - If p1 is in HOLD request_queue_flush will end p1 hold & queue flush (stop motion). * Pre-defined exit actions (coolant, spindle, Z move) are completed first * Any executing or pending "in-hold" moves are stopped prior to the exit actions + * + * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) */ void cm_request_feedhold(void) // ! @@ -194,6 +170,15 @@ void cm_request_queue_flush() // % } } +void cm_start_hold() +{ + // Can only request a feedhold if the machine is in motion and there not one is not already in progress + if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { + cm_set_motion_state(MOTION_HOLD); + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } +} + /*********************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests * diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 73173b45..64650a64 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -44,7 +44,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf); // passing bf so that body can exte static stat_t _exec_aline_tail(mpBuf_t *bf); static stat_t _exec_aline_segment(void); static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b); -static stat_t _exec_aline_feedhold_processing(mpBuf_t *bf); +static stat_t _exec_aline_feedhold(mpBuf_t *bf); static void _init_forward_diffs(float v_0, float v_1); @@ -466,7 +466,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement } - if (_exec_aline_feedhold_processing(bf) == STAT_OK) { + if (_exec_aline_feedhold(bf) == STAT_OK) { return (STAT_OK); // STAT_OK terminates aline execution for this move } } @@ -975,7 +975,7 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) } /********************************************************************************************* - * _exec_aline_feedhold_processing() - feedhold helper for mp_exec_aline() + * _exec_aline_feedhold() - feedhold helper for mp_exec_aline() * * This function performs the bulk of the feedhold state machine processing from within * mp_exec_aline(). There is also a little chunk labeled "Feedhold Case (3-continued)". @@ -984,33 +984,9 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) * * Returning STAT_OK ends the move. (i.e. returns STAT_OK from mp_exec_aline()) * Returning STAT_EAGAIN allows mp_exec_aline() to continue execution - * - * Feedhold Processing - We need to handle the following cases (listed in rough sequence order): - * (1) - Feedhold arrives while we are in the middle executing of a block - * (1a) - The block is currently accelerating - wait for the end of acceleration - * (1b) - The block is in a body - start deceleration - * (1b1) - The deceleration fits into the current block - * (1b2) - The deceleration does not fit and needs to continue in the next block - * (1c) - The block is in a head, but has not started execution yet - start deceleration - * (1c1) - The deceleration fits into the current block - * (1c2) - The deceleration does not fit and needs to continue in the next block - * (1d) - The block is currently in the tail - wait until the end of the block - * (1e) - We have a new block and a new feedhold request that arrived at EXACTLY the same time - * (unlikely, but handled as 1c). - * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block - * (3) - The block has decelerated to zero velocity - * (3a) - The end of deceleration is detected (inline in mp_exec_aline()) - * (3b) - The end of deceleration is signeled and transitioned - * (4) - We have finished all the runtime work now we have to wait for the motors to stop - * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF - * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush - * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute - * (5) - The steppers have stopped. No motion should occur. Allows hold actions to complete - * (6) - Removing the hold state and there is queued motion - see cycle_feedhold.cpp - * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp */ -static stat_t _exec_aline_feedhold_processing(mpBuf_t *bf) +static stat_t _exec_aline_feedhold(mpBuf_t *bf) { // Case (4) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { diff --git a/g2core/planner.cpp b/g2core/planner.cpp index be0e5bef..f5b1900a 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -752,7 +752,7 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state == MP_BUFFER_EMPTY) { - _clear_buffer(q->w); // RG: this is redundant, it was just cleared in mp_free_run_buffer + _clear_buffer(q->w); // NB: this is no longer redundant, as it was not just cleared in mp_free_run_buffer q->w->buffer_state = MP_BUFFER_INITIALIZING; q->buffers_available--; return (mp_get_w()); @@ -825,8 +825,9 @@ bool mp_free_run_buffer() // EMPTY current run buffer & advance to the mpBuf_t *r_now = q->r; // save this pointer is to avoid a race condition when clearing the buffer _audit_buffers(); // DIAGNOSTIC audit for buffer chain integrity (only runs in DEBUG mode) - q->r = q->r->nx; // advance to next run buffer first, - _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) + q->r = q->r->nx; // advance to next run buffer first... +// _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) + r_now->buffer_state = MP_BUFFER_EMPTY; //... then mark the buffer empty while perserving content for debug inspection q->buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count return (q->w == q->r); // return true if the queue emptied From b74aa9613fc06ca6bd2a937a739120d1532e4f8b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 25 Feb 2017 09:27:31 -0500 Subject: [PATCH 152/283] Minor commit --- g2core/cycle_feedhold.cpp | 4 ++-- g2core/cycle_probing.cpp | 27 ++++++++++++++++----------- g2core/g2core.cppproj | 4 ++-- g2core/kinematics.cpp | 13 ++++++------- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 3add8523..64af4af3 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -91,8 +91,8 @@ static stat_t _finalize_p2_hold_exit(void); * (unlikely, but handled as 1b). * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block * (3) - The block has decelerated to zero velocity - * (3a) - The end of deceleration is detected (inline in mp_exec_aline()) - * (3b) - The end of deceleration is signeled and transitioned + * (3a) - The end of deceleration is detected inline in mp_exec_aline() + * (3b) - The end of deceleration is signaled and state is transitioned * (4) - We have finished all the runtime work now we have to wait for the motors to stop * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 8c0ca4e2..262049bd 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -39,7 +39,8 @@ #include "util.h" #include "xio.h" -/**** Probe singleton structure ****/ + +/**** Local stuff ****/ #define MINIMUM_PROBE_TRAVEL 0.254 // mm of travel below which the probe will err out @@ -71,14 +72,9 @@ static stat_t _probing_backoff(); static stat_t _probing_finish(); static stat_t _probing_exception_exit(stat_t status); static stat_t _probe_move(const float target[], const bool flags[]); +static void _motion_end_callback(float* vect, bool* flag); static void _send_probe_report(void); -// helper -static void _motion_end_callback(float* vect, bool* flag) -{ - pb.wait_for_motion_end = false; -} - /*********************************************************************************** **** G38.x Probing Cycle ********************************************************** ***********************************************************************************/ @@ -147,7 +143,7 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool trip_sense, bool al // initialize the probe input; error if no probe input specified if ((pb.probe_input = gpio_get_probing_input()) == -1) { - return(cm_alarm(STAT_NO_PROBE_INPUT_CONFIGURED, "No probe input")); + return(cm_alarm(STAT_NO_PROBE_INPUT_CONFIGURED, "Probe input not configured")); } // setup @@ -273,18 +269,27 @@ static stat_t _probing_backoff() } /*********************************************************************************** - * _probe_move() - function to execute probing moves + * _probe_move() - function to execute probing moves + * _motion_end_callback() - callback completes when motion has stopped * * target[] must be provided in machine canonical coordinates (absolute, mm) * cm_set_absolute_override() also zeros work offsets, which are restored on exit. */ +static void _motion_end_callback(float* vect, bool* flag) +{ + while (!mp_runtime_is_idle()) { + __NOP(); // block until current segment is done + }; + pb.wait_for_motion_end = false; +} + static stat_t _probe_move(const float target[], const bool flags[]) { cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); pb.wait_for_motion_end = true; // set this BEFORE the motion starts - cm_straight_feed(target, flags); - mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway + cm_straight_feed(target, flags); // NB: feed rate was set earlier, so it's OK + mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway return (STAT_EAGAIN); } diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index bb1cf7a0..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/kinematics.cpp b/g2core/kinematics.cpp index 9e200f61..cc66d95d 100644 --- a/g2core/kinematics.cpp +++ b/g2core/kinematics.cpp @@ -2,7 +2,8 @@ * kinematics.cpp - inverse kinematics routines * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2017 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -127,7 +128,6 @@ static void _inverse_kinematics(const float travel[], float joint[]) { * * This function is NOT to be used where high-speed is important. If that becomes the case, * there are many opportunities for caching and optimization for performance here. - * */ void kn_forward_kinematics(const float steps[], float travel[]) { @@ -139,7 +139,7 @@ void kn_forward_kinematics(const float steps[], float travel[]) { best_steps_per_unit[axis] = -1.0; } - // Scan through each axis, and then through each motor + // Scan through each axis then through each motor for (uint8_t axis = 0; axis < AXES; axis++) { if (cm->a[axis].axis_mode == AXIS_INHIBITED) { travel[axis] = 0.0; @@ -147,13 +147,12 @@ void kn_forward_kinematics(const float steps[], float travel[]) { } for (uint8_t motor = 0; motor < MOTORS; motor++) { if (st_cfg.mot[motor].motor_map == axis) { - // If this motor has a better (or the only) resolution, then we use this motor's value + // If this motor has a better (or the only) resolution, then use this motor's value if (best_steps_per_unit[axis] < st_cfg.mot[motor].steps_per_unit) { best_steps_per_unit[axis] = st_cfg.mot[motor].steps_per_unit; travel[axis] = steps[motor] * st_cfg.mot[motor].units_per_step; - - // If a econd motor has the same reolution for the same axis, we'll average their values - } else if (fp_EQ(best_steps_per_unit[axis], st_cfg.mot[motor].steps_per_unit)) { + } // If a second motor has the same resolution for the same axis average their values + else if (fp_EQ(best_steps_per_unit[axis], st_cfg.mot[motor].steps_per_unit)) { travel[axis] = (travel[axis] + (steps[motor] * st_cfg.mot[motor].units_per_step)) / 2.0; } } From a56a09d72e0929f8a8211740f766b2739861efea Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 25 Feb 2017 12:33:39 -0500 Subject: [PATCH 153/283] Basic feedhold operations verified with regression tests --- g2core/cycle_probing.cpp | 3 --- g2core/plan_exec.cpp | 17 ++++++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 262049bd..8a841a19 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -278,9 +278,6 @@ static stat_t _probing_backoff() static void _motion_end_callback(float* vect, bool* flag) { - while (!mp_runtime_is_idle()) { - __NOP(); // block until current segment is done - }; pb.wait_for_motion_end = false; } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 64650a64..8ce31b7e 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -992,17 +992,20 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish // finalize position and velocity - copy_vector(mr->position, mr->gm.target); // update position from target - bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS +// copy_vector(mr->position, mr->gm.target); // update position from target +// copy_vector(mp->position, mr->position); // update the planner position from the runtime +// bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS mp_zero_segment_velocity(); // for reporting purposes // when homing or probing don't stay in HOLD or execute entry actions if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { + copy_vector(mp->position, mr->position); // update the planner position from the runtime + bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS cm->hold_state = FEEDHOLD_OFF; - } else if (cm == &cm2) { // if in p2 hold set up a flush + } else if (cm == &cm2) { // if in a p2 hold set up a flush of the p2 planner queue cm->hold_state = FEEDHOLD_P2_EXIT; } else { - cm->hold_state = FEEDHOLD_ACTIONS_START; // perform Z-lift, spindle, coolant actions + cm->hold_state = FEEDHOLD_ACTIONS_START; // otherwise perform Z-lift, spindle, coolant actions } sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -1019,9 +1022,9 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop // No point bothering with the rest of this move if homing or probing - if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - mp_free_run_buffer(); - } +// if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { +// mp_free_run_buffer(); +// } mp_replan_queue(mp_get_r()); // make it replan all the blocks return (STAT_OK); // stop mp_exec_aline() from further execution } From e5fa7c960fb40761241f4372af3b71cf61a683ea Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 25 Feb 2017 13:36:31 -0500 Subject: [PATCH 154/283] Testing probing code --- g2core/plan_exec.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 8ce31b7e..b17e38a5 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -991,21 +991,25 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Case (4) - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish - // finalize position and velocity -// copy_vector(mr->position, mr->gm.target); // update position from target -// copy_vector(mp->position, mr->position); // update the planner position from the runtime -// bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS - mp_zero_segment_velocity(); // for reporting purposes + mp_zero_segment_velocity(); // finalize velocity for reporting purposes - // when homing or probing don't stay in HOLD or execute entry actions + // if probing or homing exit the move and advance to the _motion_end finalization command if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { - copy_vector(mp->position, mr->position); // update the planner position from the runtime - bf->length = get_axis_vector_length(mr->target, mr->position); // reset length in buffer //+++++ TEST THIS + mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement + copy_vector(mp->position, mr->position); // update planner position from runtime + mp_free_run_buffer(); // free buffer and enable finalization move to get loaded cm->hold_state = FEEDHOLD_OFF; - } else if (cm == &cm2) { // if in a p2 hold set up a flush of the p2 planner queue + } + + // if exiting a p2 hold set up a flush of the p2 planner queue + else if (cm == &cm2) { +// copy_vector(mp->position, mr->position); // update planner position from runtime cm->hold_state = FEEDHOLD_P2_EXIT; - } else { - cm->hold_state = FEEDHOLD_ACTIONS_START; // otherwise perform Z-lift, spindle, coolant actions + } + + // if exiting a regular p1 hold perform Z-lift, spindle, coolant actions + else { + cm->hold_state = FEEDHOLD_ACTIONS_START; } sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -1026,7 +1030,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // mp_free_run_buffer(); // } mp_replan_queue(mp_get_r()); // make it replan all the blocks - return (STAT_OK); // stop mp_exec_aline() from further execution + return (STAT_OK); // exit from mp_exec_aline() } // Cases (1x), Case (2) From 58b4525afc072cb84e0f9ccc0981628ae1794ca3 Mon Sep 17 00:00:00 2001 From: "alden.hart" Date: Sat, 25 Feb 2017 15:06:10 -0500 Subject: [PATCH 155/283] Othermill settings; comments --- g2core/cycle_homing.cpp | 115 +++++---- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 23 +- g2core/settings/settings_othermill.h | 281 ++++++++++++++-------- g2core/settings/settings_othermill_test.h | 15 +- 5 files changed, 279 insertions(+), 159 deletions(-) diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index b0521b32..cff82b80 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -86,24 +86,15 @@ static stat_t _homing_axis_move(int8_t axis, float target, float velocity); static stat_t _homing_error_exit(int8_t axis, stat_t status); static stat_t _homing_finalize_exit(int8_t axis); static int8_t _get_next_axis(int8_t axis); -static void _homing_axis_move_callback(float* vect, bool* flag); -/**** HELPERS *************************************************************************** - * _set_homing_func() - a convenience for setting the next dispatch vector and exiting - */ - -static stat_t _set_homing_func(stat_t (*func)(int8_t axis)) { - hm.func = func; - return (STAT_EAGAIN); -} /*********************************************************************************** **** G28.2 Homing Cycle *********************************************************** ***********************************************************************************/ /***************************************************************************** - * cm_homing_cycle_start() - G28.2 homing cycle using limit switches - * cm_homing_cycle_callback() - main loop callback for running the homing cycle + * cm_homing_cycle_start() - G28.2 homing cycle using limit switches + * cm_homing_cycle_start_no_set() - G28.4 Homing cycle - do not set values * * --- How does this work? --- * @@ -186,10 +177,14 @@ stat_t cm_homing_cycle_start(const float axes[], const bool flags[]) { stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]) { cm_homing_cycle_start(axes, flags); - hm.set_coordinates = false; // set flag to not update position variables at the end of the cycle + hm.set_coordinates = false; // set flag to not update position variables at the end of the cycle return (STAT_OK); } +/*********************************************************************************** + * cm_homing_cycle_callback() - main loop callback for running the homing cycle + */ + stat_t cm_homing_cycle_callback(void) { if (cm->cycle_state != CYCLE_HOMING) { // exit if not in a homing cycle return (STAT_NOOP); @@ -200,18 +195,21 @@ stat_t cm_homing_cycle_callback(void) { return (hm.func(hm.axis)); // execute the current homing move } -/* - * Homing axis moves - these execute in sequence for each axis - * - * _homing_axis_start() - get next axis, initialize variables, call the clear - * _homing_axis_clear_init() - initiate a clear to move off a switch that is thrown at the start - * _homing_axis_search() - fast search for switch, closes switch - * _homing_axis_clear() - clear off the switch - * _homing_axis_latch() - slow drive until until switch closes again - * _homing_axis_final() - backoff from latch location to zero position - * _homing_axis_move() - helper that actually executes the above moves - */ +/*********************************************************************************** + * Homing axis moves and helpers - these execute in sequence for each axis + ***********************************************************************************/ +/* + * _set_homing_func() - a convenience for setting the next dispatch vector and exiting + */ +static stat_t _set_homing_func(stat_t (*func)(int8_t axis)) { + hm.func = func; + return (STAT_EAGAIN); +} + +/*********************************************************************************** + * _homing_axis_start() - get next axis, initialize variables, call the clear + */ static stat_t _homing_axis_start(int8_t axis) { // get the first or next axis @@ -247,36 +245,40 @@ static stat_t _homing_axis_start(int8_t axis) { // However, here's a good place to stash the homing_switch: hm.homing_input = cm->a[axis].homing_input; gpio_set_homing_mode(hm.homing_input, true); - hm.axis = axis; // persist the axis - hm.search_velocity = fabs(cm->a[axis].search_velocity); // search velocity is always positive - hm.latch_velocity = fabs(cm->a[axis].latch_velocity); // latch velocity is always positive + hm.axis = axis; // persist the axis + hm.search_velocity = fabs(cm->a[axis].search_velocity); // search velocity is always positive + hm.latch_velocity = fabs(cm->a[axis].latch_velocity); // latch velocity is always positive bool homing_to_max = cm->a[axis].homing_dir; // setup parameters for positive or negative travel (homing to the max or min switch) if (homing_to_max) { - hm.search_travel = travel_distance; // search travels in positive direction - hm.latch_backoff = fabs(cm->a[axis].latch_backoff); // latch travels in positive direction - hm.zero_backoff = -max(0.0f, cm->a[axis].zero_backoff); // zero backoff is negative direction (or zero) - // will set the maximum position - // (plus any negative backoff) + hm.search_travel = travel_distance; // search travels in positive direction + hm.latch_backoff = fabs(cm->a[axis].latch_backoff); // latch travels in positive direction + hm.zero_backoff = -max(0.0f, cm->a[axis].zero_backoff);// zero backoff is negative direction (or zero) + // will set the maximum position + // (plus any negative backoff) hm.setpoint = cm->a[axis].travel_max + (max(0.0f, -cm->a[axis].zero_backoff)); } else { hm.search_travel = -travel_distance; // search travels in negative direction - hm.latch_backoff = -fabs(cm->a[axis].latch_backoff); // latch travels in negative direction - hm.zero_backoff = max(0.0f, cm->a[axis].zero_backoff); // zero backoff is positive direction (or zero) + hm.latch_backoff = -fabs(cm->a[axis].latch_backoff); // latch travels in negative direction + hm.zero_backoff = max(0.0f, cm->a[axis].zero_backoff); // zero backoff is positive direction (or zero) // will set the minimum position // (minus any negative backoff) hm.setpoint = cm->a[axis].travel_min + (max(0.0f, -cm->a[axis].zero_backoff)); } // if homing is disabled for the axis then skip to the next axis - hm.saved_jerk = cm_get_axis_jerk(axis); // save the max jerk value - return (_set_homing_func(_homing_axis_clear_init)); // perform an initial clear + hm.saved_jerk = cm_get_axis_jerk(axis); // save the max jerk value + return (_set_homing_func(_homing_axis_clear_init)); // perform an initial clear } -// Handle an initial switch closure by backing off the closed switch -// NOTE: clear_init() relies on independent switches per axis (not shared) +/*********************************************************************************** + * _homing_axis_clear_init() - initiate a clear to move off a switch that is thrown at the start + * + * Handle an initial switch closure by backing off the closed switch + * NOTE: clear_init() relies on independent switches per axis (not shared) + */ static stat_t _homing_axis_clear_init(int8_t axis) // first clear move { if (gpio_read_input(hm.homing_input) == INPUT_ACTIVE) { // the switch is closed at startup @@ -293,6 +295,9 @@ static stat_t _homing_axis_clear_init(int8_t axis) // first clear move return (_set_homing_func(_homing_axis_search)); // start the search } +/*********************************************************************************** + * _homing_axis_search() - fast search for switch, closes switch + */ static stat_t _homing_axis_search(int8_t axis) // drive to switch { cm_set_axis_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for search onward @@ -300,25 +305,37 @@ static stat_t _homing_axis_search(int8_t axis) // drive to switch return (_set_homing_func(_homing_axis_clear)); } +/*********************************************************************************** + * _homing_axis_clear() - clear off the switch + */ static stat_t _homing_axis_clear(int8_t axis) // drive away from switch at search speed { _homing_axis_move(axis, -hm.latch_backoff, hm.search_velocity); return (_set_homing_func(_homing_axis_latch)); } +/*********************************************************************************** + * _homing_axis_latch() - slow drive until until switch closes again + */ static stat_t _homing_axis_latch(int8_t axis) // drive to switch at low speed { _homing_axis_move(axis, hm.latch_backoff, hm.latch_velocity); return (_set_homing_func(_homing_axis_setpoint_backoff)); } -static stat_t _homing_axis_setpoint_backoff(int8_t axis) // backoff to zero or max setpoint position +/*********************************************************************************** + * _homing_axis_setpoint_backoff() - backoff to zero or max setpoint position + */ +static stat_t _homing_axis_setpoint_backoff(int8_t axis) // { _homing_axis_move(axis, hm.zero_backoff, hm.search_velocity); return (_set_homing_func(_homing_axis_set_position)); } -static stat_t _homing_axis_set_position(int8_t axis) // set axis zero / max and finish up +/*********************************************************************************** + * _homing_axis_set_position() - set axis zero / max and finish up + */ +static stat_t _homing_axis_set_position(int8_t axis) { if (hm.set_coordinates) { cm_set_position_by_axis(axis, hm.setpoint); @@ -335,6 +352,15 @@ static stat_t _homing_axis_set_position(int8_t axis) // set axis zero / max and return (_set_homing_func(_homing_axis_start)); } +/*********************************************************************************** + * _homing_axis_move() - helper that actually executes the above moves + * _motion_end_callback() - callback completes when motion has stopped + */ +static void _motion_end_callback(float* vect, bool* flag) +{ + hm.waiting_for_motion_end = false; +} + static stat_t _homing_axis_move(int8_t axis, float target, float velocity) { float vect[] = {0, 0, 0, 0, 0, 0}; bool flags[] = {false, false, false, false, false, false}; @@ -352,15 +378,12 @@ static stat_t _homing_axis_move(int8_t axis, float target, float velocity) { } // the last two arguments are ignored anyway - mp_queue_command(_homing_axis_move_callback, nullptr, nullptr); + mp_queue_command(_motion_end_callback, nullptr, nullptr); return (STAT_EAGAIN); } -static void _homing_axis_move_callback(float* vect, bool* flag) { hm.waiting_for_motion_end = false; } - - -/* +/*********************************************************************************** * _homing_error_exit() * * Generate an error message. Since the error exit returns via the homing callback @@ -382,7 +405,7 @@ static stat_t _homing_error_exit(int8_t axis, stat_t status) { return (STAT_HOMING_CYCLE_FAILED); // homing state remains HOMING_NOT_HOMED } -/* +/*********************************************************************************** * _homing_finalize_exit() - helper to finalize homing */ @@ -398,7 +421,7 @@ static stat_t _homing_finalize_exit(int8_t axis) // third part of return to hom return (STAT_OK); } -/* +/*********************************************************************************** * _get_next_axis() - return next axis in sequence based on axis in arg * * Accepts "axis" arg as the current axis; or -1 to retrieve the first axis diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..23ff3756 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800021206 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800021206 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index b17e38a5..d3117ad6 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -993,21 +993,24 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes - // if probing or homing exit the move and advance to the _motion_end finalization command - if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { + // If in a p2 hold, exit the p2 hold set up a flush of the p2 planner queue + if (cm == &cm2) { +// copy_vector(mp->position, mr->position); // update planner position from runtime + cm->hold_state = FEEDHOLD_P2_EXIT; + } + // At this point we know we are in a p1 hold + + // If probing or homing exit the move and advance to the _motion_end finalization command. + // Stop the runtime, clear the bun buffer and do not transition to p2 planner + else if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement copy_vector(mp->position, mr->position); // update planner position from runtime mp_free_run_buffer(); // free buffer and enable finalization move to get loaded cm->hold_state = FEEDHOLD_OFF; } - - // if exiting a p2 hold set up a flush of the p2 planner queue - else if (cm == &cm2) { -// copy_vector(mp->position, mr->position); // update planner position from runtime - cm->hold_state = FEEDHOLD_P2_EXIT; - } - - // if exiting a regular p1 hold perform Z-lift, spindle, coolant actions + + // If exiting a regular p1 hold set state to FEEDHOLD_ACTIONS_START. + // This enables transition to p2 planner; then Z-lift, spindle, coolant actions else { cm->hold_state = FEEDHOLD_ACTIONS_START; } diff --git a/g2core/settings/settings_othermill.h b/g2core/settings/settings_othermill.h index 98799bcc..6b3607d5 100644 --- a/g2core/settings/settings_othermill.h +++ b/g2core/settings/settings_othermill.h @@ -32,24 +32,27 @@ //**** GLOBAL / GENERAL SETTINGS ****************************************************** -#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) -#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) +#define JUNCTION_INTEGRATION_TIME 0.75 // cornering - between 0.10 and 2.00 (higher is faster) +#define CHORDAL_TOLERANCE 0.01 // chordal accuracy for arc drawing (in mm) -#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on -#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on -#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on +#define SOFT_LIMIT_ENABLE 0 // 0=off, 1=on +#define HARD_LIMIT_ENABLE 1 // 0=off, 1=on +#define SAFETY_INTERLOCK_ENABLE 1 // 0=off, 1=on -#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high -#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high -#define SPINDLE_PAUSE_ON_HOLD true -#define SPINDLE_DWELL_TIME 1.5 // after unpausing and turning the spindle on, dwell for 1.5s +#define SPINDLE_ENABLE_POLARITY 1 // 0=active low, 1=active high +#define SPINDLE_DIR_POLARITY 0 // 0=clockwise is low, 1=clockwise is high +#define SPINDLE_PAUSE_ON_HOLD true +#define SPINDLE_DWELL_TIME 1.5 // after unpausing and turning the spindle on, dwell for 1.5s -#define ESC_BOOT_TIME 5000 // how long the ESC takes to boot, in milliseconds -#define ESC_LOCKOUT_TIME 900 // how long the interlock needs to be engaged before killing power... actually 1s, but be conservative +#define ESC_BOOT_TIME 5000 // how long the ESC takes to boot, in milliseconds +#define ESC_LOCKOUT_TIME 900 // how long the interlock needs to be engaged before killing power... actually 1s, but be conservative -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD true +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD true + +#define FEEDHOLD_Z_LIFT 3 // mm to lift Z on feedhold +#define PROBE_REPORT_ENABLE true // WARNING: Older Othermill machines use a 15deg can stack for their Z axis. // new machines use a stepper which has the same config as the other axis. @@ -66,20 +69,25 @@ // Communications and reporting settings -#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE -#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! -#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE -#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE -#define QUEUE_REPORT_VERBOSITY QR_SINGLE // one of: QR_OFF, QR_SINGLE, QR_TRIPLE +#define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE +#define XIO_ENABLE_FLOW_CONTROL FLOW_CONTROL_RTS // FLOW_CONTROL_OFF, FLOW_CONTROL_RTS -#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE -#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum -#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -#define STATUS_REPORT_DEFAULTS \ - "mpox", "mpoy", "mpoz", "ofsx", "ofsy", "ofsz", "g55x", "g55y", "g55z", "unit", "stat", "coor", "momo", "dist", \ - "home", "mots", "plan", "line", "path", "frmo", "hold", "macs", "cycs" -// "path","frmo","prbe","safe","spe","spd","hold","macs","cycs","sps" +#define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE +#define JSON_VERBOSITY JV_MESSAGES // one of: JV_SILENT, JV_FOOTER, JV_CONFIGS, JV_MESSAGES, JV_LINENUM, JV_VERBOSE +#define QUEUE_REPORT_VERBOSITY QR_SINGLE // one of: QR_OFF, QR_SINGLE, QR_TRIPLE + +#define STATUS_REPORT_VERBOSITY SR_FILTERED // one of: SR_OFF, SR_FILTERED, SR_VERBOSE +#define STATUS_REPORT_MIN_MS 100 // milliseconds - enforces a viable minimum +#define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable +#define STATUS_REPORT_DEFAULTS "mpox", "mpoy", "mpoz", \ + "ofsx", "ofsy", "ofsz", \ + "g55x", "g55y", "g55z", \ + "unit", "stat", "coor", "momo", "dist", \ + "home", "mots", "plan", "line", "path", \ + "frmo", "hold", "macs", "cycs" +// "prbe", "safe", "spe", "spd", "sps" // Gcode startup defaults #define GCODE_DEFAULT_UNITS MILLIMETERS // MILLIMETERS or INCHES @@ -92,49 +100,126 @@ // NOTE: Motor numbers are reversed from TinyGv8 in order to maintain compatibility with wiring harnesses -#define MOTOR_POWER_LEVEL_XY 0.375 // default motor power level 0.00 - 1.00 -#define MOTOR_POWER_LEVEL_XY_IDLE 0.15 -#define MOTOR_POWER_LEVEL_Z 0.375 -#define MOTOR_POWER_LEVEL_Z_IDLE 0.15 -#define MOTOR_POWER_LEVEL_DISABLED 0.05 +#define MOTOR_POWER_LEVEL_XY 0.375 // default motor power level 0.00 - 1.00 +#define MOTOR_POWER_LEVEL_XY_IDLE 0.15 +#define MOTOR_POWER_LEVEL_Z 0.375 +#define MOTOR_POWER_LEVEL_Z_IDLE 0.15 +#define MOTOR_POWER_LEVEL_DISABLED 0.05 -#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 4.8768 // 1tr -#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 -#define M1_POLARITY 1 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h -#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max -#define M1_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE +#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 4.8768 // 1tr +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max +#define M1_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M2_MOTOR_MAP AXIS_Y -#define M2_STEP_ANGLE 1.8 -#define M2_TRAVEL_PER_REV 4.8768 -#define M2_MICROSTEPS 8 -#define M2_POLARITY 1 -#define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL MOTOR_POWER_LEVEL_XY -#define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE +#define M2_MOTOR_MAP AXIS_Y +#define M2_STEP_ANGLE 1.8 +#define M2_TRAVEL_PER_REV 4.8768 +#define M2_MICROSTEPS 8 +#define M2_POLARITY 1 +#define M2_POWER_MODE MOTOR_POWER_MODE +#define M2_POWER_LEVEL MOTOR_POWER_LEVEL_XY +#define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z #if HAS_CANSTACK_Z_AXIS -#define M3_STEP_ANGLE 15 -#define M3_TRAVEL_PER_REV 1.27254 +#define M3_STEP_ANGLE 15 +#define M3_TRAVEL_PER_REV 1.27254 #else -#define M3_STEP_ANGLE 1.8 -#define M3_TRAVEL_PER_REV 4.8768 +#define M3_STEP_ANGLE 1.8 +#define M3_TRAVEL_PER_REV 4.8768 #endif -#define M3_MICROSTEPS 8 -#define M3_POLARITY 0 -#define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL MOTOR_POWER_LEVEL_Z -#define M3_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_Z_IDLE +#define M3_MICROSTEPS 8 +#define M3_POLARITY 0 +#define M3_POWER_MODE MOTOR_POWER_MODE +#define M3_POWER_LEVEL MOTOR_POWER_LEVEL_Z +#define M3_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_Z_IDLE + +#define M4_MOTOR_MAP AXIS_A +#define M4_STEP_ANGLE 1.8 +#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M4_MICROSTEPS 8 +#define M4_POLARITY 1 +#define M4_POWER_MODE MOTOR_DISABLED +#define M4_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED +#define M4_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED + +#define M5_MOTOR_MAP AXIS_B +#define M5_STEP_ANGLE 1.8 +#define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M5_MICROSTEPS 8 +#define M5_POLARITY 0 +#define M5_POWER_MODE MOTOR_DISABLED +#define M5_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED +#define M5_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED + +#define M6_MOTOR_MAP AXIS_C +#define M6_STEP_ANGLE 1.8 +#define M6_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M6_MICROSTEPS 8 +#define M6_POLARITY 0 +#define M6_POWER_MODE MOTOR_DISABLED +#define M6_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED +#define M6_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED // *** axis settings ********************************************************************************** +#define JERK_MAX 500 // 500 million mm/(min^3) +#define JERK_HIGH_SPEED 1000 // 1000 million mm/(min^3) // Jerk during homing needs to stop *fast* +#define VELOCITY_MAX 1500 +#define SEARCH_VELOCITY (VELOCITY_MAX / 3) +#define LATCH_VELOCITY 25 // reeeeally slow for accuracy + +#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define X_VELOCITY_MAX VELOCITY_MAX // xvm G0 max velocity in mm/min +#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits +#define X_TRAVEL_MAX 145.6 // xtr travel between switches or crashes +#define X_JERK_MAX JERK_MAX // xjm +#define X_JERK_HIGH_SPEED JERK_HIGH_SPEED // xjh +#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define X_SEARCH_VELOCITY SEARCH_VELOCITY // xsv +#define X_LATCH_VELOCITY LATCH_VELOCITY // xlv mm/min +#define X_LATCH_BACKOFF 2 // xlb mm +#define X_ZERO_BACKOFF 0.4 // xzb mm + +#define Y_AXIS_MODE AXIS_STANDARD +#define Y_VELOCITY_MAX X_VELOCITY_MAX +#define Y_FEEDRATE_MAX Y_VELOCITY_MAX +#define Y_TRAVEL_MIN 0 +#define Y_TRAVEL_MAX 119.1 +#define Y_JERK_MAX JERK_MAX +#define Y_JERK_HIGH_SPEED JERK_HIGH_SPEED +#define Y_HOMING_INPUT 3 +#define Y_HOMING_DIRECTION 0 +#define Y_SEARCH_VELOCITY (Y_FEEDRATE_MAX / 3) +#define Y_LATCH_VELOCITY LATCH_VELOCITY +#define Y_LATCH_BACKOFF 2 +#define Y_ZERO_BACKOFF 0.4 + +#define Z_AXIS_MODE AXIS_STANDARD +#define Z_VELOCITY_MAX X_VELOCITY_MAX +#define Z_FEEDRATE_MAX Z_VELOCITY_MAX +#define Z_TRAVEL_MIN -60.1 +#define Z_TRAVEL_MAX 0 +#define Z_JERK_MAX JERK_MAX +#define Z_JERK_HIGH_SPEED JERK_HIGH_SPEED +#define Z_HOMING_INPUT 6 +#define Z_HOMING_DIRECTION 1 +#define Z_SEARCH_VELOCITY (Z_FEEDRATE_MAX / 3) +#define Z_LATCH_VELOCITY LATCH_VELOCITY +#define Z_LATCH_BACKOFF 2 +#define Z_ZERO_BACKOFF 0.4 + + +/* #define JERK_MAX 500 // 500 million mm/(min^3) #define JERK_HIGH_SPEED 1000 // 1000 million mm/(min^3) // Jerk during homing needs to stop *fast* #define VELOCITY_MAX 1500 @@ -186,6 +271,7 @@ #define Z_LATCH_VELOCITY LATCH_VELOCITY #define Z_LATCH_BACKOFF 1 #define Z_ZERO_BACKOFF 0.4 +*/ //*** Input / output settings *** /* @@ -212,65 +298,68 @@ */ // Xmin on v9 board // X homing - see X axis setup -#define DI1_MODE NORMALLY_CLOSED -#define DI1_ACTION INPUT_ACTION_NONE -#define DI1_FUNCTION INPUT_FUNCTION_NONE +#define DI1_MODE NORMALLY_CLOSED +#define DI1_ACTION INPUT_ACTION_NONE +#define DI1_FUNCTION INPUT_FUNCTION_NONE // Xmax // External ESTOP -#define DI2_MODE IO_ACTIVE_HIGH -#define DI2_ACTION INPUT_ACTION_HALT -#define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN +#define DI2_MODE IO_ACTIVE_HIGH +#define DI2_ACTION INPUT_ACTION_HALT +#define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN // Ymin // Y homing - see Y axis setup -#define DI3_MODE NORMALLY_CLOSED -#define DI3_ACTION INPUT_ACTION_NONE -#define DI3_FUNCTION INPUT_FUNCTION_NONE +#define DI3_MODE NORMALLY_CLOSED +#define DI3_ACTION INPUT_ACTION_NONE +#define DI3_FUNCTION INPUT_FUNCTION_NONE // Ymax // Safety interlock -#define DI4_MODE IO_ACTIVE_HIGH -#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) -#define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK +#define DI4_MODE IO_ACTIVE_HIGH +#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) +#define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK // Zmin // Z probe -#define DI5_MODE IO_ACTIVE_LOW -#define DI5_ACTION INPUT_ACTION_NONE -#define DI5_FUNCTION INPUT_FUNCTION_NONE +#define DI5_MODE IO_ACTIVE_LOW +#define DI5_ACTION INPUT_ACTION_NONE +#define DI5_FUNCTION INPUT_FUNCTION_PROBE // Zmax // Z homing - see Z axis for setup -#define DI6_MODE NORMALLY_CLOSED -#define DI6_ACTION INPUT_ACTION_NONE -#define DI6_FUNCTION INPUT_FUNCTION_NONE +#define DI6_MODE NORMALLY_CLOSED +#define DI6_ACTION INPUT_ACTION_NONE +#define DI6_FUNCTION INPUT_FUNCTION_NONE // Amin // Unused -#define DI7_MODE IO_MODE_DISABLED -#define DI7_ACTION INPUT_ACTION_NONE -#define DI7_FUNCTION INPUT_FUNCTION_NONE +#define DI7_MODE IO_MODE_DISABLED +#define DI7_ACTION INPUT_ACTION_NONE +#define DI7_FUNCTION INPUT_FUNCTION_NONE // Amax // Unused -#define DI8_MODE IO_MODE_DISABLED -#define DI8_ACTION INPUT_ACTION_NONE -#define DI8_FUNCTION INPUT_FUNCTION_NONE +#define DI8_MODE IO_MODE_DISABLED +#define DI8_ACTION INPUT_ACTION_NONE +#define DI8_FUNCTION INPUT_FUNCTION_NONE // Safety line w/HW timer // Unused -#define DI9_MODE IO_MODE_DISABLED -#define DI9_ACTION INPUT_ACTION_NONE -#define DI9_FUNCTION INPUT_FUNCTION_NONE +#define DI9_MODE IO_MODE_DISABLED +#define DI9_ACTION INPUT_ACTION_NONE +#define DI9_FUNCTION INPUT_FUNCTION_NONE + // *** PWM SPINDLE CONTROL *** -#define P1_PWM_FREQUENCY 100 // in Hz -#define P1_CW_SPEED_LO 10500 // in RPM (arbitrary units) -#define P1_CW_SPEED_HI 16400 -#define P1_CW_PHASE_LO 0.13 // phase [0..1] -#define P1_CW_PHASE_HI 0.17 -#define P1_CCW_SPEED_LO 0 -#define P1_CCW_SPEED_HI 0 -#define P1_CCW_PHASE_LO 0.1 -#define P1_CCW_PHASE_HI 0.1 -#define P1_PWM_PHASE_OFF 0.1 +#define P1_PWM_FREQUENCY 100 // in Hz +#define P1_CW_SPEED_LO 10500 // in RPM (arbitrary units) +#define P1_CW_SPEED_HI 16400 +#define P1_CW_PHASE_LO 0.13 // phase [0..1] +#define P1_CW_PHASE_HI 0.17 +#define P1_CCW_SPEED_LO 0 +#define P1_CCW_SPEED_HI 0 +#define P1_CCW_PHASE_LO 0.1 +#define P1_CCW_PHASE_HI 0.1 +#define P1_PWM_PHASE_OFF 0.1 +/* #define P1_USE_MAPPING_CUBIC #define P1_MAPPING_CUBIC_X3 2.1225328766717546e-013 #define P1_MAPPING_CUBIC_X2 -7.2900167282605129e-009 #define P1_MAPPING_CUBIC_X1 8.5854646785876479e-005 #define P1_MAPPING_CUBIC_X0 -2.1301489219406905e-001 +*/ \ No newline at end of file diff --git a/g2core/settings/settings_othermill_test.h b/g2core/settings/settings_othermill_test.h index 077b2357..2c8720af 100644 --- a/g2core/settings/settings_othermill_test.h +++ b/g2core/settings/settings_othermill_test.h @@ -47,9 +47,12 @@ #define ESC_BOOT_TIME 5000 // how long the ESC takes to boot, in milliseconds #define ESC_LOCKOUT_TIME 900 // how long the interlock needs to be engaged before killing power... actually 1s, but be conservative -#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high -#define COOLANT_PAUSE_ON_HOLD true +#define COOLANT_MIST_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_FLOOD_POLARITY 1 // 0=active low, 1=active high +#define COOLANT_PAUSE_ON_HOLD true + +#define FEEDHOLD_Z_LIFT 3 // mm to lift Z on feedhold +#define PROBE_REPORT_ENABLE true // Communications and reporting settings @@ -196,8 +199,8 @@ #define Z_ZERO_BACKOFF 0.4 // Rotary values are chosen to make the motor react the same as X for testing -#define A_AXIS_MODE AXIS_DISABLED // DISABLED -#define A_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) // set to the same speed as X axis +#define A_AXIS_MODE AXIS_DISABLED // DISABLED +#define A_VELOCITY_MAX ((X_VELOCITY_MAX / M1_TRAVEL_PER_REV) * 360) // set to the same speed as X axis #define A_FEEDRATE_MAX A_VELOCITY_MAX #define A_TRAVEL_MIN -1 // min/max the same means infinite, no limit #define A_TRAVEL_MAX -1 @@ -323,8 +326,10 @@ #define P1_CCW_PHASE_HI 0.1 #define P1_PWM_PHASE_OFF 0.1 +/* #define P1_USE_MAPPING_CUBIC #define P1_MAPPING_CUBIC_X3 2.1225328766717546e-013 #define P1_MAPPING_CUBIC_X2 -7.2900167282605129e-009 #define P1_MAPPING_CUBIC_X1 8.5854646785876479e-005 #define P1_MAPPING_CUBIC_X0 -2.1301489219406905e-001 +*/ \ No newline at end of file From 1253d307e242c729aa91a0100a2daa50c3dccbb2 Mon Sep 17 00:00:00 2001 From: "alden.hart" Date: Sat, 25 Feb 2017 15:40:57 -0500 Subject: [PATCH 156/283] Probing, homing and feedholds working --- g2core/cycle_homing.cpp | 5 ++--- g2core/plan_exec.cpp | 12 +++--------- g2core/plan_line.cpp | 4 ++-- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index cff82b80..cd0e4b86 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -362,8 +362,8 @@ static void _motion_end_callback(float* vect, bool* flag) } static stat_t _homing_axis_move(int8_t axis, float target, float velocity) { - float vect[] = {0, 0, 0, 0, 0, 0}; - bool flags[] = {false, false, false, false, false, false}; + float vect[] = {0,0,0,0,0,0}; + bool flags[] = {0,0,0,0,0,0}; hm.waiting_for_motion_end = true; @@ -379,7 +379,6 @@ static stat_t _homing_axis_move(int8_t axis, float target, float velocity) { // the last two arguments are ignored anyway mp_queue_command(_motion_end_callback, nullptr, nullptr); - return (STAT_EAGAIN); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index d3117ad6..bd288825 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -993,18 +993,17 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes - // If in a p2 hold, exit the p2 hold set up a flush of the p2 planner queue + // If in a p2 hold, exit the p2 hold set up a flush of the p2 planner queue if (cm == &cm2) { // copy_vector(mp->position, mr->position); // update planner position from runtime cm->hold_state = FEEDHOLD_P2_EXIT; } // At this point we know we are in a p1 hold - // If probing or homing exit the move and advance to the _motion_end finalization command. - // Stop the runtime, clear the bun buffer and do not transition to p2 planner + // If probing or homing, exit the move and advance to the _motion_end_callback()'s. + // Stop the runtime, clear the run buffer and do not transition to p2 planner. else if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement - copy_vector(mp->position, mr->position); // update planner position from runtime mp_free_run_buffer(); // free buffer and enable finalization move to get loaded cm->hold_state = FEEDHOLD_OFF; } @@ -1027,11 +1026,6 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop - - // No point bothering with the rest of this move if homing or probing -// if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { -// mp_free_run_buffer(); -// } mp_replan_queue(mp_get_r()); // make it replan all the blocks return (STAT_OK); // exit from mp_exec_aline() } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index a1509cd9..a487c9f7 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -144,8 +144,8 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); } stat_t mp_aline(GCodeState_t* gm_in) { - float target_rotated[AXES] = {0, 0, 0, 0, 0, 0}; - float axis_square[AXES] = {0, 0, 0, 0, 0, 0}; + float target_rotated[AXES] = {0,0,0,0,0,0}; + float axis_square[AXES] = {0,0,0,0,0,0}; float axis_length[AXES]; bool flags[AXES]; float length_square = 0; From c42846090e84fcaeefebf2b3119fb50f430f3f27 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 26 Feb 2017 10:48:53 -0500 Subject: [PATCH 157/283] Project file only --- g2core/g2core.cppproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 23ff3756..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800021206 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800021206 + J41800036434 0x284E0A60 10000000 From af116e43e41386e9384e0f8272a30909821cbce1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 27 Feb 2017 11:02:03 -0500 Subject: [PATCH 158/283] Added some diagnostics and commenting. Aligned with buffer diagnostics from dev-p32 --- g2core/canonical_machine.cpp | 7 ++++++- g2core/cycle_feedhold.cpp | 29 +++++++++++++++++------------ g2core/cycle_jogging.cpp | 3 +-- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 17 ++++++++++++++--- g2core/plan_line.cpp | 23 ++++++++++------------- g2core/planner.cpp | 8 ++++---- g2core/planner.h | 5 ++++- g2core/xio.cpp | 25 ++++++++++++------------- g2core/xio.h | 16 +++++++--------- 10 files changed, 77 insertions(+), 60 deletions(-) mode change 100755 => 100644 g2core/xio.h diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8ddd1bb5..0bd4baa6 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1110,6 +1110,10 @@ stat_t cm_resume_origin_offsets() stat_t cm_straight_traverse(const float target[], const bool flags[]) { + if (target[AXIS_Y] == 20) { // +++ DEBUG TRAP + cm->gm.P_word = 20; + } + cm->gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; // it's legal for a G0 to have no axis words but we don't want to process it @@ -1151,7 +1155,8 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm // If G20 adjust stored position (always in mm) to inches so traverse will be correct float target[AXES]; // make a local stored position as it may be modified copy_vector(target, stored_position); - if (cm->gm.units_mode == INCHES) { + + if (cm->gm.units_mode == INCHES) { for (uint8_t i=0; iposition, mr->position); // +++++ Compensate for amount of move already performed sr_request_status_report(SR_REQUEST_IMMEDIATE); } @@ -382,7 +387,6 @@ static stat_t _finalize_p1_hold_exit() } // resume motion from primary planner or end cycle if no moves in planner - cm1.hold_state = FEEDHOLD_OFF; if (mp_has_runnable_buffer(&mp1)) { cm_set_motion_state(MOTION_RUN); cm_cycle_start(); @@ -391,6 +395,7 @@ static stat_t _finalize_p1_hold_exit() cm_set_motion_state(MOTION_STOP); cm_cycle_end(); } + cm1.hold_state = FEEDHOLD_OFF; return (STAT_OK); } diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index a2f7b4e2..2e781f34 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -114,7 +114,6 @@ stat_t cm_jogging_cycle_start(uint8_t axis) { return (STAT_OK); } - /* Jogging axis moves - these execute in sequence for each axis * cm_jogging_cycle_callback() - main loop callback for running the jogging cycle * _set_jogging_func() - a convenience for setting the next dispatch vector and exiting @@ -132,7 +131,7 @@ stat_t cm_jogging_cycle_callback(void) { return (STAT_EAGAIN); // sync to planner move ends } // if (jog.func == _jogging_axis_ramp_jog && mp_get_buffers_available() < PLANNER_BUFFER_HEADROOM) { - if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(mp)) { //+++++ + if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(mp)) { //+++++ return (STAT_EAGAIN); // prevent flooding the queue with jog moves } return (jog.func(jog.axis)); // execute the current jogging move diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..bb1cf7a0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index bd288825..8a2a59c9 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -403,6 +403,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (mr->block_state == BLOCK_INACTIVE) { // ASSERTIONS + // Zero length moves (and other too-short moves) should have already been removed earlier // But let's still alert the condition should it ever occur debug_trap_if_zero(bf->length, "mp_exec_aline() zero length move"); @@ -440,6 +441,9 @@ stat_t mp_exec_aline(mpBuf_t *bf) copy_vector(mr->target, bf->gm.target); copy_vector(mr->axis_flags, bf->axis_flags); + mr->run_bf = bf; // DIAGNOSTIC: points to running bf + mr->plan_bf = bf->nx; // DIAGNOSTIC: points to next bf to forward plan + // characterize the move for starting section - head/body/tail mr->section_state = SECTION_NEW; mr->section = SECTION_HEAD; @@ -456,6 +460,9 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->waypoint[SECTION_BODY][axis] = mr->position[axis] + mr->unit[axis] * (mr->r->head_length + mr->r->body_length); mr->waypoint[SECTION_TAIL][axis] = mr->position[axis] + mr->unit[axis] * (mr->r->head_length + mr->r->body_length + mr->r->tail_length); } +// if (mr->waypoint[SECTION_TAIL][AXIS_X] < 0) { //+++++ +// bf->hint = (blockHint)0; +// } } // Feed Override Processing - We need to handle the following cases (listed in rough sequence order): @@ -735,7 +742,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); return (STAT_OK); // exit without advancing position, say we're done - } + } mr->section = SECTION_HEAD; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { @@ -924,7 +931,6 @@ static stat_t _exec_aline_segment() static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) { - if ((b->head_length > 0) && (b->head_time < MIN_SEGMENT_TIME)) { // Compute the new body time. head_time !== body_time b->body_length += b->head_length; @@ -995,7 +1001,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If in a p2 hold, exit the p2 hold set up a flush of the p2 planner queue if (cm == &cm2) { -// copy_vector(mp->position, mr->position); // update planner position from runtime +// copy_vector(mp->position, mr->position); // +++++ update planner position from runtime cm->hold_state = FEEDHOLD_P2_EXIT; } // At this point we know we are in a p1 hold @@ -1011,6 +1017,11 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If exiting a regular p1 hold set state to FEEDHOLD_ACTIONS_START. // This enables transition to p2 planner; then Z-lift, spindle, coolant actions else { + if (bf->gm.linenum == 10) { // +++ DEBUG TRAP + bf->override_factor *= 1.01; + } +// copy_vector(mp->position, mr->position); // ++++ update planner position from runtime +// bf->length = get_axis_vector_length(mr->position, mr->target); //+++++ cm->hold_state = FEEDHOLD_ACTIONS_START; } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index a487c9f7..b5564636 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -296,16 +296,13 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) bf->pv->exit_vmax = min3(bf->pv->junction_vmax, bf->pv->cruise_vmax, bf->cruise_vmax); } } - _calculate_override(bf); // adjust cruise_vmax for feed/traverse override + _calculate_override(bf); // adjust cruise_vmax for feed/traverse override // bf->plannable_time = bf->pv->plannable_time; // set plannable time - excluding current move bf->buffer_state = MP_BUFFER_IN_PROCESS; - - // +++++ Why do we have to do this here? - // bf->pv_group = bf->pv; - - bf->hint = NO_HINT; // ensure we've cleared the hints + bf->hint = NO_HINT; // ensure we've cleared the hints + // Time: 12us-41us - if (bf->nx->plannable) { // read in new buffers until EMPTY + if (bf->nx->plannable) { // read in new buffers until EMPTY return (bf->nx); } mp->planning_return = bf->nx; // where to return after planning is complete @@ -422,7 +419,7 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) optimal = true; // We can't improve this entry more } - // +++++ + // DIAGNOSTICS if (bf->buffer_state == MP_BUFFER_EMPTY) { // _debug_trap("Exec apparently cleared this block while we were planning it."); break; // exit the loop, we've hit and passed the running buffer @@ -461,24 +458,24 @@ static void _calculate_override(mpBuf_t* bf) // execute ramp to adjust cruise v // generate ramp term is a ramp is active if (mp->ramp_active) { bf->override_factor += mp->ramp_dvdt * bf->block_time; - if (mp->ramp_dvdt > 0) { // positive is an acceleration ramp + if (mp->ramp_dvdt > 0) { // positive is an acceleration ramp if (bf->override_factor > mp->ramp_target) { bf->override_factor = mp->ramp_target; - mp->ramp_active = false; // detect end of ramp + mp->ramp_active = false; // detect end of ramp } bf->cruise_velocity *= bf->override_factor; if (bf->cruise_velocity > bf->absolute_vmax) { // test max cruise_velocity bf->cruise_velocity = bf->absolute_vmax; - mp->ramp_active = false; // don't allow exceeding absolute_vmax + mp->ramp_active = false; // don't allow exceeding absolute_vmax } } else { // negative is deceleration ramp if (bf->override_factor < mp->ramp_target) { bf->override_factor = mp->ramp_target; mp->ramp_active = false; } - bf->cruise_velocity *= bf->override_factor; // +++++ this is probably wrong + bf->cruise_velocity *= bf->override_factor; // +++++ this is probably wrong // bf->exit_velocity *= bf->mfo_factor; //...but I'm not sure this is right, - // bf->cruise_velocity = bf->pv->exit_velocity; //...either + // bf->cruise_velocity = bf->pv->exit_velocity;//...either } } else { bf->cruise_velocity *= bf->override_factor; // apply original or changed factor diff --git a/g2core/planner.cpp b/g2core/planner.cpp index f5b1900a..e5be1e51 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -194,10 +194,10 @@ void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uin _mr->magic_start = MAGICNUM; // mr assertions _mr->magic_end = MAGICNUM; - _mr->bf[0].nx = &_mr->bf[1]; // Handle the two "stub blocks" in the runtime structure - _mr->bf[1].nx = &_mr->bf[0]; - _mr->r = &_mr->bf[0]; - _mr->p = &_mr->bf[1]; + _mr->block[0].nx = &_mr->block[1]; // Handle the two "stub blocks" in the runtime structure + _mr->block[1].nx = &_mr->block[0]; + _mr->r = &_mr->block[0]; + _mr->p = &_mr->block[1]; } void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR activity, but leave positions alone diff --git a/g2core/planner.h b/g2core/planner.h index 606c2785..7f9ee27e 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -464,7 +464,10 @@ typedef struct mpPlannerRuntime { // persistent runtime variables mpBlockRuntimeBuf_t *r; // block that is running mpBlockRuntimeBuf_t *p; // block that is being planned, p might == r - mpBlockRuntimeBuf_t bf[2]; // buffer holding the two blocks + mpBlockRuntimeBuf_t block[2]; // buffer holding the two blocks + + mpBuf_t *plan_bf; // DIAGNOSTIC - pointer to next buffer to plan + mpBuf_t *run_bf; // DIAGNOSTIC - pointer to currently running buffer float entry_velocity; // entry values for the currently running block diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 3993150e..d8f79698 100644 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -2,8 +2,8 @@ * xio.cpp - extended IO functions * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -403,8 +403,8 @@ extern xio_t xio; // See here for a discussion of what this means if you are not familiar with C++ // https://github.com/synthetos/g2/wiki/Dual-Endpoint-USB-Internals#c-classes-virtual-functions-and-inheritance -// LineRXBuffer takes the Motate RXBuffer (which handles "transfers", usually DMA), and adds G2 line-reading -// semantics to it. +// LineRXBuffer takes the Motate RXBuffer (which handles "transfers", usually DMA), +// and adds G2 line-reading semantics to it. template struct LineRXBuffer : RXBuffer<_size, owner_type, char> { typedef RXBuffer<_size, owner_type, char> parent_type; @@ -430,15 +430,15 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // * "index" indicates it's in to _headers array // * "offset" means it's a character in the _data array - uint16_t _scan_offset; // offset into data of the last character scanned - uint16_t _line_start_offset; // offset into first character of the line, or the first char to ignore (too-long lines) - uint16_t _last_line_length; // used for ensuring lines aren't too long - bool _ignore_until_next_line; // if we get a too-long-line, we ignore the rest by setting this flag - bool _at_start_of_line; // true if the last character scanned was the end of a line + uint16_t _scan_offset; // offset into data of the last character scanned + uint16_t _line_start_offset; // offset into first character of the line, or the first char to ignore (too-long lines) + uint16_t _last_line_length; // used for ensuring lines aren't too long + bool _ignore_until_next_line; // if we get a too-long-line, we ignore the rest by setting this flag + bool _at_start_of_line; // true if the last character scanned was the end of a line - uint16_t _lines_found; // count of complete non-control lines that were found during scanning. + uint16_t _lines_found; // count of complete non-control lines that were found during scanning. - volatile uint16_t _last_scan_offset; // DEBUGGING + volatile uint16_t _last_scan_offset; // DIAGNOSTIC bool _last_returned_a_control = false; @@ -708,8 +708,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { // move the start of the next skip section to after this skip _line_start_offset = _scan_offset; } - - + return false; // no control was found }; diff --git a/g2core/xio.h b/g2core/xio.h old mode 100755 new mode 100644 index ec04b668..743d1ae2 --- a/g2core/xio.h +++ b/g2core/xio.h @@ -2,8 +2,8 @@ * xio.h - extended IO functions * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -154,13 +154,11 @@ extern "C" { /* Signal character mappings */ -#define CHAR_RESET CAN -#define CHAR_ALARM EOT -#define CHAR_FEEDHOLD (char)'!' -#define CHAR_CYCLE_START (char)'~' -#define CHAR_QUEUE_FLUSH (char)'%' -//#define CHAR_BOOTLOADER ESC - +#define CHAR_RESET CAN // Control X - Reset Board +#define CHAR_ALARM EOT // Control D - Kill Job +#define CHAR_FEEDHOLD (char)'!' // Feedhold +#define CHAR_CYCLE_START (char)'~' // Feedhold Exit and Resume +#define CHAR_QUEUE_FLUSH (char)'%' // Feedhold Exit and Flush /**** xio_flash_file - object to hold in-flash (compiled-in) "files" to run ****/ From e0f3f159d266b6555ce33d6f24639571a7284d3a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 27 Feb 2017 13:35:23 -0500 Subject: [PATCH 159/283] Added Job Kill (^d) processing to feedholds --- g2core/alarm.cpp | 24 +++++++++------ g2core/cycle_feedhold.cpp | 64 +++++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index e2da88a4..99345a21 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -37,7 +37,7 @@ #include "temperature.h" #include "util.h" -/******************************************************************************** +/**************************************************************************************** * ALARM, SHUTDOWN, and PANIC are nested dolls. * * cm_alrm() - invoke alarm from command @@ -71,7 +71,7 @@ stat_t cm_clr(nvObj_t *nv) // clear alarm or shutdown from comman return (STAT_OK); } -/* +/**************************************************************************************** * cm_clear() - clear ALARM and SHUTDOWN states * cm_parse_clear() - parse incoming gcode for M30 or M2 clears if in ALARM state * @@ -99,7 +99,7 @@ void cm_parse_clear(const char *s) } } -/* +/**************************************************************************************** * cm_is_alarmed() - return alarm status code or OK if no alarms */ @@ -111,7 +111,7 @@ stat_t cm_is_alarmed() return (STAT_OK); } -/* +/**************************************************************************************** * cm_halt_all() - stop, spindle and coolant immediately * cm_halt_motion() - stop motion immediately. Does not affect spindle, coolant, or other IO * @@ -136,7 +136,7 @@ void cm_halt_motion(void) cm->hold_state = FEEDHOLD_OFF; } -/* +/**************************************************************************************** * cm_alarm() - enter ALARM state * * An ALARM sets the ALARM machine state, starts a feedhold to stop motion, stops the @@ -165,7 +165,8 @@ stat_t cm_alarm(const stat_t status, const char *msg) (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't alarm if already in an alarm state } - cm->machine_state = MACHINE_ALARM; + cm1.machine_state = MACHINE_ALARM; // alarm both machines + cm2.machine_state = MACHINE_ALARM; cm_request_feedhold(); // stop motion cm_request_queue_flush(); // do a queue flush once runtime is not busy @@ -180,7 +181,8 @@ stat_t cm_alarm(const stat_t status, const char *msg) sr_request_status_report(SR_REQUEST_TIMED); return (status); } -/* + +/**************************************************************************************** * cm_shutdown() - enter shutdown state * * SHUTDOWN stops all motion, spindle and coolant immediately, sets a SHUTDOWN machine @@ -213,12 +215,13 @@ stat_t cm_shutdown(const stat_t status, const char *msg) } cm->homing_state = HOMING_NOT_HOMED; - cm->machine_state = MACHINE_SHUTDOWN; // do this after all other activity + cm1.machine_state = MACHINE_SHUTDOWN; // shut down both machines... + cm2.machine_state = MACHINE_SHUTDOWN; //...do this after all other activity rpt_exception(status, msg); // send exception report return (status); } -/* +/**************************************************************************************** * cm_panic() - enter panic state * * PANIC occurs if the firmware has detected an unrecoverable internal error @@ -241,7 +244,8 @@ stat_t cm_panic(const stat_t status, const char *msg) temperature_reset(); // turn off heaters and fans cm_queue_flush(&cm1); // flush all queues and reset positions - cm->machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + cm1.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable + cm2.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable rpt_exception(status, msg); // send panic report return (status); } diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 45c42227..f202cb93 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -45,10 +45,12 @@ static stat_t _run_p1_hold_exit_actions(void); static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); static stat_t _finalize_p1_hold_exit(void); static stat_t _finalize_p2_hold_exit(void); +static stat_t _feedhold_alarm_exit(void); -/*********************************************************************************** - **** Feedholds ******************************************************************** - ***********************************************************************************/ + +/**************************************************************************************** + **** Feedholds ************************************************************************* + ****************************************************************************************/ /* * Feedholds, queue flushes and end_holds are all related and are performed in this * file and in plan_exec.cpp. Feedholds are implemented as a state machine @@ -105,7 +107,7 @@ static stat_t _finalize_p2_hold_exit(void); * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp */ -/*********************************************************************************** +/**************************************************************************************** * cm_has_hold() - return true if a hold condition exists (or a pending hold request) */ bool cm_has_hold() @@ -113,7 +115,7 @@ bool cm_has_hold() return (cm1.hold_state != FEEDHOLD_OFF); } -/*********************************************************************************** +/**************************************************************************************** * cm_request_feedhold() * cm_request_exit_hold() * cm_request_queue_flush() @@ -179,7 +181,7 @@ void cm_start_hold() } } -/*********************************************************************************** +/**************************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests * * Expected behaviors: (no-hold means machine is not in hold, etc) @@ -228,6 +230,12 @@ stat_t cm_feedhold_sequencing_callback() qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } + // special handling for alarms and job kill + if ((cm1.hold_state == FEEDHOLD_HOLD) && (cm_is_alarmed())) { + cm1.hold_exit_requested = false; + return(_feedhold_alarm_exit()); + } + // exit_hold runs for both ~ and % feedhold ends if (cm1.hold_exit_requested) { @@ -246,7 +254,7 @@ stat_t cm_feedhold_sequencing_callback() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner */ @@ -257,8 +265,8 @@ stat_t cm_feedhold_command_blocker() } return (STAT_OK); } - -/*********************************************************************************** + +/**************************************************************************************** * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here * @@ -274,6 +282,7 @@ stat_t cm_feedhold_command_blocker() * not run actions, so this function is never called for p2 feedholds. It's called * from an interrupt, so it only sets a flag. */ + static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD; @@ -281,11 +290,15 @@ static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) } static stat_t _run_p1_hold_entry_actions() -{ +{ + // do not perform entry actions if in alarm state + if (cm_is_alarmed()) { + cm1.hold_state = FEEDHOLD_HOLD; + return (STAT_OK); + } + cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // penultimate state before transitioning to HOLD - - debug_trap_if_true(st_runtime_isbusy(), "_run_p1_hold_entry_actions() - runtime is busy"); - + // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner memcpy(&cm2, &cm1, sizeof(cmMachine_t)); @@ -330,7 +343,7 @@ static stat_t _run_p1_hold_entry_actions() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * _run_p1_hold_exit_actions() - initiate return from feedhold planner * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations * _finalize_p1_hold_exit() - callback to finsh return once moves are done @@ -399,7 +412,7 @@ static stat_t _finalize_p1_hold_exit() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * _finalize_p2_hold_exit() */ @@ -418,7 +431,26 @@ static stat_t _finalize_p2_hold_exit() return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** + * _feedhold_alarm_exit() + */ + +static stat_t _feedhold_alarm_exit() +{ + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + + if (cm1.flush_state == FLUSH_WAS_RUN) { // adjust p1 planner positions to runtime positions + cm_reset_position_to_absolute_position(cm); + cm1.flush_state = FLUSH_OFF; + } + cm->cycle_state = CYCLE_OFF; + cm->hold_state = FEEDHOLD_OFF; + return (STAT_OK); +} + +/**************************************************************************************** * Queue Flush operations * * This one's complicated. See here first: From 4228e56065313d1d2403f9a1506a48cd7e8de114 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 27 Feb 2017 20:46:05 -0500 Subject: [PATCH 160/283] Experimental --- g2core/canonical_machine.cpp | 4 ---- g2core/cycle_feedhold.cpp | 12 ++++++++---- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 31 +++++++++++++++++-------------- g2core/planner.cpp | 12 ++++++------ 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0bd4baa6..253ff5e1 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1110,10 +1110,6 @@ stat_t cm_resume_origin_offsets() stat_t cm_straight_traverse(const float target[], const bool flags[]) { - if (target[AXIS_Y] == 20) { // +++ DEBUG TRAP - cm->gm.P_word = 20; - } - cm->gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; // it's legal for a G0 to have no axis words but we don't want to process it diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index f202cb93..04238e0c 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -78,7 +78,7 @@ static stat_t _feedhold_alarm_exit(void); * Feedhold Processing - Performs the following cases (listed in rough sequence order): * (0) - Feedhold request arrives or cm_start_hold() * - * Control transfers to plan_exec.cpp feedhold functions: + * Control transfers to plan_exec.cpp feedhold functions: * * (1) - Feedhold arrives while we are in the middle executing of a block * (1a) - The block is currently accelerating - wait for the end of acceleration @@ -91,24 +91,28 @@ static stat_t _feedhold_alarm_exit(void); * (1d) - The block is currently in the tail - wait until the end of the block * (1e) - We have a new block and a new feedhold request that arrived at EXACTLY the same time * (unlikely, but handled as 1b). + * * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block + * * (3) - The block has decelerated to zero velocity * (3a) - The end of deceleration is detected inline in mp_exec_aline() * (3b) - The end of deceleration is signaled and state is transitioned - * (4) - We have finished all the runtime work now we have to wait for the motors to stop + * + * (4) - Finished all the runtime work, now wait for the motors to stop * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute + * * (5) - The steppers have stopped. No motion should occur. Allows hold actions to complete * - * Control transfers back to cycle_feedhold.cpp feedhold functions: + * Control transfers back to cycle_feedhold.cpp feedhold functions: * * (6) - Removing the hold state and there is queued motion - see cycle_feedhold.cpp * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp */ /**************************************************************************************** - * cm_has_hold() - return true if a hold condition exists (or a pending hold request) + * cm_has_hold() - return true if a hold condition exists (or a pending hold request) */ bool cm_has_hold() { diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index bb1cf7a0..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 8a2a59c9..20a1e8da 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -460,9 +460,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) mr->waypoint[SECTION_BODY][axis] = mr->position[axis] + mr->unit[axis] * (mr->r->head_length + mr->r->body_length); mr->waypoint[SECTION_TAIL][axis] = mr->position[axis] + mr->unit[axis] * (mr->r->head_length + mr->r->body_length + mr->r->tail_length); } -// if (mr->waypoint[SECTION_TAIL][AXIS_X] < 0) { //+++++ -// bf->hint = (blockHint)0; -// } } // Feed Override Processing - We need to handle the following cases (listed in rough sequence order): @@ -994,14 +991,14 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) static stat_t _exec_aline_feedhold(mpBuf_t *bf) { - // Case (4) - Wait for the steppers to stop + // Case (4) - Completing the feedhold - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes // If in a p2 hold, exit the p2 hold set up a flush of the p2 planner queue if (cm == &cm2) { -// copy_vector(mp->position, mr->position); // +++++ update planner position from runtime +// copy_vector(mp->position, mr->position); // +++++ update planner position from runtime cm->hold_state = FEEDHOLD_P2_EXIT; } // At this point we know we are in a p1 hold @@ -1017,12 +1014,17 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If exiting a regular p1 hold set state to FEEDHOLD_ACTIONS_START. // This enables transition to p2 planner; then Z-lift, spindle, coolant actions else { - if (bf->gm.linenum == 10) { // +++ DEBUG TRAP - bf->override_factor *= 1.01; - } -// copy_vector(mp->position, mr->position); // ++++ update planner position from runtime -// bf->length = get_axis_vector_length(mr->position, mr->target); //+++++ - cm->hold_state = FEEDHOLD_ACTIONS_START; + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + + bf->length = get_axis_vector_length(mr->position, mr->target); // get remaining length in move +// copy_vector(mr->position, mr->target); // update position from previous target + copy_vector(mp->position, mr->position); // update planner position from runtime + + bf->plannable = true; // needed so black can be adjusted + mp_replan_queue(mp_get_r()); // make it replan all the blocks + + cm->hold_state = FEEDHOLD_ACTIONS_START; // executes entirely out of p2 planner } sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -1034,10 +1036,11 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Case (3b) - Decelerated to zero. See also Feedhold Case (3a) in mp_exec_aline() // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop - mp_replan_queue(mp_get_r()); // make it replan all the blocks +// mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move +// bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer +// bf->plannable = true; // needed so black can be adjusted +// mp_replan_queue(mp_get_r()); // make it replan all the blocks return (STAT_OK); // exit from mp_exec_aline() } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index e5be1e51..eded8eb2 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -179,22 +179,22 @@ void _init_planner_queue(mpPlanner_t *_mp, mpBuf_t *queue, uint8_t size) void planner_init(mpPlanner_t *_mp, mpPlannerRuntime_t *_mr, mpBuf_t *queue, uint8_t queue_size) { // init planner master structure - memset(_mp, 0, sizeof(mpPlanner_t));// clear all values, pointers and status - _mp->magic_start = MAGICNUM; // set boundary condition assertions + memset(_mp, 0, sizeof(mpPlanner_t)); // clear all values, pointers and status + _mp->magic_start = MAGICNUM; // set boundary condition assertions _mp->magic_end = MAGICNUM; _mp->mfo_factor = 1.00; // init planner queues - _mp->q.bf = queue; // assign puffer pool to queue manager structure + _mp->q.bf = queue; // assign puffer pool to queue manager structure _init_planner_queue(_mp, queue, queue_size); // init runtime structs _mp->mr = _mr; - memset(_mr, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status - _mr->magic_start = MAGICNUM; // mr assertions + memset(_mr, 0, sizeof(mpPlannerRuntime_t)); // clear all values, pointers and status + _mr->magic_start = MAGICNUM; // mr assertions _mr->magic_end = MAGICNUM; - _mr->block[0].nx = &_mr->block[1]; // Handle the two "stub blocks" in the runtime structure + _mr->block[0].nx = &_mr->block[1]; // Handle the two "stub blocks" in the runtime structure _mr->block[1].nx = &_mr->block[0]; _mr->r = &_mr->block[0]; _mr->p = &_mr->block[1]; From 926d8d3d3ddef75896a9a5732a6e9186c9111100 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 2 Mar 2017 13:24:39 -0500 Subject: [PATCH 161/283] Experimental --- g2core/g2core.cppproj | 4 +-- g2core/plan_exec.cpp | 57 ++++++++++++++++++++++++++++--------------- g2core/plan_line.cpp | 2 +- g2core/planner.cpp | 1 + 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..95da67f1 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800019454 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800019454 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 20a1e8da..ad0e0ed4 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -399,6 +399,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) return (STAT_NOOP); } + stat_t status; + // Initialize all new blocks, regardless of normal or feedhold operation if (mr->block_state == BLOCK_INACTIVE) { @@ -468,10 +470,15 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->motion_state == MOTION_HOLD) { // if FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. No more movement + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } - if (_exec_aline_feedhold(bf) == STAT_OK) { - return (STAT_OK); // STAT_OK terminates aline execution for this move +// if (_exec_aline_feedhold(bf) == STAT_OK) { +// return (STAT_OK); +// } + status = _exec_aline_feedhold(bf); + if ((status == STAT_OK) || // STAT_OK terminates aline execution for this move + (status == STAT_NOOP)) { // STAT_NOOP terminates execution and does not load another move + return (status); } } @@ -480,7 +487,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // NB: from this point on the contents of the bf buffer do not affect execution //**** main dispatcher to process segments *** - stat_t status = STAT_OK; + status = STAT_OK; if (mr->section == SECTION_HEAD) { status = _exec_aline_head(bf); } else if (mr->section == SECTION_BODY) { status = _exec_aline_body(bf); } else if (mr->section == SECTION_TAIL) { status = _exec_aline_tail(bf); } @@ -985,8 +992,16 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) * Feedhold processing mostly manages the deceleration phase into the hold, and sets * state variables used in cycle_feedhold.cpp * - * Returning STAT_OK ends the move. (i.e. returns STAT_OK from mp_exec_aline()) - * Returning STAT_EAGAIN allows mp_exec_aline() to continue execution + * Returns: + * + * STAT_OK exits from mp_exec_aline() but allows another segment to be loaded + * and executed. This is used when the hold is still in continuous motion. + * + * STAT_NOOP exits from mp_exec_aline() and prevents another segment loading and + * executing. This is used when the hold has stopped at the hold point. + * + * STAT_EAGAIN allows mp_exec_aline() to continue execution, playing out a head, body + * or tail. */ static stat_t _exec_aline_feedhold(mpBuf_t *bf) @@ -996,13 +1011,14 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes - // If in a p2 hold, exit the p2 hold set up a flush of the p2 planner queue + // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { // copy_vector(mp->position, mr->position); // +++++ update planner position from runtime cm->hold_state = FEEDHOLD_P2_EXIT; + return (STAT_OK); // will end this exec_aline() with no more movement } // At this point we know we are in a p1 hold - + // If probing or homing, exit the move and advance to the _motion_end_callback()'s. // Stop the runtime, clear the run buffer and do not transition to p2 planner. else if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { @@ -1010,27 +1026,30 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) mp_free_run_buffer(); // free buffer and enable finalization move to get loaded cm->hold_state = FEEDHOLD_OFF; } - - // If exiting a regular p1 hold set state to FEEDHOLD_ACTIONS_START. - // This enables transition to p2 planner; then Z-lift, spindle, coolant actions + + // In a regular p1 hold else { - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + // Reset the state of the p1 planner regardless of how hold will ultimately be exited. bf->length = get_axis_vector_length(mr->position, mr->target); // get remaining length in move -// copy_vector(mr->position, mr->target); // update position from previous target copy_vector(mp->position, mr->position); // update planner position from runtime + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->plannable = true; // needed so black can be adjusted - mp_replan_queue(mp_get_r()); // make it replan all the blocks - + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks +// st_request_forward_plan(); // queue replan of the current bf block + mp_forward_plan(); // replan current bf block + copy_vector(mp->position, mr->target); // update planner position to the target + + // Set state to enable transition to p2 and perform entry actions in the p2 planner cm->hold_state = FEEDHOLD_ACTIONS_START; // executes entirely out of p2 planner } sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } - return (STAT_OK); // hold here. No more movement + return (STAT_NOOP); // hold here. leave with a NOOP so it does not attempt another load and exec. } // Case (3b) - Decelerated to zero. See also Feedhold Case (3a) in mp_exec_aline() @@ -1056,7 +1075,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) } else { cm->hold_state = FEEDHOLD_DECEL_CONTINUE; } - return (STAT_EAGAIN); + return (STAT_EAGAIN); // exiting with EAGAIN will continue exec_aline() execution } // Case (1a) - Currently accelerating (in a head), skip and waited for body or tail @@ -1114,5 +1133,5 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) } _exec_aline_normalize_block(mr->r); } - return (STAT_EAGAIN); + return (STAT_EAGAIN); // exiting with EAGAIN will continue exec_aline() execution } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index b5564636..18eae645 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -229,7 +229,7 @@ stat_t mp_aline(GCodeState_t* gm_in) _set_bf_diagnostics(bf); // DIAGNOSTIC // Note: these next lines must remain in exact order. Position must update before committing the buffer. - copy_vector(mp->position, bf->gm.target); // set the planner position + copy_vector(mp->position, bf->gm.target); // update the planner position for the next move mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) return (STAT_OK); } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index eded8eb2..64eaff3a 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -564,6 +564,7 @@ stat_t mp_planner_callback() * We don't actually need to invalidate back-planning. Only forward planning. * */ + void mp_replan_queue(mpBuf_t *bf) { do { From dc28c0006ea5075b97d44f2958c3ea57c7f5abb1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 2 Mar 2017 15:20:33 -0500 Subject: [PATCH 162/283] Checkpoint --- g2core/gcode.h | 3 ++- g2core/plan_exec.cpp | 14 +++++++------- g2core/plan_line.cpp | 33 ++++++++++++++++----------------- g2core/planner.cpp | 2 +- g2core/planner.h | 5 ++++- 5 files changed, 30 insertions(+), 27 deletions(-) diff --git a/g2core/gcode.h b/g2core/gcode.h index 048355c3..e8fee655 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -214,7 +214,7 @@ typedef struct GCodeState { // Gcode model state - used by model, pl cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, // G82, G83 G84, G85, G86, G87, G88, G89 - float target[AXES]; // XYZABC where the move should go + float target[AXES]; // XYZABC target where the move should go float target_comp[AXES]; // summation compensation (Kahan) overflow value float display_offset[AXES]; // work offsets from the machine coordinate system (for reporting only) @@ -267,6 +267,7 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used float origin_offset[AXES]; // XYZABC G92 offsets (Note: not used in gn or gf) float g28_position[AXES]; // XYZABC stored machine position for G28 float g30_position[AXES]; // XYZABC stored machine position for G30 + float p1_position[AXES]; // XYZABC stored machine position for return to p1 planner bool m48_enable; // master feedrate / spindle speed override enable bool mfo_enable; // feedrate override enable diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index ad0e0ed4..938f47cf 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -472,16 +472,14 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } -// if (_exec_aline_feedhold(bf) == STAT_OK) { -// return (STAT_OK); -// } + // STAT_OK terminates aline execution for this move + // STAT_NOOP terminates execution and does not load another move status = _exec_aline_feedhold(bf); - if ((status == STAT_OK) || // STAT_OK terminates aline execution for this move - (status == STAT_NOOP)) { // STAT_NOOP terminates execution and does not load another move + if ((status == STAT_OK) || (status == STAT_NOOP)) { return (status); } } - + mr->block_state = BLOCK_ACTIVE; // NB: from this point on the contents of the bf buffer do not affect execution @@ -542,6 +540,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) st_request_forward_plan(); } } + copy_vector(mr->end_position, mr->position); // record end position + copy_vector(mp->position, mr->position); // record end position } return (status); } @@ -1033,12 +1033,12 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Reset the state of the p1 planner regardless of how hold will ultimately be exited. bf->length = get_axis_vector_length(mr->position, mr->target); // get remaining length in move copy_vector(mp->position, mr->position); // update planner position from runtime + copy_vector(mr->end_position, mr->position);// record end position bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->plannable = true; // needed so black can be adjusted mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks -// st_request_forward_plan(); // queue replan of the current bf block mp_forward_plan(); // replan current bf block copy_vector(mp->position, mr->target); // update planner position to the target diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 18eae645..dde71515 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -142,7 +142,7 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); } * exceeds the minimums. */ -stat_t mp_aline(GCodeState_t* gm_in) +stat_t mp_aline(GCodeState_t* _gm) { float target_rotated[AXES] = {0,0,0,0,0,0}; float axis_square[AXES] = {0,0,0,0,0,0}; @@ -153,7 +153,7 @@ stat_t mp_aline(GCodeState_t* gm_in) // A few notes about the rotated coordinate space: // These are positions PRE-rotation: - // gm_in.* (anything in gm_in) + // _gm.* (anything in _gm) // // These are positions POST-rotation: // target_rotated (after the rotation here, of course) @@ -170,23 +170,23 @@ stat_t mp_aline(GCodeState_t* gm_in) // c being target[2], // x_1 being cm->rotation_matrix[1][0] - target_rotated[0] = gm_in->target[0] * cm->rotation_matrix[0][0] + - gm_in->target[1] * cm->rotation_matrix[0][1] + - gm_in->target[2] * cm->rotation_matrix[0][2]; + target_rotated[0] = _gm->target[0] * cm->rotation_matrix[0][0] + + _gm->target[1] * cm->rotation_matrix[0][1] + + _gm->target[2] * cm->rotation_matrix[0][2]; - target_rotated[1] = gm_in->target[0] * cm->rotation_matrix[1][0] + - gm_in->target[1] * cm->rotation_matrix[1][1] + - gm_in->target[2] * cm->rotation_matrix[1][2]; + target_rotated[1] = _gm->target[0] * cm->rotation_matrix[1][0] + + _gm->target[1] * cm->rotation_matrix[1][1] + + _gm->target[2] * cm->rotation_matrix[1][2]; - target_rotated[2] = gm_in->target[0] * cm->rotation_matrix[2][0] + - gm_in->target[1] * cm->rotation_matrix[2][1] + - gm_in->target[2] * cm->rotation_matrix[2][2] + + target_rotated[2] = _gm->target[0] * cm->rotation_matrix[2][0] + + _gm->target[1] * cm->rotation_matrix[2][1] + + _gm->target[2] * cm->rotation_matrix[2][2] + cm->rotation_z_offset; // copy rotation axes for ABC (no changes) - target_rotated[3] = gm_in->target[3]; - target_rotated[4] = gm_in->target[4]; - target_rotated[5] = gm_in->target[5]; + target_rotated[3] = _gm->target[3]; + target_rotated[4] = _gm->target[4]; + target_rotated[5] = _gm->target[5]; for (uint8_t axis = 0; axis < AXES; axis++) { axis_length[axis] = target_rotated[axis] - mp->position[axis]; @@ -212,13 +212,12 @@ stat_t mp_aline(GCodeState_t* gm_in) if (bf == NULL) { // never supposed to fail return (cm_panic(STAT_FAILED_GET_PLANNER_BUFFER, "aline()")); } - memcpy(&bf->gm, gm_in, sizeof(GCodeState_t)); - // Since bf->gm.target is being used all over the place, we'll make it the rotated target + memcpy(&bf->gm, _gm, sizeof(GCodeState_t)); copy_vector(bf->gm.target, target_rotated); // copy the rotated target in place // setup the buffer bf->bf_func = mp_exec_aline; // register the callback to the exec function - bf->length = length; // record the length + bf->length = length; // record the length for (uint8_t axis = 0; axis < AXES; axis++) { // compute the unit vector and set flags if ((bf->axis_flags[axis] = flags[axis])) { // yes, this is supposed to be = and not == bf->unit[axis] = axis_length[axis] / length;// nb: bf-> unit was cleared by mp_get_write_buffer() diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 64eaff3a..3c6771b7 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -262,7 +262,7 @@ void mp_set_runtime_position(uint8_t axis, const float position) { mr->position[ void mp_set_steps_to_runtime_position() { float step_position[MOTORS]; - kn_inverse_kinematics(mr->position, step_position); // convert lengths to steps in floating point + kn_inverse_kinematics(mr->position, step_position); // convert lengths to steps in floating point for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { mr->target_steps[motor] = step_position[motor]; mr->position_steps[motor] = step_position[motor]; diff --git a/g2core/planner.h b/g2core/planner.h index 7f9ee27e..c6ebe396 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -338,6 +338,7 @@ typedef struct mpBuffer { blockHint hint; // hint the block for zoid and other planning operations. Must be accurate or NO_HINT // block parameters +// float position[AXES]; // XYZABC position at start of move float unit[AXES]; // unit vector for axis scaling & planning bool axis_flags[AXES]; // set true for axes participating in the move & for command parameters @@ -390,6 +391,7 @@ typedef struct mpBuffer { hint = NO_HINT; for (uint8_t i = 0; i< AXES; i++) { +// position[i] = 0; unit[i] = 0; axis_flags[i] = 0; } @@ -454,6 +456,7 @@ typedef struct mpPlannerRuntime { // persistent runtime variables bool axis_flags[AXES]; // set true for axes participating in the move float target[AXES]; // final target for bf (used to correct rounding errors) float position[AXES]; // current move position + float end_position[AXES]; // endpoint position of previous move float waypoint[SECTIONS][AXES]; // head/body/tail endpoints for correction float target_steps[MOTORS]; // current MR target (absolute target as steps) @@ -629,7 +632,7 @@ void mp_set_runtime_display_offset(float offset[]); bool mp_get_runtime_busy(void); bool mp_runtime_is_idle(void); -stat_t mp_aline(GCodeState_t *gm_in); // line planning... +stat_t mp_aline(GCodeState_t *_gm); // line planning... void mp_plan_block_list(void); void mp_plan_block_forward(mpBuf_t *bf); From d2b27a014ffb68c710300d462ea89bc986f9cace Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 2 Mar 2017 15:43:57 -0500 Subject: [PATCH 163/283] Checkpoint --- g2core/gcode.h | 29 +++++++++++++++-------------- g2core/plan_exec.cpp | 13 ++++++------- g2core/planner.h | 4 +--- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/g2core/gcode.h b/g2core/gcode.h index e8fee655..bf915bd4 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -176,7 +176,7 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) /* Gcode state structures */ -/***************************************************************************** +/**************************************************************************************** * GCODE MODEL - The following GCodeModel/GCodeInput structs are used: * * - gm is the core Gcode model state. It keeps the internal gcode state model in @@ -193,22 +193,23 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) * Other Gcode model state is kept in the singletons for various sub-systems, such * as arcs, spindle, coolant, and others (i.e. not ALL gcode global state is in gmx) * - * - gn is used by the gcode interpreter and is re-initialized for each - * gcode block.It accepts data in the new gcode block in the formats - * present in the block (pre-normalized forms). During initialization - * some state elements are necessarily restored from gm. + * - gn is used by the gcode interpreter and is re-initialized for each gcode block. + * It accepts data in the new gcode block in the formats present in the block + * (pre-normalized forms). During initialization some state elements are necessarily + * restored from gm. * - * - gf is used by the gcode parser interpreter to hold flags for any data - * that has changed in gn during the parse. gf.target[] values are also used - * by the canonical machine during set_target(). + * - gf is used by the gcode parser interpreter to hold flags for any data that has + * changed in gn during the parse. gf.target[] values are also used by the + * canonical machine during set_target(). * - * - cfg (config struct in config.h) is also used heavily and contains some - * values that might be considered to be Gcode model values. The distinction - * is that all values in the config are persisted and restored, whereas the - * gm structs are transient. So cfg has the G54 - G59 offsets, but gm has the - * G92 offsets. cfg has the power-on / reset gcode default values, but gm has - * the operating state for the values (which may have changed). + * - cfg (config struct in config.h) is also used heavily and contains some values + * that might be considered to be Gcode model values. The distinction is that all + * values in the config are persisted and restored, whereas the gm structs are + * transient. So cfg has the G54 - G59 offsets, but gm has the G92 offsets. + * cfg has the power-on / reset gcode default values, but gm has the operating + * state for the values (which may have changed). */ + typedef struct GCodeState { // Gcode model state - used by model, planning and runtime uint32_t linenum; // Gcode block line number cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 938f47cf..c1f40e3f 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -540,8 +540,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) st_request_forward_plan(); } } - copy_vector(mr->end_position, mr->position); // record end position - copy_vector(mp->position, mr->position); // record end position +//+++++ copy_vector(mr->end_position, mr->position); // record end position + copy_vector(mp->position, mr->position); // record actual end position of the move } return (status); } @@ -1027,14 +1027,13 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) cm->hold_state = FEEDHOLD_OFF; } - // In a regular p1 hold + // In a regular p1 hold. Motion has stopped, so we can rely on positions and other values to be stable else { // Reset the state of the p1 planner regardless of how hold will ultimately be exited. bf->length = get_axis_vector_length(mr->position, mr->target); // get remaining length in move - copy_vector(mp->position, mr->position); // update planner position from runtime - copy_vector(mr->end_position, mr->position);// record end position - + copy_vector(mp->position, mr->position); // update planner position from runtime position + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->plannable = true; // needed so black can be adjusted @@ -1045,7 +1044,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Set state to enable transition to p2 and perform entry actions in the p2 planner cm->hold_state = FEEDHOLD_ACTIONS_START; // executes entirely out of p2 planner } - + sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } diff --git a/g2core/planner.h b/g2core/planner.h index c6ebe396..ed997eba 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -338,7 +338,6 @@ typedef struct mpBuffer { blockHint hint; // hint the block for zoid and other planning operations. Must be accurate or NO_HINT // block parameters -// float position[AXES]; // XYZABC position at start of move float unit[AXES]; // unit vector for axis scaling & planning bool axis_flags[AXES]; // set true for axes participating in the move & for command parameters @@ -391,7 +390,6 @@ typedef struct mpBuffer { hint = NO_HINT; for (uint8_t i = 0; i< AXES; i++) { -// position[i] = 0; unit[i] = 0; axis_flags[i] = 0; } @@ -456,7 +454,7 @@ typedef struct mpPlannerRuntime { // persistent runtime variables bool axis_flags[AXES]; // set true for axes participating in the move float target[AXES]; // final target for bf (used to correct rounding errors) float position[AXES]; // current move position - float end_position[AXES]; // endpoint position of previous move +// float end_position[AXES]; // endpoint position of previous move +++++ float waypoint[SECTIONS][AXES]; // head/body/tail endpoints for correction float target_steps[MOTORS]; // current MR target (absolute target as steps) From f9dc7e694274bfc4a99c17a8e72c0527e205ef45 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 3 Mar 2017 07:17:56 -0500 Subject: [PATCH 164/283] Stubbed in an explicit job kill command - instead of just treating it like an alarm. --- g2core/alarm.cpp | 15 +++++++++++++++ g2core/canonical_machine.h | 2 ++ g2core/controller.cpp | 2 +- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 9 ++++++++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 99345a21..dc9c0e0f 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -249,3 +249,18 @@ stat_t cm_panic(const stat_t status, const char *msg) rpt_exception(status, msg); // send panic report return (status); } + +/**************************************************************************************** + * cm_job_kill() - Control-D handler + */ + +void cm_job_kill() +{ + cm->job_kill_requested = true; + + if (cm->machine_state == MACHINE_ALARM) { + cm->machine_state = MACHINE_PROGRAM_STOP; + } else if (cm->machine_state == MACHINE_SHUTDOWN) { + cm->machine_state = MACHINE_READY; + } +} diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index e5e2978f..a5e49b4f 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -260,6 +260,7 @@ typedef struct cmMachine { // struct to manage canonical machin uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them bool hold_exit_requested; // request exit from feedhold + bool job_kill_requested; // ^d job kill received bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move cmHomingState homing_state; // home: homing cycle sub-state machine @@ -477,6 +478,7 @@ void cm_halt_motion(void); // halt motion ( stat_t cm_alarm(const stat_t status, const char *msg); // enter alarm state - preserve Gcode state stat_t cm_shutdown(const stat_t status, const char *msg); // enter shutdown state - dump all state stat_t cm_panic(const stat_t status, const char *msg); // enter panic state - needs RESET +void cm_job_kill(void); // control-D handler /**** cfgArray interface functions ****/ diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 3d853648..4cda51d9 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -239,7 +239,7 @@ static void _dispatch_kernel(const devflags_t flags) if (*cs.bufp == '!') { cm_request_feedhold(); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } else if (*cs.bufp == '~') { cm_request_exit_hold(); } - else if (*cs.bufp == EOT) { cm_alarm(STAT_KILL_JOB, "EOT Received"); } + else if (*cs.bufp == EOT) { cm_job_kill(); } else if (*cs.bufp == ENQ) { controller_request_enquiry(); } else if (*cs.bufp == CAN) { hw_hard_reset(); } // reset immediately diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 95da67f1..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800019454 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index c1f40e3f..54f4cc77 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -240,6 +240,13 @@ stat_t mp_exec_move() { mpBuf_t *bf; + // It is possible to try to try to exec from a priming planner if coming off a hold + // This occurs if new p1 commands (and were held back) arrived while in a hold +// if (mp->planner_state <= PLANNER_PRIMING) { +// st_prep_null(); +// return (STAT_NOOP); +// } + // Run an out of band dwell. It was probably set in the previous st_load_move() if (mr->out_of_band_dwell_flag) { mr->out_of_band_dwell_flag = false; @@ -258,7 +265,7 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) { - debug_trap("mp_exec_move() buffer is not prepped. Starvation"); // IMPORTANT: can't rpt_exception from here! +// debug_trap("mp_exec_move() buffer is not prepped. Starvation"); // IMPORTANT: can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); } From b30f479ff24433d600b3512141e3b5df03ada2a6 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 3 Mar 2017 09:06:35 -0500 Subject: [PATCH 165/283] Updated planner state names; edited planner diagnostics --- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 136 ++++++++++++++++++++++-------------------- g2core/plan_line.cpp | 21 ++++--- g2core/planner.cpp | 107 ++++++++++++++++++--------------- g2core/planner.h | 8 +-- 5 files changed, 145 insertions(+), 131 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..95da67f1 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800019454 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800019454 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 54f4cc77..22a562ac 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -48,25 +48,25 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf); static void _init_forward_diffs(float v_0, float v_1); -/******************************************************************************* +/**************************************************************************************** * mp_forward_plan() - plan commands and moves ahead of exec; call ramping for moves * **** WARNING **** - * This function should NOT be called directly! - * Instead call st_request_forward_plan(), which mediates access. + * mp_forward_plan() should NOT be called directly! + * Instead call st_request_forward_plan(), which mediates access. * * mp_forward_plan() performs just-in-time forward planning immediately before - * lines and commands are queued to the move execution runtime (exec). - * Unlike backward planning, buffers are only forward planned once. + * moves and commands are queued to the move execution runtime (exec). + * Unlike back planning, buffers are only forward planned once. * * mp_forward_plan() is called aggressively via st_request_forward_plan(). * It has a relatively low interrupt level to call its own. - * See also: Planner Overview notes in planner.h + * See also: Planner Background and Overview notes in planner.h * * It examines the currently running buffer and its adjacent buffers to: * - Stop the system from re-planning or planning something that's not prepped * - Plan the next available ALINE (movement) block past the COMMAND blocks - * - Skip past/ or pre-plan COMMAND blocks while labeling them as PLANNED + * - Skip past/ or pre-plan COMMAND blocks while labeling them as FULLY_PLANNED * * Returns: * - STAT_OK if exec should be called to kickstart (or continue) movement @@ -86,68 +86,73 @@ static void _init_forward_diffs(float v_0, float v_1); * * See planner.h / bufferState enum for shorthand used in the descriptions. * All cases assume a mix of moves and commands, as noted in the shorthand. - * All cases assume 2 'blocks' - Run block & Plan block. Cases will need to be - * revisited and generalized if more blocks are used in the future (deeper - * forward planning). + * All cases assume 2 'blocks' - Run block (r) & Plan block (p). These cases + * will need to be revisited and generalized if more blocks are used in the future + * (i.e. deeper forward planning). * - * 'NOT_PREPPED' refers to any preliminary state below PREPPED, i.e. < PREPPED. - * ' NOT_PREPPED' can be either a move or command, we don't care so it's not specified. + * 'NOT_PLANNED' means the block has not been back planned or forward planned + * This refers to any state below BACK_PLANNED, i.e. < MP_BUFFER_BACK_PLANNED + * 'NOT_PLANNED' can be either a move or command, we don't care so it's not specified. + * + * 'BACK_PLANNED' means the block has been back planned but not forward planned + * 'FULLY_PLANNED' means the block is back planned and forward planned, is ready for execution + * 'RUNNING' means the move is executing in the runtime. The bf is "locked" during this phase * * 'COMMAND' or 'COMMAND(s)' refers to one command or a contiguous group of command buffers - * that may be in PREPPED or PLANNED states. Processing is always the same. Plan all - * PREPPED commands and skip past all PLANNED commands. + * that may be in BACK_PLANNED or FULLY_PLANNED states. Processing is always the same; + * plan all BACK_PLANNED commands and skip past all FULLY_PLANNED commands. * - * Note 1: For MOVEs use the exit velocity of the Run block (mr->r->exit_velocity) as the - * entry velocity of the next adjacent move. + * Note 1: For MOVEs use the exit velocity of the Run block (mr->r->exit_velocity) + * as the entry velocity of the next adjacent move. * - * Note 1a: In this special COMMAND case we trust mr->r->exit_velocity because the - * backplanner has already handled this case for us. + * Note 1a: In this special COMMAND case we trust mr->r->exit_velocity because the + * back planner has already handled this case for us. * * Note 2: For COMMANDs use the entry velocity of the current runtime (mr->entry_velocity) * as the entry velocity for the next adjacent move. mr->entry_velocity is almost always 0, * but could be non-0 in a race condition. * FYI: mr->entry_velocity is set at the end of the last running block in mp_exec_aline(). * - * * CASE: - * 0. Nothing to do + * 0. Nothing to do * - * run_buffer - * ---------- - * a. Run buffer has not yet been initialized (prep null buffer and return NOOP) - * b. NOT_PREPPED No moves or commands in run buffer. Exit with no action + * run_buffer + * ---------- + * a. Run buffer has not yet been initialized (prep null buffer and return NOOP) + * b. NOT_BACK_PLANNED No moves or commands in run buffer. Exit with no action * - * 1. Bootstrap cases (buffer state < RUNNING) + * 1. Bootstrap cases (buffer state < RUNNING) * - * run_buffer next N bufs terminal buf Actions - * ---------- ----------- ------------ ---------------------------------- - * a. PREPPED-MOVE plan move, exit OK - * b. PLANNED-MOVE NOT_PREPPED exit NOOP - * c. PLANNED-MOVE PREPPED-MOVE exit NOOP (don't plan past a PLANNED buffer) - * d. PLANNED-MOVE PLANNED-MOVE trap illegal condition, exit NOOP - * e. PLANNED-MOVE COMMAND(s) exit NOOP - * f. PREPPED-COMMAND NOT_PREPPED plan command, exit OK - * g. PREPPED-COMMAND PREPPED-MOVE plan command, plan move (Note 2), exit OK - * h. PREPPED-COMMAND PLANNED-MOVE trap illegal condition, exit NOOP - * i. PLANNED-COMMAND NOT_PREPPED skip command, exit OK - * j. PLANNED-COMMAND PREPPED-MOVE skip command, plan move (Note 2), exit OK - * k. PLANNED-COMMAND PLANNED-MOVE exit NOOP + * run_buffer next N bufs terminal buf Actions + * ---------- ----------- ------------ ---------------------------------- + * a. BACK_PLANNED/MOVE plan move, exit OK + * b. FULLY_PLANNED/MOVE NOT_PLANNED exit NOOP + * c. FULLY_PLANNED/MOVE BACK_PLANNED/MOVE exit NOOP (don't plan past a PLANNED buffer) + * d. FULLY_PLANNED/MOVE FULLY_PLANNED/MOVE trap illegal condition, exit NOOP + * e. FULLY_PLANNED/MOVE COMMAND(s) exit NOOP + * f. BACK_PLANNED/COMMAND NOT_PREPPED plan command, exit OK + * g. BACK_PLANNED/COMMAND BACK_PLANNED/MOVE plan command, plan move (Note 2), exit OK + * h. BACK_PLANNED/COMMAND FULLY_PLANNED/MOVE trap illegal condition, exit NOOP + * i. BACK_PLANNED/COMMAND NOT_PLANNED skip command, exit OK + * j. BACK_PLANNED/COMMAND BACK_PLANNED/MOVE skip command, plan move (Note 2), exit OK + * k. BACK_PLANNED/COMMAND FULLY_PLANNED/MOVE exit NOOP * - * 2. Running cases (buffer state == RUNNING) + * 2. Running cases (buffer state == RUNNING) * - * run_buffer next N bufs terminal buf Actions - * ---------- ----------- ------------ ---------------------------------- - * a. RUNNING-MOVE PREPPED-MOVE plan move, exit OK - * b. RUNNING-MOVE PLANNED-MOVE exit NOOP - * c. RUNNING-MOVE COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK - * d. RUNNING-MOVE COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move, exit OK - * e. RUNNING-MOVE COMMAND(s) PLANNED-MOVE exit NOOP - * f. RUNNING-COMMAND PREPPED-MOVE plan move, exit OK - * g. RUNNING-COMMAND PLANNED-MOVE exit NOOP - * h. RUNNING-COMMAND COMMAND(s) NOT_PREPPED skip/plan command(s), exit OK - * i. RUNNING-COMMAND COMMAND(s) PREPPED-MOVE skip/plan command(s), plan move (Note 1a), exit OK - * j. RUNNING-COMMAND COMMAND(s) PLANNED-MOVE skip command(s), exit NOOP - * (Note: all COMMAND(s) in j. should be in PLANNED state) + * run_buffer next N bufs terminal buf Actions + * ---------- ----------- ------------ ---------------------------------- + * a. RUNNING/MOVE BACK_PLANNED/MOVE plan move, exit OK + * b. RUNNING/MOVE FULLY_PLANNED/MOVE exit NOOP + * c. RUNNING/MOVE COMMAND(s) NOT_PLANNED skip/plan command(s), exit OK + * d. RUNNING/MOVE COMMAND(s) BACK_PLANNED/MOVE skip/plan command(s), plan move, exit OK + * e. RUNNING/MOVE BACK_PLANNED(s) FULLY_PLANNED-MOVE exit NOOP + * f. RUNNING/COMMAND BACK_PLANNED/MOVE plan move, exit OK + * g. RUNNING/COMMAND FULLY_PLANNED/MOVE exit NOOP + * h. RUNNING/COMMAND COMMAND(s) NOT_PLANNED skip/plan command(s), exit OK + * i. RUNNING/COMMAND COMMAND(s) BACK_PLANNED/MOVE skip/plan command(s), plan move (Note 1a), exit OK + * j. RUNNING/COMMAND COMMAND(s) FULLY_PLANNED/MOVE skip command(s), exit NOOP + * + * (Note: all COMMAND(s) in 2j. should be in PLANNED state) */ // _plan_aline() - mp_forward_plan() helper @@ -174,7 +179,7 @@ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) debug_trap_if_true((block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001), "_plan_line() zero or negative length block after calculate_ramps()"); - bf->buffer_state = MP_BUFFER_PLANNED; //...here + bf->buffer_state = MP_BUFFER_FULLY_PLANNED; //...here bf->plannable = false; return (STAT_OK); // report that we planned something... } @@ -189,7 +194,7 @@ stat_t mp_forward_plan() st_prep_null(); return (STAT_NOOP); } - if (bf->buffer_state < MP_BUFFER_PREPPED) { // case 0b: nothing to do. get outta here. + if (bf->buffer_state < MP_BUFFER_BACK_PLANNED) { // case 0b: nothing to do. get outta here. return (STAT_NOOP); } @@ -206,22 +211,22 @@ stat_t mp_forward_plan() if (bf->block_type != BLOCK_TYPE_ALINE) { // meaning it's a COMMAND while (bf->block_type >= BLOCK_TYPE_COMMAND) { - if (bf->buffer_state == MP_BUFFER_PREPPED) { - bf->buffer_state = MP_BUFFER_PLANNED;// "planning" is just setting the state (for now) + if (bf->buffer_state == MP_BUFFER_BACK_PLANNED) { + bf->buffer_state = MP_BUFFER_FULLY_PLANNED; // "planning" is just setting the state (for now) planned_something = true; } bf = bf->nx; } // Note: bf now points to the first non-command buffer past the command(s) - if ((bf->block_type == BLOCK_TYPE_ALINE) && (bf->buffer_state > MP_BUFFER_PREPPED )) { // case 1i + if ((bf->block_type == BLOCK_TYPE_ALINE) && (bf->buffer_state > MP_BUFFER_BACK_PLANNED )) { // case 1i entry_velocity = mr->r->exit_velocity; // set entry_velocity for Note 1a } } // bf will always be on a non-command at this point - either a move or empty buffer // process move - if (bf->block_type == BLOCK_TYPE_ALINE) { // do cases 1a - 1e; finish cases 1f - 1k - if (bf->buffer_state == MP_BUFFER_PREPPED) {// do 1a; finish 1f, 1j, 2d, 2i + if (bf->block_type == BLOCK_TYPE_ALINE) { // do cases 1a - 1e; finish cases 1f - 1k + if (bf->buffer_state == MP_BUFFER_BACK_PLANNED) {// do 1a; finish 1f, 1j, 2d, 2i _plan_aline(bf, entry_velocity); planned_something = true; } @@ -264,19 +269,19 @@ stat_t mp_exec_move() // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { - if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) { + if ((bf->buffer_state < MP_BUFFER_BACK_PLANNED) && (cm->motion_state == MOTION_RUN)) { // debug_trap("mp_exec_move() buffer is not prepped. Starvation"); // IMPORTANT: can't rpt_exception from here! st_prep_null(); return (STAT_NOOP); } - if ((bf->nx->buffer_state < MP_BUFFER_PREPPED) && (bf->nx->buffer_state > MP_BUFFER_EMPTY)) { + if ((bf->nx->buffer_state < MP_BUFFER_BACK_PLANNED) && (bf->nx->buffer_state > MP_BUFFER_EMPTY)) { // This detects buffer starvation, but also can be a single-line "jog" or command // rpt_exception(42, "mp_exec_move() next buffer is empty"); // ^^^ CAUSES A CRASH. We can't rpt_exception from here! debug_trap("mp_exec_move() no buffer prepped - starvation"); } - if (bf->buffer_state == MP_BUFFER_PREPPED) { + if (bf->buffer_state == MP_BUFFER_BACK_PLANNED) { debug_trap_if_true((cm->motion_state == MOTION_RUN), "mp_exec_move() buffer prepped but not planned"); // IMPORTANT: can't rpt_exception from here! // We need to have it planned. We don't want to do this here, @@ -285,7 +290,7 @@ stat_t mp_exec_move() return (STAT_NOOP); } - if (bf->buffer_state == MP_BUFFER_PLANNED) { + if (bf->buffer_state == MP_BUFFER_FULLY_PLANNED) { bf->buffer_state = MP_BUFFER_RUNNING; // must precede mp_planner_time_acccounting() } else { return (STAT_NOOP); @@ -297,7 +302,7 @@ stat_t mp_exec_move() // This won't call mp_plan_move until we leave this function // (and have called mp_exec_aline via bf->bf_func). // This also allows mp_exec_aline to advance mr->p first. - if (bf->nx->buffer_state >= MP_BUFFER_PREPPED) { + if (bf->nx->buffer_state >= MP_BUFFER_BACK_PLANNED) { st_request_forward_plan(); } @@ -1045,7 +1050,8 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->plannable = true; // needed so black can be adjusted mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks - mp_forward_plan(); // replan current bf block + st_request_forward_plan(); // replan the current bf buffer +// mp_forward_plan(); // the one case where you can call this function directly copy_vector(mp->position, mr->target); // update planner position to the target // Set state to enable transition to p2 and perform entry actions in the p2 planner diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index dde71515..176a3393 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -263,10 +263,9 @@ void mp_plan_block_list() return; } - bf = _plan_block(bf); // returns next block to plan - + bf = _plan_block(bf); // returns next block to plan planned_something = true; - mp->p = bf; // DIAGNOSTIC - this is not needed but is set here for debugging purposes + mp->p = bf; // DIAGNOSTIC - this is not needed but is set here for debugging purposes } if (mp->planner_state > PLANNER_STARTUP) { if (planned_something && (cm->hold_state != FEEDHOLD_HOLD)) { @@ -297,7 +296,7 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) } _calculate_override(bf); // adjust cruise_vmax for feed/traverse override // bf->plannable_time = bf->pv->plannable_time; // set plannable time - excluding current move - bf->buffer_state = MP_BUFFER_IN_PROCESS; + bf->buffer_state = MP_BUFFER_NOT_PLANNED; bf->hint = NO_HINT; // ensure we've cleared the hints // Time: 12us-41us @@ -418,18 +417,18 @@ static mpBuf_t* _plan_block(mpBuf_t* bf) optimal = true; // We can't improve this entry more } - // DIAGNOSTICS + // Exit the loop if we've hit and passed the running buffer. It can happen. if (bf->buffer_state == MP_BUFFER_EMPTY) { - // _debug_trap("Exec apparently cleared this block while we were planning it."); - break; // exit the loop, we've hit and passed the running buffer + break; } - // if (fp_ZERO(bf->exit_velocity) && !fp_ZERO(bf->exit_vmax)) { - // _debug_trap(); // why zero? + + // if (fp_ZERO(bf->exit_velocity) && !fp_ZERO(bf->exit_vmax)) { // DIAGNOSTIC + // debug_trap("_plan_block(): Why is exit velocity zero?"); // } // We might back plan into the running or planned buffer, so we have to check. - if (bf->buffer_state < MP_BUFFER_PREPPED) { - bf->buffer_state = MP_BUFFER_PREPPED; + if (bf->buffer_state < MP_BUFFER_BACK_PLANNED) { + bf->buffer_state = MP_BUFFER_BACK_PLANNED; } } // for loop } // exits with bf pointing to a locked or EMPTY block diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 3c6771b7..a4ad0c20 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -568,10 +568,10 @@ stat_t mp_planner_callback() void mp_replan_queue(mpBuf_t *bf) { do { - if (bf->buffer_state >= MP_BUFFER_PLANNED) { // revert from PLANNED state - bf->buffer_state = MP_BUFFER_PREPPED; - } else { // If it's not "planned" then it's either PREPPED or earlier. - break; // We don't need to adjust it. + if (bf->buffer_state >= MP_BUFFER_FULLY_PLANNED) { // revert from FULLY PLANNED state + bf->buffer_state = MP_BUFFER_BACK_PLANNED; + } else { // If it's not "planned" then it's either backplanned or earlier. + break; // We don't need to adjust it. } } while ((bf = mp_get_next_buffer(bf)) != mp_get_r()); @@ -842,13 +842,20 @@ void mp_copy_buffer(mpBuf_t *bf, const mpBuf_t *bp) } */ + +/************************************************************************************ + *** DIAGNOSTICS ******************************************************************** + ************************************************************************************/ + /************************************************************************************ * mp_dump_planner * _planner_report() - * _audit_buffers() - a DEBUG diagnostic + * _audit_buffers() */ //#define __DUMP_PLANNER +//#define __PLANNER_REPORT_ENABLED +//#define __AUDIT_BUFFERS #ifdef __DUMP_PLANNER void mp_dump_planner(mpBuf_t *bf_start) // starting at bf @@ -884,47 +891,57 @@ void mp_dump_planner(mpBuf_t *bf_start) // starting at bf } #endif // __DUMP_PLANNER -#if 0 && defined(DEBUG) - -#warning DEBUG TRAPS ENABLED - -//static void _planner_report(const char *msg) -//{ -// rpt_exception(STAT_PLANNER_ASSERTION_FAILURE, msg); -// -// for (uint8_t i=0; ibuffer_state != MP_BUFFER_RUNNING) { -// _planner_report("buffer audit1"); + _planner_report("buffer audit1"); __NOP(); -// _debug_trap(); + debug_trap("buffer audit1"); } // Check that the next from the previous is correct. if (mb.r->pv->nx != mb.r || mb.r->nx->pv != mb.r){ -// _planner_report("buffer audit2"); - _debug_trap("buffer audit2"); + _planner_report("buffer audit2"); + debug_trap("buffer audit2"); } // Now check every buffer, in order we would execute them. @@ -932,8 +949,8 @@ static void _audit_buffers() while (bf != mb.r) { // Check that the next from the previous is correct. if (bf->pv->nx != bf || bf->nx->pv != bf){ -// _planner_report("buffer audit3"); - _debug_trap("buffer audit3"); + _planner_report("buffer audit3"); + debug_trap("buffer audit3"); } // Order should be: @@ -954,8 +971,8 @@ static void _audit_buffers() if ((bf->buffer_state == MP_BUFFER_INITIALIZING) || (bf->buffer_state == MP_BUFFER_IN_PROCESS)) { __NOP(); } else { -// _planner_report("buffer audit4"); - _debug_trap("buffer audit4"); + _planner_report("buffer audit4"); + debug_trap("buffer audit4"); } } @@ -965,8 +982,8 @@ static void _audit_buffers() bf->buffer_state != MP_BUFFER_INITIALIZING && bf->buffer_state != MP_BUFFER_IN_PROCESS && bf->buffer_state != MP_BUFFER_EMPTY) { -// _planner_report("buffer audit5"); - _debug_trap("buffer audit5"); + _planner_report("buffer audit5"); + debug_trap("buffer audit5"); } // After PREPPED, we can see PREPPED, INITED, IN_PROCESS, or EMPTY @@ -975,14 +992,14 @@ static void _audit_buffers() bf->buffer_state != MP_BUFFER_INITIALIZING && bf->buffer_state != MP_BUFFER_IN_PROCESS && bf->buffer_state != MP_BUFFER_EMPTY) { -// _planner_report("buffer audit6"); - _debug_trap("buffer audit6"); + _planner_report("buffer audit6"); + debug_trap("buffer audit6"); } // After EMPTY, we should only see EMPTY if (bf->pv->buffer_state == MP_BUFFER_EMPTY && bf->buffer_state != MP_BUFFER_EMPTY) { -// _planner_report("buffer audit7"); - _debug_trap("buffer audit7"); + _planner_report("buffer audit7"); + debug_trap("buffer audit7"); } // Now look at the next one. bf = bf->nx; @@ -990,15 +1007,7 @@ static void _audit_buffers() __enable_irq(); } -#else - -static void _audit_buffers() -{ - // empty stub -} - -#endif // 0 - +#endif // __AUDIT_BUFFERS /**************************** * END OF PLANNER FUNCTIONS * diff --git a/g2core/planner.h b/g2core/planner.h index ed997eba..f4894cbb 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -164,15 +164,15 @@ typedef enum { // planner operating state PLANNER_IDLE = 0, // planner and movement are idle PLANNER_STARTUP, // ingesting blocks before movement is started PLANNER_PRIMING, // preparing new moves for planning ("stitching") - PLANNER_BACK_PLANNING // plan by planning all blocks, from the newest added to the running block + PLANNER_BACK_PLANNING // actively backplanning all blocks, from the newest added to the running block } plannerState; typedef enum { // bf->buffer_state values in incresing order so > and < can be used MP_BUFFER_EMPTY = 0, // buffer is available for use (MUST BE 0) MP_BUFFER_INITIALIZING, // buffer has been checked out and is being initialzed by aline() or a command - MP_BUFFER_IN_PROCESS, // planning is in progress - at least vmaxes have been set - MP_BUFFER_PREPPED, // buffer ready for final planning; velocities have been set - MP_BUFFER_PLANNED, // buffer fully planned. May still be replanned + MP_BUFFER_NOT_PLANNED, // planning is in progress - at least vmaxes have been set + MP_BUFFER_BACK_PLANNED, // buffer ready for final planning; velocities have been set + MP_BUFFER_FULLY_PLANNED, // buffer fully planned. May still be replanned MP_BUFFER_RUNNING, // current running buffer MP_BUFFER_POLAND, // Hitler used Poland as a buffer state MP_BUFFER_UKRAINE // Later Stalin did the same to Ukraine From cdf821dbaab3e50a8ea07f850cb5b1f5be504a6e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 3 Mar 2017 09:25:19 -0500 Subject: [PATCH 166/283] Fixed problem with new move arriving while in feedhold. --- g2core/planner.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/planner.cpp b/g2core/planner.cpp index a4ad0c20..dc445862 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -753,7 +753,7 @@ mpBuf_t * mp_get_write_buffer() // get & clear a buffer mpPlannerQueue_t *q = &(mp->q); if (q->w->buffer_state == MP_BUFFER_EMPTY) { - _clear_buffer(q->w); // NB: this is no longer redundant, as it was not just cleared in mp_free_run_buffer + _clear_buffer(q->w); // NB: this is redundant if the buffer was cleared mp_free_run_buffer() q->w->buffer_state = MP_BUFFER_INITIALIZING; q->buffers_available--; return (mp_get_w()); @@ -827,8 +827,8 @@ bool mp_free_run_buffer() // EMPTY current run buffer & advance to the _audit_buffers(); // DIAGNOSTIC audit for buffer chain integrity (only runs in DEBUG mode) q->r = q->r->nx; // advance to next run buffer first... -// _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) - r_now->buffer_state = MP_BUFFER_EMPTY; //... then mark the buffer empty while perserving content for debug inspection + _clear_buffer(r_now); // ... then clear out the old buffer (& set MP_BUFFER_EMPTY) +// r_now->buffer_state = MP_BUFFER_EMPTY; //... then mark the buffer empty while preserving content for debug inspection q->buffers_available++; qr_request_queue_report(-1); // request a QR and add to the "removed buffers" count return (q->w == q->r); // return true if the queue emptied From a0710b3aaee41b8f30a122398aad8de76dc3f87b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 3 Mar 2017 12:54:21 -0500 Subject: [PATCH 167/283] Fixed position error found in regressions test FI00 --- g2core/cycle_feedhold.cpp | 1 - g2core/plan_exec.cpp | 14 +------------- g2core/plan_line.cpp | 14 +++++++------- g2core/planner.h | 1 - 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 04238e0c..496a2d2b 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -380,7 +380,6 @@ static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_P1_EXIT; // penultimate state before transitioning to FEEDHOLD_OFF - // copy_vector(mp->position, mr->position); // +++++ Compensate for amount of move already performed sr_request_status_report(SR_REQUEST_IMMEDIATE); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 22a562ac..80445f63 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -552,8 +552,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) st_request_forward_plan(); } } -//+++++ copy_vector(mr->end_position, mr->position); // record end position - copy_vector(mp->position, mr->position); // record actual end position of the move } return (status); } @@ -803,7 +801,6 @@ static stat_t _exec_aline_body(mpBuf_t *bf) debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); return (STAT_OK); // exit without advancing position, say we're done } - mr->section = SECTION_BODY; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } @@ -1025,7 +1022,6 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { -// copy_vector(mp->position, mr->position); // +++++ update planner position from runtime cm->hold_state = FEEDHOLD_P2_EXIT; return (STAT_OK); // will end this exec_aline() with no more movement } @@ -1043,16 +1039,12 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) else { // Reset the state of the p1 planner regardless of how hold will ultimately be exited. - bf->length = get_axis_vector_length(mr->position, mr->target); // get remaining length in move - copy_vector(mp->position, mr->position); // update planner position from runtime position - + bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move bf->plannable = true; // needed so black can be adjusted mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks st_request_forward_plan(); // replan the current bf buffer -// mp_forward_plan(); // the one case where you can call this function directly - copy_vector(mp->position, mr->target); // update planner position to the target // Set state to enable transition to p2 and perform entry actions in the p2 planner cm->hold_state = FEEDHOLD_ACTIONS_START; // executes entirely out of p2 planner @@ -1068,10 +1060,6 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop -// mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move -// bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer -// bf->plannable = true; // needed so black can be adjusted -// mp_replan_queue(mp_get_r()); // make it replan all the blocks return (STAT_OK); // exit from mp_exec_aline() } diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 176a3393..c9a90714 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -104,7 +104,7 @@ float mp_get_runtime_display_position(uint8_t axis) { } } -/* +/**************************************************************************************** * mp_get_runtime_busy() - returns TRUE if motion control busy (i.e. robot is moving) * mp_runtime_is_idle() - returns TRUE is steppers are not actively moving * @@ -233,7 +233,7 @@ stat_t mp_aline(GCodeState_t* _gm) return (STAT_OK); } -/* +/**************************************************************************************** * mp_plan_block_list() - plan all the blocks in the list * * This parent function is just a dispatcher that reads forward in the list @@ -275,8 +275,8 @@ void mp_plan_block_list() mp->p = bf; // update planner pointer } -/* - * _plan_block() - the block chain using pessimistic assumptions +/**************************************************************************************** + * _plan_block() - stitch and backplan a new block to the planner queue */ static mpBuf_t* _plan_block(mpBuf_t* bf) @@ -492,7 +492,7 @@ static void _calculate_override(mpBuf_t* bf) // execute ramp to adjust cruise v // } } -/* +/**************************************************************************************** * _calculate_jerk() - calculate jerk given the dynamic state * * Set the jerk scaling to the lowest axis with a non-zero unit vector. @@ -542,7 +542,7 @@ static void _calculate_jerk(mpBuf_t* bf) bf->q_recip_2_sqrt_j = q / (2 * sqrt_j); } -/* +/**************************************************************************************** * _calculate_vmaxes() - compute cruise_vmax and absolute_vmax based on velocity constraints * * The following feeds and times are compared and the longest (slowest velocity) is returned: @@ -647,7 +647,7 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa bf->block_time = block_time; // initial estimate - used for ramp computations } -/* +/**************************************************************************************** * _calculate_junction_vmax() - Giseburt's Algorithm ;-) * * WARNING: This description is out of date and needs to be updated. diff --git a/g2core/planner.h b/g2core/planner.h index f4894cbb..ed84c5c6 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -454,7 +454,6 @@ typedef struct mpPlannerRuntime { // persistent runtime variables bool axis_flags[AXES]; // set true for axes participating in the move float target[AXES]; // final target for bf (used to correct rounding errors) float position[AXES]; // current move position -// float end_position[AXES]; // endpoint position of previous move +++++ float waypoint[SECTIONS][AXES]; // head/body/tail endpoints for correction float target_steps[MOTORS]; // current MR target (absolute target as steps) From e92563d16b346297ba86f4f8ac8ba39f418542c2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 3 Mar 2017 14:38:58 -0500 Subject: [PATCH 168/283] Fixed G92 offsets not displaying; added traps in plan_exec to see about reminding a redundant statements --- g2core/canonical_machine.cpp | 11 +++++++---- g2core/plan_exec.cpp | 5 ++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 253ff5e1..5f25a020 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -591,10 +591,8 @@ stat_t cm_set_tram(nvObj_t *nv) // Step 1b: compute the combined magnitude // since sqrt(a)*sqrt(b) = sqrt(a*b), we can save a sqrt in making the unit normal - float combined_magnitude_inv = 1.0/sqrt( - (d0_x*d0_x + d0_y*d0_y + d0_z*d0_z)* - (d2_x*d2_x + d2_y*d2_y + d2_z*d2_z) - ); + float combined_magnitude_inv = 1.0/sqrt((d0_x*d0_x + d0_y*d0_y + d0_z*d0_z) * + (d2_x*d2_x + d2_y*d2_y + d2_z*d2_z)); // Step 1c: compute the cross product and normalize float n_x = (d0_z*d2_y - d0_y*d2_z)*combined_magnitude_inv; @@ -894,6 +892,7 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, else { return (STAT_L_WORD_IS_INVALID); } + cm_set_display_offsets(MODEL); return (STAT_OK); } @@ -1071,6 +1070,7 @@ stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) // now pass the offset to the callback - setting the coordinate system also applies the offsets float value[] = { (float)cm->gm.coord_system }; // pass coordinate system in value[0] element mp_queue_command(_exec_offset, value, nullptr); + cm_set_display_offsets(MODEL); return (STAT_OK); } @@ -1082,6 +1082,7 @@ stat_t cm_reset_origin_offsets() } float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); + cm_set_display_offsets(MODEL); return (STAT_OK); } @@ -1090,6 +1091,7 @@ stat_t cm_suspend_origin_offsets() cm->gmx.origin_offset_enable = false; float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); + cm_set_display_offsets(MODEL); return (STAT_OK); } @@ -1098,6 +1100,7 @@ stat_t cm_resume_origin_offsets() cm->gmx.origin_offset_enable = true; float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); + cm_set_display_offsets(MODEL); return (STAT_OK); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 80445f63..9c2cc5b4 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -756,7 +756,8 @@ static stat_t _exec_aline_head(mpBuf_t *bf) if (mr->segment_time < MIN_SEGMENT_TIME) { debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); return (STAT_OK); // exit without advancing position, say we're done - } + } + debug_trap_if_true(mr->section != SECTION_HEAD, "exec_aline() Not section head"); mr->section = SECTION_HEAD; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { @@ -801,6 +802,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf) debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); return (STAT_OK); // exit without advancing position, say we're done } + debug_trap_if_true(mr->section != SECTION_BODY, "exec_aline() Not section body"); mr->section = SECTION_BODY; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } @@ -841,6 +843,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); return (STAT_OK); // exit without advancing position, say we're done } + debug_trap_if_true(mr->section != SECTION_TAIL, "exec_aline() Not section tail"); mr->section = SECTION_TAIL; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { From 4bd5435a2a9e3d79ccf13352b228923ac1d3b51b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 4 Mar 2017 08:47:16 -0500 Subject: [PATCH 169/283] Update the display of tool change offsets in the model as they occur --- g2core/canonical_machine.cpp | 8 ++++++-- g2core/g2core.cppproj | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 5f25a020..1399fe9c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -929,6 +929,8 @@ stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool appl cm->tool_offset[axis] = tt.tt_offset[tool][axis]; } } + cm_set_display_offsets(MODEL); // display new offsets in the model right now + float value[] = { (float)cm->gm.coord_system }; // pass coordinate system in value[0] element mp_queue_command(_exec_offset, value, nullptr); // second vector (flags) is not used, so fake it return (STAT_OK); @@ -939,8 +941,10 @@ stat_t cm_cancel_tl_offset() for (uint8_t axis = AXIS_X; axis < AXES; axis++) { cm->tool_offset[axis] = 0; } + cm_set_display_offsets(MODEL); // display new offsets in the model right now + float value[] = { (float)cm->gm.coord_system }; - mp_queue_command(_exec_offset, value, nullptr); + mp_queue_command(_exec_offset, value, nullptr); // changes it in the runtime when executed return (STAT_OK); } @@ -956,7 +960,7 @@ stat_t cm_set_coord_system(const uint8_t coord_system) // set coordinate system static void _exec_offset(float *value, bool *flag) { - uint8_t coord_system = ((uint8_t)value[0]); // coordinate system is passed in value[0] element + uint8_t coord_system = ((uint8_t)value[0]); // coordinate system is passed in value[0] element float offsets[AXES]; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { offsets[axis] = cm->coord_offset[coord_system][axis] + cm->tool_offset[axis] + diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 95da67f1..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800019454 + J41800036434 0x284E0A60 10000000 From b68782a5d12633da843bb623e20943d5fe128736 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 4 Mar 2017 10:07:18 -0500 Subject: [PATCH 170/283] Renaming and commenting - no functional changes --- g2core/canonical_machine.h | 8 ++++---- g2core/cycle_feedhold.cpp | 32 ++++++++++++++------------------ g2core/plan_exec.cpp | 13 +++++++------ 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index a5e49b4f..db353a83 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -115,10 +115,10 @@ typedef enum { // feedhold state machine FEEDHOLD_SYNC, // start hold - sync to latest aline segment FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero - FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed - FEEDHOLD_MOTORS_STOPPING, // waiting to complete deceleration once planner motion stops - FEEDHOLD_ACTIONS_START, // enter secondary planner and perform feedhold actions (once) - FEEDHOLD_ACTIONS_WAIT, // wait for feedhold actions to complete + FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet + FEEDHOLD_MOTORS_STOPPING, // waiting for motors to have stopped on hold point (motion stop) + FEEDHOLD_P2_START, // enter secondary planner and perform feedhold actions (once) + FEEDHOLD_P2_WAIT, // wait for feedhold actions to complete FEEDHOLD_HOLD, // holding (steady state) Must be last state FEEDHOLD_P2_EXIT // set when p2 feedhold is finishing } cmFeedholdState; diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 496a2d2b..bdae316d 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -67,7 +67,7 @@ static stat_t _feedhold_alarm_exit(void); * A feedhold exit request (~) received while in either p1 or p2 will execute the * feedhold exit actions: * - Resume coolant (if paused) - * - Resume spindle (if paseud) with spinup delay + * - Resume spindle (if paused) with spinup delay * - Move back to starting location in XY, then plunge in Z * Motion will resume in p1 after the exit actions complete * @@ -76,7 +76,8 @@ static stat_t _feedhold_alarm_exit(void); */ /* * Feedhold Processing - Performs the following cases (listed in rough sequence order): - * (0) - Feedhold request arrives or cm_start_hold() + * + * (0) - Feedhold request arrives or cm_start_hold() is called * * Control transfers to plan_exec.cpp feedhold functions: * @@ -93,22 +94,17 @@ static stat_t _feedhold_alarm_exit(void); * (unlikely, but handled as 1b). * * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block - * - * (3) - The block has decelerated to zero velocity - * (3a) - The end of deceleration is detected inline in mp_exec_aline() - * (3b) - The end of deceleration is signaled and state is transitioned - * - * (4) - Finished all the runtime work, now wait for the motors to stop + * (3) - The end of deceleration is detected inline in mp_exec_aline() + * (4) - Finished all runtime work, now wait for the motors to stop on HOLD point. When they do: * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute * - * (5) - The steppers have stopped. No motion should occur. Allows hold actions to complete - * * Control transfers back to cycle_feedhold.cpp feedhold functions: * - * (6) - Removing the hold state and there is queued motion - see cycle_feedhold.cpp - * (7) - Removing the hold state and there is no queued motion - see cycle_feedhold.cpp + * (5) - Run the P2 entry actions and transition to HOLD state when complete + * (6) - Remove the hold state / there is queued motion - see cycle_feedhold.cpp + * (7) - Remove the hold state / there is no queued motion - see cycle_feedhold.cpp */ /**************************************************************************************** @@ -211,7 +207,7 @@ stat_t cm_feedhold_sequencing_callback() cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } - if (cm1.hold_state == FEEDHOLD_ACTIONS_START) { // perform Z lift, spindle & coolant actions + if (cm1.hold_state == FEEDHOLD_P2_START) { // enter p2 planner; perform Z lift, spindle & coolant actions _run_p1_hold_entry_actions(); } @@ -271,7 +267,7 @@ stat_t cm_feedhold_command_blocker() } /**************************************************************************************** - * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold + * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here * * This function assumes that the feedhold sequencing callback has resolved all @@ -287,13 +283,13 @@ stat_t cm_feedhold_command_blocker() * from an interrupt, so it only sets a flag. */ -static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) +static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) // Complete case (5) { cm1.hold_state = FEEDHOLD_HOLD; sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _run_p1_hold_entry_actions() +static stat_t _run_p1_hold_entry_actions() // Execute Case (5) { // do not perform entry actions if in alarm state if (cm_is_alarmed()) { @@ -301,7 +297,7 @@ static stat_t _run_p1_hold_entry_actions() return (STAT_OK); } - cm->hold_state = FEEDHOLD_ACTIONS_WAIT; // penultimate state before transitioning to HOLD + cm->hold_state = FEEDHOLD_P2_WAIT; // penultimate state before transitioning to HOLD // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner @@ -360,7 +356,7 @@ static stat_t _run_p1_hold_entry_actions() * the sync runs from an interrupt. Finalization needs to run from the main loop. */ -static stat_t _run_p1_hold_exit_actions() // LATER: if value == true return with offset corrections +static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) { // perform end-hold actions --- while still in secondary machine coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 9c2cc5b4..620f6d9c 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -480,9 +480,9 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->motion_state == MOTION_HOLD) { - // if FEEDHOLD_ACTIONS_START, FEEDHOLD_ACTIONS_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT - if (cm->hold_state >= FEEDHOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) - return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move + // if FEEDHOLD_P2_START, FEEDHOLD_P2_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT + if (cm->hold_state >= FEEDHOLD_P2_START) { // handles _exec_aline_feedhold_processing case (7) + return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } // STAT_OK terminates aline execution for this move // STAT_NOOP terminates execution and does not load another move @@ -517,7 +517,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) bf->plannable = false; } - // Feedhold Case (3b): Look for the end of the deceleration to transition HOLD states + // Feedhold Case (3): Look for the end of the deceleration to transition HOLD states // This code sets states used by _exec_feedhold_processing() helper. if (cm->hold_state == FEEDHOLD_DECEL_TO_ZERO) { if ((status == STAT_OK) || (status == STAT_NOOP)) { @@ -1050,7 +1050,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) st_request_forward_plan(); // replan the current bf buffer // Set state to enable transition to p2 and perform entry actions in the p2 planner - cm->hold_state = FEEDHOLD_ACTIONS_START; // executes entirely out of p2 planner + cm->hold_state = FEEDHOLD_P2_START; // executes entirely out of p2 planner } sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -1059,8 +1059,9 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) return (STAT_NOOP); // hold here. leave with a NOOP so it does not attempt another load and exec. } - // Case (3b) - Decelerated to zero. See also Feedhold Case (3a) in mp_exec_aline() + // Case (3') - Decelerated to zero. See also Feedhold Case (3) in mp_exec_aline() // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity + // This state might not appear necessary, but it is to handle closely packed !~ and other cases if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop return (STAT_OK); // exit from mp_exec_aline() From e7db065c80eb34f13ea9367ee26547138db21b43 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 4 Mar 2017 14:26:38 -0500 Subject: [PATCH 171/283] Checkpoint job kill code --- g2core/alarm.cpp | 13 ++--- g2core/canonical_machine.h | 4 +- g2core/cycle_feedhold.cpp | 105 ++++++++++++++++++++++++++----------- 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index dc9c0e0f..7e4fd2e5 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -256,11 +256,12 @@ stat_t cm_panic(const stat_t status, const char *msg) void cm_job_kill() { - cm->job_kill_requested = true; + cm1.hold_abort_requested = true; + cm_program_end(); - if (cm->machine_state == MACHINE_ALARM) { - cm->machine_state = MACHINE_PROGRAM_STOP; - } else if (cm->machine_state == MACHINE_SHUTDOWN) { - cm->machine_state = MACHINE_READY; - } +// if (cm->machine_state == MACHINE_ALARM) { +// cm->machine_state = MACHINE_PROGRAM_STOP; +// } else if (cm->machine_state == MACHINE_SHUTDOWN) { +// cm->machine_state = MACHINE_READY; +// } } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index db353a83..08b630a7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -259,8 +259,8 @@ typedef struct cmMachine { // struct to manage canonical machin uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them - bool hold_exit_requested; // request exit from feedhold - bool job_kill_requested; // ^d job kill received + bool hold_exit_requested; // request normal exit from feedhold + bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move cmHomingState homing_state; // home: homing cycle sub-state machine diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index bdae316d..39767fd8 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -42,10 +42,10 @@ static stat_t _run_p1_hold_entry_actions(void); static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); static stat_t _run_p1_hold_exit_actions(void); -static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); -static stat_t _finalize_p1_hold_exit(void); -static stat_t _finalize_p2_hold_exit(void); -static stat_t _feedhold_alarm_exit(void); +static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); +static void _feedhold_p1_exit(void); +static void _feedhold_p2_exit(void); +static void _feedhold_abort(void); /**************************************************************************************** @@ -219,7 +219,8 @@ stat_t cm_feedhold_sequencing_callback() } } if (cm2.hold_state == FEEDHOLD_P2_EXIT) { - return(_finalize_p2_hold_exit()); + _feedhold_p2_exit(); + return (STAT_OK); } // queue flush won't run until the hold is complete and all (subsequent) motion has stopped @@ -230,12 +231,11 @@ stat_t cm_feedhold_sequencing_callback() qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available } - // special handling for alarms and job kill - if ((cm1.hold_state == FEEDHOLD_HOLD) && (cm_is_alarmed())) { - cm1.hold_exit_requested = false; - return(_feedhold_alarm_exit()); + // special handling for feedhold abort - M2/M30, job kill, alarms + if (cm1.hold_abort_requested) { + _feedhold_abort(); } - + // exit_hold runs for both ~ and % feedhold ends if (cm1.hold_exit_requested) { @@ -249,7 +249,7 @@ stat_t cm_feedhold_sequencing_callback() } } if (cm1.hold_state == FEEDHOLD_P1_EXIT) { - return(_finalize_p1_hold_exit()); // run multiple times until actions are complete + _feedhold_p1_exit(); // run multiple times until actions are complete } return (STAT_OK); } @@ -291,9 +291,9 @@ static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) // Com static stat_t _run_p1_hold_entry_actions() // Execute Case (5) { - // do not perform entry actions if in alarm state - if (cm_is_alarmed()) { - cm1.hold_state = FEEDHOLD_HOLD; + // do not perform entry actions if feedhold abort in progress + if (cm1.hold_abort_requested) { + cm1.hold_state = FEEDHOLD_OFF; return (STAT_OK); } @@ -346,7 +346,7 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) /**************************************************************************************** * _run_p1_hold_exit_actions() - initiate return from feedhold planner * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations - * _finalize_p1_hold_exit() - callback to finsh return once moves are done + * _feedhold_p1_exit() - callback to finsh return once moves are done * * These functions assume that the feedhold sequencing callback has resolved all * state and timing issues and it's OK to call this now. Do not call this function @@ -356,8 +356,17 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) * the sync runs from an interrupt. Finalization needs to run from the main loop. */ -static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) +static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) { + // do not perform exit actions if feedhold abort in progress + if (cm1.hold_abort_requested) { + cm = &cm1; // reset to p1 planner + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + cm1.hold_state = FEEDHOLD_OFF; + return (STAT_OK); + } + // perform end-hold actions --- while still in secondary machine coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused @@ -379,11 +388,11 @@ static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _finalize_p1_hold_exit() +static void _feedhold_p1_exit() { // skip out if not ready to finalize the exit if (cm1.hold_state != FEEDHOLD_P1_EXIT) { - return (STAT_NOOP); // ??? return (STAT_EAGAIN); + return; } // return to primary planner (p1) @@ -408,14 +417,15 @@ static stat_t _finalize_p1_hold_exit() cm_cycle_end(); } cm1.hold_state = FEEDHOLD_OFF; - return (STAT_OK); } /**************************************************************************************** - * _finalize_p2_hold_exit() + * _feedhold_p2_exit() - exit from a feedhold in feedhold (from p2) + * + * Assumes planner is in p2 on entry */ -static stat_t _finalize_p2_hold_exit() +static void _feedhold_p2_exit() { float position[AXES]; copy_vector(position, mr2.position); // save the final position @@ -427,27 +437,60 @@ static stat_t _finalize_p2_hold_exit() cm_set_motion_state(MOTION_STOP); cm_cycle_end(); sr_request_status_report(SR_REQUEST_IMMEDIATE); - return (STAT_OK); } /**************************************************************************************** - * _feedhold_alarm_exit() + * _feedhold_abort() - used to exit a feedhold without completing exit actions + * + * Valid entry states (all must be handled): + * Case (1) Not in a feedhold (FEEDHOLD_OFF). Ignore the request + * + * Case (2) In a feedhold but have not yet hit the hold point. + * Leave the abort request pending to be picked up by p2 entry actions, + * which are not allowed to proceed. + * + * Case (3) In a feedhold and currently executing P2 entry actions + * Case (4) In a feedhold and currently idle in P2 + * Case (5) In a feedhold and currently moving in P2 + * Case (6) In a feedhold and currently executing P2 exit actions */ -static stat_t _feedhold_alarm_exit() +static void _feedhold_abort() { - cm = &cm1; // return to primary planner (p1) + // Exit if not in a feedhold + if (cm1.hold_state == FEEDHOLD_OFF) { + cm1.hold_abort_requested = false; + return; + } + + // No action if waiting for HOLD point - let P2_START run the abort + if ((cm1.hold_state > FEEDHOLD_OFF) && (cm1.hold_state < FEEDHOLD_P2_START)) { + return; + } + + // If in p2 perform the p2 exit first + if (cm == &cm2) { + _feedhold_p2_exit(); + } + + // perform a complete exit from p1 + cm = &cm1; // return to p1 if not already here mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; - - if (cm1.flush_state == FLUSH_WAS_RUN) { // adjust p1 planner positions to runtime positions + + // execute this block if a queue flush was performed + // adjust p1 planner positions to runtime positions + if (cm1.flush_state == FLUSH_WAS_RUN) { cm_reset_position_to_absolute_position(cm); cm1.flush_state = FLUSH_OFF; } - cm->cycle_state = CYCLE_OFF; - cm->hold_state = FEEDHOLD_OFF; - return (STAT_OK); -} + + // end cycle + cm_set_motion_state(MOTION_STOP); +// cm_cycle_end(); + cm1.hold_state = FEEDHOLD_OFF; + cm1.hold_abort_requested = false; +} /**************************************************************************************** * Queue Flush operations From f265c57d7d6ae2c24c8239fb92130892d8316ca7 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Mar 2017 10:18:51 -0500 Subject: [PATCH 172/283] Added Feedhold request enum and some comments about it. --- g2core/canonical_machine.h | 22 +++++++++ g2core/cycle_feedhold.cpp | 97 ++++++++++++++++++++++++++++++++------ 2 files changed, 104 insertions(+), 15 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 08b630a7..28b62599 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -108,6 +108,28 @@ typedef enum { MOTION_HOLD // feedhold in progress: set whenever we leave FEEDHOLD_OFF, unset whenever we enter FEEDHOLD_OFF } cmMotionState; +typedef enum { // feedhold requests + FEEDHOLD_NO_REQUEST =0, // no pending request; reverts here when complete (read-only; cannot be set) + FEEDHOLD_HOLD_P1 =1, // enter p1 feedhold, enter HOLD state in p1 + FEEDHOLD_HOLD_P2 =2, // (!) enter p1 feedhold, enter p2 with entry actions + FEEDHOLD_EXIT_RESUME =3, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion + FEEDHOLD_EXIT_FLUSH =4, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP + + // Feedholds with specialized exits + // If not in hold, perform hold (or halt), then perform the exit immediately + // If already in hold just perform the exit + FEEDHOLD_HOLD_SKIP, // enter p1 feedhold, skip remainder of block, resume from next block (for homing & probes) + FEEDHOLD_HOLD_STOP, // enter p1 feedhold, enter PROGRAM_STOP state + FEEDHOLD_HOLD_FAST_STOP, // enter p1 feedhold, perform FAST_STOP, enter STOP state + FEEDHOLD_HOLD_HALT, // enter p1 feedhold, enter PROGRAM_STOP state + FEEDHOLD_HOLD_END, // enter p1 feedhold, flush queue, perform PROGRAM_END + FEEDHOLD_HOLD_END_ALARM, // enter p1 feedhold, flush queue, perform PROGRAM_END, trigger ALARM + FEEDHOLD_HOLD_ALARM, // enter p1 feedhold, flush queue, trigger ALARM + FEEDHOLD_HOLD_SHUTDOWN, // enter p1 feedhold, flush queue, trigger SHUTDOWN + FEEDHOLD_HOLD_PANIC, // perform HALT, trigger PANIC + FEEDHOLD_HOLD_INTERLOCK // enter p1 feedhold, trigger and release INTERLOCK +} cmFeedholdRequest; + typedef enum { // feedhold state machine FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 39767fd8..b7dc9599 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -74,6 +74,73 @@ static void _feedhold_abort(void); * A feedhold flush request (%) received while in either p1 or p2 will execute the * exit actions, flush the p1 and p2 queues, then stop motion at the hold point. */ +/* + * Feedhold Enumerations and Use Cases + * + * The cmFeedholdRequest enum supports the following feedhold use cases. Feedholds and + * feedhold exits using these enums to get specific behaviors. First the normal ones: + * + * - FEEDHOLD_NO_REQUEST No request pending. Requests transition here when complete. + * This value cannot be set (i.e. there is no CANCEL command). + * + * - FEEDHOLD_HOLD_P1 Enter HOLD state in P1. Do not enter p2 or perform entry actions. + * + * - FEEDHOLD_HOLD_P2 (!) Enter HOLD state in P1. Enter p2 and perform entry actions. + * If this command is received while in p2, a FEEDHOLD_HOLD_SKIP + * is executed in p2. + * + * - FEEDHOLD_EXIT_RESUME (~) Exit HOLD state in P1 or p2. If in p2 perform exit actions, + * then resume motion in p1 planner. + * + * - FEEDHOLD_EXIT_FLUSH (%) Exit HOLD state in P1 or p2. If in p2 perform exit actions, + * then flush p1 planner. End in PROGRAM_STOP state. + * + * Now the specialized ones. If these are called with FEEDHOLD_OFF (i.e. while not in a feedhold) + * A feedhold is performed followed by the indicated actions. If called while in a feedhold the + * feedhold is exited with the indicated actions. Most of these commands are not available in p2. + * + * - FEEDHOLD_HOLD_SKIP Enter HOLD state in P1 or P2. Skip the remainder of the move in the + * held block. If the next block following held block is labeled as a + * SYNC block, execute it. Otherwise flush the queue and STOP. Used + * by homing and probing to stop motion and trigger next actions. + * + * - FEEDHOLD_HOLD_STOP Enter HOLD state in P1. Enter PROGRAM_STOP state. A cycle start or + * FEEDHOLD_EXIT_RESUME will restart motion. + * + * - FEEDHOLD_HOLD_FAST_STOP Enter HOLD state in P1 using a fast hold. Perform PROGRAM_STOP. + * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. + * + * - FEEDHOLD_HOLD_HALT Enter HOLD state in P1 using a HALT. Perform PROGRAM_STOP. + * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. + * + * - FEEDHOLD_HOLD_END Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. + * This has the effect of entering an asynchronous M30. Useful for Job Kill + * if the sender knows there are no commands following the HOLD command. + * + * - FEEDHOLD_HOLD_END_ALARM Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. + * Trigger ALARM. Useful for Job Kill if there may be subsequent commands + * queued by the sender. Requires {clear:n} or M2/M30 to recover operation. + * + * - FEEDHOLD_HOLD_ALARM Enter HOLD state in P1. Flush planner queue. Trigger ALARM. + * Requires {clear:n} or M2/M30 to recover operation. + * + * - FEEDHOLD_HOLD_SHUTDOWN Enter HOLD state in P1. Flush planner queue. Trigger SHUTDOWN. + * Requires {clear:n} or M2/M30 to recover operation. + * + * - FEEDHOLD_HOLD_PANIC Enter HOLD state in P1 using a HALT. Trigger PANIC. + * Requires reset to recover operation. + * + * Interlocks are also handled here. Invoking FEEDHOLD_HOLD_INTERLOCK when the interlock is + * not active will engage it. Invoking it while engaged releases the interlock and resumes + * normal operation. + * + * - FEEDHOLD_HOLD_INTERLOCK Enter HOLD state in P1. Enter INTERLOCK_DISENGAGED state. + * Exit hold and resume motion when interlock is cleared. This may + * require some combination of interlock switch transitions, interlock + * JSON commands and {clear:n} depending on interlock configuration. + * + * + */ /* * Feedhold Processing - Performs the following cases (listed in rough sequence order): * @@ -116,14 +183,16 @@ bool cm_has_hold() } /**************************************************************************************** - * cm_request_feedhold() - * cm_request_exit_hold() - * cm_request_queue_flush() - * cm_start_hold() - start a feedhhold external to feedhold request & sequencing + * cm_start_hold() - start a feedhhold external to feedhold request equencing + * cm_request_feedhold() - reqeust a feedhold + * cm_request_exit_hold() - reqeust feedhold exit with resume motion + * cm_request_queue_flush() - request feedhold exit with queue flush * * p1 is the primary planner, p2 is the secondary planner, which is active if the * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. * Request_feedhold, request_end_hold, and request_queue_flush are contextual: + * + * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) * * request_feedhold: * - If p1 is not in HOLD & is in motion, request_feedhold requests a p1 hold @@ -141,10 +210,17 @@ bool cm_has_hold() * - If p1 is in HOLD request_queue_flush will end p1 hold & queue flush (stop motion). * Pre-defined exit actions (coolant, spindle, Z move) are completed first * Any executing or pending "in-hold" moves are stopped prior to the exit actions - * - * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) */ +void cm_start_hold() +{ + // Can only request a feedhold if the machine is in motion and there not one is not already in progress + if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { + cm_set_motion_state(MOTION_HOLD); + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } +} + void cm_request_feedhold(void) // ! { // Only generate request if not already in a feedhold and the machine is in motion @@ -172,15 +248,6 @@ void cm_request_queue_flush() // % } } -void cm_start_hold() -{ - // Can only request a feedhold if the machine is in motion and there not one is not already in progress - if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { - cm_set_motion_state(MOTION_HOLD); - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} - /**************************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests * From c457e50dd46237d5d9f6860dfc03bde04dcc8c1c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Mar 2017 11:19:41 -0500 Subject: [PATCH 173/283] Changed cycle_state to cycle_type --- g2core/alarm.cpp | 2 +- g2core/canonical_machine.cpp | 34 ++++++++++++++-------------- g2core/canonical_machine.h | 43 +++++++++++++++++++++--------------- g2core/cycle_feedhold.cpp | 10 +++++---- g2core/cycle_homing.cpp | 4 ++-- g2core/cycle_jogging.cpp | 10 ++++----- g2core/cycle_probing.cpp | 4 ++-- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 2 +- g2core/plan_line.cpp | 2 +- 10 files changed, 62 insertions(+), 53 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 7e4fd2e5..ed6e5d52 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -131,7 +131,7 @@ void cm_halt_motion(void) { mp_halt_runtime(); // stop the runtime. Do this immediately. (Reset is in cm_clear) canonical_machine_reset(cm); // halt the currently active machine - cm->cycle_state = CYCLE_OFF; // Note: leaves machine_state alone + cm->cycle_type = CYCLE_NONE; // Note: leaves machine_state alone cm->motion_state = MOTION_STOP; cm->hold_state = FEEDHOLD_OFF; } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 1399fe9c..f0272250 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -199,7 +199,7 @@ void canonical_machine_reset(cmMachine_t *_cm) _cm->shutdown_requested = 0; // ditto // set initial state and signal that the machine is ready for action - _cm->cycle_state = CYCLE_OFF; + _cm->cycle_type = CYCLE_NONE; _cm->motion_state = MOTION_STOP; _cm->hold_state = FEEDHOLD_OFF; _cm->esc_boot_timer = SysTickTimer_getValue(); @@ -271,13 +271,13 @@ void cm_set_motion_state(const cmMotionState motion_state) /* * cm_get_machine_state() * cm_get_motion_state() - * cm_get_cycle_state() + * cm_get_cycle_type() * cm_get_hold_state() * cm_get_homing_state() * cm_get_probe_state() */ cmMachineState cm_get_machine_state() { return cm->machine_state;} -cmCycleState cm_get_cycle_state() { return cm->cycle_state;} +cmCycleType cm_get_cycle_type() { return cm->cycle_type;} cmMotionState cm_get_motion_state() { return cm->motion_state;} cmFeedholdState cm_get_hold_state() { return cm->hold_state;} cmHomingState cm_get_homing_state() { return cm->homing_state;} @@ -304,11 +304,11 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) case MACHINE_SHUTDOWN: { return (COMBINED_SHUTDOWN); } case MACHINE_PANIC: { return (COMBINED_PANIC); } case MACHINE_CYCLE: { - switch(_cm->cycle_state) { + switch(_cm->cycle_type) { case CYCLE_HOMING: { return (COMBINED_HOMING); } case CYCLE_PROBE: { return (COMBINED_PROBE); } case CYCLE_JOG: { return (COMBINED_JOG); } - case CYCLE_MACHINING: case CYCLE_OFF: { + case CYCLE_MACHINING: case CYCLE_NONE: { switch(_cm->motion_state) { case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE_1, above case MOTION_PLANNING: { return (COMBINED_RUN); } @@ -534,7 +534,7 @@ void cm_update_model_position() stat_t cm_deferred_write_callback() { - if ((cm->cycle_state == CYCLE_OFF) && (cm->deferred_write_flag == true)) { + if ((cm->cycle_type == CYCLE_NONE) && (cm->deferred_write_flag == true)) { cm->deferred_write_flag = false; nvObj_t nv; for (uint8_t i=1; i<=COORDS; i++) { @@ -1563,18 +1563,18 @@ stat_t cm_tro_control(const float P_word, const bool P_flag) // M50.1 static void _exec_program_finalize(float *value, bool *flag) { cmMachineState machine_state = (cmMachineState)value[0]; - cm_set_motion_state(MOTION_STOP); // also changes active model back to MODEL + cm_set_motion_state(MOTION_STOP); // also changes active model back to MODEL // Allow update in the alarm state, to accommodate queue flush (RAS) - if ((cm->cycle_state == CYCLE_MACHINING || cm->cycle_state == CYCLE_OFF) && -// (cm->machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) + if ((cm->cycle_type == CYCLE_MACHINING || cm->cycle_type == CYCLE_NONE) && +// (cm->machine_state != MACHINE_ALARM) && // omitted by OMC (RAS) (cm->machine_state != MACHINE_SHUTDOWN)) { - cm->machine_state = machine_state; // don't update macs/cycs if we're in the middle of a canned cycle, - cm->cycle_state = CYCLE_OFF; // or if we're in machine alarm/shutdown mode + cm->machine_state = machine_state; // don't update macs/cycs if we're in the middle of a canned cycle, + cm->cycle_type = CYCLE_NONE; // or if we're in machine alarm/shutdown mode } // reset the rest of the states - cm->cycle_state = CYCLE_OFF; + cm->cycle_type = CYCLE_NONE; cm->hold_state = FEEDHOLD_OFF; mp_zero_segment_velocity(); // for reporting purposes @@ -1599,16 +1599,16 @@ static void _exec_program_finalize(float *value, bool *flag) void cm_cycle_start() { - if (cm->cycle_state == CYCLE_OFF) { // don't (re)start homing, probe or other canned cycles + if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles + cm->cycle_type = CYCLE_MACHINING; cm->machine_state = MACHINE_CYCLE; - cm->cycle_state = CYCLE_MACHINING; qr_init_queue_report(); // clear queue reporting buffer counts } } void cm_cycle_end() { - if (cm->cycle_state == CYCLE_MACHINING) { + if (cm->cycle_type == CYCLE_MACHINING) { float value[] = { (float)MACHINE_PROGRAM_STOP }; _exec_program_finalize(value, nullptr); } @@ -1616,7 +1616,7 @@ void cm_cycle_end() void cm_canned_cycle_end() { - cm->cycle_state = CYCLE_OFF; + cm->cycle_type = CYCLE_NONE; float value[] = { (float)MACHINE_PROGRAM_STOP }; _exec_program_finalize(value, nullptr); } @@ -1979,7 +1979,7 @@ stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], uint8_t value stat_t cm_get_stat(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm1)));} stat_t cm_get_stat2(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm2)));} stat_t cm_get_macs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_macs, cm_get_machine_state()));} -stat_t cm_get_cycs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_cycs, cm_get_cycle_state()));} +stat_t cm_get_cycs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_cycs, cm_get_cycle_type()));} stat_t cm_get_mots(nvObj_t *nv) { return(_get_msg_helper(nv, msg_mots, cm_get_motion_state()));} stat_t cm_get_hold(nvObj_t *nv) { return(_get_msg_helper(nv, msg_hold, cm_get_hold_state()));} diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 28b62599..fea8b4e1 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -83,23 +83,25 @@ typedef enum { // check alignment with messages in config.c / m typedef enum { MACHINE_INITIALIZING = 0, // machine is initializing - MACHINE_READY, // machine is ready for use - MACHINE_ALARM, // machine in alarm state + MACHINE_READY, // machine is ready for use but idle + MACHINE_ALARM, // machine is in alarm state MACHINE_PROGRAM_STOP, // no blocks to run; like PROGRAM_END but without the M2 to reset gcode state MACHINE_PROGRAM_END, // program end (same as MACHINE_READY, really...) - MACHINE_CYCLE, // machine is running; blocks still to run, or steppers are busy - MACHINE_INTERLOCK, // machine in interlock state - MACHINE_SHUTDOWN, // machine in shutdown state - MACHINE_PANIC // machine in panic state + MACHINE_CYCLE, // machine is in cycle, running; blocks still to run, or steppers are busy + MACHINE_INTERLOCK, // machine is in interlock state + MACHINE_SHUTDOWN, // machine is in shutdown state + MACHINE_PANIC // machine is in panic state } cmMachineState; typedef enum { - CYCLE_OFF = 0, // machine is idle + CYCLE_NONE = 0, // machine is not ins a cycle CYCLE_MACHINING, // in normal machining cycle CYCLE_HOMING, // in homing cycle CYCLE_PROBE, // in probe cycle CYCLE_JOG // in jogging cycle -} cmCycleState; +// CYCLE_G81 // illustration of canned cycles +// ... +} cmCycleType; typedef enum { MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue @@ -109,11 +111,11 @@ typedef enum { } cmMotionState; typedef enum { // feedhold requests - FEEDHOLD_NO_REQUEST =0, // no pending request; reverts here when complete (read-only; cannot be set) - FEEDHOLD_HOLD_P1 =1, // enter p1 feedhold, enter HOLD state in p1 - FEEDHOLD_HOLD_P2 =2, // (!) enter p1 feedhold, enter p2 with entry actions - FEEDHOLD_EXIT_RESUME =3, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion - FEEDHOLD_EXIT_FLUSH =4, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP + FEEDHOLD_NO_REQUEST = 0, // no pending request; reverts here when complete (read-only; cannot be set) + FEEDHOLD_HOLD_P1, // enter p1 feedhold, enter HOLD state in p1 + FEEDHOLD_HOLD_P2, // (!) enter p1 feedhold, enter p2 with entry actions + FEEDHOLD_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion + FEEDHOLD_EXIT_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP // Feedholds with specialized exits // If not in hold, perform hold (or halt), then perform the exit immediately @@ -267,11 +269,17 @@ typedef struct cmMachine { // struct to manage canonical machin // Global state variables and flags cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state - cmCycleState cycle_state; // cycs + cmCycleType cycle_type; // cycs cmMotionState motion_state; // momo + cmFeedholdState hold_state; // hold: feedhold state machine + cmFeedholdRequest hold_request; // hold: pending feedhold request + cmFeedholdRequest hold_exit; // hold: pending feedhold exit request + cmFlushState flush_state; // hold: queue flush state machine + bool hold_exit_requested; // request normal exit from feedhold + bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) + cmOverrideState mfo_state; // feed override state machine - cmFlushState flush_state; // queue flush state machine uint8_t safety_interlock_disengaged; // set non-zero to start interlock processing (value is input number) uint8_t safety_interlock_reengaged; // set non-zero to end interlock processing (value is input number) @@ -281,8 +289,7 @@ typedef struct cmMachine { // struct to manage canonical machin uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them - bool hold_exit_requested; // request normal exit from feedhold - bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) + bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move cmHomingState homing_state; // home: homing cycle sub-state machine @@ -328,7 +335,7 @@ extern cmToolTable_t tt; // Model state getters and setters cmCombinedState cm_get_combined_state(cmMachine_t *_cm); cmMachineState cm_get_machine_state(void); -cmCycleState cm_get_cycle_state(void); +cmCycleType cm_get_cycle_type(void); cmMotionState cm_get_motion_state(void); cmFeedholdState cm_get_hold_state(void); cmHomingState cm_get_homing_state(void); diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index b7dc9599..19feb703 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -89,7 +89,7 @@ static void _feedhold_abort(void); * If this command is received while in p2, a FEEDHOLD_HOLD_SKIP * is executed in p2. * - * - FEEDHOLD_EXIT_RESUME (~) Exit HOLD state in P1 or p2. If in p2 perform exit actions, + * - FEEDHOLD_CYCLE_START (~) Exit HOLD state in P1 or p2. If in p2 perform exit actions, * then resume motion in p1 planner. * * - FEEDHOLD_EXIT_FLUSH (%) Exit HOLD state in P1 or p2. If in p2 perform exit actions, @@ -138,8 +138,6 @@ static void _feedhold_abort(void); * Exit hold and resume motion when interlock is cleared. This may * require some combination of interlock switch transitions, interlock * JSON commands and {clear:n} depending on interlock configuration. - * - * */ /* * Feedhold Processing - Performs the following cases (listed in rough sequence order): @@ -225,7 +223,9 @@ void cm_request_feedhold(void) // ! { // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_state = FEEDHOLD_REQUESTED; + cm1.hold_request = FEEDHOLD_HOLD_P2; // request a hold to p2 + cm1.hold_exit = FEEDHOLD_NO_REQUEST; // no exit specified + cm1.hold_state = FEEDHOLD_REQUESTED; // signal request to state machine } else if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { cm2.hold_state = FEEDHOLD_REQUESTED; @@ -235,6 +235,7 @@ void cm_request_feedhold(void) // ! void cm_request_exit_hold(void) // ~ { if (cm1.hold_state != FEEDHOLD_OFF) { + cm1.hold_exit = FEEDHOLD_CYCLE_START; // signal a normal feedhold resume as exit cm1.hold_exit_requested = true; } } @@ -244,6 +245,7 @@ void cm_request_queue_flush() // % // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm1.flush_state == FLUSH_OFF)) { // ...and only once + cm1.hold_exit = FEEDHOLD_EXIT_FLUSH; // signal a flush exit cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped } } diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index cd0e4b86..ec3244ac 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -170,7 +170,7 @@ stat_t cm_homing_cycle_start(const float axes[], const bool flags[]) { hm.axis = -1; // set to retrieve initial axis hm.func = _homing_axis_start; // bind initial processing function cm->machine_state = MACHINE_CYCLE; - cm->cycle_state = CYCLE_HOMING; + cm->cycle_type = CYCLE_HOMING; cm->homing_state = HOMING_NOT_HOMED; return (STAT_OK); } @@ -186,7 +186,7 @@ stat_t cm_homing_cycle_start_no_set(const float axes[], const bool flags[]) { */ stat_t cm_homing_cycle_callback(void) { - if (cm->cycle_state != CYCLE_HOMING) { // exit if not in a homing cycle + if (cm->cycle_type != CYCLE_HOMING) { // exit if not in a homing cycle return (STAT_NOOP); } if (hm.waiting_for_motion_end) { // sync to planner move ends (using callback) diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index 2e781f34..35cbe72f 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -100,17 +100,17 @@ stat_t cm_jogging_cycle_start(uint8_t axis) { cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); jog.velocity_start = JOGGING_START_VELOCITY; // see canonical_machine.h for #define - jog.velocity_max = cm->a[axis].velocity_max; + jog.velocity_max = cm->a[axis].velocity_max; jog.start_pos = cm_get_absolute_position(RUNTIME, axis); - jog.dest_pos = cm_get_jogging_dest(); - jog.step = 0; + jog.dest_pos = cm_get_jogging_dest(); + jog.step = 0; jog.axis = axis; jog.func = _jogging_axis_start; // bind initial processing function cm->machine_state = MACHINE_CYCLE; - cm->cycle_state = CYCLE_JOG; + cm->cycle_type = CYCLE_JOG; return (STAT_OK); } @@ -124,7 +124,7 @@ stat_t cm_jogging_cycle_start(uint8_t axis) { */ stat_t cm_jogging_cycle_callback(void) { - if (cm->cycle_state != CYCLE_JOG) { + if (cm->cycle_type != CYCLE_JOG) { return (STAT_NOOP); // exit if not in a jogging cycle } if (jog.func == _jogging_finalize_exit && cm_get_runtime_busy() == true) { diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 8a841a19..a9337d2e 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -184,7 +184,7 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool trip_sense, bool al uint8_t cm_probing_cycle_callback(void) { - if ((cm->cycle_state != CYCLE_PROBE) && (cm->probe_state[0] != PROBE_WAITING)) { + if ((cm->cycle_type != CYCLE_PROBE) && (cm->probe_state[0] != PROBE_WAITING)) { return (STAT_NOOP); // exit if not in a probing cycle } if (pb.wait_for_motion_end) { // sync to planner move ends (using callback) @@ -207,7 +207,7 @@ static uint8_t _probing_start() cm->probe_state[0] = PROBE_FAILED; cm->machine_state = MACHINE_CYCLE; - cm->cycle_state = CYCLE_PROBE; + cm->cycle_type = CYCLE_PROBE; // save relevant non-axis parameters from Gcode model pb.saved_distance_mode = (cmDistanceMode)cm_get_distance_mode(ACTIVE_MODEL); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..95da67f1 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800019454 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800019454 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 620f6d9c..230f66ef 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1032,7 +1032,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If probing or homing, exit the move and advance to the _motion_end_callback()'s. // Stop the runtime, clear the run buffer and do not transition to p2 planner. - else if ((cm->cycle_state == CYCLE_HOMING) || (cm->cycle_state == CYCLE_PROBE)) { + else if ((cm->cycle_type == CYCLE_HOMING) || (cm->cycle_type == CYCLE_PROBE)) { mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement mp_free_run_buffer(); // free buffer and enable finalization move to get loaded cm->hold_state = FEEDHOLD_OFF; diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index c9a90714..3d814c1b 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -113,7 +113,7 @@ float mp_get_runtime_display_position(uint8_t axis) { */ bool mp_get_runtime_busy() { - if (cm->cycle_state == CYCLE_OFF) { + if (cm->cycle_type == CYCLE_NONE) { return (false); } if ((st_runtime_isbusy() == true) || From d87b3a3e4cd3bd9a2da6c768afc07c94dc9953d6 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 6 Mar 2017 11:44:42 -0500 Subject: [PATCH 174/283] Removed MOTION_PLANNING from motion state. Not needed anymore. --- g2core/canonical_machine.cpp | 2 -- g2core/canonical_machine.h | 13 ++++++------- g2core/planner.cpp | 6 +----- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f0272250..15498dea 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -262,7 +262,6 @@ void cm_set_motion_state(const cmMotionState motion_state) switch (motion_state) { case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } - case (MOTION_PLANNING): { ACTIVE_MODEL = RUNTIME; break; } case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; } case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; } } @@ -311,7 +310,6 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) case CYCLE_MACHINING: case CYCLE_NONE: { switch(_cm->motion_state) { case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE_1, above - case MOTION_PLANNING: { return (COMBINED_RUN); } case MOTION_RUN: { return (COMBINED_RUN); } case MOTION_HOLD: { return (COMBINED_HOLD); } default: { diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index fea8b4e1..d0d6f611 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -93,6 +93,12 @@ typedef enum { MACHINE_PANIC // machine is in panic state } cmMachineState; +typedef enum { + MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue + MOTION_RUN, // machine is in motion: set when the steppers execute an ALINE segment + MOTION_HOLD // feedhold in progress: set whenever we leave FEEDHOLD_OFF, unset whenever we enter FEEDHOLD_OFF +} cmMotionState; + typedef enum { CYCLE_NONE = 0, // machine is not ins a cycle CYCLE_MACHINING, // in normal machining cycle @@ -103,13 +109,6 @@ typedef enum { // ... } cmCycleType; -typedef enum { - MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue - MOTION_PLANNING, // machine has planned an ALINE segment, but not yet started to execute them - MOTION_RUN, // machine is in motion: set when the steppers execute an ALINE segment - MOTION_HOLD // feedhold in progress: set whenever we leave FEEDHOLD_OFF, unset whenever we enter FEEDHOLD_OFF -} cmMotionState; - typedef enum { // feedhold requests FEEDHOLD_NO_REQUEST = 0, // no pending request; reverts here when complete (read-only; cannot be set) FEEDHOLD_HOLD_P1, // enter p1 feedhold, enter HOLD state in p1 diff --git a/g2core/planner.cpp b/g2core/planner.cpp index dc445862..ba4c7ba8 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -785,11 +785,7 @@ void mp_commit_write_buffer(const blockType block_type) q->w->block_type = block_type; q->w->block_state = BLOCK_INITIAL_ACTION; - if (block_type == BLOCK_TYPE_ALINE) { - if (cm->motion_state == MOTION_STOP) { - cm_set_motion_state(MOTION_PLANNING); - } - } else { + if (block_type != BLOCK_TYPE_ALINE) { if ((mp->planner_state > PLANNER_STARTUP) && (cm->hold_state == FEEDHOLD_OFF)) { // NB: BEWARE! the requested exec may result in the planner buffer being // processed IMMEDIATELY and then freed - invalidating the contents From 6f490526794800b7ae1e6ba6b8f73a982a31d8d2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 10 Mar 2017 06:21:42 -0500 Subject: [PATCH 175/283] Work in process --- g2core/canonical_machine.cpp | 18 +-- g2core/canonical_machine.h | 48 +++---- g2core/controller.cpp | 1 + g2core/cycle_feedhold.cpp | 237 +++++++++++++++++++++++++++++++---- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 6 + 6 files changed, 253 insertions(+), 61 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 15498dea..cb332a6f 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -261,9 +261,9 @@ void cm_set_motion_state(const cmMotionState motion_state) cm->motion_state = motion_state; switch (motion_state) { - case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } - case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; } - case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; } + case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } + case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; } + case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; } } } @@ -285,11 +285,11 @@ cmProbeState cm_get_probe_state() { return cm->probe_state[0];} /* * cm_get_combined_state() - combines raw states into something a user might want to see * - * Note: - * On issuing a gcode command we call cm_cycle_start() before the motion gets queued. We don't go - * to MOTION_RUN until the command is executed by mp_exec_aline(), planned, queued, and started. - * So MOTION_STOP must actually return COMBINED_RUN to address this case, even though under some - * circumstances it might actually ne an exception case. Therefore this assertion isn't valid: + * NOTE: On issuing a gcode command we call cm_cycle_start() before the motion gets queued. + * We don't go to MOTION_RUN until the command is executed by mp_exec_aline(), planned, + * queued, and started. So MOTION_STOP must actually return COMBINED_RUN to address this + * case, even though under some circumstances it might actually be an exception case. + * Therefore this assertion isn't valid: * cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "mots2"));//"mots is stop but machine is in cycle" * return (COMBINED_PANIC); */ @@ -309,7 +309,7 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) case CYCLE_JOG: { return (COMBINED_JOG); } case CYCLE_MACHINING: case CYCLE_NONE: { switch(_cm->motion_state) { - case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE_1, above + case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE, above case MOTION_RUN: { return (COMBINED_RUN); } case MOTION_HOLD: { return (COMBINED_HOLD); } default: { diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index d0d6f611..12c07ff2 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -81,7 +81,7 @@ typedef enum { // check alignment with messages in config.c / m } cmCombinedState; //### END CRITICAL REGION ### -typedef enum { +typedef enum { // Note: MachineState signals if the machine is in cycle (5) or some other non-cycle state MACHINE_INITIALIZING = 0, // machine is initializing MACHINE_READY, // machine is ready for use but idle MACHINE_ALARM, // machine is in alarm state @@ -109,27 +109,27 @@ typedef enum { // ... } cmCycleType; -typedef enum { // feedhold requests - FEEDHOLD_NO_REQUEST = 0, // no pending request; reverts here when complete (read-only; cannot be set) - FEEDHOLD_HOLD_P1, // enter p1 feedhold, enter HOLD state in p1 - FEEDHOLD_HOLD_P2, // (!) enter p1 feedhold, enter p2 with entry actions - FEEDHOLD_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion - FEEDHOLD_EXIT_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP - - // Feedholds with specialized exits - // If not in hold, perform hold (or halt), then perform the exit immediately - // If already in hold just perform the exit - FEEDHOLD_HOLD_SKIP, // enter p1 feedhold, skip remainder of block, resume from next block (for homing & probes) - FEEDHOLD_HOLD_STOP, // enter p1 feedhold, enter PROGRAM_STOP state - FEEDHOLD_HOLD_FAST_STOP, // enter p1 feedhold, perform FAST_STOP, enter STOP state - FEEDHOLD_HOLD_HALT, // enter p1 feedhold, enter PROGRAM_STOP state - FEEDHOLD_HOLD_END, // enter p1 feedhold, flush queue, perform PROGRAM_END - FEEDHOLD_HOLD_END_ALARM, // enter p1 feedhold, flush queue, perform PROGRAM_END, trigger ALARM - FEEDHOLD_HOLD_ALARM, // enter p1 feedhold, flush queue, trigger ALARM - FEEDHOLD_HOLD_SHUTDOWN, // enter p1 feedhold, flush queue, trigger SHUTDOWN - FEEDHOLD_HOLD_PANIC, // perform HALT, trigger PANIC - FEEDHOLD_HOLD_INTERLOCK // enter p1 feedhold, trigger and release INTERLOCK -} cmFeedholdRequest; +typedef enum { // cycle start and feedhold requests + OPERATION_NULL = 0, // no operation; reverts here when complete + OPERATION_CYCLE_START, // perform a cycle start with no other actions + OPERATION_HOLD_TO_P2, // feedhold into p2 with p2 entry actions + OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 + OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner + OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner + OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush + OPERATION_JOB_KILL, // fast hold followed by queue flush and program end + OPERATION_END_JOG, // fast hold followed by program stop + OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit + OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit + OPERATION_SHUTDOWN, // actions to run when a shutdown is received + OPERATION_PANIC, // actions to run when a panic is received + OPERATION_INTERLOCK_START, // enter an interlock state + OPERATION_INTERLOCK_END, // exit interlocked state + OPERATION_DI_FUNC_STOP, // run digital input STOP function + OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function + OPERATION_DI_FUNC_HALT, // run digital input HALT function + OPERATION_TOOL_CHANGE // run a tool change sequence +} cmOperationType; typedef enum { // feedhold state machine FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit @@ -272,8 +272,6 @@ typedef struct cmMachine { // struct to manage canonical machin cmMotionState motion_state; // momo cmFeedholdState hold_state; // hold: feedhold state machine - cmFeedholdRequest hold_request; // hold: pending feedhold request - cmFeedholdRequest hold_exit; // hold: pending feedhold exit request cmFlushState flush_state; // hold: queue flush state machine bool hold_exit_requested; // request normal exit from feedhold bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) @@ -469,6 +467,8 @@ stat_t cm_json_wait(char *json_string); // M102 void cm_request_feedhold(void); void cm_request_exit_hold(void); void cm_request_queue_flush(void); +stat_t cm_request_operation(cmOperationType operation); // request a new operation +stat_t cm_operation_callback(void); // operation action runner stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests stat_t cm_feedhold_command_blocker(void); diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 4cda51d9..357b5708 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -160,6 +160,7 @@ static void _controller_HSM() DISPATCH(qr_queue_report_callback()); // conditionally send queue report DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner + DISPATCH(cm_operation_callback()); // operation action runner DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 19feb703..553b1480 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -47,6 +47,198 @@ static void _feedhold_p1_exit(void); static void _feedhold_p2_exit(void); static void _feedhold_abort(void); +static stat_t action_hold(float* value, bool* flag); +static stat_t action_halt(float* value, bool* flag); +static stat_t action_p2_entry(float* value, bool* flag); +static stat_t action_p2_exit(float* value, bool* flag); +static stat_t action_parking_move(float* value, bool* flag); +static stat_t action_return_move(float* value, bool* flag); +static stat_t action_spindle_control(float* value, bool* flag); +static stat_t action_coolant_control(float* value, bool* flag); +static stat_t action_heater_control(float* value, bool* flag); +static stat_t action_output_control(float* value, bool* flag); +static stat_t action_cycle_start(float* value, bool* flag); +static stat_t action_queue_flush(float* value, bool* flag); +static stat_t action_input_function(float* value, bool* flag); +static stat_t action_finalize_program(float* value, bool* flag); +static stat_t action_trigger_alarm(float* value, bool* flag); + +typedef enum { // Operation Actions + // Initiation actions + ACTION_NULL = 0, // no pending action; reverts here when complete (read-only; cannot be set) + ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1 + ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used) + ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1 + ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2 + ACTION_HALT_MOTION, // halt all motion immediately (regardless of p1 or p2) + + // Hold Entry Actions - run when motion has stopped + ACTION_P2_ENTRY, // Z lift, spindle and coolant actions (bundled) + ACTION_PARKING_MOVE, // perform a pre-defined toolhead parking move + ACTION_PAUSE_SPINDLE, + ACTION_PAUSE_COOLANT, + ACTION_PAUSE_HEATERS, + ACTION_PAUSE_OUTPUTS, // programmed special purpose outputs + ACTION_STOP_SPINDLE, + ACTION_STOP_COOLANT, + ACTION_STOP_HEATERS, + ACTION_STOP_OUTPUTS, + + // In-Hold actions + ACTION_TOOL_CHANGE, + + // Feedhold Exit Actions // This set is kept in a separate vector, so the bit shifts start over. + ACTION_P2_EXIT, // coolant, spindle, return move actions (bundled) + ACTION_RESUME_HEATERS, + ACTION_RESUME_COOLANT, + ACTION_RESUME_SPINDLE, + ACTION_RESUME_OUTPUTS, // programmed special purpose outputs + ACTION_RETURN_MOVE, // returns to hold pint an re-enters p1 + + // Cycle start, restart, exit hold + ACTION_SKIP_TO_SYNC, // discard remaining length, execute next block if SYNC command, otherwise flush buffer + ACTION_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion + ACTION_QUEUE_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP + + // Finalization actions + ACTION_DI_FUNCTION, // function as assigned by digital input configuration (TBD) + ACTION_PROGRAM_STOP, // invoke PROGRAM_STOP + ACTION_PROGRAM_END, // invoke PROGRAM_END + ACTION_TRIGGER_ALARM, // trigger ALARM + ACTION_TRIGGER_SHUTDOWN, // trigger SHUTDOWN + ACTION_TRIGGER_PANIC, // trigger PANIC state + ACTION_PERFORM_RESET, // defined, but not implemented +} cmOpAction; + + +/*** Object Definitions ***/ + +#define ACTION_MAX 12 +typedef stat_t (*action_exec_t)(float[], bool[]); // callback to operation action execution function + +typedef struct cmAction { // struct to manage execution of operations + struct cmAction *nx; // static pointer to next buffer + + action_exec_t func; // callback to operation action function. NULL == disabled + float value[AXES]; // parameters for the function + bool flag[AXES]; + + // clears this structure (except the pointer) + void reset() { + func = NULL; + } +} cmAction_t; + +typedef struct cmOperation { // struct to manage execution of operations + cmAction action[ACTION_MAX]; // singly linked list of action control structures + + cmAction *current_action; // current action being worked + + void add_action(stat_t(*action_exec)(float[], bool[]), float* value, bool* flag) { + if (action_exec == NULL) { + return; + } + current_action->func = action_exec; + + for (uint8_t i = 0; i < AXES; i++) { + current_action->value[i] = value[i]; + current_action->flag[i] = flag[i]; + } + }; + + stat_t run_action(void) { + stat_t status; + status = current_action->func(current_action->value, current_action->flag); + if (status == STAT_OK) { + current_action = current_action->nx; + } + return (status); + }; + + void reset(void) { + for (uint8_t i=0; i < ACTION_MAX; i++) { + action[i].reset(); + action[i].nx = &action[i+1]; + } + action[ACTION_MAX-1].nx = &action[0]; + current_action = &action[0]; + }; + +} cmOperation_t; + +cmOperation_t op; // operations runner + +/**************************************************************************************** + **** Operations ************************************************************************ + ****************************************************************************************/ + +/**************************************************************************************** + * cm_request_operation() + * cm_operation_callback() + */ + +stat_t cm_request_operation(cmOperationType operation) +{ + op.reset(); // start with a fresh operation controller + + switch (operation) { + + case OP_CYCLE_START: { + op.add_action(action_cycle_start, nullptr, nullptr); + break; + } + + default: { + + } + } + return (STAT_OK); +} + +stat_t cm_operation_callback() +{ + stat_t status = STAT_OK; + while ((status = op.run_action()) == STAT_OK); + + return (status); +} + +/**************************************************************************************** + * cm_action_functions + * + * Coding an action: + * + * Actions can complete in one call or take multiple calls (continuations). + * In the latter case they will be called multiple times by the action runner. + * The returned status defines this: + * + * STAT_OK - signals completion of the action. Runner will run the next action + * STAT_EAGAIN - signals that the action needs to be called again later to complete + * STAT_(anything else) - aborts the operation + */ + +static stat_t action_hold(float* value, bool* flag) { return (STAT_OK); } // p1, p2, regular and fast holds +static stat_t action_halt(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_p2_entry(float* value, bool* flag) { return (STAT_OK); } // p2 entry actions, bundled +static stat_t action_p2_exit(float* value, bool* flag) { return (STAT_OK); } // p2 exit actions, bundled +static stat_t action_parking_move(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_return_move(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_spindle_control(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_coolant_control(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_heater_control(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_output_control(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_queue_flush(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_input_function(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_finalize_program(float* value, bool* flag) { return (STAT_OK); } +static stat_t action_trigger_alarm(float* value, bool* flag) { return (STAT_OK); } + +static stat_t action_cycle_start(float* value, bool* flag) +{ + cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); + return (STAT_OK); +} /**************************************************************************************** **** Feedholds ************************************************************************* @@ -181,10 +373,11 @@ bool cm_has_hold() } /**************************************************************************************** - * cm_start_hold() - start a feedhhold external to feedhold request equencing * cm_request_feedhold() - reqeust a feedhold * cm_request_exit_hold() - reqeust feedhold exit with resume motion * cm_request_queue_flush() - request feedhold exit with queue flush + * cm_start_hold() - start a feedhhold external to feedhold request equencing + * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner * * p1 is the primary planner, p2 is the secondary planner, which is active if the * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. @@ -210,21 +403,10 @@ bool cm_has_hold() * Any executing or pending "in-hold" moves are stopped prior to the exit actions */ -void cm_start_hold() -{ - // Can only request a feedhold if the machine is in motion and there not one is not already in progress - if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { - cm_set_motion_state(MOTION_HOLD); - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} - void cm_request_feedhold(void) // ! { // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_request = FEEDHOLD_HOLD_P2; // request a hold to p2 - cm1.hold_exit = FEEDHOLD_NO_REQUEST; // no exit specified cm1.hold_state = FEEDHOLD_REQUESTED; // signal request to state machine } else if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { @@ -235,7 +417,6 @@ void cm_request_feedhold(void) // ! void cm_request_exit_hold(void) // ~ { if (cm1.hold_state != FEEDHOLD_OFF) { - cm1.hold_exit = FEEDHOLD_CYCLE_START; // signal a normal feedhold resume as exit cm1.hold_exit_requested = true; } } @@ -245,11 +426,27 @@ void cm_request_queue_flush() // % // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold (cm1.flush_state == FLUSH_OFF)) { // ...and only once - cm1.hold_exit = FEEDHOLD_EXIT_FLUSH; // signal a flush exit cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped } } +void cm_start_hold() +{ + // Can only request a feedhold if the machine is in motion and there not one is not already in progress + if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { + cm_set_motion_state(MOTION_HOLD); + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } +} + +stat_t cm_feedhold_command_blocker() +{ + if (cm1.hold_state != FEEDHOLD_OFF) { + return (STAT_EAGAIN); + } + return (STAT_OK); +} + /**************************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests * @@ -323,18 +520,6 @@ stat_t cm_feedhold_sequencing_callback() return (STAT_OK); } -/**************************************************************************************** - * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner - */ - -stat_t cm_feedhold_command_blocker() -{ - if (cm1.hold_state != FEEDHOLD_OFF) { - return (STAT_EAGAIN); - } - return (STAT_OK); -} - /**************************************************************************************** * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 95da67f1..eb6d528e 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 2000000 SWD @@ -102,7 +102,7 @@ true J41800019454 0x284E0A60 - 10000000 + 2000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 230f66ef..729d8819 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -407,6 +407,12 @@ stat_t mp_exec_move() stat_t mp_exec_aline(mpBuf_t *bf) { + // don't run the block if the machine is not in cycle + if (cm_get_machine_state() != MACHINE_CYCLE) { + return (STAT_NOOP); + } + + // don't run the block if the block is inactive if (bf->block_state == BLOCK_INACTIVE) { return (STAT_NOOP); } From 9ac4d7d1c47672204461efb80c35ade95a92c141 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 10 Mar 2017 11:41:56 -0500 Subject: [PATCH 176/283] unfinished work --- g2core/canonical_machine.cpp | 26 ++-- g2core/canonical_machine.h | 22 +-- g2core/config_app.cpp | 72 --------- g2core/cycle_feedhold.cpp | 278 ++++++++++++++++++++--------------- g2core/g2core.cppproj | 8 +- g2core/plan_exec.cpp | 5 +- 6 files changed, 195 insertions(+), 216 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index cb332a6f..2497a6ba 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -307,16 +307,24 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) case CYCLE_HOMING: { return (COMBINED_HOMING); } case CYCLE_PROBE: { return (COMBINED_PROBE); } case CYCLE_JOG: { return (COMBINED_JOG); } - case CYCLE_MACHINING: case CYCLE_NONE: { - switch(_cm->motion_state) { - case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE, above - case MOTION_RUN: { return (COMBINED_RUN); } - case MOTION_HOLD: { return (COMBINED_HOLD); } - default: { - cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() mots bad");// "mots has impossible value" - return (COMBINED_PANIC); - } +// case CYCLE_MACHINING: case CYCLE_NONE: { +// switch(_cm->motion_state) { +// case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE, above +// case MOTION_RUN: { return (COMBINED_RUN); } +// case MOTION_HOLD: { return (COMBINED_HOLD); } +// default: { +// cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() mots bad");// "mots has impossible value" +// return (COMBINED_PANIC); +// } +// } + + case CYCLE_MACHINING: { + if (_cm->hold_state != FEEDHOLD_OFF) { + return (COMBINED_HOLD); + } else { + return (COMBINED_RUN); } + } default: { cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() cycs bad"); // "cycs has impossible value" diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 12c07ff2..aeccc690 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -55,9 +55,9 @@ * MACHINE STATE MODEL * * The following main variables track canonical machine state and state transitions. - * - cm->machine_state - overall state of machine and program execution - * - cm->cycle_state - what cycle the machine is executing (or none) + * - cm->machine_state - overall state of machine and program execution * - cm->motion_state - state of movement + * - cm->cycle_type - what type of cycle the machine is executing (or none) */ // *** Note: check config printout strings align with all the state variables @@ -100,7 +100,7 @@ typedef enum { } cmMotionState; typedef enum { - CYCLE_NONE = 0, // machine is not ins a cycle + CYCLE_NONE = 0, // not in a cycle CYCLE_MACHINING, // in normal machining cycle CYCLE_HOMING, // in homing cycle CYCLE_PROBE, // in probe cycle @@ -112,11 +112,12 @@ typedef enum { typedef enum { // cycle start and feedhold requests OPERATION_NULL = 0, // no operation; reverts here when complete OPERATION_CYCLE_START, // perform a cycle start with no other actions - OPERATION_HOLD_TO_P2, // feedhold into p2 with p2 entry actions - OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 + OPERATION_HOLD, // feedhold in p1 or p2 with no entry actions + OPERATION_HOLD_WITH_ACTIONS,// feedhold into p2 with entry actions +// OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 +// OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner - OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush OPERATION_JOB_KILL, // fast hold followed by queue flush and program end OPERATION_END_JOG, // fast hold followed by program stop OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit @@ -134,12 +135,13 @@ typedef enum { // cycle start and feedhold requests typedef enum { // feedhold state machine FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect - FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet + FEEDHOLD_INITIATED, // feedhold has been requested but not started yet FEEDHOLD_SYNC, // start hold - sync to latest aline segment FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet - FEEDHOLD_MOTORS_STOPPING, // waiting for motors to have stopped on hold point (motion stop) + FEEDHOLD_MOTION_STOPPING, // waiting for motors to have stopped at hold point (motion stop) + FEEDHOLD_MOTION_STOPPED, // motion has stopped at hold point FEEDHOLD_P2_START, // enter secondary planner and perform feedhold actions (once) FEEDHOLD_P2_WAIT, // wait for feedhold actions to complete FEEDHOLD_HOLD, // holding (steady state) Must be last state @@ -269,7 +271,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleType cycle_type; // cycs - cmMotionState motion_state; // momo + cmMotionState motion_state; // mots cmFeedholdState hold_state; // hold: feedhold state machine cmFlushState flush_state; // hold: queue flush state machine @@ -467,7 +469,7 @@ stat_t cm_json_wait(char *json_string); // M102 void cm_request_feedhold(void); void cm_request_exit_hold(void); void cm_request_queue_flush(void); -stat_t cm_request_operation(cmOperationType operation); // request a new operation +stat_t cm_request_operation(cmOperationType operation, float *param); // request an operation stat_t cm_operation_callback(void); // operation action runner stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests stat_t cm_feedhold_command_blocker(void); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index bed2a3fd..651982ee 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -268,78 +268,6 @@ const cfgItem_t cfgArray[] = { { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M6_POWER_LEVEL }, // { "6","6pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, // { "6","6mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, - -/* ======= - { "1","1ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_1].motor_map, M1_MOTOR_MAP }, - { "1","1sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_1].step_angle, M1_STEP_ANGLE }, - { "1","1tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_1].travel_rev, M1_TRAVEL_PER_REV }, - { "1","1mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_1].microsteps, M1_MICROSTEPS }, - { "1","1su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, - { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, - { "1","1pm",_fip, 0, st_print_pm, st_get_pm,st_set_pm, (float *)&cs.null, M1_POWER_MODE }, - { "1","1pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_1].power_level, M1_POWER_LEVEL }, -// { "1","1pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, -// { "1","1mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, -#if (MOTORS >= 2) - { "2","2ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_2].motor_map, M2_MOTOR_MAP }, - { "2","2sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_2].step_angle, M2_STEP_ANGLE }, - { "2","2tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_2].travel_rev, M2_TRAVEL_PER_REV }, - { "2","2mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_2].microsteps, M2_MICROSTEPS }, - { "2","2su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, - { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, - { "2","2pm",_fip, 0, st_print_pm, st_get_pm,st_set_pm, (float *)&cs.null, M2_POWER_MODE }, - { "2","2pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_2].power_level, M2_POWER_LEVEL}, -// { "2","2pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, -// { "2","2mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 3) - { "3","3ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_3].motor_map, M3_MOTOR_MAP }, - { "3","3sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_3].step_angle, M3_STEP_ANGLE }, - { "3","3tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_3].travel_rev, M3_TRAVEL_PER_REV }, - { "3","3mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_3].microsteps, M3_MICROSTEPS }, - { "3","3su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, - { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, - { "3","3pm",_fip, 0, st_print_pm, st_get_pm,st_set_pm, (float *)&cs.null, M3_POWER_MODE }, - { "3","3pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_3].power_level, M3_POWER_LEVEL }, -// { "3","3pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, -// { "3","3mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 4) - { "4","4ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_4].motor_map, M4_MOTOR_MAP }, - { "4","4sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_4].step_angle, M4_STEP_ANGLE }, - { "4","4tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_4].travel_rev, M4_TRAVEL_PER_REV }, - { "4","4mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_4].microsteps, M4_MICROSTEPS }, - { "4","4su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, - { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, - { "4","4pm",_fip, 0, st_print_pm, st_get_pm,st_set_pm, (float *)&cs.null, M4_POWER_MODE }, - { "4","4pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_4].power_level, M4_POWER_LEVEL }, -// { "4","4pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, -// { "4","4mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 5) - { "5","5ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_5].motor_map, M5_MOTOR_MAP }, - { "5","5sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_5].step_angle, M5_STEP_ANGLE }, - { "5","5tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_5].travel_rev, M5_TRAVEL_PER_REV }, - { "5","5mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_5].microsteps, M5_MICROSTEPS }, - { "5","5su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, - { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, - { "5","5pm",_fip, 0, st_print_pm, st_get_pm,st_set_pm, (float *)&cs.null, M5_POWER_MODE }, - { "5","5pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_5].power_level, M5_POWER_LEVEL }, -// { "5","5pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, -// { "5","5mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_5].motor_timeout, M5_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 6) - { "6","6ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_6].motor_map, M6_MOTOR_MAP }, - { "6","6sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_6].step_angle, M6_STEP_ANGLE }, - { "6","6tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_6].travel_rev, M6_TRAVEL_PER_REV }, - { "6","6mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_6].microsteps, M6_MICROSTEPS }, - { "6","6su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, - { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, - { "6","6pm",_fip, 0, st_print_pm, st_get_pm,st_set_pm, (float *)&cs.null, M6_POWER_MODE }, - { "6","6pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_6].power_level, M6_POWER_LEVEL }, -// { "6","6pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, -// { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, ->>>>>>> refs/heads/edge */ #endif // Axis parameters { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 553b1480..ba95cd52 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -47,29 +47,30 @@ static void _feedhold_p1_exit(void); static void _feedhold_p2_exit(void); static void _feedhold_abort(void); -static stat_t action_hold(float* value, bool* flag); -static stat_t action_halt(float* value, bool* flag); -static stat_t action_p2_entry(float* value, bool* flag); -static stat_t action_p2_exit(float* value, bool* flag); -static stat_t action_parking_move(float* value, bool* flag); -static stat_t action_return_move(float* value, bool* flag); -static stat_t action_spindle_control(float* value, bool* flag); -static stat_t action_coolant_control(float* value, bool* flag); -static stat_t action_heater_control(float* value, bool* flag); -static stat_t action_output_control(float* value, bool* flag); -static stat_t action_cycle_start(float* value, bool* flag); -static stat_t action_queue_flush(float* value, bool* flag); -static stat_t action_input_function(float* value, bool* flag); -static stat_t action_finalize_program(float* value, bool* flag); -static stat_t action_trigger_alarm(float* value, bool* flag); +static stat_t _action_hold(float *param); +static stat_t _action_halt(float *param); +static stat_t _action_p2_entry(float* param); +static stat_t _action_p2_exit(float *param); +static stat_t _action_parking_move(float *param); +static stat_t _action_return_move(float *param); +static stat_t _action_spindle_control(float *param); +static stat_t _action_coolant_control(float *param); +static stat_t _action_heater_control(float *param); +static stat_t _action_output_control(float *param); +static stat_t _action_cycle_start(float *param); +static stat_t _action_queue_flush(float *param); +static stat_t _action_input_function(float *param); +static stat_t _action_finalize_program(float *param); +static stat_t _action_trigger_alarm(float *param); typedef enum { // Operation Actions // Initiation actions ACTION_NULL = 0, // no pending action; reverts here when complete (read-only; cannot be set) - ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1 - ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used) - ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1 - ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2 + ACTION_HOLD, // p1/p2 feedhold at selected jerk ending in HOLD state +// ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1 +// ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used) +// ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1 +// ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2 ACTION_HALT_MOTION, // halt all motion immediately (regardless of p1 or p2) // Hold Entry Actions - run when motion has stopped @@ -113,15 +114,15 @@ typedef enum { // Operation Actions /*** Object Definitions ***/ -#define ACTION_MAX 12 -typedef stat_t (*action_exec_t)(float[], bool[]); // callback to operation action execution function +#define ACTION_MAX 12 // maximum actions that can be queued for an operation +#define PARAM_MAX 4 // maximum number of parameters that can be passed in param +typedef stat_t (*action_exec_t)(float *); // callback to operation action execution function -typedef struct cmAction { // struct to manage execution of operations - struct cmAction *nx; // static pointer to next buffer +typedef struct cmAction { // struct to manage execution of operations + struct cmAction *nx; // static pointer to next buffer - action_exec_t func; // callback to operation action function. NULL == disabled - float value[AXES]; // parameters for the function - bool flag[AXES]; + action_exec_t func; // callback to operation action function. NULL == disabled + float param[PARAM_MAX]; // parameters for the function // clears this structure (except the pointer) void reset() { @@ -134,21 +135,20 @@ typedef struct cmOperation { // struct to manage execution of operati cmAction *current_action; // current action being worked - void add_action(stat_t(*action_exec)(float[], bool[]), float* value, bool* flag) { + void add_action(stat_t(*action_exec)(float *), float* param) { if (action_exec == NULL) { return; } current_action->func = action_exec; for (uint8_t i = 0; i < AXES; i++) { - current_action->value[i] = value[i]; - current_action->flag[i] = flag[i]; + current_action->param[i] = param[i]; } }; stat_t run_action(void) { stat_t status; - status = current_action->func(current_action->value, current_action->flag); + status = current_action->func(current_action->param); if (status == STAT_OK) { current_action = current_action->nx; } @@ -175,16 +175,31 @@ cmOperation_t op; // operations runner /**************************************************************************************** * cm_request_operation() * cm_operation_callback() + * + * Operations are defined as: + * + * - OPERATION_CYCLE_START - start cycle from STOP or restart from hold + * + * - OPERATION_HOLD - initiate a hold of a given form. Parameters: + * - param[0] - p1/p2 0=hold-into-p1, 1=hold-into-p2 (with entry actions) + * - param[1] - jerk 0=normal-jerk, 1=high-jerk (fast hold) + * - param[2] - endstate */ -stat_t cm_request_operation(cmOperationType operation) +stat_t cm_request_operation(cmOperationType operation, float *param) { op.reset(); // start with a fresh operation controller switch (operation) { - case OP_CYCLE_START: { - op.add_action(action_cycle_start, nullptr, nullptr); + case OPERATION_CYCLE_START: { + op.add_action(_action_cycle_start, nullptr); + break; + } + + // Generate hold request if not already in a hold and machine is in motion + case OPERATION_HOLD: { + op.add_action(_action_cycle_start, param); break; } @@ -217,24 +232,47 @@ stat_t cm_operation_callback() * STAT_(anything else) - aborts the operation */ -static stat_t action_hold(float* value, bool* flag) { return (STAT_OK); } // p1, p2, regular and fast holds -static stat_t action_halt(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_p2_entry(float* value, bool* flag) { return (STAT_OK); } // p2 entry actions, bundled -static stat_t action_p2_exit(float* value, bool* flag) { return (STAT_OK); } // p2 exit actions, bundled -static stat_t action_parking_move(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_return_move(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_spindle_control(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_coolant_control(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_heater_control(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_output_control(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_queue_flush(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_input_function(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_finalize_program(float* value, bool* flag) { return (STAT_OK); } -static stat_t action_trigger_alarm(float* value, bool* flag) { return (STAT_OK); } - -static stat_t action_cycle_start(float* value, bool* flag) +/* + * _action_hold() - initiate hold, retirn STAT_OK once hold has been reached + * + * Initiate a feedhold in the active planner - p1 or p2 + */ +static stat_t _action_hold(float *param) // p1, p2, regular and fast holds { - cm_set_motion_state(MOTION_RUN); + // Not in feedhold + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + cm1.hold_state = FEEDHOLD_INITIATED; // initiate hold to feedhold state machine + return (STAT_EAGAIN); + } else + if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { + cm2.hold_state = FEEDHOLD_INITIATED; + return (STAT_EAGAIN); + } + + // Feedhold has already been initiated +// if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { + + return (STAT_OK); +} + + +static stat_t _action_halt(float *param) { return (STAT_OK); } +static stat_t _action_p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled +static stat_t _action_p2_exit(float *param) { return (STAT_OK); } // p2 exit actions, bundled +static stat_t _action_parking_move(float *param) { return (STAT_OK); } +static stat_t _action_return_move(float *param) { return (STAT_OK); } +static stat_t _action_spindle_control(float *param) { return (STAT_OK); } +static stat_t _action_coolant_control(float *param) { return (STAT_OK); } +static stat_t _action_heater_control(float *param) { return (STAT_OK); } +static stat_t _action_output_control(float *param) { return (STAT_OK); } +static stat_t _action_queue_flush(float *param) { return (STAT_OK); } +static stat_t _action_input_function(float *param) { return (STAT_OK); } +static stat_t _action_finalize_program(float *param) { return (STAT_OK); } +static stat_t _action_trigger_alarm(float *param) { return (STAT_OK); } + +static stat_t _action_cycle_start(float *param) +{ +// cm_set_motion_state(MOTION_RUN); cm_cycle_start(); st_request_exec_move(); return (STAT_OK); @@ -266,71 +304,6 @@ static stat_t action_cycle_start(float* value, bool* flag) * A feedhold flush request (%) received while in either p1 or p2 will execute the * exit actions, flush the p1 and p2 queues, then stop motion at the hold point. */ -/* - * Feedhold Enumerations and Use Cases - * - * The cmFeedholdRequest enum supports the following feedhold use cases. Feedholds and - * feedhold exits using these enums to get specific behaviors. First the normal ones: - * - * - FEEDHOLD_NO_REQUEST No request pending. Requests transition here when complete. - * This value cannot be set (i.e. there is no CANCEL command). - * - * - FEEDHOLD_HOLD_P1 Enter HOLD state in P1. Do not enter p2 or perform entry actions. - * - * - FEEDHOLD_HOLD_P2 (!) Enter HOLD state in P1. Enter p2 and perform entry actions. - * If this command is received while in p2, a FEEDHOLD_HOLD_SKIP - * is executed in p2. - * - * - FEEDHOLD_CYCLE_START (~) Exit HOLD state in P1 or p2. If in p2 perform exit actions, - * then resume motion in p1 planner. - * - * - FEEDHOLD_EXIT_FLUSH (%) Exit HOLD state in P1 or p2. If in p2 perform exit actions, - * then flush p1 planner. End in PROGRAM_STOP state. - * - * Now the specialized ones. If these are called with FEEDHOLD_OFF (i.e. while not in a feedhold) - * A feedhold is performed followed by the indicated actions. If called while in a feedhold the - * feedhold is exited with the indicated actions. Most of these commands are not available in p2. - * - * - FEEDHOLD_HOLD_SKIP Enter HOLD state in P1 or P2. Skip the remainder of the move in the - * held block. If the next block following held block is labeled as a - * SYNC block, execute it. Otherwise flush the queue and STOP. Used - * by homing and probing to stop motion and trigger next actions. - * - * - FEEDHOLD_HOLD_STOP Enter HOLD state in P1. Enter PROGRAM_STOP state. A cycle start or - * FEEDHOLD_EXIT_RESUME will restart motion. - * - * - FEEDHOLD_HOLD_FAST_STOP Enter HOLD state in P1 using a fast hold. Perform PROGRAM_STOP. - * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. - * - * - FEEDHOLD_HOLD_HALT Enter HOLD state in P1 using a HALT. Perform PROGRAM_STOP. - * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. - * - * - FEEDHOLD_HOLD_END Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. - * This has the effect of entering an asynchronous M30. Useful for Job Kill - * if the sender knows there are no commands following the HOLD command. - * - * - FEEDHOLD_HOLD_END_ALARM Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. - * Trigger ALARM. Useful for Job Kill if there may be subsequent commands - * queued by the sender. Requires {clear:n} or M2/M30 to recover operation. - * - * - FEEDHOLD_HOLD_ALARM Enter HOLD state in P1. Flush planner queue. Trigger ALARM. - * Requires {clear:n} or M2/M30 to recover operation. - * - * - FEEDHOLD_HOLD_SHUTDOWN Enter HOLD state in P1. Flush planner queue. Trigger SHUTDOWN. - * Requires {clear:n} or M2/M30 to recover operation. - * - * - FEEDHOLD_HOLD_PANIC Enter HOLD state in P1 using a HALT. Trigger PANIC. - * Requires reset to recover operation. - * - * Interlocks are also handled here. Invoking FEEDHOLD_HOLD_INTERLOCK when the interlock is - * not active will engage it. Invoking it while engaged releases the interlock and resumes - * normal operation. - * - * - FEEDHOLD_HOLD_INTERLOCK Enter HOLD state in P1. Enter INTERLOCK_DISENGAGED state. - * Exit hold and resume motion when interlock is cleared. This may - * require some combination of interlock switch transitions, interlock - * JSON commands and {clear:n} depending on interlock configuration. - */ /* * Feedhold Processing - Performs the following cases (listed in rough sequence order): * @@ -407,10 +380,10 @@ void cm_request_feedhold(void) // ! { // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_state = FEEDHOLD_REQUESTED; // signal request to state machine + cm1.hold_state = FEEDHOLD_INITIATED; // signal request to state machine } else if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { - cm2.hold_state = FEEDHOLD_REQUESTED; + cm2.hold_state = FEEDHOLD_INITIATED; } } @@ -467,7 +440,7 @@ stat_t cm_feedhold_command_blocker() stat_t cm_feedhold_sequencing_callback() { // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions - if (cm1.hold_state == FEEDHOLD_REQUESTED) { + if (cm1.hold_state == FEEDHOLD_INITIATED) { if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution @@ -478,7 +451,7 @@ stat_t cm_feedhold_sequencing_callback() } // p2 feedhold states - feedhold in feedhold - if (cm2.hold_state == FEEDHOLD_REQUESTED) { + if (cm2.hold_state == FEEDHOLD_INITIATED) { if (mp_has_runnable_buffer(&mp2)) { cm_set_motion_state(MOTION_HOLD); cm2.hold_state = FEEDHOLD_SYNC; @@ -797,3 +770,70 @@ void cm_queue_flush(cmMachine_t *_cm) planner_reset((mpPlanner_t *)_cm->mp); // reset primary planner. also resets the mr under the planner _cm->flush_state = FLUSH_WAS_RUN; } + + +/* + * Feedhold Enumerations and Use Cases + * + * The cmFeedholdRequest enum supports the following feedhold use cases. Feedholds and + * feedhold exits using these enums to get specific behaviors. First the normal ones: + * + * - FEEDHOLD_NO_REQUEST No request pending. Requests transition here when complete. + * This value cannot be set (i.e. there is no CANCEL command). + * + * - FEEDHOLD_HOLD_P1 Enter HOLD state in P1. Do not enter p2 or perform entry actions. + * + * - FEEDHOLD_HOLD_P2 (!) Enter HOLD state in P1. Enter p2 and perform entry actions. + * If this command is received while in p2, a FEEDHOLD_HOLD_SKIP + * is executed in p2. + * + * - FEEDHOLD_CYCLE_START (~) Exit HOLD state in P1 or p2. If in p2 perform exit actions, + * then resume motion in p1 planner. + * + * - FEEDHOLD_EXIT_FLUSH (%) Exit HOLD state in P1 or p2. If in p2 perform exit actions, + * then flush p1 planner. End in PROGRAM_STOP state. + * + * Now the specialized ones. If these are called with FEEDHOLD_OFF (i.e. while not in a feedhold) + * A feedhold is performed followed by the indicated actions. If called while in a feedhold the + * feedhold is exited with the indicated actions. Most of these commands are not available in p2. + * + * - FEEDHOLD_HOLD_SKIP Enter HOLD state in P1 or P2. Skip the remainder of the move in the + * held block. If the next block following held block is labeled as a + * SYNC block, execute it. Otherwise flush the queue and STOP. Used + * by homing and probing to stop motion and trigger next actions. + * + * - FEEDHOLD_HOLD_STOP Enter HOLD state in P1. Enter PROGRAM_STOP state. A cycle start or + * FEEDHOLD_EXIT_RESUME will restart motion. + * + * - FEEDHOLD_HOLD_FAST_STOP Enter HOLD state in P1 using a fast hold. Perform PROGRAM_STOP. + * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. + * + * - FEEDHOLD_HOLD_HALT Enter HOLD state in P1 using a HALT. Perform PROGRAM_STOP. + * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. + * + * - FEEDHOLD_HOLD_END Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. + * This has the effect of entering an asynchronous M30. Useful for Job Kill + * if the sender knows there are no commands following the HOLD command. + * + * - FEEDHOLD_HOLD_END_ALARM Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. + * Trigger ALARM. Useful for Job Kill if there may be subsequent commands + * queued by the sender. Requires {clear:n} or M2/M30 to recover operation. + * + * - FEEDHOLD_HOLD_ALARM Enter HOLD state in P1. Flush planner queue. Trigger ALARM. + * Requires {clear:n} or M2/M30 to recover operation. + * + * - FEEDHOLD_HOLD_SHUTDOWN Enter HOLD state in P1. Flush planner queue. Trigger SHUTDOWN. + * Requires {clear:n} or M2/M30 to recover operation. + * + * - FEEDHOLD_HOLD_PANIC Enter HOLD state in P1 using a HALT. Trigger PANIC. + * Requires reset to recover operation. + * + * Interlocks are also handled here. Invoking FEEDHOLD_HOLD_INTERLOCK when the interlock is + * not active will engage it. Invoking it while engaged releases the interlock and resumes + * normal operation. + * + * - FEEDHOLD_HOLD_INTERLOCK Enter HOLD state in P1. Enter INTERLOCK_DISENGAGED state. + * Exit hold and resume motion when interlock is cleared. This may + * require some combination of interlock switch transitions, interlock + * JSON commands and {clear:n} depending on interlock configuration. + */ \ No newline at end of file diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index eb6d528e..cfe353f5 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 9951353 SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800030015 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800019454 + J41800030015 0x284E0A60 - 2000000 + 9951353 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 729d8819..d5eecc7c 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1025,9 +1025,10 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) static stat_t _exec_aline_feedhold(mpBuf_t *bf) { // Case (4) - Completing the feedhold - Wait for the steppers to stop - if (cm->hold_state == FEEDHOLD_MOTORS_STOPPING) { + if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes + cm->hold_state = FEEDHOLD_MOTION_STOPPED; // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { @@ -1069,7 +1070,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity // This state might not appear necessary, but it is to handle closely packed !~ and other cases if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { - cm->hold_state = FEEDHOLD_MOTORS_STOPPING; // wait for the motors to come to a complete stop + cm->hold_state = FEEDHOLD_MOTION_STOPPING; // wait for motion to come to a complete stop return (STAT_OK); // exit from mp_exec_aline() } From 66e57594b5ea7fc8c467874d9b175273489a37d5 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 11 Mar 2017 07:08:44 -0500 Subject: [PATCH 177/283] Checkpoint. Functioning --- g2core/controller.cpp | 2 +- g2core/cycle_feedhold.cpp | 99 ++++++++++++++++++++++++--------------- g2core/g2core.cppproj | 8 ++-- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 357b5708..855410ad 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -160,7 +160,7 @@ static void _controller_HSM() DISPATCH(qr_queue_report_callback()); // conditionally send queue report DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner - DISPATCH(cm_operation_callback()); // operation action runner +// DISPATCH(cm_operation_callback()); // operation action runner DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index ba95cd52..6a2f8f5a 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -47,21 +47,22 @@ static void _feedhold_p1_exit(void); static void _feedhold_p2_exit(void); static void _feedhold_abort(void); -static stat_t _action_hold(float *param); -static stat_t _action_halt(float *param); -static stat_t _action_p2_entry(float* param); -static stat_t _action_p2_exit(float *param); -static stat_t _action_parking_move(float *param); -static stat_t _action_return_move(float *param); -static stat_t _action_spindle_control(float *param); -static stat_t _action_coolant_control(float *param); -static stat_t _action_heater_control(float *param); -static stat_t _action_output_control(float *param); static stat_t _action_cycle_start(float *param); -static stat_t _action_queue_flush(float *param); -static stat_t _action_input_function(float *param); -static stat_t _action_finalize_program(float *param); -static stat_t _action_trigger_alarm(float *param); +static stat_t _action_hold(float *param); + +//static stat_t _action_halt(float *param); +//static stat_t _action_p2_entry(float* param); +//static stat_t _action_p2_exit(float *param); +//static stat_t _action_parking_move(float *param); +//static stat_t _action_return_move(float *param); +//static stat_t _action_spindle_control(float *param); +//static stat_t _action_coolant_control(float *param); +//static stat_t _action_heater_control(float *param); +//static stat_t _action_output_control(float *param); +//static stat_t _action_queue_flush(float *param); +//static stat_t _action_input_function(float *param); +//static stat_t _action_finalize_program(float *param); +//static stat_t _action_trigger_alarm(float *param); typedef enum { // Operation Actions // Initiation actions @@ -111,6 +112,20 @@ typedef enum { // Operation Actions ACTION_PERFORM_RESET, // defined, but not implemented } cmOpAction; +/* + * Operations work by queueing a set of actions, then running then in sequence until the + * operation is complete or an error occurs. Works like this: + * + * - Invoke an operation by calling cm_request_operation(), possibly with one or more parameters + * - The operation runner must be idle: an operation cannot interrupt a currently running operation + * - There may be need for Cancel Operation semantics, but this could get overcomplicated + * - When a new operation is requested the operations runner object is cleared + * and one or more actions are queued by calling add_action() on the object. + * - The operation will be started immediately if run_action() is called during the request. + * If run_action() is not called the operation will begin the next time cm_operation_callback() + * + * + */ /*** Object Definitions ***/ @@ -147,6 +162,9 @@ typedef struct cmOperation { // struct to manage execution of operati }; stat_t run_action(void) { + if (current_action->func == NULL) { + return (STAT_NOOP); + } stat_t status; status = current_action->func(current_action->param); if (status == STAT_OK) { @@ -199,7 +217,7 @@ stat_t cm_request_operation(cmOperationType operation, float *param) // Generate hold request if not already in a hold and machine is in motion case OPERATION_HOLD: { - op.add_action(_action_cycle_start, param); + op.add_action(_action_hold, param); break; } @@ -233,9 +251,20 @@ stat_t cm_operation_callback() */ /* - * _action_hold() - initiate hold, retirn STAT_OK once hold has been reached - * - * Initiate a feedhold in the active planner - p1 or p2 + * _action_cycle_start() - start a cycle or restart from hold + */ +static stat_t _action_cycle_start(float *param) +{ + // cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); + return (STAT_OK); +} + +/* + * _action_hold() - initiate a feedhold in the active planner - p1 or p2 + * + * Return STAT_OK once hold has been reached */ static stat_t _action_hold(float *param) // p1, p2, regular and fast holds { @@ -256,27 +285,19 @@ static stat_t _action_hold(float *param) // p1, p2, regular and fast holds } -static stat_t _action_halt(float *param) { return (STAT_OK); } -static stat_t _action_p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled -static stat_t _action_p2_exit(float *param) { return (STAT_OK); } // p2 exit actions, bundled -static stat_t _action_parking_move(float *param) { return (STAT_OK); } -static stat_t _action_return_move(float *param) { return (STAT_OK); } -static stat_t _action_spindle_control(float *param) { return (STAT_OK); } -static stat_t _action_coolant_control(float *param) { return (STAT_OK); } -static stat_t _action_heater_control(float *param) { return (STAT_OK); } -static stat_t _action_output_control(float *param) { return (STAT_OK); } -static stat_t _action_queue_flush(float *param) { return (STAT_OK); } -static stat_t _action_input_function(float *param) { return (STAT_OK); } -static stat_t _action_finalize_program(float *param) { return (STAT_OK); } -static stat_t _action_trigger_alarm(float *param) { return (STAT_OK); } - -static stat_t _action_cycle_start(float *param) -{ -// cm_set_motion_state(MOTION_RUN); - cm_cycle_start(); - st_request_exec_move(); - return (STAT_OK); -} +//static stat_t _action_halt(float *param) { return (STAT_OK); } +//static stat_t _action_p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled +//static stat_t _action_p2_exit(float *param) { return (STAT_OK); } // p2 exit actions, bundled +//static stat_t _action_parking_move(float *param) { return (STAT_OK); } +//static stat_t _action_return_move(float *param) { return (STAT_OK); } +//static stat_t _action_spindle_control(float *param) { return (STAT_OK); } +//static stat_t _action_coolant_control(float *param) { return (STAT_OK); } +//static stat_t _action_heater_control(float *param) { return (STAT_OK); } +//static stat_t _action_output_control(float *param) { return (STAT_OK); } +//static stat_t _action_queue_flush(float *param) { return (STAT_OK); } +//static stat_t _action_input_function(float *param) { return (STAT_OK); } +//static stat_t _action_finalize_program(float *param) { return (STAT_OK); } +//static stat_t _action_trigger_alarm(float *param) { return (STAT_OK); } /**************************************************************************************** **** Feedholds ************************************************************************* diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index cfe353f5..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 9951353 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800030015 + J41800036434 0x284E0A60 - 9951353 + 10000000 From 741014988dbaa37d39a6d7d8068fd3a96d47bdd3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 11 Mar 2017 08:29:54 -0500 Subject: [PATCH 178/283] Simplified cm_get_combined_state --- g2core/canonical_machine.cpp | 55 +++++++++--------------------------- g2core/plan_exec.cpp | 2 ++ 2 files changed, 15 insertions(+), 42 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 2497a6ba..082fd591 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -284,59 +284,30 @@ cmProbeState cm_get_probe_state() { return cm->probe_state[0];} /* * cm_get_combined_state() - combines raw states into something a user might want to see - * - * NOTE: On issuing a gcode command we call cm_cycle_start() before the motion gets queued. - * We don't go to MOTION_RUN until the command is executed by mp_exec_aline(), planned, - * queued, and started. So MOTION_STOP must actually return COMBINED_RUN to address this - * case, even though under some circumstances it might actually be an exception case. - * Therefore this assertion isn't valid: - * cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "mots2"));//"mots is stop but machine is in cycle" - * return (COMBINED_PANIC); */ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) { - if (_cm->machine_state <= MACHINE_PROGRAM_END) { // replaces first 5 cm->machine_state cases - return ((cmCombinedState)_cm->machine_state); //...where MACHINE_xxx == COMBINED_xxx - } switch(_cm->machine_state) { + case MACHINE_INITIALIZING: + case MACHINE_READY: + case MACHINE_ALARM: + case MACHINE_PROGRAM_STOP: + case MACHINE_PROGRAM_END: { return ((cmCombinedState)_cm->machine_state); } case MACHINE_INTERLOCK: { return (COMBINED_INTERLOCK); } case MACHINE_SHUTDOWN: { return (COMBINED_SHUTDOWN); } case MACHINE_PANIC: { return (COMBINED_PANIC); } case MACHINE_CYCLE: { - switch(_cm->cycle_type) { - case CYCLE_HOMING: { return (COMBINED_HOMING); } - case CYCLE_PROBE: { return (COMBINED_PROBE); } - case CYCLE_JOG: { return (COMBINED_JOG); } -// case CYCLE_MACHINING: case CYCLE_NONE: { -// switch(_cm->motion_state) { -// case MOTION_STOP: { return (COMBINED_RUN); } // See NOTE, above -// case MOTION_RUN: { return (COMBINED_RUN); } -// case MOTION_HOLD: { return (COMBINED_HOLD); } -// default: { -// cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() mots bad");// "mots has impossible value" -// return (COMBINED_PANIC); -// } -// } - - case CYCLE_MACHINING: { - if (_cm->hold_state != FEEDHOLD_OFF) { - return (COMBINED_HOLD); - } else { - return (COMBINED_RUN); - } - - } - default: { - cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() cycs bad"); // "cycs has impossible value" - return (COMBINED_PANIC); - } + switch(_cm->cycle_type) { + case CYCLE_NONE: { break; } // CYCLE_NONE cannot ever get here + case CYCLE_MACHINING: { return (_cm->hold_state == FEEDHOLD_OFF ? COMBINED_RUN : COMBINED_HOLD); } + case CYCLE_HOMING: { return (COMBINED_HOMING); } + case CYCLE_PROBE: { return (COMBINED_PROBE); } + case CYCLE_JOG: { return (COMBINED_JOG); } } } - default: { - cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() macs bad"); // "macs has impossible value" - return (COMBINED_PANIC); - } } + cm_panic(STAT_STATE_MANAGEMENT_ASSERTION_FAILURE, "cm_get_combined_state() undefined state"); + return (COMBINED_PANIC); } /*********************************************************************************** diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index d5eecc7c..c6ba70d7 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -308,6 +308,7 @@ stat_t mp_exec_move() // Manage motion state transitions if ((cm->motion_state != MOTION_RUN) && (cm->motion_state != MOTION_HOLD)) { +// +++++ if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); // also sets active model to RUNTIME } } @@ -552,6 +553,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) if (bf->block_state == BLOCK_ACTIVE) { if (mp_free_run_buffer()) { // returns true of the buffer is empty if (cm->hold_state == FEEDHOLD_OFF) { + cm_set_motion_state(MOTION_STOP); // also sets active model to RUNTIME cm_cycle_end(); // free buffer & end cycle if planner is empty } } else { From c5a969775ca39391adab3027d117e1e327cb0080 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 11 Mar 2017 08:55:50 -0500 Subject: [PATCH 179/283] Removed MOTION_HOLD state --- g2core/canonical_machine.cpp | 11 ++++++----- g2core/canonical_machine.h | 4 ++-- g2core/cycle_feedhold.cpp | 6 +++--- g2core/plan_exec.cpp | 10 ++++++---- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 082fd591..187bb52e 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -259,12 +259,13 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) void cm_set_motion_state(const cmMotionState motion_state) { cm->motion_state = motion_state; + ACTIVE_MODEL = (motion_state ? MODEL : RUNTIME); - switch (motion_state) { - case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } - case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; } - case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; } - } +// switch (motion_state) { +// case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } +// case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; } +// case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; } +// } } /* diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index aeccc690..fb8a181a 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -95,8 +95,8 @@ typedef enum { // Note: MachineState signals if the machine is typedef enum { MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue - MOTION_RUN, // machine is in motion: set when the steppers execute an ALINE segment - MOTION_HOLD // feedhold in progress: set whenever we leave FEEDHOLD_OFF, unset whenever we enter FEEDHOLD_OFF + MOTION_RUN // machine is in motion: set when the steppers execute an ALINE segment +// MOTION_HOLD // feedhold in progress: set whenever we leave FEEDHOLD_OFF, unset whenever we enter FEEDHOLD_OFF } cmMotionState; typedef enum { diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 6a2f8f5a..3a714b9f 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -428,7 +428,7 @@ void cm_start_hold() { // Can only request a feedhold if the machine is in motion and there not one is not already in progress if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { - cm_set_motion_state(MOTION_HOLD); +// cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } @@ -463,7 +463,7 @@ stat_t cm_feedhold_sequencing_callback() // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_INITIATED) { if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here - cm_set_motion_state(MOTION_HOLD); +// cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } @@ -474,7 +474,7 @@ stat_t cm_feedhold_sequencing_callback() // p2 feedhold states - feedhold in feedhold if (cm2.hold_state == FEEDHOLD_INITIATED) { if (mp_has_runnable_buffer(&mp2)) { - cm_set_motion_state(MOTION_HOLD); +// cm_set_motion_state(MOTION_HOLD); cm2.hold_state = FEEDHOLD_SYNC; } } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index c6ba70d7..1bdea124 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -307,8 +307,8 @@ stat_t mp_exec_move() } // Manage motion state transitions - if ((cm->motion_state != MOTION_RUN) && (cm->motion_state != MOTION_HOLD)) { -// +++++ if (cm->motion_state != MOTION_RUN) { +// if ((cm->motion_state != MOTION_RUN) && (cm->motion_state != MOTION_HOLD)) { + if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); // also sets active model to RUNTIME } } @@ -486,7 +486,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feed Override Processing - We need to handle the following cases (listed in rough sequence order): // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): - if (cm->motion_state == MOTION_HOLD) { +// if (cm->motion_state == MOTION_HOLD) { + if (cm->hold_state != FEEDHOLD_OFF) { // if FEEDHOLD_P2_START, FEEDHOLD_P2_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT if (cm->hold_state >= FEEDHOLD_P2_START) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move @@ -899,7 +900,8 @@ static stat_t _exec_aline_segment() // Otherwise if not at a section waypoint compute target from segment time and velocity // Don't do waypoint correction if you are going into a hold. - if ((--mr->segment_count == 0) && (cm->motion_state != MOTION_HOLD)) { +// if ((--mr->segment_count == 0) && (cm->motion_state != MOTION_HOLD)) { + if ((--mr->segment_count == 0) && (cm->hold_state == FEEDHOLD_OFF)) { copy_vector(mr->gm.target, mr->waypoint[mr->section]); } else { float segment_length = mr->segment_velocity * mr->segment_time; From 6b7f08b74cace529ef171ea7e7a0c7cddaa53403 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 11 Mar 2017 10:12:43 -0500 Subject: [PATCH 180/283] Reduced motion_state down to MOTION_STOP and MOTION_RUN --- g2core/canonical_machine.cpp | 8 +------- g2core/canonical_machine.h | 29 ++++++++++++++--------------- g2core/cycle_feedhold.cpp | 3 --- g2core/cycle_jogging.cpp | 2 +- g2core/plan_exec.cpp | 15 +++++---------- 5 files changed, 21 insertions(+), 36 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 187bb52e..1fd1cfee 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -259,13 +259,7 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) void cm_set_motion_state(const cmMotionState motion_state) { cm->motion_state = motion_state; - ACTIVE_MODEL = (motion_state ? MODEL : RUNTIME); - -// switch (motion_state) { -// case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; } -// case (MOTION_RUN): { ACTIVE_MODEL = RUNTIME; break; } -// case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; } -// } + ACTIVE_MODEL = ((motion_state == MOTION_STOP) ? MODEL : RUNTIME); } /* diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index fb8a181a..e74dedb2 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -64,20 +64,20 @@ // ### LAYER 8 CRITICAL REGION ### // ### DO NOT CHANGE THESE ENUMERATIONS WITHOUT COMMUNITY INPUT ### typedef enum { // check alignment with messages in config.c / msg_stat strings - COMBINED_INITIALIZING = 0, // [0] machine is initializing //iff macs == MACHINE_INITIALIZING - COMBINED_READY, // [1] machine is ready for use //iff macs == MACHINE_READY - COMBINED_ALARM, // [2] machine in alarm state //iff macs == MACHINE_ALARM - COMBINED_PROGRAM_STOP, // [3] program stop/no more blocks //iff macs == MACHINE_PROGRAM_STOP - COMBINED_PROGRAM_END, // [4] program end //iff macs == MACHINE_PROGRAM_END - COMBINED_RUN, // [5] machine is running //iff macs == MACHINE_CYCLE, cycs == CYCLE_OFF, mots != MOTION_HOLD - COMBINED_HOLD, // [6] machine is holding //iff macs == MACHINE_CYCLE, cycs == CYCLE_OFF, mots == MOTION_HOLD - COMBINED_PROBE, // [7] probe cycle active //iff macs == MACHINE_CYCLE, cycs == CYCLE_PROBE - COMBINED_CYCLE, // [8] reserved for canned cycles < not used > - COMBINED_HOMING, // [9] homing cycle active //iff macs == MACHINE_CYCLE, cycs = CYCLE_HOMING - COMBINED_JOG, // [10] jogging cycle active //iff macs == MACHINE_CYCLE, cycs = CYCLE_JOG - COMBINED_INTERLOCK, // [11] machine in safety interlock hold//iff macs == MACHINE_INTERLOCK - COMBINED_SHUTDOWN, // [12] machine in shutdown state //iff macs == MACHINE_SHUTDOWN - COMBINED_PANIC // [13] machine in panic state //iff macs == MACHINE_PANIC + COMBINED_INITIALIZING = 0, // [0] machine is initializing + COMBINED_READY, // [1] machine is ready for use + COMBINED_ALARM, // [2] machine in alarm state + COMBINED_PROGRAM_STOP, // [3] program stop/no more blocks + COMBINED_PROGRAM_END, // [4] program end + COMBINED_RUN, // [5] machine is running + COMBINED_HOLD, // [6] machine is holding + COMBINED_PROBE, // [7] probe cycle activ + COMBINED_CYCLE, // [8] reserved for canned cycles + COMBINED_HOMING, // [9] homing cycle active + COMBINED_JOG, // [10] jogging cycle active + COMBINED_INTERLOCK, // [11] machine in safety interlock hold + COMBINED_SHUTDOWN, // [12] machine in shutdown state + COMBINED_PANIC // [13] machine in panic state } cmCombinedState; //### END CRITICAL REGION ### @@ -96,7 +96,6 @@ typedef enum { // Note: MachineState signals if the machine is typedef enum { MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue MOTION_RUN // machine is in motion: set when the steppers execute an ALINE segment -// MOTION_HOLD // feedhold in progress: set whenever we leave FEEDHOLD_OFF, unset whenever we enter FEEDHOLD_OFF } cmMotionState; typedef enum { diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 3a714b9f..b4716e95 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -428,7 +428,6 @@ void cm_start_hold() { // Can only request a feedhold if the machine is in motion and there not one is not already in progress if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { -// cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } @@ -463,7 +462,6 @@ stat_t cm_feedhold_sequencing_callback() // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions if (cm1.hold_state == FEEDHOLD_INITIATED) { if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here -// cm_set_motion_state(MOTION_HOLD); cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } @@ -474,7 +472,6 @@ stat_t cm_feedhold_sequencing_callback() // p2 feedhold states - feedhold in feedhold if (cm2.hold_state == FEEDHOLD_INITIATED) { if (mp_has_runnable_buffer(&mp2)) { -// cm_set_motion_state(MOTION_HOLD); cm2.hold_state = FEEDHOLD_SYNC; } } diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index 35cbe72f..ccc4f664 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -131,7 +131,7 @@ stat_t cm_jogging_cycle_callback(void) { return (STAT_EAGAIN); // sync to planner move ends } // if (jog.func == _jogging_axis_ramp_jog && mp_get_buffers_available() < PLANNER_BUFFER_HEADROOM) { - if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(mp)) { //+++++ + if (jog.func == _jogging_axis_ramp_jog && mp_planner_is_full(mp)) { // +++++ return (STAT_EAGAIN); // prevent flooding the queue with jog moves } return (jog.func(jog.axis)); // execute the current jogging move diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 1bdea124..982db6b8 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -306,11 +306,8 @@ stat_t mp_exec_move() st_request_forward_plan(); } - // Manage motion state transitions -// if ((cm->motion_state != MOTION_RUN) && (cm->motion_state != MOTION_HOLD)) { - if (cm->motion_state != MOTION_RUN) { - cm_set_motion_state(MOTION_RUN); // also sets active model to RUNTIME - } + // Perform motion state transition. Also sets active model to RUNTIME + if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); } } if (bf->bf_func == NULL) { return(cm_panic(STAT_INTERNAL_ERROR, "mp_exec_move()")); // never supposed to get here @@ -486,7 +483,6 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feed Override Processing - We need to handle the following cases (listed in rough sequence order): // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): -// if (cm->motion_state == MOTION_HOLD) { if (cm->hold_state != FEEDHOLD_OFF) { // if FEEDHOLD_P2_START, FEEDHOLD_P2_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT if (cm->hold_state >= FEEDHOLD_P2_START) { // handles _exec_aline_feedhold_processing case (7) @@ -767,7 +763,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf) return (STAT_OK); // exit without advancing position, say we're done } debug_trap_if_true(mr->section != SECTION_HEAD, "exec_aline() Not section head"); - mr->section = SECTION_HEAD; // +++++ Redundant??? +// mr->section = SECTION_HEAD; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { mr->segment_velocity += mr->forward_diff_5; @@ -812,7 +808,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf) return (STAT_OK); // exit without advancing position, say we're done } debug_trap_if_true(mr->section != SECTION_BODY, "exec_aline() Not section body"); - mr->section = SECTION_BODY; // +++++ Redundant??? +// mr->section = SECTION_BODY; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done @@ -853,7 +849,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) return (STAT_OK); // exit without advancing position, say we're done } debug_trap_if_true(mr->section != SECTION_TAIL, "exec_aline() Not section tail"); - mr->section = SECTION_TAIL; // +++++ Redundant??? +// mr->section = SECTION_TAIL; // +++++ Redundant??? mr->section_state = SECTION_RUNNING; } else { mr->segment_velocity += mr->forward_diff_5; @@ -900,7 +896,6 @@ static stat_t _exec_aline_segment() // Otherwise if not at a section waypoint compute target from segment time and velocity // Don't do waypoint correction if you are going into a hold. -// if ((--mr->segment_count == 0) && (cm->motion_state != MOTION_HOLD)) { if ((--mr->segment_count == 0) && (cm->hold_state == FEEDHOLD_OFF)) { copy_vector(mr->gm.target, mr->waypoint[mr->section]); } else { From 7855bdb8485ab2438e7f55c22b5561107e059bc2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 11 Mar 2017 15:59:31 -0500 Subject: [PATCH 181/283] The ops runner is finally alive. First breath. --- g2core/canonical_machine.cpp | 6 ++ g2core/canonical_machine.h | 6 +- g2core/controller.cpp | 2 +- g2core/cycle_feedhold.cpp | 158 ++++++++++++++++++++++------------- g2core/planner.cpp | 2 +- g2core/planner.h | 2 +- 6 files changed, 112 insertions(+), 64 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 1fd1cfee..57f7c323 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -207,6 +207,8 @@ void canonical_machine_reset(cmMachine_t *_cm) _cm->gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; // never start in a motion mode _cm->machine_state = MACHINE_READY; + cm_operation_init(); // reset operations runner + canonical_machine_reset_rotation(_cm); memset(&_cm->probe_state, 0, sizeof(cmProbeState)*PROBES_STORED); memset(&_cm->probe_results, 0, sizeof(float)*PROBES_STORED*AXES); @@ -1571,11 +1573,15 @@ static void _exec_program_finalize(float *value, bool *flag) void cm_cycle_start() { +#if (1) // +++++ + cm_request_operation(OPERATION_CYCLE_START, nullptr); +#else if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles cm->cycle_type = CYCLE_MACHINING; cm->machine_state = MACHINE_CYCLE; qr_init_queue_report(); // clear queue reporting buffer counts } +#endif } void cm_cycle_end() diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index e74dedb2..1d9c37e5 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -465,11 +465,13 @@ stat_t cm_json_wait(char *json_string); // M102 /**** Cycles and External FIles ****/ // Feedhold and related functions (cycle_feedhold.cpp) +void cm_operation_init(void); +stat_t cm_operation_callback(void); // operation action runner +stat_t cm_request_operation(cmOperationType operation, float *param); // request an operation + void cm_request_feedhold(void); void cm_request_exit_hold(void); void cm_request_queue_flush(void); -stat_t cm_request_operation(cmOperationType operation, float *param); // request an operation -stat_t cm_operation_callback(void); // operation action runner stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests stat_t cm_feedhold_command_blocker(void); diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 855410ad..357b5708 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -160,7 +160,7 @@ static void _controller_HSM() DISPATCH(qr_queue_report_callback()); // conditionally send queue report DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner -// DISPATCH(cm_operation_callback()); // operation action runner + DISPATCH(cm_operation_callback()); // operation action runner DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index b4716e95..afe326d8 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -47,8 +47,8 @@ static void _feedhold_p1_exit(void); static void _feedhold_p2_exit(void); static void _feedhold_abort(void); -static stat_t _action_cycle_start(float *param); -static stat_t _action_hold(float *param); +stat_t _action_cycle_start(float *param); +stat_t _action_hold(float *param); //static stat_t _action_halt(float *param); //static stat_t _action_p2_entry(float* param); @@ -112,80 +112,112 @@ typedef enum { // Operation Actions ACTION_PERFORM_RESET, // defined, but not implemented } cmOpAction; -/* +/**************************************************************************************** * Operations work by queueing a set of actions, then running then in sequence until the * operation is complete or an error occurs. Works like this: * - * - Invoke an operation by calling cm_request_operation(), possibly with one or more parameters + * - Invoke an operation by calling cm_request_operation(); may require one or more parameters * - The operation runner must be idle: an operation cannot interrupt a currently running operation - * - There may be need for Cancel Operation semantics, but this could get overcomplicated - * - When a new operation is requested the operations runner object is cleared - * and one or more actions are queued by calling add_action() on the object. - * - The operation will be started immediately if run_action() is called during the request. - * If run_action() is not called the operation will begin the next time cm_operation_callback() - * - * + * - Future may need Cancel Operation semantics, but this could get overcomplicated quickly + * + * - When a new operation is requested the operations runner object is cleared and one or + * more actions are queued by calling add_action() on the object. + * + * - To start the operation immediately call run_action() at the end of the request. + * Otherwise the operation will begin the next time cm_operation_callback(). + * + * It is assumed that all actions are added at once, and that this cannot be interrupted + * by a run request. So no attempt is made at mutual exclusion. Just behave. */ /*** Object Definitions ***/ -#define ACTION_MAX 12 // maximum actions that can be queued for an operation -#define PARAM_MAX 4 // maximum number of parameters that can be passed in param -typedef stat_t (*action_exec_t)(float *); // callback to operation action execution function +#define PARAM_MAX 4 // maximum number of parameters that can be passed in param +#define ACTION_MAX 12 // maximum actions that can be queued for an operation +typedef stat_t (*action_exec_t)(float *); // callback to action execution function -typedef struct cmAction { // struct to manage execution of operations - struct cmAction *nx; // static pointer to next buffer +typedef struct cmAction { // struct to manage execution of operations - action_exec_t func; // callback to operation action function. NULL == disabled - float param[PARAM_MAX]; // parameters for the function + uint8_t number; + struct cmAction *nx; // static pointer to next buffer + action_exec_t func; // callback to operation action function. NULL == disabled + float param[PARAM_MAX]; // parameters for the function - // clears this structure (except the pointer) - void reset() { + void reset() { // clears this structure (except the pointer) func = NULL; - } + }; } cmAction_t; -typedef struct cmOperation { // struct to manage execution of operations - cmAction action[ACTION_MAX]; // singly linked list of action control structures +typedef struct cmOperation { // struct to manage execution of operations - cmAction *current_action; // current action being worked - - void add_action(stat_t(*action_exec)(float *), float* param) { - if (action_exec == NULL) { - return; - } - current_action->func = action_exec; - - for (uint8_t i = 0; i < AXES; i++) { - current_action->param[i] = param[i]; - } - }; - - stat_t run_action(void) { - if (current_action->func == NULL) { - return (STAT_NOOP); - } - stat_t status; - status = current_action->func(current_action->param); - if (status == STAT_OK) { - current_action = current_action->nx; - } - return (status); - }; + cmAction action[ACTION_MAX]; // singly linked list of action control structures + cmAction *add; // pointer to next action to be added + cmAction *run; // pointer to action being executed + bool in_operation; // set true when an operation is running void reset(void) { for (uint8_t i=0; i < ACTION_MAX; i++) { - action[i].reset(); - action[i].nx = &action[i+1]; + action[i].reset(); // reset the action controller object + action[i].number = i; + action[i].nx = &action[i+1]; // link to the next action } - action[ACTION_MAX-1].nx = &action[0]; - current_action = &action[0]; + action[ACTION_MAX-1].nx = NULL; // set last action (end of list) + add = action; + run = action; + }; + + stat_t add_action(stat_t(*action_exec)(float *), float* param) { + + if (in_operation) { // error if an operation is currently running + return (STAT_COMMAND_NOT_ACCEPTED); + } +// if (action_exec == NULL) { // illegal input +// return (STAT_INVALID_OR_MALFORMED_COMMAND); +// } + if (add == NULL) { // no more room for a new action + return (STAT_INPUT_EXCEEDS_MAX_LENGTH); + } + add->func = action_exec; + if (param != NULL) { + for (uint8_t i=0; iparam[i] = param[i]; + } + }; + add = add->nx; + return (STAT_OK); + }; + + stat_t run_operation(void) { + + if (run->func == NULL) { // not an error if nothing to run + return (STAT_NOOP); // break out of cm_operation_callback() run loop + } + in_operation = true; // disable add_action during operations + stat_t status = run->func(run->param); + if (status == STAT_EAGAIN) { // continuation: return with no change to action pointer + return (status); + } + if (status == STAT_OK) { // current action complete, advance to next action + run = run->nx; + if (run->func != NULL) { // action is complete but operation is not yet complete + return (STAT_OK); + } + in_operation = false; + status = STAT_COMPLETE; // break out of the cm_operation_callback() run loop + } + reset(); // reset the operation if complete or if action threw an error + return (status); // return error or COMPLETE }; } cmOperation_t; cmOperation_t op; // operations runner +void cm_operation_init() +{ + op.reset(); +} + /**************************************************************************************** **** Operations ************************************************************************ ****************************************************************************************/ @@ -206,13 +238,15 @@ cmOperation_t op; // operations runner stat_t cm_request_operation(cmOperationType operation, float *param) { - op.reset(); // start with a fresh operation controller + if (op.in_operation) { + return (STAT_COMMAND_NOT_ACCEPTED); // already has a current running action + } switch (operation) { case OPERATION_CYCLE_START: { op.add_action(_action_cycle_start, nullptr); - break; + return(op.run_operation()); } // Generate hold request if not already in a hold and machine is in motion @@ -231,7 +265,7 @@ stat_t cm_request_operation(cmOperationType operation, float *param) stat_t cm_operation_callback() { stat_t status = STAT_OK; - while ((status = op.run_action()) == STAT_OK); + while ((status = op.run_operation()) == STAT_OK); return (status); } @@ -253,11 +287,16 @@ stat_t cm_operation_callback() /* * _action_cycle_start() - start a cycle or restart from hold */ -static stat_t _action_cycle_start(float *param) +//static stat_t _action_cycle_start(float *param) +stat_t _action_cycle_start(float *param) { - // cm_set_motion_state(MOTION_RUN); - cm_cycle_start(); - st_request_exec_move(); +// cm_cycle_start(); + if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles + cm->cycle_type = CYCLE_MACHINING; + cm->machine_state = MACHINE_CYCLE; +// qr_init_queue_report(); // clear queue reporting buffer counts + st_request_exec_move(); + } return (STAT_OK); } @@ -266,7 +305,8 @@ static stat_t _action_cycle_start(float *param) * * Return STAT_OK once hold has been reached */ -static stat_t _action_hold(float *param) // p1, p2, regular and fast holds +//static stat_t _action_hold(float *param) // p1, p2, regular and fast holds +stat_t _action_hold(float *param) // p1, p2, regular and fast holds { // Not in feedhold if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { diff --git a/g2core/planner.cpp b/g2core/planner.cpp index ba4c7ba8..943cf30d 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -297,7 +297,7 @@ void mp_set_steps_to_runtime_position() * and makes keeping the queue full much easier - therefore avoiding Q starvation */ -void mp_queue_command(void(*cm_exec)(float[], bool[]), float *value, bool *flag) +void mp_queue_command(void(*cm_exec)(float *, bool *), float *value, bool *flag) { mpBuf_t *bf; diff --git a/g2core/planner.h b/g2core/planner.h index ed84c5c6..e5cd9b68 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -579,7 +579,7 @@ void mp_set_planner_position(uint8_t axis, const float position); void mp_set_runtime_position(uint8_t axis, const float position); void mp_set_steps_to_runtime_position(void); -void mp_queue_command(void(*cm_exec_t)(float[], bool[]), float *value, bool *flag); +void mp_queue_command(void(*cm_exec)(float *, bool *), float *value, bool *flag); stat_t mp_runtime_command(mpBuf_t *bf); stat_t mp_json_command(char *json_string); From 7a5b0f892f6296d09744ced7dfd93dadcb35d007 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 11 Mar 2017 18:43:26 -0500 Subject: [PATCH 182/283] Reformatting --- g2core/cycle_feedhold.cpp | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index afe326d8..44dbd600 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -137,7 +137,6 @@ typedef enum { // Operation Actions typedef stat_t (*action_exec_t)(float *); // callback to action execution function typedef struct cmAction { // struct to manage execution of operations - uint8_t number; struct cmAction *nx; // static pointer to next buffer action_exec_t func; // callback to operation action function. NULL == disabled @@ -167,16 +166,8 @@ typedef struct cmOperation { // struct to manage execution of ope }; stat_t add_action(stat_t(*action_exec)(float *), float* param) { - - if (in_operation) { // error if an operation is currently running - return (STAT_COMMAND_NOT_ACCEPTED); - } -// if (action_exec == NULL) { // illegal input -// return (STAT_INVALID_OR_MALFORMED_COMMAND); -// } - if (add == NULL) { // no more room for a new action - return (STAT_INPUT_EXCEEDS_MAX_LENGTH); - } + if (in_operation) { return (STAT_COMMAND_NOT_ACCEPTED); } // can't add + if (add == NULL) { return (STAT_INPUT_EXCEEDS_MAX_LENGTH); } // no more room add->func = action_exec; if (param != NULL) { for (uint8_t i=0; ifunc == NULL) { // not an error if nothing to run - return (STAT_NOOP); // break out of cm_operation_callback() run loop - } + if (run->func == NULL) { return (STAT_NOOP); } // not an error. This is normal in_operation = true; // disable add_action during operations stat_t status = run->func(run->param); if (status == STAT_EAGAIN) { // continuation: return with no change to action pointer From 0a466861f60bab43f3fb576c469fb5f220b1d911 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 12 Mar 2017 07:52:27 -0400 Subject: [PATCH 183/283] Converted cm_cycle_start to use operations runner; Stubbed in motion profiles --- g2core/canonical_machine.cpp | 174 +++++++++++++++++++---------------- g2core/canonical_machine.h | 27 ++++-- g2core/cycle_feedhold.cpp | 2 +- g2core/cycle_homing.cpp | 6 +- g2core/cycle_jogging.cpp | 2 +- g2core/cycle_probing.cpp | 4 +- g2core/gcode_parser.cpp | 4 +- 7 files changed, 122 insertions(+), 97 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 57f7c323..394b7345 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -111,18 +111,18 @@ #include "util.h" #include "xio.h" -/*********************************************************************************** - **** CM GLOBALS & STRUCTURE ALLOCATIONS ******************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** CM GLOBALS & STRUCTURE ALLOCATIONS ************************************************ + ****************************************************************************************/ cmMachine_t *cm; // pointer to active canonical machine cmMachine_t cm1; // canonical machine primary machine cmMachine_t cm2; // canonical machine secondary machine cmToolTable_t tt; // global tool table -/*********************************************************************************** - **** GENERIC STATIC FUNCTIONS AND VARIABLES *************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** GENERIC STATIC FUNCTIONS AND VARIABLES ******************************************** + ****************************************************************************************/ // command execution callbacks from planner queue static void _exec_offset(float *value, bool *flag); @@ -133,13 +133,13 @@ static void _exec_program_finalize(float *value, bool *flag); static int8_t _axis(const nvObj_t *nv); -/*********************************************************************************** - **** CODE ************************************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** CODE ****************************************************************************** + ****************************************************************************************/ -/*********************************************************************************** - **** Initialization *************************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Initialization ******************************************************************** + ****************************************************************************************/ /* * canonical_machine_inits() - combined cm inits * canonical_machine_init() - initialize cm struct @@ -227,7 +227,7 @@ void canonical_machine_reset_rotation(cmMachine_t *_cm) { _cm->rotation_z_offset = 0.0; } -/* +/**************************************************************************************** * canonical_machine_init_assertions() * canonical_machine_test_assertions() - test assertions, return error code if violation exists */ @@ -252,9 +252,9 @@ stat_t canonical_machine_test_assertions(cmMachine_t *_cm) return (STAT_OK); } -/*********************************************************************************** - **** Canonical Machine State Management ******************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Canonical Machine State Management ************************************************ + ****************************************************************************************/ /* * cm_set_motion_state() - adjusts active model pointer as well */ @@ -307,9 +307,9 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) return (COMBINED_PANIC); } -/*********************************************************************************** - **** Model State Getters and Setters ********************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Model State Getters and Setters *************************************************** + ****************************************************************************************/ /* These getters and setters will work on any gm model with inputs: * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct @@ -351,16 +351,17 @@ void cm_set_model_linenum(const uint32_t linenum) nv_add_object((const char *)"n"); // then add the line number to the nv list } -/*********************************************************************************** - **** COORDINATE SYSTEMS AND OFFSETS *********************************************** - *********************************************************************************** +/**************************************************************************************** + **** COORDINATE SYSTEMS AND OFFSETS **************************************************** + **************************************************************************************** * Functions to get, set and report coordinate systems and work offsets * These functions are not part of the NIST defined functions - ***********************************************************************************/ + ****************************************************************************************/ /* * cm_get_combined_offset() - return the combined offsets for an axis (G53-G59, G92, Tools) * cm_get_display_offset() - return the current display offset from pecified Gcode model - * cm_set_display_offsets() - capture combined offsets from the model into absolute values in the active Gcode dynamic model + * cm_set_display_offsets() - capture combined offsets from the model into absolute values + * in the active Gcode dynamic model * * Notes on Coordinate System and Offset functions * @@ -478,12 +479,12 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax return (mp_get_runtime_absolute_position(mr, axis)); } -/*********************************************************************************** - **** CRITICAL HELPERS ************************************************************* - *********************************************************************************** +/**************************************************************************************** + **** CRITICAL HELPERS ****************************************************************** + **************************************************************************************** * Core functions supporting the canonical machining functions * These functions are not part of the NIST defined functions - ***********************************************************************************/ + ****************************************************************************************/ /* * cm_update_model_position() - set gmx endpoint position for a traverse, feed or arc @@ -499,7 +500,7 @@ void cm_update_model_position() copy_vector(cm->gmx.position, cm->gm.target); // would be mr->gm.target if from runtime } -/* +/**************************************************************************************** * cm_deferred_write_callback() - write any changed G10 values back to persistence * * Only runs if there is G10 data to write, there is no movement, and the serial queues are quiescent @@ -523,7 +524,7 @@ stat_t cm_deferred_write_callback() return (STAT_OK); } -/* +/**************************************************************************************** * cm_set_tram() - JSON command to trigger computing the rotation matrix * cm_get_tram() - JSON query to determine if the rotation matrix is set (non-identity) * @@ -649,7 +650,7 @@ stat_t cm_get_tram(nvObj_t *nv) return (STAT_OK); } -/* +/**************************************************************************************** * cm_set_model_target() - set target vector in GM model * * This is a core routine. It handles: @@ -718,7 +719,7 @@ void cm_set_model_target(const float target[], const bool flags[]) } } -/* +/**************************************************************************************** * cm_get_soft_limits() * cm_set_soft_limits() * cm_test_soft_limits() - return error code if soft limit is exceeded @@ -761,17 +762,17 @@ stat_t cm_test_soft_limits(const float target[]) return (STAT_OK); } -/*********************************************************************************** - **** CANONICAL MACHINING FUNCTIONS ************************************************ - *********************************************************************************** +/**************************************************************************************** + **** CANONICAL MACHINING FUNCTIONS ***************************************************** + **************************************************************************************** * Organized by section number in the order they are found in NIST RS274 NGCv3 - **********************************************************************************/ + ***************************************************************************************/ -/*********************************************************************************** - **** Representation (4.3.3) ******************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Representation (4.3.3) ************************************************************ + ****************************************************************************************/ -/************************************************************************************ +/***************************************************************************************** * Representation functions that affect the Gcode model only (asynchronous) * * cm_select_plane() - G17,G18,G19 select axis plane @@ -807,7 +808,7 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode) return (STAT_OK); } -/* +/**************************************************************************************** * cm_set_g10_data() - G10 L1/L2/L10/L20 Pn (affects MODEL only) * * This function applies the offset to the GM model but does not persist the offsets @@ -943,7 +944,7 @@ static void _exec_offset(float *value, bool *flag) mp_set_runtime_display_offset(offsets); } -/* +/****************************************************************************************** * cm_set_position_by_axis() - set the position of a single axis in the model, planner and runtime * cm_reset_position_to_absolute_position() - set all positions to current absolute position in mr * @@ -981,7 +982,8 @@ void cm_reset_position_to_absolute_position(cmMachine_t *_cm) } } -/*** G28.3 functions and support *** +/**************************************************************************************** + *** G28.3 functions and support *** * * cm_set_absolute_origin() - G28.3 - model, planner and queue to runtime * _exec_absolute_origin() - callback from planner @@ -1023,7 +1025,7 @@ static void _exec_absolute_origin(float *value, bool *flag) mp_set_steps_to_runtime_position(); } -/* +/****************************************************************************************** * cm_set_origin_offsets() - G92 * cm_reset_origin_offsets() - G92.1 * cm_suspend_origin_offsets() - G92.2 @@ -1082,14 +1084,15 @@ stat_t cm_resume_origin_offsets() return (STAT_OK); } -/*********************************************************************************** - **** Free Space Motion (4.3.4) **************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Free Space Motion (4.3.4) ********************************************************* + ****************************************************************************************/ /* * cm_straight_traverse() - G0 linear rapid */ -stat_t cm_straight_traverse(const float target[], const bool flags[]) +//stat_t cm_straight_traverse(const float target[], const bool flags[]) +stat_t cm_straight_traverse(const float *target, const bool *flags, const uint8_t motion_profile) { cm->gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; @@ -1113,7 +1116,7 @@ stat_t cm_straight_traverse(const float target[], const bool flags[]) return (status); } -/*********************************************************************************** +/**************************************************************************************** * cm_set_g28_position() - G28.1 * cm_goto_g28_position() - G28 * cm_set_g30_position() - G30.1 @@ -1127,7 +1130,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm { // Go through intermediate point if one is provided while (mp_planner_is_full(mp)); // Make sure you have available buffers - ritorno(cm_straight_traverse(intermediate_target, flags)); // w/no action if no axis flags + ritorno(cm_straight_traverse(intermediate_target, flags, PROFILE_NORMAL)); // w/no action if no axis flags // If G20 adjust stored position (always in mm) to inches so traverse will be correct float target[AXES]; // make a local stored position as it may be modified @@ -1147,7 +1150,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm cm_set_distance_mode(ABSOLUTE_DISTANCE_MODE); // Must run in absolute distance mode bool flags2[] = { 1,1,1,1,1,1 }; - stat_t status = cm_straight_traverse(target, flags2); // Go to stored position + stat_t status = cm_straight_traverse(target, flags2, PROFILE_NORMAL); // Go to stored position cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_OFF); cm_set_distance_mode(saved_distance_mode); // Restore distance mode return (status); @@ -1175,9 +1178,9 @@ stat_t cm_goto_g30_position(const float target[], const bool flags[]) return (_goto_stored_position(cm->gmx.g30_position, target, flags)); } -/*********************************************************************************** - **** Machining Attributes (4.3.5) ************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Machining Attributes (4.3.5) ****************************************************** + ****************************************************************************************/ /* * cm_set_feed_rate() - F parameter (affects MODEL only) * @@ -1197,7 +1200,7 @@ stat_t cm_set_feed_rate(const float feed_rate) return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * cm_set_feed_rate_mode() - G93, G94 (affects MODEL only) * * INVERSE_TIME_MODE = 0, // G93 @@ -1211,7 +1214,7 @@ stat_t cm_set_feed_rate_mode(const uint8_t mode) return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * cm_set_path_control() - G61, G61.1, G64 */ @@ -1221,14 +1224,14 @@ stat_t cm_set_path_control(GCodeState_t *gcode_state, const uint8_t mode) return (STAT_OK); } -/*********************************************************************************** - **** Machining Functions (4.3.6) ************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Machining Functions (4.3.6) ******************************************************* + ****************************************************************************************/ /* * cm_arc_feed() - SEE plan_arc.cpp */ -/*********************************************************************************** +/**************************************************************************************** * cm_dwell() - G4, P parameter (seconds) */ stat_t cm_dwell(const float seconds) @@ -1238,10 +1241,12 @@ stat_t cm_dwell(const float seconds) return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * cm_straight_feed() - G1 */ -stat_t cm_straight_feed(const float target[], const bool flags[]) +//stat_t cm_straight_feed(const float target[], const bool flags[]) +//stat_t cm_straight_feed(const float *target, const bool *flags) +stat_t cm_straight_feed(const float *target, const bool *flags, const uint8_t motion_profile) { // trap zero feed rate condition if (fp_ZERO(cm->gm.feed_rate)) { @@ -1573,15 +1578,12 @@ static void _exec_program_finalize(float *value, bool *flag) void cm_cycle_start() { -#if (1) // +++++ cm_request_operation(OPERATION_CYCLE_START, nullptr); -#else - if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles - cm->cycle_type = CYCLE_MACHINING; - cm->machine_state = MACHINE_CYCLE; - qr_init_queue_report(); // clear queue reporting buffer counts - } -#endif +// if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles +// cm->cycle_type = CYCLE_MACHINING; +// cm->machine_state = MACHINE_CYCLE; +// qr_init_queue_report(); // clear queue reporting buffer counts// +// } } void cm_cycle_end() @@ -1618,7 +1620,7 @@ void cm_program_end() } /*********************************************************************************** - **** Additional Fucntions ********************************************************* + **** Additional Functions ********************************************************* ***********************************************************************************/ /* * cm_json_command() - M100 @@ -2089,8 +2091,8 @@ stat_t cm_get_ra(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].radius)); stat_t cm_set_ra(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].radius, RADIUS_MIN, 1000000)); } /**** Axis Jerk Primitives - * cm_get_axis_jerk() - returns jerk for an axis - * cm_set_axis_jerk() - sets the jerk for an axis, including recirpcal and cached values + * cm_get_axis_jerk() - returns max jerk for an axis + * cm_set_axis_jerk() - sets the jerk for an axis, including reciprocal and cached values */ float cm_get_axis_jerk(const uint8_t axis) { return (cm->a[axis].jerk_max); } @@ -2100,17 +2102,23 @@ static const float _junction_accel_multiplier = sqrt(3.0)/10.0; // Important note: Actual jerk is stored jerk * JERK_MULTIPLIER, and // Time Quanta is junction_integration_time / 1000. -void _cm_recalc_max_junction_accel(const uint8_t axis) { +void _cm_recalc_junction_accel(const uint8_t axis) { float T = cm->junction_integration_time / 1000.0; float T2 = T*T; cm->a[axis].max_junction_accel = _junction_accel_multiplier * T2 * (cm->a[axis].jerk_max * JERK_MULTIPLIER); + cm->a[axis].high_junction_accel = _junction_accel_multiplier * T2 * (cm->a[axis].jerk_high * JERK_MULTIPLIER); } -void cm_set_axis_jerk(const uint8_t axis, const float jerk) +void cm_set_axis_max_jerk(const uint8_t axis, const float jerk) { cm->a[axis].jerk_max = jerk; - _cm_recalc_max_junction_accel(axis); // Must recalculate the max_junction_accel now that the jerk has changed. + _cm_recalc_junction_accel(axis); // Must recalculate the max_junction_accel now that the jerk has changed. +} +void cm_set_axis_high_jerk(const uint8_t axis, const float jerk) +{ + cm->a[axis].jerk_high = jerk; + _cm_recalc_junction_accel(axis); // Must recalculate the max_junction_accel now that the jerk has changed. } /**** Axis Velocity and Jerk Settings @@ -2156,13 +2164,19 @@ stat_t cm_set_jm(nvObj_t *nv) { uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].jerk_max, JERK_INPUT_MIN, JERK_INPUT_MAX)); - cm_set_axis_jerk(axis, nv->value); + cm_set_axis_max_jerk(axis, nv->value); return(STAT_OK); } stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].jerk_high)); } -stat_t cm_set_jh(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); } - +stat_t cm_set_jh(nvObj_t *nv) +// { return (set_float_range(nv, cm->a[_axis(nv)].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); } +{ + uint8_t axis = _axis(nv); + ritorno(set_float_range(nv, cm->a[axis].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); + cm_set_axis_high_jerk(axis, nv->value); + return(STAT_OK); +} /**** Axis Homing Settings * cm_get_hi() - get homing input @@ -2214,7 +2228,7 @@ stat_t cm_set_jt(nvObj_t *nv) { ritorno(set_float_range(nv, cm->junction_integration_time, JUNCTION_INTEGRATION_MIN, JUNCTION_INTEGRATION_MAX)); for (uint8_t axis=0; axisfeedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode - cm_straight_traverse(target, flags); + cm_straight_traverse(target, flags, PROFILE_NORMAL); cm_set_distance_mode(cm1.gm.distance_mode); // restore distance mode to p1 setting } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index ec3244ac..f2041e69 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -300,7 +300,7 @@ static stat_t _homing_axis_clear_init(int8_t axis) // first clear move */ static stat_t _homing_axis_search(int8_t axis) // drive to switch { - cm_set_axis_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for search onward + cm_set_axis_max_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for search onward _homing_axis_move(axis, hm.search_travel, hm.search_velocity); return (_set_homing_func(_homing_axis_clear)); } @@ -346,7 +346,7 @@ static stat_t _homing_axis_set_position(int8_t axis) kn_forward_kinematics(en_get_encoder_snapshot_vector(), contact_position); _homing_axis_move(axis, contact_position[AXIS_Z], hm.search_velocity); } - cm_set_axis_jerk(axis, hm.saved_jerk); // restore the max jerk value + cm_set_axis_max_jerk(axis, hm.saved_jerk); // restore the max jerk value gpio_set_homing_mode(hm.homing_input, false); // end homing mode return (_set_homing_func(_homing_axis_start)); @@ -371,7 +371,7 @@ static stat_t _homing_axis_move(int8_t axis, float target, float velocity) { flags[axis] = true; cm_set_feed_rate(velocity); - stat_t status = cm_straight_feed(vect, flags); + stat_t status = cm_straight_feed(vect, flags, PROFILE_FAST); if (status != STAT_OK) { rpt_exception(status, "Homing move failed. Check min/max settings"); return (_homing_error_exit(axis, STAT_HOMING_CYCLE_FAILED)); diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index ccc4f664..e9e4251b 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -183,7 +183,7 @@ static stat_t _jogging_axis_move(int8_t axis, float target, float velocity) { vect[axis] = target; flags[axis] = true; cm_set_feed_rate(velocity); - ritorno(cm_straight_feed(vect, flags)); + ritorno(cm_straight_feed(vect, flags, PROFILE_FAST)); return (STAT_EAGAIN); } diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index a9337d2e..87181a07 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -222,7 +222,7 @@ static uint8_t _probing_start() // Save the current jerk settings & change to the high-speed jerk settings for (uint8_t axis = 0; axis < AXES; axis++) { pb.saved_jerk[axis] = cm_get_axis_jerk(axis); // save the max jerk value - cm_set_axis_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for probe + cm_set_axis_max_jerk(axis, cm->a[axis].jerk_high); // use the high-speed jerk for probe } // Error if the probe target is too close to the current position @@ -285,7 +285,7 @@ static stat_t _probe_move(const float target[], const bool flags[]) { cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); pb.wait_for_motion_end = true; // set this BEFORE the motion starts - cm_straight_feed(target, flags); // NB: feed rate was set earlier, so it's OK + cm_straight_feed(target, flags, PROFILE_FAST); // NB: feed rate was set earlier, so it's OK mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway return (STAT_EAGAIN); } diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 7b6d8309..67252900 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -829,8 +829,8 @@ static stat_t _execute_gcode_block(char *active_comment) cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override & display as absolute switch (gv.motion_mode) { case MOTION_MODE_CANCEL_MOTION_MODE: { cm->gm.motion_mode = gv.motion_mode; break;} // G80 - case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gv.target, gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target); break;} // G1 + case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gv.target, gf.target, PROFILE_NORMAL); break;} // G0 + case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target, PROFILE_NORMAL); break;} // G1 case MOTION_MODE_CW_ARC: // G2 case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gv.target, gf.target, // G3 gv.arc_offset, gf.arc_offset, From 16fc941e0cde19a0b6ac31fbb709ae5b36b62941 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 13 Mar 2017 09:20:45 -0400 Subject: [PATCH 184/283] Checkpoint --- g2core/canonical_machine.cpp | 12 +- g2core/canonical_machine.h | 15 +- g2core/controller.cpp | 5 +- g2core/cycle_feedhold.cpp | 353 +++++++++++++++++++++++++---------- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 5 +- 6 files changed, 285 insertions(+), 109 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 394b7345..a084883d 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1578,12 +1578,12 @@ static void _exec_program_finalize(float *value, bool *flag) void cm_cycle_start() { - cm_request_operation(OPERATION_CYCLE_START, nullptr); -// if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles -// cm->cycle_type = CYCLE_MACHINING; -// cm->machine_state = MACHINE_CYCLE; -// qr_init_queue_report(); // clear queue reporting buffer counts// -// } +// cm_request_operation(OPERATION_CYCLE_START, nullptr); + if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles + cm->cycle_type = CYCLE_MACHINING; + cm->machine_state = MACHINE_CYCLE; + qr_init_queue_report(); // clear queue reporting buffer counts// + } } void cm_cycle_end() diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index d1cebb99..6cbf31e6 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -134,16 +134,25 @@ typedef enum { // cycle start and feedhold requests typedef enum { // feedhold state machine FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect - FEEDHOLD_INITIATED, // feedhold has been requested but not started yet +// FEEDHOLD_INITIATED, // feedhold has been requested but not started yet FEEDHOLD_SYNC, // start hold - sync to latest aline segment FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet FEEDHOLD_MOTION_STOPPING, // waiting for motors to have stopped at hold point (motion stop) FEEDHOLD_MOTION_STOPPED, // motion has stopped at hold point - FEEDHOLD_P2_START, // enter secondary planner and perform feedhold actions (once) - FEEDHOLD_P2_WAIT, // wait for feedhold actions to complete +// FEEDHOLD_P2_START, // enter secondary planner and perform feedhold actions (once) +// FEEDHOLD_P2_WAIT, // wait for feedhold actions to complete + + FEEDHOLD_HOLD_ACTION_START, + FEEDHOLD_HOLD_PENDING, // wait for feedhold actions to complete + FEEDHOLD_HOLD_DONE, // + FEEDHOLD_HOLD, // holding (steady state) Must be last state + + FEEDHOLD_HOLD_EXIT_PENDING, // performing exit actions + FEEDHOLD_HOLD_EXIT_DONE, // completed exit actions + FEEDHOLD_P2_EXIT // set when p2 feedhold is finishing } cmFeedholdState; diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 357b5708..57b6e452 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -159,10 +159,11 @@ static void _controller_HSM() DISPATCH(sr_status_report_callback()); // conditionally send status report DISPATCH(qr_queue_report_callback()); // conditionally send queue report - DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner - DISPATCH(cm_operation_callback()); // operation action runner +// DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines + DISPATCH(cm_operation_callback()); // operation action runner + DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 8905a634..3795e172 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -38,21 +38,23 @@ #include "util.h" //#include "xio.h" // DIAGNOSTIC -static stat_t _run_p1_hold_entry_actions(void); -static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); +//static stat_t _run_p1_hold_entry_actions(void); +//static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); -static stat_t _run_p1_hold_exit_actions(void); -static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); -static void _feedhold_p1_exit(void); -static void _feedhold_p2_exit(void); -static void _feedhold_abort(void); +//static stat_t _run_p1_hold_exit_actions(void); +//static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); +//static void _feedhold_p1_exit(void); +//static void _feedhold_p2_exit(void); +//static void _feedhold_abort(void); -stat_t _action_cycle_start(float *param); -stat_t _action_hold(float *param); +//static stat_t _action_cycle_start(float *param); +//static stat_t _action_hold_no_actions(float *param); +static stat_t _action_hold_with_actions(float *param); +//static stat_t _action_hold_exit_no_actions(float *param); +static stat_t _action_hold_exit_with_actions(float *param); //static stat_t _action_halt(float *param); //static stat_t _action_p2_entry(float* param); -//static stat_t _action_p2_exit(float *param); //static stat_t _action_parking_move(float *param); //static stat_t _action_return_move(float *param); //static stat_t _action_spindle_control(float *param); @@ -113,21 +115,21 @@ typedef enum { // Operation Actions } cmOpAction; /**************************************************************************************** - * Operations work by queueing a set of actions, then running then in sequence until the - * operation is complete or an error occurs. Works like this: + * OPERATIONS AND ACTIONS * - * - Invoke an operation by calling cm_request_operation(); may require one or more parameters - * - The operation runner must be idle: an operation cannot interrupt a currently running operation - * - Future may need Cancel Operation semantics, but this could get overcomplicated quickly + * Operations work by queueing a set of actions, then running them in sequence until + * the operation is complete or an error occurs. * - * - When a new operation is requested the operations runner object is cleared and one or - * more actions are queued by calling add_action() on the object. + * Actions are coded to return: + * STAT_OK - successful completion of the action + * STAT_EAGAIN - ran to continuation - the action needs to be called again to complete + * STAT_XXXXX - any other status is an error that quits the operation * - * - To start the operation immediately call run_action() at the end of the request. - * Otherwise the operation will begin the next time cm_operation_callback(). - * - * It is assumed that all actions are added at once, and that this cannot be interrupted - * by a run request. So no attempt is made at mutual exclusion. Just behave. + * run_operation returns: + * STAT_NOOP - no operation is set up, but it's OK to call the operation runner + * STAT_OK - operation has completed successfully + * STAT_EAGAIN - operation needs to be re-entered to complete (via operation callback) + * STAT_XXXXX - any other status is an error that quits the operation */ /*** Object Definitions ***/ @@ -137,17 +139,17 @@ typedef enum { // Operation Actions typedef stat_t (*action_exec_t)(float *); // callback to action execution function typedef struct cmAction { // struct to manage execution of operations - uint8_t number; + uint8_t number; // DIAGNOSTIC for easier debugging. Not used functionally. struct cmAction *nx; // static pointer to next buffer action_exec_t func; // callback to operation action function. NULL == disabled float param[PARAM_MAX]; // parameters for the function - void reset() { // clears this structure (except the pointer) + void reset() { // clears function pointer func = NULL; }; } cmAction_t; -typedef struct cmOperation { // struct to manage execution of operations +typedef struct cmOperation { // operation runner object cmAction action[ACTION_MAX]; // singly linked list of action control structures cmAction *add; // pointer to next action to be added @@ -157,12 +159,13 @@ typedef struct cmOperation { // struct to manage execution of ope void reset(void) { for (uint8_t i=0; i < ACTION_MAX; i++) { action[i].reset(); // reset the action controller object - action[i].number = i; + action[i].number = i; // DIAGNOSTIC only. Otherwise not used action[i].nx = &action[i+1]; // link to the next action } action[ACTION_MAX-1].nx = NULL; // set last action (end of list) - add = action; + add = action; // initialize pointers to first action struct run = action; + in_operation = false; }; stat_t add_action(stat_t(*action_exec)(float *), float* param) { @@ -179,40 +182,58 @@ typedef struct cmOperation { // struct to manage execution of ope }; stat_t run_operation(void) { - if (run->func == NULL) { return (STAT_NOOP); } // not an error. This is normal + if (run->func == NULL) { return (STAT_NOOP); } // not an error. This is normal. in_operation = true; // disable add_action during operations - stat_t status = run->func(run->param); - if (status == STAT_EAGAIN) { // continuation: return with no change to action pointer - return (status); - } - if (status == STAT_OK) { // current action complete, advance to next action - run = run->nx; - if (run->func != NULL) { // action is complete but operation is not yet complete + + stat_t status; + while ((status = run->func(run->param)) == STAT_OK) { + if ((run = run->nx) == NULL) { // operation has completed + reset(); // setup for next operation return (STAT_OK); } - in_operation = false; - status = STAT_COMPLETE; // break out of the cm_operation_callback() run loop } - reset(); // reset the operation if complete or if action threw an error - return (status); // return error or COMPLETE + if (status == STAT_EAGAIN) { return (STAT_EAGAIN); } + reset(); // reset operation if action threw an error + return (status); // return error code }; - + } cmOperation_t; -cmOperation_t op; // operations runner +cmOperation_t op; // operations runner object +/**************************************************************************************** + * cm_operation_init() + * cm_operation_callback() + */ void cm_operation_init() { op.reset(); } +stat_t cm_operation_callback() +{ + return (op.run_operation()); +} + /**************************************************************************************** **** Operations ************************************************************************ ****************************************************************************************/ /**************************************************************************************** * cm_request_operation() - * cm_operation_callback() + * + * Invoke an operation by calling cm_request_operation(); may require one or more parameters + * - The operation runner must be idle: an operation cannot interrupt a currently running operation + * - Future may need Cancel Operation semantics, but this could get overcomplicated quickly + * + * When a new operation is requested the operations runner object is cleared and one or + * more actions are queued by calling add_action() on the object. + * + * To start the operation immediately call run_action() at the end of the request. + * Otherwise the operation will begin the next time cm_operation_callback(). + * + * It is assumed that all actions are added at once, and that this cannot be interrupted + * by a run request. So no attempt is made at mutual exclusion. Just behave. * * Operations are defined as: * @@ -232,14 +253,14 @@ stat_t cm_request_operation(cmOperationType operation, float *param) switch (operation) { - case OPERATION_CYCLE_START: { - op.add_action(_action_cycle_start, nullptr); - return(op.run_operation()); - } +// case OPERATION_CYCLE_START: { +// op.add_action(_action_cycle_start, nullptr); +// return(op.run_operation()); +// } // Generate hold request if not already in a hold and machine is in motion case OPERATION_HOLD: { - op.add_action(_action_hold, param); + op.add_action(_action_hold_with_actions, param); break; } @@ -250,51 +271,43 @@ stat_t cm_request_operation(cmOperationType operation, float *param) return (STAT_OK); } -stat_t cm_operation_callback() -{ - stat_t status = STAT_OK; - while ((status = op.run_operation()) == STAT_OK); - - return (status); -} - /**************************************************************************************** - * cm_action_functions - * - * Coding an action: - * - * Actions can complete in one call or take multiple calls (continuations). - * In the latter case they will be called multiple times by the action runner. - * The returned status defines this: - * - * STAT_OK - signals completion of the action. Runner will run the next action - * STAT_EAGAIN - signals that the action needs to be called again later to complete - * STAT_(anything else) - aborts the operation - */ - -/* + * request_cycle_start() * _action_cycle_start() - start a cycle or restart from hold */ -//static stat_t _action_cycle_start(float *param) -stat_t _action_cycle_start(float *param) + +stat_t request_cycle_start() { -// cm_cycle_start(); - if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles + // Normal cycle start - not in a feedhold + if (cm1.hold_state != FEEDHOLD_OFF) { + cm_cycle_start(); // execute cycle start directly + st_request_exec_move(); + } + + // Feedhold cycle starts run an operation to complete multiple actions + op.add_action(_action_hold_exit_with_actions, nullptr); + return(op.run_operation()); +} + +/* +static stat_t _action_cycle_start(float *param) +{ + if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles cm->cycle_type = CYCLE_MACHINING; cm->machine_state = MACHINE_CYCLE; -// qr_init_queue_report(); // clear queue reporting buffer counts st_request_exec_move(); } return (STAT_OK); } +*/ /* - * _action_hold() - initiate a feedhold in the active planner - p1 or p2 + * _action_hold_with_actions() - initiate a feedhold in the active planner - p1 or p2 * * Return STAT_OK once hold has been reached */ -//static stat_t _action_hold(float *param) // p1, p2, regular and fast holds -stat_t _action_hold(float *param) // p1, p2, regular and fast holds +/* +static stat_t _action_hold_with_actions(float *param) { // Not in feedhold if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { @@ -311,11 +324,10 @@ stat_t _action_hold(float *param) // p1, p2, regular and fast holds return (STAT_OK); } - +*/ //static stat_t _action_halt(float *param) { return (STAT_OK); } //static stat_t _action_p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled -//static stat_t _action_p2_exit(float *param) { return (STAT_OK); } // p2 exit actions, bundled //static stat_t _action_parking_move(float *param) { return (STAT_OK); } //static stat_t _action_return_move(float *param) { return (STAT_OK); } //static stat_t _action_spindle_control(float *param) { return (STAT_OK); } @@ -424,17 +436,18 @@ bool cm_has_hold() * Pre-defined exit actions (coolant, spindle, Z move) are completed first * Any executing or pending "in-hold" moves are stopped prior to the exit actions */ - +/* void cm_request_feedhold(void) // ! { // Only generate request if not already in a feedhold and the machine is in motion if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_state = FEEDHOLD_INITIATED; // signal request to state machine + cm1.hold_state = FEEDHOLD_INITIATED; // signal request to state machine } else if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { cm2.hold_state = FEEDHOLD_INITIATED; } } +*/ void cm_request_exit_hold(void) // ~ { @@ -484,7 +497,7 @@ stat_t cm_feedhold_command_blocker() * (in-cycle) !%~ Same as above * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) */ - +/* stat_t cm_feedhold_sequencing_callback() { // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions @@ -538,7 +551,7 @@ stat_t cm_feedhold_sequencing_callback() } return (STAT_OK); } - +*/ /**************************************************************************************** * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold * _sync_to_p1_hold_entry_actions_done() - final state change occurs here @@ -556,6 +569,96 @@ stat_t cm_feedhold_sequencing_callback() * from an interrupt, so it only sets a flag. */ + +/**************************************************************************************** + * request_feedhold() - initiate a feedhold + * _action_hold_sync() - planner callback to reach sync point + * _action_hold_with_actions() - perform hold entry actions + */ + +void cm_request_feedhold(void) // ! +{ + // Only generate P1 feedhold if not already in a feedhold and the machine is in motion + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + op.add_action(_action_hold_with_actions, nullptr); // do this first for safety + cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec +// op.run_operation(); + } else + + // P2 feedhold + if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { + cm2.hold_state = FEEDHOLD_SYNC; + } +} + +static void _action_hold_sync(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD_DONE; // penultimate state before transitioning to FEEDHOLD_HOLD + sr_request_status_report(SR_REQUEST_IMMEDIATE); +} + +static stat_t _action_hold_with_actions(float *param) // Execute Case (5) +{ + // Check to run first-time code + if (cm1.hold_state == FEEDHOLD_HOLD_ACTION_START) { + cm->hold_state = FEEDHOLD_HOLD_PENDING; // next state + + // copy the primary canonical machine to the secondary, + // fix the planner pointer, and reset the secondary planner + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // set parameters in cm, gm and gmx so you can actually use it + cm2.hold_state = FEEDHOLD_OFF; + cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + cm2.flush_state = FLUSH_OFF; + cm2.gm.feed_rate = 0; + + // clear the target and set the positions to the current hold position + memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); + memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); + copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation + copy_vector(cm2.gmx.position, mr1.position); + copy_vector(mp2.position, mr1.position); + copy_vector(mr2.position, mr1.position); + + // reassign the globals to the secondary CM + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer + mr = mp->mr; + + // set a return position + cm_set_g30_position(); + + // execute feedhold actions + if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift + cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); + bool flags[] = { 0,0,1,0,0,0 }; + float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode + cm_straight_traverse(target, flags, PROFILE_NORMAL); + cm_set_distance_mode(cm1.gm.distance_mode); // restore distance mode to p1 setting + } + spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause + coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause + mp_queue_command(_action_hold_sync, nullptr, nullptr); + return (STAT_EAGAIN); + } + + // wait for hold actions to complete + if (cm1.hold_state == FEEDHOLD_HOLD_PENDING) { + return (STAT_EAGAIN); + } + + // finalize feedhold exit + if (cm1.hold_state == FEEDHOLD_HOLD_DONE) { + cm1.hold_state = FEEDHOLD_HOLD; + return (STAT_OK); + } + return (STAT_EAGAIN); +} +/* static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) // Complete case (5) { cm1.hold_state = FEEDHOLD_HOLD; @@ -600,7 +703,7 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 cm_set_g30_position(); - cm_set_motion_state(MOTION_STOP); // sets cm2 active model to MODEL +// cm_set_motion_state(MOTION_STOP); // sets cm2 active model to MODEL // execute feedhold actions if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift @@ -615,7 +718,7 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); return (STAT_OK); } - +*/ /**************************************************************************************** * _run_p1_hold_exit_actions() - initiate return from feedhold planner * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations @@ -629,6 +732,68 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) * the sync runs from an interrupt. Finalization needs to run from the main loop. */ +/**************************************************************************************** + * _action_hold_exit_sync() - planner callback to reach sync point + * _action_hold_exit_with_actions() - perform hold exit actions + */ + +static void _action_hold_exit_sync(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD_EXIT_DONE; // penultimate state before transitioning to FEEDHOLD_OFF + sr_request_status_report(SR_REQUEST_IMMEDIATE); +} + +static stat_t _action_hold_exit_with_actions(float *param) // Execute Cases (6) and (7) +{ + // Check to run first-time code + if (cm1.hold_state == FEEDHOLD_HOLD) { + // perform end-hold actions --- while still in secondary machine + coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused + spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused + + // do return move though an intermediate point; queue a wait + cm2.return_flags[AXIS_Z] = false; + cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); + mp_queue_command(_action_hold_exit_sync, nullptr, nullptr); + cm1.hold_state = FEEDHOLD_HOLD_EXIT_PENDING; + return (STAT_EAGAIN); + } + + // wait for exit actions to complete + if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_PENDING) { + return (STAT_EAGAIN); + } + + // finalize feedhold exit + if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_DONE) { + + // return to primary planner (p1) + cm = &cm1; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + + // execute this block if a queue flush was performed + // adjust p1 planner positions to runtime positions + if (cm1.flush_state == FLUSH_WAS_RUN) { + cm_reset_position_to_absolute_position(cm); + cm1.flush_state = FLUSH_OFF; + } + + // resume motion from primary planner or end cycle if no moves in planner + if (mp_has_runnable_buffer(&mp1)) { +// cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); + } else { +// cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); + } + cm1.hold_state = FEEDHOLD_OFF; + return (STAT_OK); + } + return (STAT_EAGAIN); +} +/* static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) { // do not perform exit actions if feedhold abort in progress @@ -682,22 +847,22 @@ static void _feedhold_p1_exit() // resume motion from primary planner or end cycle if no moves in planner if (mp_has_runnable_buffer(&mp1)) { - cm_set_motion_state(MOTION_RUN); +// cm_set_motion_state(MOTION_RUN); cm_cycle_start(); st_request_exec_move(); } else { - cm_set_motion_state(MOTION_STOP); +// cm_set_motion_state(MOTION_STOP); cm_cycle_end(); } cm1.hold_state = FEEDHOLD_OFF; } - +*/ /**************************************************************************************** * _feedhold_p2_exit() - exit from a feedhold in feedhold (from p2) * * Assumes planner is in p2 on entry */ - +/* static void _feedhold_p2_exit() { float position[AXES]; @@ -707,11 +872,11 @@ static void _feedhold_p2_exit() cm_reset_position_to_absolute_position(&cm2); // propagate position cm2.hold_state = FEEDHOLD_OFF; - cm_set_motion_state(MOTION_STOP); +// cm_set_motion_state(MOTION_STOP); cm_cycle_end(); sr_request_status_report(SR_REQUEST_IMMEDIATE); } - +*/ /**************************************************************************************** * _feedhold_abort() - used to exit a feedhold without completing exit actions * @@ -727,7 +892,7 @@ static void _feedhold_p2_exit() * Case (5) In a feedhold and currently moving in P2 * Case (6) In a feedhold and currently executing P2 exit actions */ - +/* static void _feedhold_abort() { // Exit if not in a feedhold @@ -759,12 +924,12 @@ static void _feedhold_abort() } // end cycle - cm_set_motion_state(MOTION_STOP); +// cm_set_motion_state(MOTION_STOP); // cm_cycle_end(); cm1.hold_state = FEEDHOLD_OFF; cm1.hold_abort_requested = false; } - +*/ /**************************************************************************************** * Queue Flush operations * diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..bb1cf7a0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 982db6b8..be9304fe 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -485,7 +485,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->hold_state != FEEDHOLD_OFF) { // if FEEDHOLD_P2_START, FEEDHOLD_P2_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT - if (cm->hold_state >= FEEDHOLD_P2_START) { // handles _exec_aline_feedhold_processing case (7) +// if (cm->hold_state >= FEEDHOLD_P2_START) { // handles _exec_aline_feedhold_processing case (7) + if (cm->hold_state >= FEEDHOLD_HOLD_ACTION_START) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } // STAT_OK terminates aline execution for this move @@ -1056,7 +1057,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) st_request_forward_plan(); // replan the current bf buffer // Set state to enable transition to p2 and perform entry actions in the p2 planner - cm->hold_state = FEEDHOLD_P2_START; // executes entirely out of p2 planner + cm->hold_state = FEEDHOLD_HOLD_ACTION_START; // signal operations runner to start actions } sr_request_status_report(SR_REQUEST_IMMEDIATE); From b1f7fa8ca65c929e0501438859f3cd70d4815e9b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 13 Mar 2017 15:02:25 -0400 Subject: [PATCH 185/283] checkpoint --- g2core/alarm.cpp | 46 +- g2core/canonical_machine.cpp | 8 +- g2core/canonical_machine.h | 92 +-- g2core/config_app.cpp | 2 +- g2core/controller.cpp | 14 +- g2core/cycle_feedhold.cpp | 1029 +++++++++++++++++++--------------- g2core/gpio.cpp | 2 +- g2core/plan_exec.cpp | 2 +- g2core/temperature.cpp | 1 - 9 files changed, 666 insertions(+), 530 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index ed6e5d52..f38ffd4c 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -112,7 +112,7 @@ stat_t cm_is_alarmed() } /**************************************************************************************** - * cm_halt_all() - stop, spindle and coolant immediately + * cm_halt() - stop motion, spindle, coolant and heaters immediately * cm_halt_motion() - stop motion immediately. Does not affect spindle, coolant, or other IO * * Stop motors and reset all system states accordingly. @@ -120,11 +120,12 @@ stat_t cm_is_alarmed() * in order to prevent an axis from crashing. */ -void cm_halt_all(void) +void cm_halt(void) { cm_halt_motion(); spindle_control_immediate(SPINDLE_OFF); coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); + temperature_init(); } void cm_halt_motion(void) @@ -165,19 +166,8 @@ stat_t cm_alarm(const stat_t status, const char *msg) (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't alarm if already in an alarm state } - cm1.machine_state = MACHINE_ALARM; // alarm both machines - cm2.machine_state = MACHINE_ALARM; - cm_request_feedhold(); // stop motion - cm_request_queue_flush(); // do a queue flush once runtime is not busy - -// TBD - these functions should probably be called - See cm_shutdown() -// cm_spindle_control_immediate(SPINDLE_OFF); -// cm_coolant_off_immediate(); -// cm_spindle_optional_pause(spindle.pause_on_hold); -// cm_coolant_optional_pause(coolant.pause_on_hold); - rpt_exception(status, msg); // send alarm message - - // If "stat" is in the status report, we need to poke it to send. + cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_FINAL_ALARM); // fast stop and alarm + rpt_exception(status, msg); // send alarm message sr_request_status_report(SR_REQUEST_TIMED); return (status); } @@ -204,20 +194,23 @@ stat_t cm_shutdown(const stat_t status, const char *msg) if ((cm->machine_state == MACHINE_SHUTDOWN) || (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't shutdown if shutdown or panic'd } - cm_halt_motion(); // halt motors (may have already been done from GPIO) - spindle_reset(); // stop spindle immediately and set speed to 0 RPM - coolant_reset(); // stop coolant immediately - temperature_reset(); // turn off heaters and fans - cm_queue_flush(&cm1); // flush all queues and reset positions + cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_FINAL_SHUTDOWN); // fast stop and shutdown + +// cm_halt_motion(); // halt motors (may have already been done from GPIO) +// spindle_reset(); // stop spindle immediately and set speed to 0 RPM +// coolant_reset(); // stop coolant immediately +// temperature_reset(); // turn off heaters and fans +// cm_queue_flush(&cm1); // flush all queues and reset positions for (uint8_t i = 0; i < HOMING_AXES; i++) { // unhome axes and the machine cm->homed[i] = false; } cm->homing_state = HOMING_NOT_HOMED; - cm1.machine_state = MACHINE_SHUTDOWN; // shut down both machines... - cm2.machine_state = MACHINE_SHUTDOWN; //...do this after all other activity +// cm1.machine_state = MACHINE_SHUTDOWN; // shut down both machines... +// cm2.machine_state = MACHINE_SHUTDOWN; //...do this after all other activity rpt_exception(status, msg); // send exception report + sr_request_status_report(SR_REQUEST_TIMED); return (status); } @@ -256,12 +249,5 @@ stat_t cm_panic(const stat_t status, const char *msg) void cm_job_kill() { - cm1.hold_abort_requested = true; - cm_program_end(); - -// if (cm->machine_state == MACHINE_ALARM) { -// cm->machine_state = MACHINE_PROGRAM_STOP; -// } else if (cm->machine_state == MACHINE_SHUTDOWN) { -// cm->machine_state = MACHINE_READY; -// } + cm1.request_job_kill = true; } diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a084883d..8f34252d 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -192,12 +192,15 @@ void canonical_machine_reset(cmMachine_t *_cm) // reset request flags _cm->flush_state = FLUSH_OFF; - _cm->hold_exit_requested = false; _cm->limit_requested = 0; // resets switch closures that occurred during initialization _cm->safety_interlock_disengaged = 0; // ditto _cm->safety_interlock_reengaged = 0; // ditto _cm->shutdown_requested = 0; // ditto + _cm->request_interlock = false; + _cm->request_interlock_exit = false; + _cm->request_job_kill = false; + // set initial state and signal that the machine is ready for action _cm->cycle_type = CYCLE_NONE; _cm->motion_state = MOTION_STOP; @@ -1731,12 +1734,13 @@ char cm_get_axis_char(const int8_t axis) * cm_run_qf() - flush planner queue * cm_run_home() - run homing sequence */ - +/* stat_t cm_run_qf(nvObj_t *nv) { cm_request_queue_flush(); return (STAT_OK); } +*/ stat_t cm_run_home(nvObj_t *nv) { diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 6cbf31e6..d60d511c 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -98,6 +98,12 @@ typedef enum { MOTION_RUN // machine is in motion: set when the steppers execute an ALINE segment } cmMotionState; +typedef enum { // state machine for cycle start + CYCLE_START_NONE = 0, // not in a cycle + CYCLE_START_REQUESTED, + CYCLE_START_COMPLETE +} cmCycleState; + typedef enum { CYCLE_NONE = 0, // not in a cycle CYCLE_MACHINING, // in normal machining cycle @@ -108,33 +114,27 @@ typedef enum { // ... } cmCycleType; -typedef enum { // cycle start and feedhold requests - OPERATION_NULL = 0, // no operation; reverts here when complete - OPERATION_CYCLE_START, // perform a cycle start with no other actions - OPERATION_HOLD, // feedhold in p1 or p2 with no entry actions -// OPERATION_HOLD_WITH_ACTIONS,// feedhold into p2 with entry actions -// OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 -// OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush - OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner - OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner - OPERATION_JOB_KILL, // fast hold followed by queue flush and program end - OPERATION_END_JOG, // fast hold followed by program stop - OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit - OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit - OPERATION_SHUTDOWN, // actions to run when a shutdown is received - OPERATION_PANIC, // actions to run when a panic is received - OPERATION_INTERLOCK_START, // enter an interlock state - OPERATION_INTERLOCK_END, // exit interlocked state - OPERATION_DI_FUNC_STOP, // run digital input STOP function - OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function - OPERATION_DI_FUNC_HALT, // run digital input HALT function - OPERATION_TOOL_CHANGE // run a tool change sequence -} cmOperationType; +typedef enum { // feedhold type parameter + FEEDHOLD_TYPE_ACTIONS = 0, // feedhold at max jerk with actions + FEEDHOLD_TYPE_NO_ACTIONS, // feedhold at max jerk with no actions + FEEDHOLD_TYPE_SYNC, // feedhold at max jerk with queue flush and sync command + FEEDHOLD_TYPE_FAST, // feedhold at high jerk with no actions. Can resume + FEEDHOLD_TYPE_SCRAM // feedhold at high jerk and stop all active devices +} cmFeedholdType; + +typedef enum { // feedhold final operation + FEEDHOLD_FINAL_NONE = 0, // normal final state - HOLD or STOP, depending on type + FEEDHOLD_FINAL_STOP, // perform program stop + FEEDHOLD_FINAL_END, // perform program end + FEEDHOLD_FINAL_ALARM, // perform alarm + FEEDHOLD_FINAL_SHUTDOWN, // perform shutdown + FEEDHOLD_FINAL_INTERLOCK // report as interlock +} cmFeedholdFinal; typedef enum { // feedhold state machine - FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit +// FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit FEEDHOLD_OFF = 0, // no feedhold in effect -// FEEDHOLD_INITIATED, // feedhold has been requested but not started yet + FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet FEEDHOLD_SYNC, // start hold - sync to latest aline segment FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero @@ -153,7 +153,7 @@ typedef enum { // feedhold state machine FEEDHOLD_HOLD_EXIT_PENDING, // performing exit actions FEEDHOLD_HOLD_EXIT_DONE, // completed exit actions - FEEDHOLD_P2_EXIT // set when p2 feedhold is finishing +// FEEDHOLD_P2_EXIT // set when p2 feedhold is finishing } cmFeedholdState; typedef enum { // applies to cm->homing_state @@ -273,24 +273,31 @@ typedef struct cmMachine { // struct to manage canonical machin cfgAxis_t a[AXES]; // gcode power-on default settings - defaults are not the same as the gm state - cmCoordSystem default_coord_system; // G10 active coordinate system default - cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default - cmUnitsMode default_units_mode; // G20,G21 reset default - cmPathControl default_path_control; // G61,G61.1,G64 reset default - cmDistanceMode default_distance_mode; // G90,G91 reset default + cmCoordSystem default_coord_system; // G10 active coordinate system default + cmCanonicalPlane default_select_plane; // G17,G18,G19 reset default + cmUnitsMode default_units_mode; // G20,G21 reset default + cmPathControl default_path_control; // G61,G61.1,G64 reset default + cmDistanceMode default_distance_mode; // G90,G91 reset default /**** Runtime variables (PRIVATE) ****/ // Global state variables and flags - cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state - cmCycleType cycle_type; // cycs - cmMotionState motion_state; // mots + cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state + cmCycleType cycle_type; // cycs + cmMotionState motion_state; // mots + cmCycleState cycle_state; // used to manage cycle start + cmFeedholdType hold_type; // hold: type of feedhold requested + cmFeedholdFinal hold_final; // hold: final state of hold cmFeedholdState hold_state; // hold: feedhold state machine - cmFlushState flush_state; // hold: queue flush state machine - bool hold_exit_requested; // request normal exit from feedhold - bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) + cmFlushState flush_state; // hold: queue flush state machine +// bool hold_exit_requested; // request normal exit from feedhold +++++ +// bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) + + bool request_interlock; // enter interlock + bool request_interlock_exit; // exit interlock + bool request_job_kill; // ^d - end hold, flush and alarm cmOverrideState mfo_state; // feed override state machine @@ -485,11 +492,12 @@ stat_t cm_json_wait(char *json_string); // M102 // Feedhold and related functions (cycle_feedhold.cpp) void cm_operation_init(void); -stat_t cm_operation_callback(void); // operation action runner -stat_t cm_request_operation(cmOperationType operation, float *param); // request an operation +stat_t cm_operation_sequencing_callback(void); // operation action runner -void cm_request_feedhold(void); -void cm_request_exit_hold(void); +void cm_request_alarm(void); +void cm_request_fasthold(void); +void cm_request_cycle_start(void); +void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final); void cm_request_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests stat_t cm_feedhold_command_blocker(void); @@ -523,7 +531,7 @@ stat_t cm_clr(nvObj_t *nv); // clear alarm a void cm_clear(void); // raw clear command void cm_parse_clear(const char *s); // parse gcode for M30 or M2 clear condition stat_t cm_is_alarmed(void); // return non-zero status if alarm, shutdown or panic -void cm_halt_all(void); // halt motion, spindle and coolant +void cm_halt(void); // halt motion, spindle, coolant, heaters void cm_halt_motion(void); // halt motion (immediate stop) but not spindle & other IO stat_t cm_alarm(const stat_t status, const char *msg); // enter alarm state - preserve Gcode state stat_t cm_shutdown(const stat_t status, const char *msg); // enter shutdown state - dump all state @@ -574,7 +582,7 @@ stat_t cm_get_g92(nvObj_t *nv); // get g92 offset stat_t cm_get_g28(nvObj_t *nv); // get g28 offset stat_t cm_get_g30(nvObj_t *nv); // get g30 offset -stat_t cm_run_qf(nvObj_t *nv); // run queue flush +//stat_t cm_run_qf(nvObj_t *nv); // run queue flush stat_t cm_run_home(nvObj_t *nv); // start homing cycle //stat_t cm_dam(nvObj_t *nv); // dump active model (debugging command) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 7f016921..19bc13ec 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -667,7 +667,7 @@ const cfgItem_t cfgArray[] = { { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing - { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush +// { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets { "", "dw", _f0, 0, tx_print_int, st_get_dw, set_noop, (float *)&cs.null, 0 }, // get dwell time remaining { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 57b6e452..b08ceeea 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -159,10 +159,10 @@ static void _controller_HSM() DISPATCH(sr_status_report_callback()); // conditionally send status report DISPATCH(qr_queue_report_callback()); // conditionally send queue report -// DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner +// DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner +++++ DISPATCH(mp_planner_callback()); // motion planner DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines - DISPATCH(cm_operation_callback()); // operation action runner + DISPATCH(cm_operation_sequencing_callback());// operation action runner DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) @@ -238,9 +238,10 @@ static void _dispatch_kernel(const devflags_t flags) } // trap single character commands - if (*cs.bufp == '!') { cm_request_feedhold(); } + if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_FINAL_NONE); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } - else if (*cs.bufp == '~') { cm_request_exit_hold(); } +// else if (*cs.bufp == '~') { cm_request_exit_hold(); } +++++ + else if (*cs.bufp == '~') { cm_request_cycle_start(); } else if (*cs.bufp == EOT) { cm_job_kill(); } else if (*cs.bufp == ENQ) { controller_request_enquiry(); } else if (*cs.bufp == CAN) { hw_hard_reset(); } // reset immediately @@ -434,7 +435,7 @@ static stat_t _interlock_handler(void) if (cm->safety_interlock_disengaged != 0) { cm->safety_interlock_disengaged = 0; cm->safety_interlock_state = SAFETY_INTERLOCK_DISENGAGED; - cm_request_feedhold(); // may have already requested STOP as INPUT_ACTION + cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_FINAL_INTERLOCK); // may have already requested STOP as INPUT_ACTION // feedhold was initiated by input action in gpio // pause spindle // pause coolant @@ -444,7 +445,8 @@ static stat_t _interlock_handler(void) if ((cm->safety_interlock_reengaged != 0) && (mp_runtime_is_idle())) { cm->safety_interlock_reengaged = 0; cm->safety_interlock_state = SAFETY_INTERLOCK_ENGAGED; // interlock restored - cm_request_exit_hold(); // use cm_request_exit_hold() instead of just ending +// cm_request_exit_hold(); // use cm_request_exit_hold() instead of just ending +++++ + cm_request_cycle_start(); // proper way to restart the cycle } } return(STAT_OK); diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 3795e172..8d1c648f 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -38,81 +38,21 @@ #include "util.h" //#include "xio.h" // DIAGNOSTIC -//static stat_t _run_p1_hold_entry_actions(void); -//static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); +static void _initiate_feedhold(void); +static stat_t _action_feedhold_actions(float *param); +static stat_t _action_feedhold_no_actions(float *param); +static stat_t _action_feedhold_sync(float *param); +static stat_t _action_feedhold_exit_with_actions(float *param); -//static stat_t _run_p1_hold_exit_actions(void); -//static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); -//static void _feedhold_p1_exit(void); -//static void _feedhold_p2_exit(void); -//static void _feedhold_abort(void); +static stat_t _action_program_stop(float *param); +static stat_t _action_program_end(float *param); +static stat_t _action_alarm(float *param); +static stat_t _action_shutdown(float *param); +static stat_t _action_interlock(float *param); //static stat_t _action_cycle_start(float *param); //static stat_t _action_hold_no_actions(float *param); -static stat_t _action_hold_with_actions(float *param); //static stat_t _action_hold_exit_no_actions(float *param); -static stat_t _action_hold_exit_with_actions(float *param); - -//static stat_t _action_halt(float *param); -//static stat_t _action_p2_entry(float* param); -//static stat_t _action_parking_move(float *param); -//static stat_t _action_return_move(float *param); -//static stat_t _action_spindle_control(float *param); -//static stat_t _action_coolant_control(float *param); -//static stat_t _action_heater_control(float *param); -//static stat_t _action_output_control(float *param); -//static stat_t _action_queue_flush(float *param); -//static stat_t _action_input_function(float *param); -//static stat_t _action_finalize_program(float *param); -//static stat_t _action_trigger_alarm(float *param); - -typedef enum { // Operation Actions - // Initiation actions - ACTION_NULL = 0, // no pending action; reverts here when complete (read-only; cannot be set) - ACTION_HOLD, // p1/p2 feedhold at selected jerk ending in HOLD state -// ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1 -// ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used) -// ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1 -// ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2 - ACTION_HALT_MOTION, // halt all motion immediately (regardless of p1 or p2) - - // Hold Entry Actions - run when motion has stopped - ACTION_P2_ENTRY, // Z lift, spindle and coolant actions (bundled) - ACTION_PARKING_MOVE, // perform a pre-defined toolhead parking move - ACTION_PAUSE_SPINDLE, - ACTION_PAUSE_COOLANT, - ACTION_PAUSE_HEATERS, - ACTION_PAUSE_OUTPUTS, // programmed special purpose outputs - ACTION_STOP_SPINDLE, - ACTION_STOP_COOLANT, - ACTION_STOP_HEATERS, - ACTION_STOP_OUTPUTS, - - // In-Hold actions - ACTION_TOOL_CHANGE, - - // Feedhold Exit Actions // This set is kept in a separate vector, so the bit shifts start over. - ACTION_P2_EXIT, // coolant, spindle, return move actions (bundled) - ACTION_RESUME_HEATERS, - ACTION_RESUME_COOLANT, - ACTION_RESUME_SPINDLE, - ACTION_RESUME_OUTPUTS, // programmed special purpose outputs - ACTION_RETURN_MOVE, // returns to hold pint an re-enters p1 - - // Cycle start, restart, exit hold - ACTION_SKIP_TO_SYNC, // discard remaining length, execute next block if SYNC command, otherwise flush buffer - ACTION_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion - ACTION_QUEUE_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP - - // Finalization actions - ACTION_DI_FUNCTION, // function as assigned by digital input configuration (TBD) - ACTION_PROGRAM_STOP, // invoke PROGRAM_STOP - ACTION_PROGRAM_END, // invoke PROGRAM_END - ACTION_TRIGGER_ALARM, // trigger ALARM - ACTION_TRIGGER_SHUTDOWN, // trigger SHUTDOWN - ACTION_TRIGGER_PANIC, // trigger PANIC state - ACTION_PERFORM_RESET, // defined, but not implemented -} cmOpAction; /**************************************************************************************** * OPERATIONS AND ACTIONS @@ -182,17 +122,22 @@ typedef struct cmOperation { // operation runner object }; stat_t run_operation(void) { - if (run->func == NULL) { return (STAT_NOOP); } // not an error. This is normal. + if (run->func == NULL) { + return (STAT_NOOP); + } // not an error. This is normal. in_operation = true; // disable add_action during operations - + stat_t status; while ((status = run->func(run->param)) == STAT_OK) { - if ((run = run->nx) == NULL) { // operation has completed + run = run->nx; + if (run->func == NULL) { // operation has completed reset(); // setup for next operation return (STAT_OK); } } - if (status == STAT_EAGAIN) { return (STAT_EAGAIN); } + if (status == STAT_EAGAIN) { + return (STAT_EAGAIN); + } reset(); // reset operation if action threw an error return (status); // return error code }; @@ -203,22 +148,556 @@ cmOperation_t op; // operations runner object /**************************************************************************************** * cm_operation_init() - * cm_operation_callback() */ + void cm_operation_init() { op.reset(); } -stat_t cm_operation_callback() +/**************************************************************************************** + * cm_operation_callback() - run operations and sequence requests + * + * Expected behaviors: (no-hold means machine is not in hold, etc) + * + * (no-cycle) ! No action. Feedhold is not run (nothing to hold!) + * (no-hold) ~ No action. Cannot exit a feedhold that does not exist + * (no-hold) % No action. Queue flush is not honored except during a feedhold + * (in-cycle) ! Start a feedhold + * (in-hold) ~ Wait for feedhold actions to complete, exit feedhold, resume motion + * (in-hold) % Wait for feedhold actions to complete, exit feedhold, do not resume motion + * (in-cycle) !~ Start a feedhold, do enter and exit actions, exit feedhold, resume motion + * (in-cycle) !% Start a feedhold, do enter and exit actions, exit feedhold, do not resume motion + * (in-cycle) !%~ Same as above + * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) + * + * The operation callback can hold a set of requests and makes decisions on which to run + * based on priorities and other factors: + + bool request_alarm; // stop all operations with feedhold and alarm + bool request_feedhold; // normal feedhold with actions + bool request_cycle_start; // start cycle, or exit feedhold if in hold state + bool request_queue_flush; // exit hold and flush queues + bool request_interlock; // enter interlock + bool request_interlock_exit; // exit interlock + bool request_job_kill; // ^d - end hold, flush and alarm + + * Feedhold parameters + * - Action type (1=normal, 2=fast_hold, 3=fast-hold_flush_sync) + * - Final state (STOP, END, HOLD (CYCLE), ALARM, SHUTDOWN) + */ + +stat_t cm_operation_sequencing_callback() { + if (cm1.hold_state == FEEDHOLD_REQUESTED) { + _initiate_feedhold(); + } +// if (cm1.flush_state == FLUSH_REQUESTED) { +// _initiate_queue_flush(); +// } +/* + + // queue flush won't run until the hold is complete and all (subsequent) motion has stopped + if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && + (mp_runtime_is_idle())) { // don't flush planner during movement + cm_queue_flush(&cm1); + cm1.hold_exit_requested = true; // p1 queue flush always ends the hold + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available + } + + // special handling for feedhold abort - M2/M30, job kill, alarms + if (cm1.hold_abort_requested) { + _feedhold_abort(); + } + + // exit_hold runs for both ~ and % feedhold ends + if (cm1.hold_exit_requested) { + + // Flush must complete before exit_hold runs. Trap possible race condition if flush request was + if (cm1.flush_state == FLUSH_REQUESTED) { // ...received when this callback was running + return (STAT_OK); + } + if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold + cm1.hold_exit_requested = false; + _run_p1_hold_exit_actions(); // runs once only + } + } + if (cm1.hold_state == FEEDHOLD_P1_EXIT) { + _feedhold_p1_exit(); // run multiple times until actions are complete + } +*/ return (op.run_operation()); + +} +/**************************************************************************************** + **** Functions ************************************************************************* + ****************************************************************************************/ + +/* + * cm_has_hold() - return true if a hold condition exists (or a pending hold request) + */ +bool cm_has_hold() +{ + return (cm1.hold_state != FEEDHOLD_OFF); +} + +void cm_start_hold() +{ + // Can only request a feedhold if the machine is in motion and there not one is not already in progress + if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { + cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution + } +} + +stat_t cm_feedhold_command_blocker() +{ + if (cm1.hold_state != FEEDHOLD_OFF) { + return (STAT_EAGAIN); + } + return (STAT_OK); +} + +void cm_request_alarm() +{ + } /**************************************************************************************** - **** Operations ************************************************************************ - ****************************************************************************************/ + * request_cycle_start() - set request flag only + * start_cycle_start() - run the cycle start + */ +void cm_request_cycle_start() +{ + cm->cycle_state = CYCLE_START_REQUESTED; +} + +void cm_start_cycle_start() +{ + // Normal cycle start - not in a feedhold + if (cm1.hold_state != FEEDHOLD_OFF) { + cm_cycle_start(); // execute cycle start directly + st_request_exec_move(); + return; + } + + // Feedhold cycle starts run an operation to complete multiple actions + op.add_action(_action_feedhold_exit_with_actions, nullptr); + op.run_operation(); +} + + + +/**************************************************************************************** + * cm_request_feedhold() - request a feedhold - d0 not run it yet + * _initiate_feedhold() - start feedhold of correct type and finalization + * _action_feedhold_sync() - planner callback to reach sync point + * _action_feedhold_with_actions() - perform hold entry actions + */ + +void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) +{ + cm->hold_type = type; + cm->hold_final = final; + cm->hold_state = FEEDHOLD_REQUESTED; +} + +static void _initiate_feedhold() +{ + // This function is "safe" and will not initiate a feedhold unless it's OK to. + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state == MOTION_RUN)) { + switch (cm1.hold_type) { + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_action_feedhold_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_action_feedhold_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_SYNC: { op.add_action(_action_feedhold_sync, nullptr); break; } + default: {} + } + switch (cm1.hold_final) { + case FEEDHOLD_FINAL_STOP: { op.add_action(_action_program_stop, nullptr); break; } + case FEEDHOLD_FINAL_END: { op.add_action(_action_program_end, nullptr); break; } + case FEEDHOLD_FINAL_ALARM: { op.add_action(_action_alarm, nullptr); break; } + case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_action_shutdown, nullptr); break; } + case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_action_interlock, nullptr); break; } + default: {} + } + cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec + return; + } + + // P2 feedhold + if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state == MOTION_RUN)) { + op.add_action(_action_feedhold_sync, nullptr); + cm2.hold_state = FEEDHOLD_SYNC; + } +} + +static void _action_feedhold_sync_to_planner(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD_DONE; // penultimate state before transitioning to FEEDHOLD_HOLD + sr_request_status_report(SR_REQUEST_IMMEDIATE); +} + +static stat_t _action_feedhold_no_actions(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_feedhold_sync(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_program_stop(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_program_end(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_alarm(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_shutdown(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_interlock(float *param) +{ + return (STAT_OK); +} + + +static stat_t _action_feedhold_actions(float *param) // Execute Case (5) +{ + // Check to run first-time code + if (cm1.hold_state == FEEDHOLD_HOLD_ACTION_START) { + cm->hold_state = FEEDHOLD_HOLD_PENDING; // next state + + // copy the primary canonical machine to the secondary, + // fix the planner pointer, and reset the secondary planner + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // set parameters in cm, gm and gmx so you can actually use it + cm2.hold_state = FEEDHOLD_OFF; + cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + cm2.flush_state = FLUSH_OFF; + cm2.gm.feed_rate = 0; + + // clear the target and set the positions to the current hold position + memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); + memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); + copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation + copy_vector(cm2.gmx.position, mr1.position); + copy_vector(mp2.position, mr1.position); + copy_vector(mr2.position, mr1.position); + + // reassign the globals to the secondary CM + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer + mr = mp->mr; + + // set a return position + cm_set_g30_position(); + + // execute feedhold actions + if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift + cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); + bool flags[] = { 0,0,1,0,0,0 }; + float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode + cm_straight_traverse(target, flags, PROFILE_NORMAL); + cm_set_distance_mode(cm1.gm.distance_mode); // restore distance mode to p1 setting + } + spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause + coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause + mp_queue_command(_action_feedhold_sync_to_planner, nullptr, nullptr); + return (STAT_EAGAIN); + } + + // wait for hold actions to complete + if (cm1.hold_state == FEEDHOLD_HOLD_PENDING) { + return (STAT_EAGAIN); + } + + // finalize feedhold exit + if (cm1.hold_state == FEEDHOLD_HOLD_DONE) { + cm1.hold_state = FEEDHOLD_HOLD; + return (STAT_OK); + } + return (STAT_EAGAIN); +} + +/**************************************************************************************** + * _action_hold_exit_sync() - planner callback to reach sync point + * _action_hold_exit_with_actions() - perform hold exit actions + */ + +static void _action_hold_exit_sync(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD_EXIT_DONE; // penultimate state before transitioning to FEEDHOLD_OFF + sr_request_status_report(SR_REQUEST_IMMEDIATE); +} + +static stat_t _action_hold_exit_with_actions(float *param) // Execute Cases (6) and (7) +{ + // Check to run first-time code + if (cm1.hold_state == FEEDHOLD_HOLD) { + // perform end-hold actions --- while still in secondary machine + coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused + spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused + + // do return move though an intermediate point; queue a wait + cm2.return_flags[AXIS_Z] = false; + cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); + mp_queue_command(_action_hold_exit_sync, nullptr, nullptr); + cm1.hold_state = FEEDHOLD_HOLD_EXIT_PENDING; + return (STAT_EAGAIN); + } + + // wait for exit actions to complete + if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_PENDING) { + return (STAT_EAGAIN); + } + + // finalize feedhold exit + if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_DONE) { + + // return to primary planner (p1) + cm = &cm1; + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + + // execute this block if a queue flush was performed + // adjust p1 planner positions to runtime positions + if (cm1.flush_state == FLUSH_WAS_RUN) { + cm_reset_position_to_absolute_position(cm); + cm1.flush_state = FLUSH_OFF; + } + + // resume motion from primary planner or end cycle if no moves in planner + if (mp_has_runnable_buffer(&mp1)) { +// cm_set_motion_state(MOTION_RUN); + cm_cycle_start(); + st_request_exec_move(); + } else { +// cm_set_motion_state(MOTION_STOP); + cm_cycle_end(); + } + cm1.hold_state = FEEDHOLD_OFF; + return (STAT_OK); + } + return (STAT_EAGAIN); +} + + +/**************************************************************************************** + * Queue Flush operations + * + * This one's complicated. See here first: + * https://github.com/synthetos/g2/wiki/Job-Exception-Handling + * https://github.com/synthetos/g2/wiki/Alarm-Processing + * + * We want to use queue flush for a few different use cases, as per the above wiki pages. + * The % behavior implements Exception Handling cases 1 and 2 - Stop a Single Move and + * Stop Multiple Moves. This is complicated further by the processing in single USB and + * dual USB being different. Also, the state handling is located in xio.cpp / readline(), + * controller.cpp _dispatch_kernel() and cm_request_queue_flush(), below. + * So it's documented here. + * + * Single or Dual USB Channels: + * - If a % is received outside of a feed hold or ALARM state, ignore it. + * Change the % to a ; comment symbol (xio) + * + * Single USB Channel Operation: + * - Enter a feedhold (!) + * - Receive a queue flush (%) Both dispatch it and store a marker (ACK) in the input + * buffer in place of the the % (xio) + * - Execute the feedhold to a hold condition (plan_exec) + * - Execute the dispatched % to flush queues (canonical_machine) + * - Silently reject any commands up to the % in the input queue (controller) + * - When ETX is encountered transition to STOP state (controller/canonical_machine) + * + * Dual USB Channel Operation: + * - Same as above except that we expect the % to arrive on the control channel + * - The system will read and dump all commands in the data channel until either a + * clear is encountered ({clear:n} or $clear), or an ETX is encountered on either + * channel, but it really should be on the data channel to ensure all queued commands + * are dumped. It is the host's responsibility to both write the clear (or ETX), and + * to ensure that it either arrives on the data channel or that the data channel is + * empty before writing it to the control channel. + */ + +/*********************************************************************************** + * cm_reqeust_queue_flush() - Flush planner queue + * cm_queue_flush() - Flush planner queue + * + * This function assumes that the feedhold sequencing callback has resolved all + * state and timing issues and it's OK to call this now. Do not call this function + * directly. Always use the feedhold sequencing callback. + */ + +void cm_request_queue_flush() +{ + cm->flush_state = FLUSH_REQUESTED; +} + +void cm_queue_flush(cmMachine_t *_cm) +{ + cm_abort_arc(_cm); // kill arcs so they don't just create more alines + planner_reset((mpPlanner_t *)_cm->mp); // reset primary planner. also resets the mr under the planner + _cm->flush_state = FLUSH_WAS_RUN; +} + + + + + + + + + + + + + +//static stat_t _run_p1_hold_entry_actions(void); +//static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); + +//static stat_t _run_p1_hold_exit_actions(void); +//static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); +//static void _feedhold_p1_exit(void); +//static void _feedhold_p2_exit(void); +//static void _feedhold_abort(void); + +//static stat_t _action_halt(float *param); +//static stat_t _action_p2_entry(float* param); +//static stat_t _action_parking_move(float *param); +//static stat_t _action_return_move(float *param); +//static stat_t _action_spindle_control(float *param); +//static stat_t _action_coolant_control(float *param); +//static stat_t _action_heater_control(float *param); +//static stat_t _action_output_control(float *param); +//static stat_t _action_queue_flush(float *param); +//static stat_t _action_input_function(float *param); +//static stat_t _action_finalize_program(float *param); +//static stat_t _action_trigger_alarm(float *param); +/* +typedef enum { // Operation Actions + // Initiation actions + ACTION_NULL = 0, // no pending action; reverts here when complete (read-only; cannot be set) + ACTION_HOLD, // p1/p2 feedhold at selected jerk ending in HOLD state + // ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1 + // ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used) + // ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1 + // ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2 + ACTION_HALT_MOTION, // halt all motion immediately (regardless of p1 or p2) + + // Hold Entry Actions - run when motion has stopped + ACTION_P2_ENTRY, // Z lift, spindle and coolant actions (bundled) + ACTION_PARKING_MOVE, // perform a pre-defined toolhead parking move + ACTION_PAUSE_SPINDLE, + ACTION_PAUSE_COOLANT, + ACTION_PAUSE_HEATERS, + ACTION_PAUSE_OUTPUTS, // programmed special purpose outputs + ACTION_STOP_SPINDLE, + ACTION_STOP_COOLANT, + ACTION_STOP_HEATERS, + ACTION_STOP_OUTPUTS, + + // In-Hold actions + ACTION_TOOL_CHANGE, + + // Feedhold Exit Actions // This set is kept in a separate vector, so the bit shifts start over. + ACTION_P2_EXIT, // coolant, spindle, return move actions (bundled) + ACTION_RESUME_HEATERS, + ACTION_RESUME_COOLANT, + ACTION_RESUME_SPINDLE, + ACTION_RESUME_OUTPUTS, // programmed special purpose outputs + ACTION_RETURN_MOVE, // returns to hold pint an re-enters p1 + + // Cycle start, restart, exit hold + ACTION_SKIP_TO_SYNC, // discard remaining length, execute next block if SYNC command, otherwise flush buffer + ACTION_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion + ACTION_QUEUE_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP + + // Finalization actions + ACTION_DI_FUNCTION, // function as assigned by digital input configuration (TBD) + ACTION_PROGRAM_STOP, // invoke PROGRAM_STOP + ACTION_PROGRAM_END, // invoke PROGRAM_END + ACTION_TRIGGER_ALARM, // trigger ALARM + ACTION_TRIGGER_SHUTDOWN, // trigger SHUTDOWN + ACTION_TRIGGER_PANIC, // trigger PANIC state + ACTION_PERFORM_RESET, // defined, but not implemented +} cmOpAction; + +*/ + +/**************************************************************************************** + * cm_request_feedhold() - reqeust a feedhold + * cm_request_exit_hold() - reqeust feedhold exit with resume motion + * cm_request_queue_flush() - request feedhold exit with queue flush + * cm_start_hold() - start a feedhhold external to feedhold request equencing + * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner + * + * p1 is the primary planner, p2 is the secondary planner, which is active if the + * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. + * Request_feedhold, request_end_hold, and request_queue_flush are contextual: + * + * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) + * + * request_feedhold: + * - If p1 is not in HOLD & is in motion, request_feedhold requests a p1 hold + * - If p1 is in HOLD & p2 is in motion, request_feedhold requests a p2 hold + * - If both p1 and p2 are in HOLD, request_feedhold is ignored + * + * request_end_hold: + * - If p1 is not in HOLD, request_end_hold is ignored + * - If p1 is in HOLD request_end_hold will end p1 hold & resume motion. + * Pre-defined exit actions (coolant, spindle, Z move) are completed first + * Any executing or pending "in-hold" moves are stopped prior to the exit actions + * + * request_queue_flush: + * - If p1 is not in HOLD, request_queue_flush is ignored + * - If p1 is in HOLD request_queue_flush will end p1 hold & queue flush (stop motion). + * Pre-defined exit actions (coolant, spindle, Z move) are completed first + * Any executing or pending "in-hold" moves are stopped prior to the exit actions + */ +/* +void cm_request_feedhold(void) // ! +{ + // Only generate request if not already in a feedhold and the machine is in motion + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { + cm1.hold_state = FEEDHOLD_INITIATED; // signal request to state machine + } else + if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { + cm2.hold_state = FEEDHOLD_INITIATED; + } +} + +void cm_request_exit_hold(void) // ~ +{ + if (cm1.hold_state != FEEDHOLD_OFF) { + cm1.hold_exit_requested = true; + } +} + +void cm_request_queue_flush() // % +{ + // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now + if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold + (cm1.flush_state == FLUSH_OFF)) { // ...and only once + cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped + } +} +*/ /**************************************************************************************** * cm_request_operation() * @@ -244,7 +723,7 @@ stat_t cm_operation_callback() * - param[1] - jerk 0=normal-jerk, 1=high-jerk (fast hold) * - param[2] - endstate */ - +/* stat_t cm_request_operation(cmOperationType operation, float *param) { if (op.in_operation) { @@ -270,25 +749,7 @@ stat_t cm_request_operation(cmOperationType operation, float *param) } return (STAT_OK); } - -/**************************************************************************************** - * request_cycle_start() - * _action_cycle_start() - start a cycle or restart from hold - */ - -stat_t request_cycle_start() -{ - // Normal cycle start - not in a feedhold - if (cm1.hold_state != FEEDHOLD_OFF) { - cm_cycle_start(); // execute cycle start directly - st_request_exec_move(); - } - - // Feedhold cycle starts run an operation to complete multiple actions - op.add_action(_action_hold_exit_with_actions, nullptr); - return(op.run_operation()); -} - +*/ /* static stat_t _action_cycle_start(float *param) { @@ -398,89 +859,6 @@ static stat_t _action_hold_with_actions(float *param) * (7) - Remove the hold state / there is no queued motion - see cycle_feedhold.cpp */ -/**************************************************************************************** - * cm_has_hold() - return true if a hold condition exists (or a pending hold request) - */ -bool cm_has_hold() -{ - return (cm1.hold_state != FEEDHOLD_OFF); -} - -/**************************************************************************************** - * cm_request_feedhold() - reqeust a feedhold - * cm_request_exit_hold() - reqeust feedhold exit with resume motion - * cm_request_queue_flush() - request feedhold exit with queue flush - * cm_start_hold() - start a feedhhold external to feedhold request equencing - * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner - * - * p1 is the primary planner, p2 is the secondary planner, which is active if the - * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. - * Request_feedhold, request_end_hold, and request_queue_flush are contextual: - * - * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) - * - * request_feedhold: - * - If p1 is not in HOLD & is in motion, request_feedhold requests a p1 hold - * - If p1 is in HOLD & p2 is in motion, request_feedhold requests a p2 hold - * - If both p1 and p2 are in HOLD, request_feedhold is ignored - * - * request_end_hold: - * - If p1 is not in HOLD, request_end_hold is ignored - * - If p1 is in HOLD request_end_hold will end p1 hold & resume motion. - * Pre-defined exit actions (coolant, spindle, Z move) are completed first - * Any executing or pending "in-hold" moves are stopped prior to the exit actions - * - * request_queue_flush: - * - If p1 is not in HOLD, request_queue_flush is ignored - * - If p1 is in HOLD request_queue_flush will end p1 hold & queue flush (stop motion). - * Pre-defined exit actions (coolant, spindle, Z move) are completed first - * Any executing or pending "in-hold" moves are stopped prior to the exit actions - */ -/* -void cm_request_feedhold(void) // ! -{ - // Only generate request if not already in a feedhold and the machine is in motion - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_state = FEEDHOLD_INITIATED; // signal request to state machine - } else - if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { - cm2.hold_state = FEEDHOLD_INITIATED; - } -} -*/ - -void cm_request_exit_hold(void) // ~ -{ - if (cm1.hold_state != FEEDHOLD_OFF) { - cm1.hold_exit_requested = true; - } -} - -void cm_request_queue_flush() // % -{ - // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now - if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm1.flush_state == FLUSH_OFF)) { // ...and only once - cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped - } -} - -void cm_start_hold() -{ - // Can only request a feedhold if the machine is in motion and there not one is not already in progress - if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} - -stat_t cm_feedhold_command_blocker() -{ - if (cm1.hold_state != FEEDHOLD_OFF) { - return (STAT_EAGAIN); - } - return (STAT_OK); -} - /**************************************************************************************** * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests * @@ -568,96 +946,6 @@ stat_t cm_feedhold_sequencing_callback() * not run actions, so this function is never called for p2 feedholds. It's called * from an interrupt, so it only sets a flag. */ - - -/**************************************************************************************** - * request_feedhold() - initiate a feedhold - * _action_hold_sync() - planner callback to reach sync point - * _action_hold_with_actions() - perform hold entry actions - */ - -void cm_request_feedhold(void) // ! -{ - // Only generate P1 feedhold if not already in a feedhold and the machine is in motion - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - op.add_action(_action_hold_with_actions, nullptr); // do this first for safety - cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec -// op.run_operation(); - } else - - // P2 feedhold - if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { - cm2.hold_state = FEEDHOLD_SYNC; - } -} - -static void _action_hold_sync(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_HOLD_DONE; // penultimate state before transitioning to FEEDHOLD_HOLD - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} - -static stat_t _action_hold_with_actions(float *param) // Execute Case (5) -{ - // Check to run first-time code - if (cm1.hold_state == FEEDHOLD_HOLD_ACTION_START) { - cm->hold_state = FEEDHOLD_HOLD_PENDING; // next state - - // copy the primary canonical machine to the secondary, - // fix the planner pointer, and reset the secondary planner - memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // set parameters in cm, gm and gmx so you can actually use it - cm2.hold_state = FEEDHOLD_OFF; - cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - cm2.flush_state = FLUSH_OFF; - cm2.gm.feed_rate = 0; - - // clear the target and set the positions to the current hold position - memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); - memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); - copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation - copy_vector(cm2.gmx.position, mr1.position); - copy_vector(mp2.position, mr1.position); - copy_vector(mr2.position, mr1.position); - - // reassign the globals to the secondary CM - cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // mp is a void pointer - mr = mp->mr; - - // set a return position - cm_set_g30_position(); - - // execute feedhold actions - if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift - cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); - bool flags[] = { 0,0,1,0,0,0 }; - float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode - cm_straight_traverse(target, flags, PROFILE_NORMAL); - cm_set_distance_mode(cm1.gm.distance_mode); // restore distance mode to p1 setting - } - spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause - coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - mp_queue_command(_action_hold_sync, nullptr, nullptr); - return (STAT_EAGAIN); - } - - // wait for hold actions to complete - if (cm1.hold_state == FEEDHOLD_HOLD_PENDING) { - return (STAT_EAGAIN); - } - - // finalize feedhold exit - if (cm1.hold_state == FEEDHOLD_HOLD_DONE) { - cm1.hold_state = FEEDHOLD_HOLD; - return (STAT_OK); - } - return (STAT_EAGAIN); -} /* static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) // Complete case (5) { @@ -732,67 +1020,7 @@ static stat_t _run_p1_hold_entry_actions() // Execute Case (5) * the sync runs from an interrupt. Finalization needs to run from the main loop. */ -/**************************************************************************************** - * _action_hold_exit_sync() - planner callback to reach sync point - * _action_hold_exit_with_actions() - perform hold exit actions - */ -static void _action_hold_exit_sync(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_HOLD_EXIT_DONE; // penultimate state before transitioning to FEEDHOLD_OFF - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} - -static stat_t _action_hold_exit_with_actions(float *param) // Execute Cases (6) and (7) -{ - // Check to run first-time code - if (cm1.hold_state == FEEDHOLD_HOLD) { - // perform end-hold actions --- while still in secondary machine - coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused - spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused - - // do return move though an intermediate point; queue a wait - cm2.return_flags[AXIS_Z] = false; - cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); - mp_queue_command(_action_hold_exit_sync, nullptr, nullptr); - cm1.hold_state = FEEDHOLD_HOLD_EXIT_PENDING; - return (STAT_EAGAIN); - } - - // wait for exit actions to complete - if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_PENDING) { - return (STAT_EAGAIN); - } - - // finalize feedhold exit - if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_DONE) { - - // return to primary planner (p1) - cm = &cm1; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; - - // execute this block if a queue flush was performed - // adjust p1 planner positions to runtime positions - if (cm1.flush_state == FLUSH_WAS_RUN) { - cm_reset_position_to_absolute_position(cm); - cm1.flush_state = FLUSH_OFF; - } - - // resume motion from primary planner or end cycle if no moves in planner - if (mp_has_runnable_buffer(&mp1)) { -// cm_set_motion_state(MOTION_RUN); - cm_cycle_start(); - st_request_exec_move(); - } else { -// cm_set_motion_state(MOTION_STOP); - cm_cycle_end(); - } - cm1.hold_state = FEEDHOLD_OFF; - return (STAT_OK); - } - return (STAT_EAGAIN); -} /* static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) { @@ -930,121 +1158,30 @@ static void _feedhold_abort() cm1.hold_abort_requested = false; } */ -/**************************************************************************************** - * Queue Flush operations - * - * This one's complicated. See here first: - * https://github.com/synthetos/g2/wiki/Job-Exception-Handling - * https://github.com/synthetos/g2/wiki/Alarm-Processing - * - * We want to use queue flush for a few different use cases, as per the above wiki pages. - * The % behavior implements Exception Handling cases 1 and 2 - Stop a Single Move and - * Stop Multiple Moves. This is complicated further by the processing in single USB and - * dual USB being different. Also, the state handling is located in xio.cpp / readline(), - * controller.cpp _dispatch_kernel() and cm_request_queue_flush(), below. - * So it's documented here. - * - * Single or Dual USB Channels: - * - If a % is received outside of a feed hold or ALARM state, ignore it. - * Change the % to a ; comment symbol (xio) - * - * Single USB Channel Operation: - * - Enter a feedhold (!) - * - Receive a queue flush (%) Both dispatch it and store a marker (ACK) in the input - * buffer in place of the the % (xio) - * - Execute the feedhold to a hold condition (plan_exec) - * - Execute the dispatched % to flush queues (canonical_machine) - * - Silently reject any commands up to the % in the input queue (controller) - * - When ETX is encountered transition to STOP state (controller/canonical_machine) - * - * Dual USB Channel Operation: - * - Same as above except that we expect the % to arrive on the control channel - * - The system will read and dump all commands in the data channel until either a - * clear is encountered ({clear:n} or $clear), or an ETX is encountered on either - * channel, but it really should be on the data channel to ensure all queued commands - * are dumped. It is the host's responsibility to both write the clear (or ETX), and - * to ensure that it either arrives on the data channel or that the data channel is - * empty before writing it to the control channel. - */ - -/*********************************************************************************** - * cm_queue_flush() - Flush planner queue - * - * This function assumes that the feedhold sequencing callback has resolved all - * state and timing issues and it's OK to call this now. Do not call this function - * directly. Always use the feedhold sequencing callback. - */ - -void cm_queue_flush(cmMachine_t *_cm) -{ - cm_abort_arc(_cm); // kill arcs so they don't just create more alines - planner_reset((mpPlanner_t *)_cm->mp); // reset primary planner. also resets the mr under the planner - _cm->flush_state = FLUSH_WAS_RUN; -} /* - * Feedhold Enumerations and Use Cases - * - * The cmFeedholdRequest enum supports the following feedhold use cases. Feedholds and - * feedhold exits using these enums to get specific behaviors. First the normal ones: - * - * - FEEDHOLD_NO_REQUEST No request pending. Requests transition here when complete. - * This value cannot be set (i.e. there is no CANCEL command). - * - * - FEEDHOLD_HOLD_P1 Enter HOLD state in P1. Do not enter p2 or perform entry actions. - * - * - FEEDHOLD_HOLD_P2 (!) Enter HOLD state in P1. Enter p2 and perform entry actions. - * If this command is received while in p2, a FEEDHOLD_HOLD_SKIP - * is executed in p2. - * - * - FEEDHOLD_CYCLE_START (~) Exit HOLD state in P1 or p2. If in p2 perform exit actions, - * then resume motion in p1 planner. - * - * - FEEDHOLD_EXIT_FLUSH (%) Exit HOLD state in P1 or p2. If in p2 perform exit actions, - * then flush p1 planner. End in PROGRAM_STOP state. - * - * Now the specialized ones. If these are called with FEEDHOLD_OFF (i.e. while not in a feedhold) - * A feedhold is performed followed by the indicated actions. If called while in a feedhold the - * feedhold is exited with the indicated actions. Most of these commands are not available in p2. - * - * - FEEDHOLD_HOLD_SKIP Enter HOLD state in P1 or P2. Skip the remainder of the move in the - * held block. If the next block following held block is labeled as a - * SYNC block, execute it. Otherwise flush the queue and STOP. Used - * by homing and probing to stop motion and trigger next actions. - * - * - FEEDHOLD_HOLD_STOP Enter HOLD state in P1. Enter PROGRAM_STOP state. A cycle start or - * FEEDHOLD_EXIT_RESUME will restart motion. - * - * - FEEDHOLD_HOLD_FAST_STOP Enter HOLD state in P1 using a fast hold. Perform PROGRAM_STOP. - * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. - * - * - FEEDHOLD_HOLD_HALT Enter HOLD state in P1 using a HALT. Perform PROGRAM_STOP. - * A cycle start or FEEDHOLD_EXIT_RESUME will restart motion. - * - * - FEEDHOLD_HOLD_END Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. - * This has the effect of entering an asynchronous M30. Useful for Job Kill - * if the sender knows there are no commands following the HOLD command. - * - * - FEEDHOLD_HOLD_END_ALARM Enter HOLD state in P1. Flush planner queue. Perform PROGRAM_END. - * Trigger ALARM. Useful for Job Kill if there may be subsequent commands - * queued by the sender. Requires {clear:n} or M2/M30 to recover operation. - * - * - FEEDHOLD_HOLD_ALARM Enter HOLD state in P1. Flush planner queue. Trigger ALARM. - * Requires {clear:n} or M2/M30 to recover operation. - * - * - FEEDHOLD_HOLD_SHUTDOWN Enter HOLD state in P1. Flush planner queue. Trigger SHUTDOWN. - * Requires {clear:n} or M2/M30 to recover operation. - * - * - FEEDHOLD_HOLD_PANIC Enter HOLD state in P1 using a HALT. Trigger PANIC. - * Requires reset to recover operation. - * - * Interlocks are also handled here. Invoking FEEDHOLD_HOLD_INTERLOCK when the interlock is - * not active will engage it. Invoking it while engaged releases the interlock and resumes - * normal operation. - * - * - FEEDHOLD_HOLD_INTERLOCK Enter HOLD state in P1. Enter INTERLOCK_DISENGAGED state. - * Exit hold and resume motion when interlock is cleared. This may - * require some combination of interlock switch transitions, interlock - * JSON commands and {clear:n} depending on interlock configuration. - */ \ No newline at end of file +typedef enum { // cycle start and feedhold requests + OPERATION_NULL = 0, // no operation; reverts here when complete + OPERATION_CYCLE_START, // perform a cycle start with no other actions + OPERATION_HOLD, // feedhold in p1 or p2 with no entry actions +// OPERATION_HOLD_WITH_ACTIONS,// feedhold into p2 with entry actions +// OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 +// OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush + OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner + OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner + OPERATION_JOB_KILL, // fast hold followed by queue flush and program end + OPERATION_END_JOG, // fast hold followed by program stop + OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit + OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit + OPERATION_SHUTDOWN, // actions to run when a shutdown is received + OPERATION_PANIC, // actions to run when a panic is received + OPERATION_INTERLOCK_START, // enter an interlock state + OPERATION_INTERLOCK_END, // exit interlocked state + OPERATION_DI_FUNC_STOP, // run digital input STOP function + OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function + OPERATION_DI_FUNC_HALT, // run digital input HALT function + OPERATION_TOOL_CHANGE // run a tool change sequence +} cmOperationType; +*/ + diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index b55e706c..c7db899d 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -169,7 +169,7 @@ struct ioDigitalInputExt { cm_start_hold(); // for now is same as STOP } if (in->action == INPUT_ACTION_HALT) { - cm_halt_all(); // hard stop, including spindle and coolant + cm_halt(); // hard stop, including spindle, coolant and heaters } if (in->action == INPUT_ACTION_ALARM) { char msg[10]; diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index be9304fe..ffb09ccb 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1032,7 +1032,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { - cm->hold_state = FEEDHOLD_P2_EXIT; + cm->hold_state = FEEDHOLD_HOLD_EXIT_PENDING; return (STAT_OK); // will end this exec_aline() with no more movement } // At this point we know we are in a p1 hold diff --git a/g2core/temperature.cpp b/g2core/temperature.cpp index f5209677..09af8221 100644 --- a/g2core/temperature.cpp +++ b/g2core/temperature.cpp @@ -477,7 +477,6 @@ HeaterFan heater_fan1; /* * temperature_init() - * temperature_init() - stop spindle, set speed to zero, and reset values */ void temperature_init() { From 375142f66b9b595927bf9321c5daf6dc9af8fff4 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 13 Mar 2017 15:28:55 -0400 Subject: [PATCH 186/283] checkpoint --- g2core/canonical_machine.h | 4 +- g2core/cycle_feedhold.cpp | 95 ++++++++++++++++++++++++-------------- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index d60d511c..afe1feda 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -286,14 +286,12 @@ typedef struct cmMachine { // struct to manage canonical machin cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleType cycle_type; // cycs cmMotionState motion_state; // mots - cmCycleState cycle_state; // used to manage cycle start cmFeedholdType hold_type; // hold: type of feedhold requested cmFeedholdFinal hold_final; // hold: final state of hold cmFeedholdState hold_state; // hold: feedhold state machine cmFlushState flush_state; // hold: queue flush state machine -// bool hold_exit_requested; // request normal exit from feedhold +++++ -// bool hold_abort_requested; // request emergency exit from feedhold (typically ^d job kill) + cmCycleState cycle_state; // used to manage cycle start bool request_interlock; // enter interlock bool request_interlock_exit; // exit interlock diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 8d1c648f..affa2dfa 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -39,21 +39,22 @@ //#include "xio.h" // DIAGNOSTIC static void _initiate_feedhold(void); -static stat_t _action_feedhold_actions(float *param); -static stat_t _action_feedhold_no_actions(float *param); -static stat_t _action_feedhold_sync(float *param); -static stat_t _action_feedhold_exit_with_actions(float *param); +static void _initiate_cycle_start(void); +static void _initiate_queue_flush(void); +static stat_t _action_feedhold_with_actions(float *param); +static stat_t _action_feedhold_with_no_actions(float *param); +static stat_t _action_feedhold_with_sync(float *param); +static stat_t _action_feedhold_exit_with_actions(float *param); +static stat_t _action_feedhold_exit_with_no_actions(float *param); + +//static stat_t _action_cycle_start(float *param); static stat_t _action_program_stop(float *param); static stat_t _action_program_end(float *param); static stat_t _action_alarm(float *param); static stat_t _action_shutdown(float *param); static stat_t _action_interlock(float *param); -//static stat_t _action_cycle_start(float *param); -//static stat_t _action_hold_no_actions(float *param); -//static stat_t _action_hold_exit_no_actions(float *param); - /**************************************************************************************** * OPERATIONS AND ACTIONS * @@ -192,9 +193,14 @@ stat_t cm_operation_sequencing_callback() if (cm1.hold_state == FEEDHOLD_REQUESTED) { _initiate_feedhold(); } -// if (cm1.flush_state == FLUSH_REQUESTED) { -// _initiate_queue_flush(); -// } + if (cm1.flush_state == FLUSH_REQUESTED) { + _initiate_queue_flush(); + } + if (cm1.cycle_state == CYCLE_START_REQUESTED) { + _initiate_cycle_start(); + } + return (op.run_operation()); +} /* // queue flush won't run until the hold is complete and all (subsequent) motion has stopped @@ -226,9 +232,7 @@ stat_t cm_operation_sequencing_callback() _feedhold_p1_exit(); // run multiple times until actions are complete } */ - return (op.run_operation()); -} /**************************************************************************************** **** Functions ************************************************************************* ****************************************************************************************/ @@ -272,22 +276,34 @@ void cm_request_cycle_start() cm->cycle_state = CYCLE_START_REQUESTED; } -void cm_start_cycle_start() +static void _initiate_cycle_start() { // Normal cycle start - not in a feedhold - if (cm1.hold_state != FEEDHOLD_OFF) { + if (cm1.hold_state == FEEDHOLD_OFF) { cm_cycle_start(); // execute cycle start directly st_request_exec_move(); return; } // Feedhold cycle starts run an operation to complete multiple actions - op.add_action(_action_feedhold_exit_with_actions, nullptr); - op.run_operation(); + if (cm1.hold_state == FEEDHOLD_HOLD) { + switch (cm1.hold_type) { + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_action_feedhold_exit_with_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_action_feedhold_exit_with_no_actions, nullptr); break; } + default: {} + } +// switch (cm1.hold_final) { +// case FEEDHOLD_FINAL_STOP: { op.add_action(_action_program_stop, nullptr); break; } +// case FEEDHOLD_FINAL_END: { op.add_action(_action_program_end, nullptr); break; } +// case FEEDHOLD_FINAL_ALARM: { op.add_action(_action_alarm, nullptr); break; } +// case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_action_shutdown, nullptr); break; } +// case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_action_interlock, nullptr); break; } +// default: {} +// } + } + op.run_operation(); } - - /**************************************************************************************** * cm_request_feedhold() - request a feedhold - d0 not run it yet * _initiate_feedhold() - start feedhold of correct type and finalization @@ -305,11 +321,12 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) static void _initiate_feedhold() { // This function is "safe" and will not initiate a feedhold unless it's OK to. - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state == MOTION_RUN)) { + + if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_action_feedhold_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_action_feedhold_no_actions, nullptr); break; } - case FEEDHOLD_TYPE_SYNC: { op.add_action(_action_feedhold_sync, nullptr); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_action_feedhold_with_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_action_feedhold_with_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_SYNC: { op.add_action(_action_feedhold_with_sync, nullptr); break; } default: {} } switch (cm1.hold_final) { @@ -324,9 +341,9 @@ static void _initiate_feedhold() return; } - // P2 feedhold - if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state == MOTION_RUN)) { - op.add_action(_action_feedhold_sync, nullptr); + // P2 feedholds only allow feedhold sync types + if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { + op.add_action(_action_feedhold_with_sync, nullptr); cm2.hold_state = FEEDHOLD_SYNC; } } @@ -337,12 +354,12 @@ static void _action_feedhold_sync_to_planner(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _action_feedhold_no_actions(float *param) +static stat_t _action_feedhold_with_no_actions(float *param) { return (STAT_OK); } -static stat_t _action_feedhold_sync(float *param) +static stat_t _action_feedhold_with_sync(float *param) { return (STAT_OK); } @@ -373,7 +390,7 @@ static stat_t _action_interlock(float *param) } -static stat_t _action_feedhold_actions(float *param) // Execute Case (5) +static stat_t _action_feedhold_with_actions(float *param) // Execute Case (5) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD_ACTION_START) { @@ -436,17 +453,22 @@ static stat_t _action_feedhold_actions(float *param) // Execute Case (5) } /**************************************************************************************** - * _action_hold_exit_sync() - planner callback to reach sync point - * _action_hold_exit_with_actions() - perform hold exit actions + * _feedhold_exit_sync() - planner callback to reach sync point + * _action_feedhold_exit_with_actions() - perform hold exit actions */ -static void _action_hold_exit_sync(float* vect, bool* flag) +static void _feedhold_exit_sync_to_planner(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD_EXIT_DONE; // penultimate state before transitioning to FEEDHOLD_OFF sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _action_hold_exit_with_actions(float *param) // Execute Cases (6) and (7) +static stat_t _action_feedhold_exit_with_no_actions(float *param) +{ + return (STAT_OK); +} + +static stat_t _action_feedhold_exit_with_actions(float *param) // Execute Cases (6) and (7) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD) { @@ -457,7 +479,7 @@ static stat_t _action_hold_exit_with_actions(float *param) // Execute Cases (6 // do return move though an intermediate point; queue a wait cm2.return_flags[AXIS_Z] = false; cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); - mp_queue_command(_action_hold_exit_sync, nullptr, nullptr); + mp_queue_command(_feedhold_exit_sync_to_planner, nullptr, nullptr); cm1.hold_state = FEEDHOLD_HOLD_EXIT_PENDING; return (STAT_EAGAIN); } @@ -549,6 +571,11 @@ void cm_request_queue_flush() cm->flush_state = FLUSH_REQUESTED; } +static void _initiate_queue_flush() +{ + cm_queue_flush(cm); +} + void cm_queue_flush(cmMachine_t *_cm) { cm_abort_arc(_cm); // kill arcs so they don't just create more alines From c3427cf86814e21cf140886142b8ac6f3b7f782a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 13 Mar 2017 20:12:08 -0400 Subject: [PATCH 187/283] checkpoint --- g2core/canonical_machine.cpp | 1 - g2core/canonical_machine.h | 6 +- g2core/controller.cpp | 2 +- g2core/cycle_feedhold.cpp | 180 +++++++++++++++++++---------------- g2core/g2core.cppproj | 4 +- g2core/gpio.cpp | 12 ++- 6 files changed, 110 insertions(+), 95 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8f34252d..5f6fb982 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1581,7 +1581,6 @@ static void _exec_program_finalize(float *value, bool *flag) void cm_cycle_start() { -// cm_request_operation(OPERATION_CYCLE_START, nullptr); if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles cm->cycle_type = CYCLE_MACHINING; cm->machine_state = MACHINE_CYCLE; diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index afe1feda..5b801da7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -123,11 +123,11 @@ typedef enum { // feedhold type parameter } cmFeedholdType; typedef enum { // feedhold final operation - FEEDHOLD_FINAL_NONE = 0, // normal final state - HOLD or STOP, depending on type + FEEDHOLD_FINAL_CYCLE = 0, // normal final state - HOLD or STOP, depending on type FEEDHOLD_FINAL_STOP, // perform program stop FEEDHOLD_FINAL_END, // perform program end FEEDHOLD_FINAL_ALARM, // perform alarm - FEEDHOLD_FINAL_SHUTDOWN, // perform shutdown + FEEDHOLD_FINAL_SHUTDOWN, // perform shutdown FEEDHOLD_FINAL_INTERLOCK // report as interlock } cmFeedholdFinal; @@ -501,7 +501,7 @@ stat_t cm_feedhold_sequencing_callback(void); // process feedh stat_t cm_feedhold_command_blocker(void); bool cm_has_hold(void); // has hold in primary planner -void cm_start_hold(void); // starts hold in primary planner +//void cm_start_hold(void); // starts hold in primary planner void cm_queue_flush(cmMachine_t *_cm); // queue flush in either planner // Homing cycles (cycle_homing.cpp) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index b08ceeea..24d1d6da 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -238,7 +238,7 @@ static void _dispatch_kernel(const devflags_t flags) } // trap single character commands - if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_FINAL_NONE); } + if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_FINAL_CYCLE); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } // else if (*cs.bufp == '~') { cm_request_exit_hold(); } +++++ else if (*cs.bufp == '~') { cm_request_cycle_start(); } diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index affa2dfa..70b552b9 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -42,18 +42,18 @@ static void _initiate_feedhold(void); static void _initiate_cycle_start(void); static void _initiate_queue_flush(void); -static stat_t _action_feedhold_with_actions(float *param); -static stat_t _action_feedhold_with_no_actions(float *param); -static stat_t _action_feedhold_with_sync(float *param); -static stat_t _action_feedhold_exit_with_actions(float *param); -static stat_t _action_feedhold_exit_with_no_actions(float *param); +static stat_t _feedhold_with_actions(float *param); +static stat_t _feedhold_with_no_actions(float *param); +static stat_t _feedhold_with_sync(float *param); +static stat_t _feedhold_exit_with_actions(float *param); +static stat_t _feedhold_exit_with_no_actions(float *param); -//static stat_t _action_cycle_start(float *param); -static stat_t _action_program_stop(float *param); -static stat_t _action_program_end(float *param); -static stat_t _action_alarm(float *param); -static stat_t _action_shutdown(float *param); -static stat_t _action_interlock(float *param); +static stat_t _cycle_exit(float *param); +static stat_t _program_stop(float *param); +static stat_t _program_end(float *param); +static stat_t _alarm(float *param); +static stat_t _shutdown(float *param); +static stat_t _interlock(float *param); /**************************************************************************************** * OPERATIONS AND ACTIONS @@ -244,7 +244,7 @@ bool cm_has_hold() { return (cm1.hold_state != FEEDHOLD_OFF); } - +/* void cm_start_hold() { // Can only request a feedhold if the machine is in motion and there not one is not already in progress @@ -252,7 +252,7 @@ void cm_start_hold() cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution } } - +*/ stat_t cm_feedhold_command_blocker() { if (cm1.hold_state != FEEDHOLD_OFF) { @@ -288,27 +288,28 @@ static void _initiate_cycle_start() // Feedhold cycle starts run an operation to complete multiple actions if (cm1.hold_state == FEEDHOLD_HOLD) { switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_action_feedhold_exit_with_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_action_feedhold_exit_with_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_exit_with_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_exit_with_no_actions, nullptr); break; } + default: {} + } + switch (cm1.hold_final) { + case FEEDHOLD_FINAL_CYCLE: { op.add_action(_cycle_exit, nullptr); break; } + case FEEDHOLD_FINAL_STOP: { op.add_action(_program_stop, nullptr); break; } + case FEEDHOLD_FINAL_END: { op.add_action(_program_end, nullptr); break; } + case FEEDHOLD_FINAL_ALARM: { op.add_action(_alarm, nullptr); break; } + case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } + case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_interlock, nullptr); break; } default: {} } -// switch (cm1.hold_final) { -// case FEEDHOLD_FINAL_STOP: { op.add_action(_action_program_stop, nullptr); break; } -// case FEEDHOLD_FINAL_END: { op.add_action(_action_program_end, nullptr); break; } -// case FEEDHOLD_FINAL_ALARM: { op.add_action(_action_alarm, nullptr); break; } -// case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_action_shutdown, nullptr); break; } -// case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_action_interlock, nullptr); break; } -// default: {} -// } } op.run_operation(); } /**************************************************************************************** - * cm_request_feedhold() - request a feedhold - d0 not run it yet - * _initiate_feedhold() - start feedhold of correct type and finalization - * _action_feedhold_sync() - planner callback to reach sync point - * _action_feedhold_with_actions() - perform hold entry actions + * cm_request_feedhold() - request a feedhold - d0 not run it yet + * _initiate_feedhold() - start feedhold of correct type and finalization + * _feedhold_sync() - planner callback to reach sync point + * _feedhold_with_actions() - perform hold entry actions */ void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) @@ -316,6 +317,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) cm->hold_type = type; cm->hold_final = final; cm->hold_state = FEEDHOLD_REQUESTED; + _initiate_feedhold(); // attempt to run it immediately } static void _initiate_feedhold() @@ -324,73 +326,73 @@ static void _initiate_feedhold() if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_action_feedhold_with_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_action_feedhold_with_no_actions, nullptr); break; } - case FEEDHOLD_TYPE_SYNC: { op.add_action(_action_feedhold_with_sync, nullptr); break; } - default: {} + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_with_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync, nullptr); break; } + default: { } } switch (cm1.hold_final) { - case FEEDHOLD_FINAL_STOP: { op.add_action(_action_program_stop, nullptr); break; } - case FEEDHOLD_FINAL_END: { op.add_action(_action_program_end, nullptr); break; } - case FEEDHOLD_FINAL_ALARM: { op.add_action(_action_alarm, nullptr); break; } - case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_action_shutdown, nullptr); break; } - case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_action_interlock, nullptr); break; } - default: {} + case FEEDHOLD_FINAL_STOP: { op.add_action(_program_stop, nullptr); break; } + case FEEDHOLD_FINAL_END: { op.add_action(_program_end, nullptr); break; } + case FEEDHOLD_FINAL_ALARM: { op.add_action(_alarm, nullptr); break; } + case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } + case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_interlock, nullptr); break; } + default: { } } - cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec + cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec return; } // P2 feedholds only allow feedhold sync types if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { - op.add_action(_action_feedhold_with_sync, nullptr); + op.add_action(_feedhold_with_sync, nullptr); cm2.hold_state = FEEDHOLD_SYNC; } } -static void _action_feedhold_sync_to_planner(float* vect, bool* flag) +static void _feedhold_sync_to_planner(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD_DONE; // penultimate state before transitioning to FEEDHOLD_HOLD sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _action_feedhold_with_no_actions(float *param) +static stat_t _feedhold_with_no_actions(float *param) { return (STAT_OK); } -static stat_t _action_feedhold_with_sync(float *param) +static stat_t _feedhold_with_sync(float *param) { return (STAT_OK); } -static stat_t _action_program_stop(float *param) +static stat_t _program_stop(float *param) { return (STAT_OK); } -static stat_t _action_program_end(float *param) +static stat_t _program_end(float *param) { return (STAT_OK); } -static stat_t _action_alarm(float *param) +static stat_t _alarm(float *param) { return (STAT_OK); } -static stat_t _action_shutdown(float *param) +static stat_t _shutdown(float *param) { return (STAT_OK); } -static stat_t _action_interlock(float *param) +static stat_t _interlock(float *param) { return (STAT_OK); } -static stat_t _action_feedhold_with_actions(float *param) // Execute Case (5) +static stat_t _feedhold_with_actions(float *param) // Execute Case (5) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD_ACTION_START) { @@ -435,7 +437,7 @@ static stat_t _action_feedhold_with_actions(float *param) // Execute Case (5) } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - mp_queue_command(_action_feedhold_sync_to_planner, nullptr, nullptr); + mp_queue_command(_feedhold_sync_to_planner, nullptr, nullptr); return (STAT_EAGAIN); } @@ -454,7 +456,7 @@ static stat_t _action_feedhold_with_actions(float *param) // Execute Case (5) /**************************************************************************************** * _feedhold_exit_sync() - planner callback to reach sync point - * _action_feedhold_exit_with_actions() - perform hold exit actions + * _feedhold_exit_with_actions() - perform hold exit actions */ static void _feedhold_exit_sync_to_planner(float* vect, bool* flag) @@ -463,12 +465,12 @@ static void _feedhold_exit_sync_to_planner(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _action_feedhold_exit_with_no_actions(float *param) +static stat_t _feedhold_exit_with_no_actions(float *param) { return (STAT_OK); } -static stat_t _action_feedhold_exit_with_actions(float *param) // Execute Cases (6) and (7) +static stat_t _feedhold_exit_with_actions(float *param) // Execute Cases (6) and (7) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD) { @@ -503,22 +505,32 @@ static stat_t _action_feedhold_exit_with_actions(float *param) // Execute Case cm_reset_position_to_absolute_position(cm); cm1.flush_state = FLUSH_OFF; } - +/* // resume motion from primary planner or end cycle if no moves in planner if (mp_has_runnable_buffer(&mp1)) { -// cm_set_motion_state(MOTION_RUN); cm_cycle_start(); st_request_exec_move(); } else { -// cm_set_motion_state(MOTION_STOP); cm_cycle_end(); } cm1.hold_state = FEEDHOLD_OFF; +*/ return (STAT_OK); } return (STAT_EAGAIN); } +static stat_t _cycle_exit(float *param) +{ + if (mp_has_runnable_buffer(&mp1)) { + cm_cycle_start(); + st_request_exec_move(); + } else { + cm_cycle_end(); + } + cm1.hold_state = FEEDHOLD_OFF; + return (STAT_OK); +} /**************************************************************************************** * Queue Flush operations @@ -604,18 +616,18 @@ void cm_queue_flush(cmMachine_t *_cm) //static void _feedhold_p2_exit(void); //static void _feedhold_abort(void); -//static stat_t _action_halt(float *param); -//static stat_t _action_p2_entry(float* param); -//static stat_t _action_parking_move(float *param); -//static stat_t _action_return_move(float *param); -//static stat_t _action_spindle_control(float *param); -//static stat_t _action_coolant_control(float *param); -//static stat_t _action_heater_control(float *param); -//static stat_t _action_output_control(float *param); -//static stat_t _action_queue_flush(float *param); -//static stat_t _action_input_function(float *param); -//static stat_t _action_finalize_program(float *param); -//static stat_t _action_trigger_alarm(float *param); +//static stat_t _halt(float *param); +//static stat_t _p2_entry(float* param); +//static stat_t _parking_move(float *param); +//static stat_t _return_move(float *param); +//static stat_t _spindle_control(float *param); +//static stat_t _coolant_control(float *param); +//static stat_t _heater_control(float *param); +//static stat_t _output_control(float *param); +//static stat_t _queue_flush(float *param); +//static stat_t _input_function(float *param); +//static stat_t _finalize_program(float *param); +//static stat_t _trigger_alarm(float *param); /* typedef enum { // Operation Actions // Initiation actions @@ -760,13 +772,13 @@ stat_t cm_request_operation(cmOperationType operation, float *param) switch (operation) { // case OPERATION_CYCLE_START: { -// op.add_action(_action_cycle_start, nullptr); +// op.add_action(_cycle_start, nullptr); // return(op.run_operation()); // } // Generate hold request if not already in a hold and machine is in motion case OPERATION_HOLD: { - op.add_action(_action_hold_with_actions, param); + op.add_action(_hold_with_actions, param); break; } @@ -778,7 +790,7 @@ stat_t cm_request_operation(cmOperationType operation, float *param) } */ /* -static stat_t _action_cycle_start(float *param) +static stat_t _cycle_start(float *param) { if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles cm->cycle_type = CYCLE_MACHINING; @@ -790,12 +802,12 @@ static stat_t _action_cycle_start(float *param) */ /* - * _action_hold_with_actions() - initiate a feedhold in the active planner - p1 or p2 + * _hold_with_actions() - initiate a feedhold in the active planner - p1 or p2 * * Return STAT_OK once hold has been reached */ /* -static stat_t _action_hold_with_actions(float *param) +static stat_t _hold_with_actions(float *param) { // Not in feedhold if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { @@ -814,18 +826,18 @@ static stat_t _action_hold_with_actions(float *param) } */ -//static stat_t _action_halt(float *param) { return (STAT_OK); } -//static stat_t _action_p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled -//static stat_t _action_parking_move(float *param) { return (STAT_OK); } -//static stat_t _action_return_move(float *param) { return (STAT_OK); } -//static stat_t _action_spindle_control(float *param) { return (STAT_OK); } -//static stat_t _action_coolant_control(float *param) { return (STAT_OK); } -//static stat_t _action_heater_control(float *param) { return (STAT_OK); } -//static stat_t _action_output_control(float *param) { return (STAT_OK); } -//static stat_t _action_queue_flush(float *param) { return (STAT_OK); } -//static stat_t _action_input_function(float *param) { return (STAT_OK); } -//static stat_t _action_finalize_program(float *param) { return (STAT_OK); } -//static stat_t _action_trigger_alarm(float *param) { return (STAT_OK); } +//static stat_t _halt(float *param) { return (STAT_OK); } +//static stat_t _p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled +//static stat_t _parking_move(float *param) { return (STAT_OK); } +//static stat_t _return_move(float *param) { return (STAT_OK); } +//static stat_t _spindle_control(float *param) { return (STAT_OK); } +//static stat_t _coolant_control(float *param) { return (STAT_OK); } +//static stat_t _heater_control(float *param) { return (STAT_OK); } +//static stat_t _output_control(float *param) { return (STAT_OK); } +//static stat_t _queue_flush(float *param) { return (STAT_OK); } +//static stat_t _input_function(float *param) { return (STAT_OK); } +//static stat_t _finalize_program(float *param) { return (STAT_OK); } +//static stat_t _trigger_alarm(float *param) { return (STAT_OK); } /**************************************************************************************** **** Feedholds ************************************************************************* diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index bb1cf7a0..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index c7db899d..c7d0ef02 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -143,7 +143,8 @@ struct ioDigitalInputExt { if (in->homing_mode) { if (in->edge == INPUT_EDGE_LEADING) { // we only want the leading edge to fire en_take_encoder_snapshot(); - cm_start_hold(); +//+++++ cm_start_hold(); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); } return; } @@ -154,7 +155,8 @@ struct ioDigitalInputExt { // Probing tests the start condition for the correct direction ahead of time. // If we see any edge, it's the right one. en_take_encoder_snapshot(); - cm_start_hold(); +//+++++ cm_start_hold(); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); return; } @@ -163,10 +165,12 @@ struct ioDigitalInputExt { // trigger the action on leading edges if (in->edge == INPUT_EDGE_LEADING) { if (in->action == INPUT_ACTION_STOP) { - cm_start_hold(); +//+++++ cm_start_hold(); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); } if (in->action == INPUT_ACTION_FAST_STOP) { - cm_start_hold(); // for now is same as STOP +//+++++ cm_start_hold(); // for now is same as STOP + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); } if (in->action == INPUT_ACTION_HALT) { cm_halt(); // hard stop, including spindle, coolant and heaters From 6811849aa30a38f6f1b0da7a170acbf88cb829b6 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 14 Mar 2017 07:07:03 -0400 Subject: [PATCH 188/283] Milestone: First time it makes it all the way through a !~ cycle with actions --- g2core/alarm.cpp | 4 +- g2core/canonical_machine.h | 169 +++++++++++++------------- g2core/controller.cpp | 5 +- g2core/cycle_feedhold.cpp | 238 ++++++++++++++++++------------------- g2core/gpio.cpp | 12 +- g2core/plan_exec.cpp | 19 +-- 6 files changed, 216 insertions(+), 231 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index f38ffd4c..1e6f885b 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -166,7 +166,7 @@ stat_t cm_alarm(const stat_t status, const char *msg) (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't alarm if already in an alarm state } - cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_FINAL_ALARM); // fast stop and alarm + cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_EXIT_ALARM); // fast stop and alarm rpt_exception(status, msg); // send alarm message sr_request_status_report(SR_REQUEST_TIMED); return (status); @@ -194,7 +194,7 @@ stat_t cm_shutdown(const stat_t status, const char *msg) if ((cm->machine_state == MACHINE_SHUTDOWN) || (cm->machine_state == MACHINE_PANIC)) { return (STAT_OK); // don't shutdown if shutdown or panic'd } - cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_FINAL_SHUTDOWN); // fast stop and shutdown + cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_EXIT_SHUTDOWN); // fast stop and shutdown // cm_halt_motion(); // halt motors (may have already been done from GPIO) // spindle_reset(); // stop spindle immediately and set speed to 0 RPM diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 5b801da7..86e9eff7 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -63,131 +63,124 @@ // ### LAYER 8 CRITICAL REGION ### // ### DO NOT CHANGE THESE ENUMERATIONS WITHOUT COMMUNITY INPUT ### -typedef enum { // check alignment with messages in config.c / msg_stat strings - COMBINED_INITIALIZING = 0, // [0] machine is initializing - COMBINED_READY, // [1] machine is ready for use - COMBINED_ALARM, // [2] machine in alarm state - COMBINED_PROGRAM_STOP, // [3] program stop/no more blocks - COMBINED_PROGRAM_END, // [4] program end - COMBINED_RUN, // [5] machine is running - COMBINED_HOLD, // [6] machine is holding - COMBINED_PROBE, // [7] probe cycle activ - COMBINED_CYCLE, // [8] reserved for canned cycles - COMBINED_HOMING, // [9] homing cycle active - COMBINED_JOG, // [10] jogging cycle active - COMBINED_INTERLOCK, // [11] machine in safety interlock hold - COMBINED_SHUTDOWN, // [12] machine in shutdown state - COMBINED_PANIC // [13] machine in panic state +typedef enum { // check alignment with messages in config.c / msg_stat strings + COMBINED_INITIALIZING = 0, // [0] machine is initializing + COMBINED_READY, // [1] machine is ready for use + COMBINED_ALARM, // [2] machine in alarm state + COMBINED_PROGRAM_STOP, // [3] program stop/no more blocks + COMBINED_PROGRAM_END, // [4] program end + COMBINED_RUN, // [5] machine is running + COMBINED_HOLD, // [6] machine is holding + COMBINED_PROBE, // [7] probe cycle activ + COMBINED_CYCLE, // [8] reserved for canned cycles + COMBINED_HOMING, // [9] homing cycle active + COMBINED_JOG, // [10] jogging cycle active + COMBINED_INTERLOCK, // [11] machine in safety interlock hold + COMBINED_SHUTDOWN, // [12] machine in shutdown state + COMBINED_PANIC // [13] machine in panic state } cmCombinedState; //### END CRITICAL REGION ### -typedef enum { // Note: MachineState signals if the machine is in cycle (5) or some other non-cycle state - MACHINE_INITIALIZING = 0, // machine is initializing - MACHINE_READY, // machine is ready for use but idle - MACHINE_ALARM, // machine is in alarm state - MACHINE_PROGRAM_STOP, // no blocks to run; like PROGRAM_END but without the M2 to reset gcode state - MACHINE_PROGRAM_END, // program end (same as MACHINE_READY, really...) - MACHINE_CYCLE, // machine is in cycle, running; blocks still to run, or steppers are busy - MACHINE_INTERLOCK, // machine is in interlock state - MACHINE_SHUTDOWN, // machine is in shutdown state - MACHINE_PANIC // machine is in panic state +typedef enum { // Note: MachineState signals if the machine is in cycle (5) or some other non-cycle state + MACHINE_INITIALIZING = 0, // machine is initializing + MACHINE_READY, // machine is ready for use but idle + MACHINE_ALARM, // machine is in alarm state + MACHINE_PROGRAM_STOP, // no blocks to run; like PROGRAM_END but without the M2 to reset gcode state + MACHINE_PROGRAM_END, // program end (same as MACHINE_READY, really...) + MACHINE_CYCLE, // machine is in cycle, running; blocks still to run, or steppers are busy + MACHINE_INTERLOCK, // machine is in interlock state + MACHINE_SHUTDOWN, // machine is in shutdown state + MACHINE_PANIC // machine is in panic state } cmMachineState; typedef enum { - MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue - MOTION_RUN // machine is in motion: set when the steppers execute an ALINE segment + MOTION_STOP = 0, // motion has stopped: set when the steppers reach the end of the planner queue + MOTION_RUN // machine is in motion: set when the steppers execute an ALINE segment } cmMotionState; -typedef enum { // state machine for cycle start - CYCLE_START_NONE = 0, // not in a cycle +typedef enum { // state machine for cycle start + CYCLE_START_OFF = 0, // not requested CYCLE_START_REQUESTED, CYCLE_START_COMPLETE } cmCycleState; typedef enum { - CYCLE_NONE = 0, // not in a cycle - CYCLE_MACHINING, // in normal machining cycle - CYCLE_HOMING, // in homing cycle - CYCLE_PROBE, // in probe cycle - CYCLE_JOG // in jogging cycle -// CYCLE_G81 // illustration of canned cycles + CYCLE_NONE = 0, // not in a cycle + CYCLE_MACHINING, // in normal machining cycle + CYCLE_HOMING, // in homing cycle + CYCLE_PROBE, // in probe cycle + CYCLE_JOG // in jogging cycle +// CYCLE_G81 // illustration of canned cycles // ... } cmCycleType; -typedef enum { // feedhold type parameter - FEEDHOLD_TYPE_ACTIONS = 0, // feedhold at max jerk with actions - FEEDHOLD_TYPE_NO_ACTIONS, // feedhold at max jerk with no actions - FEEDHOLD_TYPE_SYNC, // feedhold at max jerk with queue flush and sync command - FEEDHOLD_TYPE_FAST, // feedhold at high jerk with no actions. Can resume - FEEDHOLD_TYPE_SCRAM // feedhold at high jerk and stop all active devices +typedef enum { // feedhold type parameter + FEEDHOLD_TYPE_ACTIONS = 0, // feedhold at max jerk with actions + FEEDHOLD_TYPE_NO_ACTIONS, // feedhold at max jerk with no actions + FEEDHOLD_TYPE_SYNC, // feedhold at max jerk with queue flush and sync command + FEEDHOLD_TYPE_FAST, // feedhold at high jerk with no actions. Can resume + FEEDHOLD_TYPE_SCRAM // feedhold at high jerk and stop all active devices } cmFeedholdType; -typedef enum { // feedhold final operation - FEEDHOLD_FINAL_CYCLE = 0, // normal final state - HOLD or STOP, depending on type - FEEDHOLD_FINAL_STOP, // perform program stop - FEEDHOLD_FINAL_END, // perform program end - FEEDHOLD_FINAL_ALARM, // perform alarm - FEEDHOLD_FINAL_SHUTDOWN, // perform shutdown - FEEDHOLD_FINAL_INTERLOCK // report as interlock +typedef enum { // feedhold final operation + FEEDHOLD_EXIT_CYCLE = 0, // exit feedhold with cycle restart - HOLD or STOP, depending on type + FEEDHOLD_EXIT_FLUSH, // exit feedhold with flush + FEEDHOLD_EXIT_STOP, // perform program stop + FEEDHOLD_EXIT_END, // perform program end + FEEDHOLD_EXIT_ALARM, // perform alarm + FEEDHOLD_EXIT_SHUTDOWN, // perform shutdown + FEEDHOLD_EXIT_INTERLOCK // report as interlock } cmFeedholdFinal; -typedef enum { // feedhold state machine -// FEEDHOLD_P1_EXIT = -1, // set when p1 feedhold is due to exit - FEEDHOLD_OFF = 0, // no feedhold in effect - FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet - FEEDHOLD_SYNC, // start hold - sync to latest aline segment - FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero - FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero - FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet - FEEDHOLD_MOTION_STOPPING, // waiting for motors to have stopped at hold point (motion stop) - FEEDHOLD_MOTION_STOPPED, // motion has stopped at hold point -// FEEDHOLD_P2_START, // enter secondary planner and perform feedhold actions (once) -// FEEDHOLD_P2_WAIT, // wait for feedhold actions to complete - - FEEDHOLD_HOLD_ACTION_START, - FEEDHOLD_HOLD_PENDING, // wait for feedhold actions to complete - FEEDHOLD_HOLD_DONE, // - - FEEDHOLD_HOLD, // holding (steady state) Must be last state - - FEEDHOLD_HOLD_EXIT_PENDING, // performing exit actions - FEEDHOLD_HOLD_EXIT_DONE, // completed exit actions - -// FEEDHOLD_P2_EXIT // set when p2 feedhold is finishing +typedef enum { // feedhold state machine + FEEDHOLD_OFF = 0, // no feedhold in effect + FEEDHOLD_REQUESTED, // feedhold has been requested but not started yet + FEEDHOLD_SYNC, // start hold - sync to latest aline segment + FEEDHOLD_DECEL_CONTINUE, // in deceleration that will not end at zero + FEEDHOLD_DECEL_TO_ZERO, // in deceleration that will go to zero + FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet + FEEDHOLD_MOTION_STOPPING, // waiting for motors to have stopped at hold point (motion stop) + FEEDHOLD_MOTION_STOPPED, // motion has stopped at hold point + FEEDHOLD_HOLD_ACTIONS_START, + FEEDHOLD_HOLD_ACTIONS_PENDING, // wait for feedhold actions to complete + FEEDHOLD_HOLD_ACTIONS_COMPLETE, // + FEEDHOLD_HOLD, // HOLDING (steady state) + FEEDHOLD_EXIT_ACTIONS_PENDING, // performing exit actions + FEEDHOLD_EXIT_ACTIONS_COMPLETE // completed exit actions } cmFeedholdState; -typedef enum { // applies to cm->homing_state - HOMING_NOT_HOMED = 0, // machine is not homed (0=false) - HOMING_HOMED = 1, // machine is homed (1=true) - HOMING_WAITING // machine waiting to be homed +typedef enum { // applies to cm->homing_state + HOMING_NOT_HOMED = 0, // machine is not homed (0=false) + HOMING_HOMED = 1, // machine is homed (1=true) + HOMING_WAITING // machine waiting to be homed } cmHomingState; -typedef enum { // applies to cm->probe_state - PROBE_FAILED = 0, // probe reached endpoint without triggering - PROBE_SUCCEEDED = 1, // probe was triggered, cm.probe_results has position - PROBE_WAITING = 2 // probe is waiting to be started or is running +typedef enum { // applies to cm->probe_state + PROBE_FAILED = 0, // probe reached endpoint without triggering + PROBE_SUCCEEDED = 1, // probe was triggered, cm.probe_results has position + PROBE_WAITING = 2 // probe is waiting to be started or is running } cmProbeState; typedef enum { - SAFETY_INTERLOCK_ENGAGED = 0, // meaning the interlock input is CLOSED (low) + SAFETY_INTERLOCK_ENGAGED = 0, // meaning the interlock input is CLOSED (low) SAFETY_INTERLOCK_DISENGAGED } cmSafetyState; -typedef enum { // feed override state machine +typedef enum { // feed override state machine MFO_OFF = 0, MFO_REQUESTED, MFO_SYNC } cmOverrideState; -typedef enum { // queue flush state machine - FLUSH_OFF = 0, // no queue flush in effect - FLUSH_REQUESTED, // flush has been requested but not started yet - FLUSH_WAS_RUN // transient state to note that a queue flush has been run +typedef enum { // queue flush state machine + FLUSH_OFF = 0, // no queue flush in effect + FLUSH_REQUESTED, // flush has been requested but not started yet + FLUSH_WAS_RUN // transient state to note that a queue flush has been run } cmFlushState; -typedef enum { // Motion profiles - PROFILE_NORMAL = 0, // Normal jerk in effect - PROFILE_FAST // High speed jerk in effect +typedef enum { // Motion profiles + PROFILE_NORMAL = 0, // Normal jerk in effect + PROFILE_FAST // High speed jerk in effect } cmMotion_profile; /***************************************************************************** diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 24d1d6da..882ebede 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -238,9 +238,8 @@ static void _dispatch_kernel(const devflags_t flags) } // trap single character commands - if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_FINAL_CYCLE); } + if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } -// else if (*cs.bufp == '~') { cm_request_exit_hold(); } +++++ else if (*cs.bufp == '~') { cm_request_cycle_start(); } else if (*cs.bufp == EOT) { cm_job_kill(); } else if (*cs.bufp == ENQ) { controller_request_enquiry(); } @@ -435,7 +434,7 @@ static stat_t _interlock_handler(void) if (cm->safety_interlock_disengaged != 0) { cm->safety_interlock_disengaged = 0; cm->safety_interlock_state = SAFETY_INTERLOCK_DISENGAGED; - cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_FINAL_INTERLOCK); // may have already requested STOP as INPUT_ACTION + cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_INTERLOCK); // may have already requested STOP as INPUT_ACTION // feedhold was initiated by input action in gpio // pause spindle // pause coolant diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 70b552b9..51986600 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -42,13 +42,16 @@ static void _initiate_feedhold(void); static void _initiate_cycle_start(void); static void _initiate_queue_flush(void); +// Feedhold actions static stat_t _feedhold_with_actions(float *param); static stat_t _feedhold_with_no_actions(float *param); static stat_t _feedhold_with_sync(float *param); -static stat_t _feedhold_exit_with_actions(float *param); -static stat_t _feedhold_exit_with_no_actions(float *param); +static stat_t _feedhold_restart_with_actions(float *param); +static stat_t _feedhold_restart_with_no_actions(float *param); -static stat_t _cycle_exit(float *param); +// Feedhold exits (finalization) +static stat_t _restart_cycle(float *param); +static stat_t _restart_flush(float *param); static stat_t _program_stop(float *param); static stat_t _program_end(float *param); static stat_t _alarm(float *param); @@ -71,11 +74,15 @@ static stat_t _interlock(float *param); * STAT_OK - operation has completed successfully * STAT_EAGAIN - operation needs to be re-entered to complete (via operation callback) * STAT_XXXXX - any other status is an error that quits the operation + * + * Constraints: + * - Operations run to completion. They are not preemptable (at this point) + * - Actions cannot be added to an operation once it is being run */ /*** Object Definitions ***/ -#define PARAM_MAX 4 // maximum number of parameters that can be passed in param +#define PARAM_MAX 2 // maximum number of parameters that can be passed in param #define ACTION_MAX 12 // maximum actions that can be queued for an operation typedef stat_t (*action_exec_t)(float *); // callback to action execution function @@ -123,9 +130,7 @@ typedef struct cmOperation { // operation runner object }; stat_t run_operation(void) { - if (run->func == NULL) { - return (STAT_NOOP); - } // not an error. This is normal. + if (run->func == NULL) { return (STAT_NOOP); } // not an error. This is normal. in_operation = true; // disable add_action during operations stat_t status; @@ -136,9 +141,7 @@ typedef struct cmOperation { // operation runner object return (STAT_OK); } } - if (status == STAT_EAGAIN) { - return (STAT_EAGAIN); - } + if (status == STAT_EAGAIN) { return (STAT_EAGAIN); } reset(); // reset operation if action threw an error return (status); // return error code }; @@ -244,15 +247,7 @@ bool cm_has_hold() { return (cm1.hold_state != FEEDHOLD_OFF); } -/* -void cm_start_hold() -{ - // Can only request a feedhold if the machine is in motion and there not one is not already in progress - if ((cm1.hold_state == FEEDHOLD_OFF) && (mp_has_runnable_buffer(mp))) { - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } -} -*/ + stat_t cm_feedhold_command_blocker() { if (cm1.hold_state != FEEDHOLD_OFF) { @@ -261,14 +256,9 @@ stat_t cm_feedhold_command_blocker() return (STAT_OK); } -void cm_request_alarm() -{ - -} - /**************************************************************************************** - * request_cycle_start() - set request flag only - * start_cycle_start() - run the cycle start + * cm_request_cycle_start() - set request flag only + * _initiate_cycle_start() - run the cycle start */ void cm_request_cycle_start() @@ -280,6 +270,7 @@ static void _initiate_cycle_start() { // Normal cycle start - not in a feedhold if (cm1.hold_state == FEEDHOLD_OFF) { + cm1.cycle_state = CYCLE_START_OFF; cm_cycle_start(); // execute cycle start directly st_request_exec_move(); return; @@ -287,83 +278,23 @@ static void _initiate_cycle_start() // Feedhold cycle starts run an operation to complete multiple actions if (cm1.hold_state == FEEDHOLD_HOLD) { + cm1.cycle_state = CYCLE_START_OFF; switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_exit_with_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_exit_with_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_with_no_actions, nullptr); break; } default: {} } switch (cm1.hold_final) { - case FEEDHOLD_FINAL_CYCLE: { op.add_action(_cycle_exit, nullptr); break; } - case FEEDHOLD_FINAL_STOP: { op.add_action(_program_stop, nullptr); break; } - case FEEDHOLD_FINAL_END: { op.add_action(_program_end, nullptr); break; } - case FEEDHOLD_FINAL_ALARM: { op.add_action(_alarm, nullptr); break; } - case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } - case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_interlock, nullptr); break; } + case FEEDHOLD_EXIT_CYCLE: { op.add_action(_restart_cycle, nullptr); break; } + case FEEDHOLD_EXIT_FLUSH: { op.add_action(_restart_flush, nullptr); break; } + case FEEDHOLD_EXIT_STOP: { op.add_action(_program_stop, nullptr); break; } + case FEEDHOLD_EXIT_END: { op.add_action(_program_end, nullptr); break; } + case FEEDHOLD_EXIT_ALARM: { op.add_action(_alarm, nullptr); break; } + case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } + case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_interlock, nullptr); break; } default: {} } } - op.run_operation(); -} - -/**************************************************************************************** - * cm_request_feedhold() - request a feedhold - d0 not run it yet - * _initiate_feedhold() - start feedhold of correct type and finalization - * _feedhold_sync() - planner callback to reach sync point - * _feedhold_with_actions() - perform hold entry actions - */ - -void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) -{ - cm->hold_type = type; - cm->hold_final = final; - cm->hold_state = FEEDHOLD_REQUESTED; - _initiate_feedhold(); // attempt to run it immediately -} - -static void _initiate_feedhold() -{ - // This function is "safe" and will not initiate a feedhold unless it's OK to. - - if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { - switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_with_no_actions, nullptr); break; } - case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync, nullptr); break; } - default: { } - } - switch (cm1.hold_final) { - case FEEDHOLD_FINAL_STOP: { op.add_action(_program_stop, nullptr); break; } - case FEEDHOLD_FINAL_END: { op.add_action(_program_end, nullptr); break; } - case FEEDHOLD_FINAL_ALARM: { op.add_action(_alarm, nullptr); break; } - case FEEDHOLD_FINAL_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } - case FEEDHOLD_FINAL_INTERLOCK: { op.add_action(_interlock, nullptr); break; } - default: { } - } - cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec - return; - } - - // P2 feedholds only allow feedhold sync types - if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { - op.add_action(_feedhold_with_sync, nullptr); - cm2.hold_state = FEEDHOLD_SYNC; - } -} - -static void _feedhold_sync_to_planner(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_HOLD_DONE; // penultimate state before transitioning to FEEDHOLD_HOLD - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} - -static stat_t _feedhold_with_no_actions(float *param) -{ - return (STAT_OK); -} - -static stat_t _feedhold_with_sync(float *param) -{ - return (STAT_OK); } static stat_t _program_stop(float *param) @@ -391,12 +322,74 @@ static stat_t _interlock(float *param) return (STAT_OK); } +/**************************************************************************************** + * cm_request_feedhold() - request a feedhold - d0 not run it yet + * _initiate_feedhold() - start feedhold of correct type and finalization + * _feedhold_sync_to_planner() - planner callback to reach sync point + * _feedhold_with_sync() + * _feedhold_with_no_actions() + * _feedhold_with_actions() - perform hold entry actions + */ + +void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) +{ + cm->hold_type = type; + cm->hold_final = final; + cm->hold_state = FEEDHOLD_REQUESTED; + _initiate_feedhold(); // attempt to run it immediately +} + +static void _initiate_feedhold() +{ + // This function is "safe" and will not initiate a feedhold unless it's OK to. + + if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { + switch (cm1.hold_type) { + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions, nullptr); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_with_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync, nullptr); break; } + default: { } + } + switch (cm1.hold_final) { + case FEEDHOLD_EXIT_STOP: { op.add_action(_program_stop, nullptr); break; } + case FEEDHOLD_EXIT_END: { op.add_action(_program_end, nullptr); break; } + case FEEDHOLD_EXIT_ALARM: { op.add_action(_alarm, nullptr); break; } + case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } + case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_interlock, nullptr); break; } + default: { } + } + cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec + return; + } + + // P2 feedholds only allow feedhold sync types + if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { + op.add_action(_feedhold_with_sync, nullptr); + cm2.hold_state = FEEDHOLD_SYNC; + } +} + +static void _feedhold_sync_to_planner(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_HOLD + sr_request_status_report(SR_REQUEST_IMMEDIATE); +} + +static stat_t _feedhold_with_no_actions(float *param) +{ + return (STAT_OK); +} + +static stat_t _feedhold_with_sync(float *param) +{ + return (STAT_OK); +} static stat_t _feedhold_with_actions(float *param) // Execute Case (5) { // Check to run first-time code - if (cm1.hold_state == FEEDHOLD_HOLD_ACTION_START) { - cm->hold_state = FEEDHOLD_HOLD_PENDING; // next state + if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_START) { + cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner @@ -442,12 +435,12 @@ static stat_t _feedhold_with_actions(float *param) // Execute Case (5) } // wait for hold actions to complete - if (cm1.hold_state == FEEDHOLD_HOLD_PENDING) { + if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_PENDING) { return (STAT_EAGAIN); } - // finalize feedhold exit - if (cm1.hold_state == FEEDHOLD_HOLD_DONE) { + // finalize feedhold entry after callback (this is needed so we can return STAT_OK) + if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_COMPLETE) { cm1.hold_state = FEEDHOLD_HOLD; return (STAT_OK); } @@ -455,44 +448,45 @@ static stat_t _feedhold_with_actions(float *param) // Execute Case (5) } /**************************************************************************************** - * _feedhold_exit_sync() - planner callback to reach sync point - * _feedhold_exit_with_actions() - perform hold exit actions + * _feedhold_restart_sync_to_planner() - planner callback to reach sync point + * _feedhold_restart_with_no_actions() - perform hold restart with no actions + * _feedhold_restart_with_actions() - perform hold restart with actions */ -static void _feedhold_exit_sync_to_planner(float* vect, bool* flag) +static void _feedhold_restart_sync_to_planner(float* vect, bool* flag) { - cm1.hold_state = FEEDHOLD_HOLD_EXIT_DONE; // penultimate state before transitioning to FEEDHOLD_OFF + cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_OFF sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _feedhold_exit_with_no_actions(float *param) +static stat_t _feedhold_restart_with_no_actions(float *param) { return (STAT_OK); } -static stat_t _feedhold_exit_with_actions(float *param) // Execute Cases (6) and (7) +static stat_t _feedhold_restart_with_actions(float *param) // Execute Cases (6) and (7) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD) { // perform end-hold actions --- while still in secondary machine coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused - + // do return move though an intermediate point; queue a wait cm2.return_flags[AXIS_Z] = false; cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); - mp_queue_command(_feedhold_exit_sync_to_planner, nullptr, nullptr); - cm1.hold_state = FEEDHOLD_HOLD_EXIT_PENDING; + mp_queue_command(_feedhold_restart_sync_to_planner, nullptr, nullptr); + cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_PENDING; return (STAT_EAGAIN); } // wait for exit actions to complete - if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_PENDING) { + if (cm1.hold_state == FEEDHOLD_EXIT_ACTIONS_PENDING) { return (STAT_EAGAIN); } // finalize feedhold exit - if (cm1.hold_state == FEEDHOLD_HOLD_EXIT_DONE) { + if (cm1.hold_state == FEEDHOLD_EXIT_ACTIONS_COMPLETE) { // return to primary planner (p1) cm = &cm1; @@ -505,29 +499,25 @@ static stat_t _feedhold_exit_with_actions(float *param) // Execute Cases (6) a cm_reset_position_to_absolute_position(cm); cm1.flush_state = FLUSH_OFF; } -/* - // resume motion from primary planner or end cycle if no moves in planner - if (mp_has_runnable_buffer(&mp1)) { - cm_cycle_start(); - st_request_exec_move(); - } else { - cm_cycle_end(); - } - cm1.hold_state = FEEDHOLD_OFF; -*/ return (STAT_OK); } return (STAT_EAGAIN); } -static stat_t _cycle_exit(float *param) +static stat_t _restart_cycle(float *param) { + cm1.hold_state = FEEDHOLD_OFF; // must precede st_request_exec_move() if (mp_has_runnable_buffer(&mp1)) { cm_cycle_start(); st_request_exec_move(); } else { cm_cycle_end(); } + return (STAT_OK); +} + +static stat_t _restart_flush(float *param) +{ cm1.hold_state = FEEDHOLD_OFF; return (STAT_OK); } @@ -607,6 +597,8 @@ void cm_queue_flush(cmMachine_t *_cm) + + //static stat_t _run_p1_hold_entry_actions(void); //static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index c7d0ef02..00cb39e6 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -143,8 +143,7 @@ struct ioDigitalInputExt { if (in->homing_mode) { if (in->edge == INPUT_EDGE_LEADING) { // we only want the leading edge to fire en_take_encoder_snapshot(); -//+++++ cm_start_hold(); - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); } return; } @@ -155,8 +154,7 @@ struct ioDigitalInputExt { // Probing tests the start condition for the correct direction ahead of time. // If we see any edge, it's the right one. en_take_encoder_snapshot(); -//+++++ cm_start_hold(); - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); return; } @@ -165,12 +163,10 @@ struct ioDigitalInputExt { // trigger the action on leading edges if (in->edge == INPUT_EDGE_LEADING) { if (in->action == INPUT_ACTION_STOP) { -//+++++ cm_start_hold(); - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); } if (in->action == INPUT_ACTION_FAST_STOP) { -//+++++ cm_start_hold(); // for now is same as STOP - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_FINAL_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); } if (in->action == INPUT_ACTION_HALT) { cm_halt(); // hard stop, including spindle, coolant and heaters diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index ffb09ccb..1fe32a0d 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -484,9 +484,8 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->hold_state != FEEDHOLD_OFF) { - // if FEEDHOLD_P2_START, FEEDHOLD_P2_WAIT, FEEDHOLD HOLD or FEEDHOLD_P2_EXIT -// if (cm->hold_state >= FEEDHOLD_P2_START) { // handles _exec_aline_feedhold_processing case (7) - if (cm->hold_state >= FEEDHOLD_HOLD_ACTION_START) { // handles _exec_aline_feedhold_processing case (7) + // if running actions, or in HOLD state, or exiting with actions + if (cm->hold_state >= FEEDHOLD_HOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } // STAT_OK terminates aline execution for this move @@ -1032,18 +1031,20 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { - cm->hold_state = FEEDHOLD_HOLD_EXIT_PENDING; +// cm->hold_type = FEEDHOLD_TYPE_SYNC; // force to a sync hold + cm->hold_state = FEEDHOLD_HOLD; return (STAT_OK); // will end this exec_aline() with no more movement } // At this point we know we are in a p1 hold - + // If probing or homing, exit the move and advance to the _motion_end_callback()'s. // Stop the runtime, clear the run buffer and do not transition to p2 planner. else if ((cm->cycle_type == CYCLE_HOMING) || (cm->cycle_type == CYCLE_PROBE)) { +// else if (cm->hold_type == FEEDHOLD_TYPE_SYNC) { mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement mp_free_run_buffer(); // free buffer and enable finalization move to get loaded cm->hold_state = FEEDHOLD_OFF; - } + } // In a regular p1 hold. Motion has stopped, so we can rely on positions and other values to be stable else { @@ -1057,7 +1058,11 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) st_request_forward_plan(); // replan the current bf buffer // Set state to enable transition to p2 and perform entry actions in the p2 planner - cm->hold_state = FEEDHOLD_HOLD_ACTION_START; // signal operations runner to start actions + if (cm->hold_type == FEEDHOLD_TYPE_ACTIONS) { + cm->hold_state = FEEDHOLD_HOLD_ACTIONS_START; // signal to start entry actions + } else { + cm->hold_state = FEEDHOLD_HOLD; // achieved hold state + } } sr_request_status_report(SR_REQUEST_IMMEDIATE); From b58ceba8e370a7052246126811fea30e8f75fbad Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 14 Mar 2017 09:53:20 -0400 Subject: [PATCH 189/283] Testing --- g2core/alarm.cpp | 4 ++-- g2core/canonical_machine.cpp | 1 + g2core/canonical_machine.h | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 1e6f885b..c1a22400 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -196,7 +196,7 @@ stat_t cm_shutdown(const stat_t status, const char *msg) } cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_EXIT_SHUTDOWN); // fast stop and shutdown -// cm_halt_motion(); // halt motors (may have already been done from GPIO) +//+++++ cm_halt_motion(); // halt motors (may have already been done from GPIO) // spindle_reset(); // stop spindle immediately and set speed to 0 RPM // coolant_reset(); // stop coolant immediately // temperature_reset(); // turn off heaters and fans @@ -235,7 +235,7 @@ stat_t cm_panic(const stat_t status, const char *msg) spindle_reset(); // stop spindle immediately and set speed to 0 RPM coolant_reset(); // stop coolant immediately temperature_reset(); // turn off heaters and fans - cm_queue_flush(&cm1); // flush all queues and reset positions +//+++++ cm_queue_flush(&cm1); // flush all queues and reset positions cm1.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable cm2.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 5f6fb982..955fdd38 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1579,6 +1579,7 @@ static void _exec_program_finalize(float *value, bool *flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); // request a final and full status report (not filtered) } +// Will start a cycle regardless of whether the planner has moves or not void cm_cycle_start() { if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 86e9eff7..21c7672b 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -494,8 +494,6 @@ stat_t cm_feedhold_sequencing_callback(void); // process feedh stat_t cm_feedhold_command_blocker(void); bool cm_has_hold(void); // has hold in primary planner -//void cm_start_hold(void); // starts hold in primary planner -void cm_queue_flush(cmMachine_t *_cm); // queue flush in either planner // Homing cycles (cycle_homing.cpp) stat_t cm_homing_cycle_start(const float axes[], const bool flags[]); // G28.2 From eed0e5a89ab774d1e03b5814592075a8bfe73c50 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 14 Mar 2017 11:18:51 -0400 Subject: [PATCH 190/283] Passes !, ~ and % tests, but still failing combinations --- g2core/canonical_machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 21c7672b..8128e2ca 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -175,7 +175,7 @@ typedef enum { // feed override state machine typedef enum { // queue flush state machine FLUSH_OFF = 0, // no queue flush in effect FLUSH_REQUESTED, // flush has been requested but not started yet - FLUSH_WAS_RUN // transient state to note that a queue flush has been run +// FLUSH_WAS_RUN // transient state to note that a queue flush has been run } cmFlushState; typedef enum { // Motion profiles From dd0b0d95a090667dea73661bbc9f65605fc18773 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 14 Mar 2017 11:44:03 -0400 Subject: [PATCH 191/283] Removed params args from actions. Simplified things. --- g2core/cycle_feedhold.cpp | 788 +++++++++++--------------------------- 1 file changed, 223 insertions(+), 565 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 51986600..5a351222 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -39,24 +39,24 @@ //#include "xio.h" // DIAGNOSTIC static void _initiate_feedhold(void); -static void _initiate_cycle_start(void); +static void _initiate_cycle_restart(void); static void _initiate_queue_flush(void); // Feedhold actions -static stat_t _feedhold_with_actions(float *param); -static stat_t _feedhold_with_no_actions(float *param); -static stat_t _feedhold_with_sync(float *param); -static stat_t _feedhold_restart_with_actions(float *param); -static stat_t _feedhold_restart_with_no_actions(float *param); +static stat_t _feedhold_with_actions(void); +static stat_t _feedhold_with_no_actions(void); +static stat_t _feedhold_with_sync(void); +static stat_t _feedhold_restart_with_actions(void); +static stat_t _feedhold_restart_with_no_actions(void); // Feedhold exits (finalization) -static stat_t _restart_cycle(float *param); -static stat_t _restart_flush(float *param); -static stat_t _program_stop(float *param); -static stat_t _program_end(float *param); -static stat_t _alarm(float *param); -static stat_t _shutdown(float *param); -static stat_t _interlock(float *param); +static stat_t _run_restart_cycle(void); +static stat_t _run_queue_flush(void); +static stat_t _run_program_stop(void); +static stat_t _run_program_end(void); +static stat_t _run_alarm(void); +static stat_t _run_shutdown(void); +static stat_t _run_interlock(void); /**************************************************************************************** * OPERATIONS AND ACTIONS @@ -82,15 +82,13 @@ static stat_t _interlock(float *param); /*** Object Definitions ***/ -#define PARAM_MAX 2 // maximum number of parameters that can be passed in param -#define ACTION_MAX 12 // maximum actions that can be queued for an operation -typedef stat_t (*action_exec_t)(float *); // callback to action execution function +#define ACTION_MAX 6 // maximum actions that can be queued for an operation +typedef stat_t (*action_exec_t)(); // callback to action execution function typedef struct cmAction { // struct to manage execution of operations uint8_t number; // DIAGNOSTIC for easier debugging. Not used functionally. struct cmAction *nx; // static pointer to next buffer action_exec_t func; // callback to operation action function. NULL == disabled - float param[PARAM_MAX]; // parameters for the function void reset() { // clears function pointer func = NULL; @@ -99,7 +97,7 @@ typedef struct cmAction { // struct to manage execution of ope typedef struct cmOperation { // operation runner object - cmAction action[ACTION_MAX]; // singly linked list of action control structures + cmAction action[ACTION_MAX]; // singly linked list of action structures cmAction *add; // pointer to next action to be added cmAction *run; // pointer to action being executed bool in_operation; // set true when an operation is running @@ -116,15 +114,10 @@ typedef struct cmOperation { // operation runner object in_operation = false; }; - stat_t add_action(stat_t(*action_exec)(float *), float* param) { + stat_t add_action(stat_t(*action_exec)()) { if (in_operation) { return (STAT_COMMAND_NOT_ACCEPTED); } // can't add if (add == NULL) { return (STAT_INPUT_EXCEEDS_MAX_LENGTH); } // no more room add->func = action_exec; - if (param != NULL) { - for (uint8_t i=0; iparam[i] = param[i]; - } - }; add = add->nx; return (STAT_OK); }; @@ -134,7 +127,7 @@ typedef struct cmOperation { // operation runner object in_operation = true; // disable add_action during operations stat_t status; - while ((status = run->func(run->param)) == STAT_OK) { + while ((status = run->func()) == STAT_OK) { run = run->nx; if (run->func == NULL) { // operation has completed reset(); // setup for next operation @@ -160,9 +153,12 @@ void cm_operation_init() } /**************************************************************************************** - * cm_operation_callback() - run operations and sequence requests + * cm_operation_sequencing_callback() - run operations and sequence requests * - * Expected behaviors: (no-hold means machine is not in hold, etc) + * The operation callback can hold a set of requests and makes decisions on which to run + * based on priorities and other factors. + * + * Expected behaviors: (no-hold means machine is not in hold, etc) * * (no-cycle) ! No action. Feedhold is not run (nothing to hold!) * (no-hold) ~ No action. Cannot exit a feedhold that does not exist @@ -174,21 +170,6 @@ void cm_operation_init() * (in-cycle) !% Start a feedhold, do enter and exit actions, exit feedhold, do not resume motion * (in-cycle) !%~ Same as above * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) - * - * The operation callback can hold a set of requests and makes decisions on which to run - * based on priorities and other factors: - - bool request_alarm; // stop all operations with feedhold and alarm - bool request_feedhold; // normal feedhold with actions - bool request_cycle_start; // start cycle, or exit feedhold if in hold state - bool request_queue_flush; // exit hold and flush queues - bool request_interlock; // enter interlock - bool request_interlock_exit; // exit interlock - bool request_job_kill; // ^d - end hold, flush and alarm - - * Feedhold parameters - * - Action type (1=normal, 2=fast_hold, 3=fast-hold_flush_sync) - * - Final state (STOP, END, HOLD (CYCLE), ALARM, SHUTDOWN) */ stat_t cm_operation_sequencing_callback() @@ -200,41 +181,10 @@ stat_t cm_operation_sequencing_callback() _initiate_queue_flush(); } if (cm1.cycle_state == CYCLE_START_REQUESTED) { - _initiate_cycle_start(); + _initiate_cycle_restart(); } return (op.run_operation()); } -/* - - // queue flush won't run until the hold is complete and all (subsequent) motion has stopped - if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && - (mp_runtime_is_idle())) { // don't flush planner during movement - cm_queue_flush(&cm1); - cm1.hold_exit_requested = true; // p1 queue flush always ends the hold - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available - } - - // special handling for feedhold abort - M2/M30, job kill, alarms - if (cm1.hold_abort_requested) { - _feedhold_abort(); - } - - // exit_hold runs for both ~ and % feedhold ends - if (cm1.hold_exit_requested) { - - // Flush must complete before exit_hold runs. Trap possible race condition if flush request was - if (cm1.flush_state == FLUSH_REQUESTED) { // ...received when this callback was running - return (STAT_OK); - } - if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold - cm1.hold_exit_requested = false; - _run_p1_hold_exit_actions(); // runs once only - } - } - if (cm1.hold_state == FEEDHOLD_P1_EXIT) { - _feedhold_p1_exit(); // run multiple times until actions are complete - } -*/ /**************************************************************************************** **** Functions ************************************************************************* @@ -243,6 +193,7 @@ stat_t cm_operation_sequencing_callback() /* * cm_has_hold() - return true if a hold condition exists (or a pending hold request) */ + bool cm_has_hold() { return (cm1.hold_state != FEEDHOLD_OFF); @@ -257,67 +208,136 @@ stat_t cm_feedhold_command_blocker() } /**************************************************************************************** - * cm_request_cycle_start() - set request flag only + * cm_request_cycle_start() - set request enum only * _initiate_cycle_start() - run the cycle start */ void cm_request_cycle_start() { - cm->cycle_state = CYCLE_START_REQUESTED; + if (cm1.hold_state != FEEDHOLD_OFF) { // restart from a feedhold + cm1.cycle_state = CYCLE_START_REQUESTED; + } else { // execute cycle start directly + if (mp_has_runnable_buffer(&mp1)) { + cm_cycle_start(); + st_request_exec_move(); + } + cm1.cycle_state = CYCLE_START_OFF; + } } -static void _initiate_cycle_start() +static void _initiate_cycle_restart() { - // Normal cycle start - not in a feedhold - if (cm1.hold_state == FEEDHOLD_OFF) { - cm1.cycle_state = CYCLE_START_OFF; - cm_cycle_start(); // execute cycle start directly - st_request_exec_move(); - return; - } - // Feedhold cycle starts run an operation to complete multiple actions if (cm1.hold_state == FEEDHOLD_HOLD) { cm1.cycle_state = CYCLE_START_OFF; switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_with_no_actions, nullptr); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_with_no_actions); break; } default: {} } switch (cm1.hold_final) { - case FEEDHOLD_EXIT_CYCLE: { op.add_action(_restart_cycle, nullptr); break; } - case FEEDHOLD_EXIT_FLUSH: { op.add_action(_restart_flush, nullptr); break; } - case FEEDHOLD_EXIT_STOP: { op.add_action(_program_stop, nullptr); break; } - case FEEDHOLD_EXIT_END: { op.add_action(_program_end, nullptr); break; } - case FEEDHOLD_EXIT_ALARM: { op.add_action(_alarm, nullptr); break; } - case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } - case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_interlock, nullptr); break; } + case FEEDHOLD_EXIT_CYCLE: { + op.add_action(_run_restart_cycle); + break; + } + case FEEDHOLD_EXIT_FLUSH: { + op.add_action(_run_queue_flush); + op.add_action(_run_program_stop); + break; + } + case FEEDHOLD_EXIT_STOP: { + op.add_action(_run_program_stop); + break; + } + case FEEDHOLD_EXIT_END: { + op.add_action(_run_program_end); + break; + } + case FEEDHOLD_EXIT_ALARM: { + op.add_action(_run_alarm); + break; + } + case FEEDHOLD_EXIT_SHUTDOWN: { + op.add_action(_run_shutdown); + break; + } + case FEEDHOLD_EXIT_INTERLOCK: { + op.add_action(_run_interlock); + break; + } default: {} } } } -static stat_t _program_stop(float *param) +/**************************************************************************************** + * cm_request_queue_flush() - set request enum only + * _initiate_queue_flush() - run a queue flush from a % + * _restart_flush() - run a queue flush from an action + * + * _restart_flush() assumes that the operations sequencing callback has resolved + * all state and timing issues and it's OK to call this now. Do not call this + * function directly. Always call using the operations runner. + */ + +void cm_request_queue_flush() +{ + // Can only initiate a queue flush if in a feedhold + if (cm->hold_state != FEEDHOLD_OFF) { + cm->flush_state = FLUSH_REQUESTED; + } else { + cm->flush_state = FLUSH_OFF; + } +} + +static void _initiate_queue_flush() +{ + // Don't initiate the queue until in HOLD state (this also means that runtime is idle) + if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD)) { + if (cm1.hold_type == FEEDHOLD_TYPE_ACTIONS) { + op.add_action(_feedhold_restart_with_actions); + } else { + op.add_action(_feedhold_restart_with_no_actions); + } + op.add_action(_run_queue_flush); + op.add_action(_run_program_stop); + } +} + +static stat_t _run_queue_flush() // typically runs from cm1 planner +{ + cm_abort_arc(cm); // kill arcs so they don't just create more alines + planner_reset((mpPlanner_t *)cm->mp); // reset primary planner. also resets the mr under the planner + cm_reset_position_to_absolute_position(cm); + cm1.flush_state = FLUSH_OFF; + qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available + return (STAT_OK); +} + +static stat_t _run_program_stop() +{ + cm_cycle_end(); // end cycle and run program stop +// cm_program_stop(); + return (STAT_OK); +} + +static stat_t _run_program_end() +{ + cm_program_end(); + return (STAT_OK); +} + +static stat_t _run_alarm() { return (STAT_OK); } -static stat_t _program_end(float *param) +static stat_t _run_shutdown() { return (STAT_OK); } -static stat_t _alarm(float *param) -{ - return (STAT_OK); -} - -static stat_t _shutdown(float *param) -{ - return (STAT_OK); -} - -static stat_t _interlock(float *param) +static stat_t _run_interlock() { return (STAT_OK); } @@ -325,18 +345,27 @@ static stat_t _interlock(float *param) /**************************************************************************************** * cm_request_feedhold() - request a feedhold - d0 not run it yet * _initiate_feedhold() - start feedhold of correct type and finalization - * _feedhold_sync_to_planner() - planner callback to reach sync point + * _feedhold_sync_to_planner() - planner callback to reach sync point * _feedhold_with_sync() * _feedhold_with_no_actions() * _feedhold_with_actions() - perform hold entry actions + * + * Input arguments + * - See cmFeedholdType - how the feedhold will execute + * - See cmFeedholdFinal - the final state when the feedhold is exited */ void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) { - cm->hold_type = type; - cm->hold_final = final; - cm->hold_state = FEEDHOLD_REQUESTED; - _initiate_feedhold(); // attempt to run it immediately + // Can only initiate a feedhold if you are in a machining cycle not already in a feedhold + if ((cm->hold_state == FEEDHOLD_OFF) && (cm->machine_state == MACHINE_CYCLE)) { + cm->hold_type = type; + cm->hold_final = final; + cm->hold_state = FEEDHOLD_REQUESTED; + _initiate_feedhold(); // attempt to run it immediately + } else { + cm->hold_state = FEEDHOLD_OFF; // reset + } } static void _initiate_feedhold() @@ -345,17 +374,17 @@ static void _initiate_feedhold() if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions, nullptr); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_with_no_actions, nullptr); break; } - case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync, nullptr); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_with_no_actions); break; } + case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync); break; } default: { } } switch (cm1.hold_final) { - case FEEDHOLD_EXIT_STOP: { op.add_action(_program_stop, nullptr); break; } - case FEEDHOLD_EXIT_END: { op.add_action(_program_end, nullptr); break; } - case FEEDHOLD_EXIT_ALARM: { op.add_action(_alarm, nullptr); break; } - case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_shutdown, nullptr); break; } - case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_interlock, nullptr); break; } + case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } + case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } + case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } + case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } + case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } default: { } } cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec @@ -364,7 +393,7 @@ static void _initiate_feedhold() // P2 feedholds only allow feedhold sync types if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { - op.add_action(_feedhold_with_sync, nullptr); + op.add_action(_feedhold_with_sync); cm2.hold_state = FEEDHOLD_SYNC; } } @@ -375,17 +404,17 @@ static void _feedhold_sync_to_planner(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _feedhold_with_no_actions(float *param) +static stat_t _feedhold_with_no_actions() { return (STAT_OK); } -static stat_t _feedhold_with_sync(float *param) +static stat_t _feedhold_with_sync() { return (STAT_OK); } -static stat_t _feedhold_with_actions(float *param) // Execute Case (5) +static stat_t _feedhold_with_actions() // Execute Case (5) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_START) { @@ -443,8 +472,9 @@ static stat_t _feedhold_with_actions(float *param) // Execute Case (5) if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_COMPLETE) { cm1.hold_state = FEEDHOLD_HOLD; return (STAT_OK); - } - return (STAT_EAGAIN); + } + + return (STAT_EAGAIN); // keep the compiler happy. Never executed. } /**************************************************************************************** @@ -459,12 +489,12 @@ static void _feedhold_restart_sync_to_planner(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _feedhold_restart_with_no_actions(float *param) +static stat_t _feedhold_restart_with_no_actions() { return (STAT_OK); } -static stat_t _feedhold_restart_with_actions(float *param) // Execute Cases (6) and (7) +static stat_t _feedhold_restart_with_actions() // Execute Cases (6) and (7) { // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD) { @@ -487,26 +517,18 @@ static stat_t _feedhold_restart_with_actions(float *param) // Execute Cases (6 // finalize feedhold exit if (cm1.hold_state == FEEDHOLD_EXIT_ACTIONS_COMPLETE) { - - // return to primary planner (p1) - cm = &cm1; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; - - // execute this block if a queue flush was performed - // adjust p1 planner positions to runtime positions - if (cm1.flush_state == FLUSH_WAS_RUN) { - cm_reset_position_to_absolute_position(cm); - cm1.flush_state = FLUSH_OFF; - } return (STAT_OK); } - return (STAT_EAGAIN); + + return (STAT_EAGAIN); // keep the compiler happy. Never executed. } -static stat_t _restart_cycle(float *param) +static stat_t _run_restart_cycle(void) { - cm1.hold_state = FEEDHOLD_OFF; // must precede st_request_exec_move() + cm1.hold_state = FEEDHOLD_OFF; // must precede st_request_exec_move() if (mp_has_runnable_buffer(&mp1)) { cm_cycle_start(); st_request_exec_move(); @@ -516,11 +538,29 @@ static stat_t _restart_cycle(float *param) return (STAT_OK); } -static stat_t _restart_flush(float *param) -{ - cm1.hold_state = FEEDHOLD_OFF; - return (STAT_OK); -} + + + + + + + + + + + + + + + + + + + + + + + /**************************************************************************************** * Queue Flush operations @@ -559,67 +599,44 @@ static stat_t _restart_flush(float *param) * empty before writing it to the control channel. */ -/*********************************************************************************** - * cm_reqeust_queue_flush() - Flush planner queue - * cm_queue_flush() - Flush planner queue - * - * This function assumes that the feedhold sequencing callback has resolved all - * state and timing issues and it's OK to call this now. Do not call this function - * directly. Always use the feedhold sequencing callback. - */ +/* +static stat_t _parking_move(float *param); +static stat_t _return_move(float *param); +static stat_t _spindle_control(float *param); +static stat_t _coolant_control(float *param); +static stat_t _heater_control(float *param); +static stat_t _output_control(float *param); +static stat_t _queue_flush(float *param); +static stat_t _input_function(float *param); +static stat_t _finalize_program(float *param); +static stat_t _trigger_alarm(float *param); +*/ -void cm_request_queue_flush() -{ - cm->flush_state = FLUSH_REQUESTED; -} +/* +typedef enum { // cycle start and feedhold requests + OPERATION_NULL = 0, // no operation; reverts here when complete + OPERATION_CYCLE_START, // perform a cycle start with no other actions + OPERATION_HOLD, // feedhold in p1 or p2 with no entry actions +// OPERATION_HOLD_WITH_ACTIONS,// feedhold into p2 with entry actions +// OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 +// OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush + OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner + OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner + OPERATION_JOB_KILL, // fast hold followed by queue flush and program end + OPERATION_END_JOG, // fast hold followed by program stop + OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit + OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit + OPERATION_SHUTDOWN, // actions to run when a shutdown is received + OPERATION_PANIC, // actions to run when a panic is received + OPERATION_INTERLOCK_START, // enter an interlock state + OPERATION_INTERLOCK_END, // exit interlocked state + OPERATION_DI_FUNC_STOP, // run digital input STOP function + OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function + OPERATION_DI_FUNC_HALT, // run digital input HALT function + OPERATION_TOOL_CHANGE // run a tool change sequence +} cmOperationType; +*/ -static void _initiate_queue_flush() -{ - cm_queue_flush(cm); -} - -void cm_queue_flush(cmMachine_t *_cm) -{ - cm_abort_arc(_cm); // kill arcs so they don't just create more alines - planner_reset((mpPlanner_t *)_cm->mp); // reset primary planner. also resets the mr under the planner - _cm->flush_state = FLUSH_WAS_RUN; -} - - - - - - - - - - - - - - - -//static stat_t _run_p1_hold_entry_actions(void); -//static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag); - -//static stat_t _run_p1_hold_exit_actions(void); -//static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag); -//static void _feedhold_p1_exit(void); -//static void _feedhold_p2_exit(void); -//static void _feedhold_abort(void); - -//static stat_t _halt(float *param); -//static stat_t _p2_entry(float* param); -//static stat_t _parking_move(float *param); -//static stat_t _return_move(float *param); -//static stat_t _spindle_control(float *param); -//static stat_t _coolant_control(float *param); -//static stat_t _heater_control(float *param); -//static stat_t _output_control(float *param); -//static stat_t _queue_flush(float *param); -//static stat_t _input_function(float *param); -//static stat_t _finalize_program(float *param); -//static stat_t _trigger_alarm(float *param); /* typedef enum { // Operation Actions // Initiation actions @@ -668,7 +685,6 @@ typedef enum { // Operation Actions ACTION_TRIGGER_PANIC, // trigger PANIC state ACTION_PERFORM_RESET, // defined, but not implemented } cmOpAction; - */ /**************************************************************************************** @@ -701,34 +717,7 @@ typedef enum { // Operation Actions * Pre-defined exit actions (coolant, spindle, Z move) are completed first * Any executing or pending "in-hold" moves are stopped prior to the exit actions */ -/* -void cm_request_feedhold(void) // ! -{ - // Only generate request if not already in a feedhold and the machine is in motion - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_state = FEEDHOLD_INITIATED; // signal request to state machine - } else - if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { - cm2.hold_state = FEEDHOLD_INITIATED; - } -} -void cm_request_exit_hold(void) // ~ -{ - if (cm1.hold_state != FEEDHOLD_OFF) { - cm1.hold_exit_requested = true; - } -} - -void cm_request_queue_flush() // % -{ - // NOTE: this function used to flush input buffers, but this is handled in xio *prior* to queue flush now - if ((cm1.hold_state != FEEDHOLD_OFF) && // don't honor request unless you are in a feedhold - (cm1.flush_state == FLUSH_OFF)) { // ...and only once - cm1.flush_state = FLUSH_REQUESTED; // request planner flush once motion has stopped - } -} -*/ /**************************************************************************************** * cm_request_operation() * @@ -754,82 +743,6 @@ void cm_request_queue_flush() // % * - param[1] - jerk 0=normal-jerk, 1=high-jerk (fast hold) * - param[2] - endstate */ -/* -stat_t cm_request_operation(cmOperationType operation, float *param) -{ - if (op.in_operation) { - return (STAT_COMMAND_NOT_ACCEPTED); // already has a current running action - } - - switch (operation) { - -// case OPERATION_CYCLE_START: { -// op.add_action(_cycle_start, nullptr); -// return(op.run_operation()); -// } - - // Generate hold request if not already in a hold and machine is in motion - case OPERATION_HOLD: { - op.add_action(_hold_with_actions, param); - break; - } - - default: { - - } - } - return (STAT_OK); -} -*/ -/* -static stat_t _cycle_start(float *param) -{ - if (cm->cycle_type == CYCLE_NONE) { // don't (re)start homing, probe or other canned cycles - cm->cycle_type = CYCLE_MACHINING; - cm->machine_state = MACHINE_CYCLE; - st_request_exec_move(); - } - return (STAT_OK); -} -*/ - -/* - * _hold_with_actions() - initiate a feedhold in the active planner - p1 or p2 - * - * Return STAT_OK once hold has been reached - */ -/* -static stat_t _hold_with_actions(float *param) -{ - // Not in feedhold - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.motion_state != MOTION_STOP)) { - cm1.hold_state = FEEDHOLD_INITIATED; // initiate hold to feedhold state machine - return (STAT_EAGAIN); - } else - if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { - cm2.hold_state = FEEDHOLD_INITIATED; - return (STAT_EAGAIN); - } - - // Feedhold has already been initiated -// if ((cm2.hold_state == FEEDHOLD_OFF) && (cm2.motion_state != MOTION_STOP)) { - - return (STAT_OK); -} -*/ - -//static stat_t _halt(float *param) { return (STAT_OK); } -//static stat_t _p2_entry(float *param) { return (STAT_OK); } // p2 entry actions, bundled -//static stat_t _parking_move(float *param) { return (STAT_OK); } -//static stat_t _return_move(float *param) { return (STAT_OK); } -//static stat_t _spindle_control(float *param) { return (STAT_OK); } -//static stat_t _coolant_control(float *param) { return (STAT_OK); } -//static stat_t _heater_control(float *param) { return (STAT_OK); } -//static stat_t _output_control(float *param) { return (STAT_OK); } -//static stat_t _queue_flush(float *param) { return (STAT_OK); } -//static stat_t _input_function(float *param) { return (STAT_OK); } -//static stat_t _finalize_program(float *param) { return (STAT_OK); } -//static stat_t _trigger_alarm(float *param) { return (STAT_OK); } /**************************************************************************************** **** Feedholds ************************************************************************* @@ -906,236 +819,7 @@ static stat_t _hold_with_actions(float *param) * (in-cycle) !%~ Same as above * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) */ -/* -stat_t cm_feedhold_sequencing_callback() -{ - // invoking a p1 feedhold is a 2 step process - get to the stop, then execute the hold actions - if (cm1.hold_state == FEEDHOLD_INITIATED) { - if (mp_has_runnable_buffer(&mp1)) { // bypass cm_start_hold() to start from here - cm1.hold_state = FEEDHOLD_SYNC; // invokes hold from aline execution - } - } - if (cm1.hold_state == FEEDHOLD_P2_START) { // enter p2 planner; perform Z lift, spindle & coolant actions - _run_p1_hold_entry_actions(); - } - // p2 feedhold states - feedhold in feedhold - if (cm2.hold_state == FEEDHOLD_INITIATED) { - if (mp_has_runnable_buffer(&mp2)) { - cm2.hold_state = FEEDHOLD_SYNC; - } - } - if (cm2.hold_state == FEEDHOLD_P2_EXIT) { - _feedhold_p2_exit(); - return (STAT_OK); - } - - // queue flush won't run until the hold is complete and all (subsequent) motion has stopped - if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD) && - (mp_runtime_is_idle())) { // don't flush planner during movement - cm_queue_flush(&cm1); - cm1.hold_exit_requested = true; // p1 queue flush always ends the hold - qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available - } - - // special handling for feedhold abort - M2/M30, job kill, alarms - if (cm1.hold_abort_requested) { - _feedhold_abort(); - } - - // exit_hold runs for both ~ and % feedhold ends - if (cm1.hold_exit_requested) { - - // Flush must complete before exit_hold runs. Trap possible race condition if flush request was - if (cm1.flush_state == FLUSH_REQUESTED) { // ...received when this callback was running - return (STAT_OK); - } - if (cm1.hold_state == FEEDHOLD_HOLD) { // don't run end_hold until fully into a hold - cm1.hold_exit_requested = false; - _run_p1_hold_exit_actions(); // runs once only - } - } - if (cm1.hold_state == FEEDHOLD_P1_EXIT) { - _feedhold_p1_exit(); // run multiple times until actions are complete - } - return (STAT_OK); -} -*/ -/**************************************************************************************** - * _run_p1_hold_entry_actions() - run actions in p2 that complete the p1 hold - * _sync_to_p1_hold_entry_actions_done() - final state change occurs here - * - * This function assumes that the feedhold sequencing callback has resolved all - * state and timing issues and it's OK to call this now. Do not call this function - * directly. Always use the feedhold sequencing callback. - * - * Moving between planners is only safe when the machine is completely stopped. - * - * _sync_to_p1_hold_entry_actions_done() is a callback to run when the ACTIONS from - * feedhold in p1 are finished. This function hits cm1 directly as ACTIONS for a - * feedhold in p1 actually run in the secondary planner (p2). Feedholds from p2 do - * not run actions, so this function is never called for p2 feedholds. It's called - * from an interrupt, so it only sets a flag. - */ -/* -static void _sync_to_p1_hold_entry_actions_done(float* vect, bool* flag) // Complete case (5) -{ - cm1.hold_state = FEEDHOLD_HOLD; - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} - -static stat_t _run_p1_hold_entry_actions() // Execute Case (5) -{ - // do not perform entry actions if feedhold abort in progress - if (cm1.hold_abort_requested) { - cm1.hold_state = FEEDHOLD_OFF; - return (STAT_OK); - } - - cm->hold_state = FEEDHOLD_P2_WAIT; // penultimate state before transitioning to HOLD - - // copy the primary canonical machine to the secondary, - // fix the planner pointer, and reset the secondary planner - memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // set parameters in cm, gm and gmx so you can actually use it - cm2.hold_state = FEEDHOLD_OFF; - cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - cm2.flush_state = FLUSH_OFF; - cm2.gm.feed_rate = 0; - - // clear the target and set the positions to the current hold position - memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); - memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); - copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation - copy_vector(cm2.gmx.position, mr1.position); - copy_vector(mp2.position, mr1.position); - copy_vector(mr2.position, mr1.position); - - // reassign the globals to the secondary CM - cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // mp is a void pointer - mr = mp->mr; - - // set motion state and ACTIVE_MODEL. This must be performed after cm is set to cm2 - cm_set_g30_position(); -// cm_set_motion_state(MOTION_STOP); // sets cm2 active model to MODEL - - // execute feedhold actions - if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift - cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); - bool flags[] = { 0,0,1,0,0,0 }; - float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode - cm_straight_traverse(target, flags, PROFILE_NORMAL); - cm_set_distance_mode(cm1.gm.distance_mode); // restore distance mode to p1 setting - } - spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause - coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - mp_queue_command(_sync_to_p1_hold_entry_actions_done, nullptr, nullptr); - return (STAT_OK); -} -*/ -/**************************************************************************************** - * _run_p1_hold_exit_actions() - initiate return from feedhold planner - * _sync_to_p1_hold_exit_actions_done() - callback to sync to end of planner operations - * _feedhold_p1_exit() - callback to finsh return once moves are done - * - * These functions assume that the feedhold sequencing callback has resolved all - * state and timing issues and it's OK to call this now. Do not call this function - * directly. Always use the feedhold sequencing callback. - * - * The finalization moves are performed in _sync_to_p1_hold_exit_actions_done() because - * the sync runs from an interrupt. Finalization needs to run from the main loop. - */ - - -/* -static stat_t _run_p1_hold_exit_actions() // Execute Cases (6) and (7) -{ - // do not perform exit actions if feedhold abort in progress - if (cm1.hold_abort_requested) { - cm = &cm1; // reset to p1 planner - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; - cm1.hold_state = FEEDHOLD_OFF; - return (STAT_OK); - } - - // perform end-hold actions --- while still in secondary machine - coolant_control_sync(COOLANT_RESUME, COOLANT_BOTH); // resume coolant if paused - spindle_control_sync(SPINDLE_RESUME); // resume spindle if paused - - // do return move though an intermediate point; queue a wait - cm2.return_flags[AXIS_Z] = false; - cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); - mp_queue_command(_sync_to_p1_hold_exit_actions_done, nullptr, nullptr); - return (STAT_OK); -} - -// Callback to run when the G30 return move is finished. This function is only ever -// called by the secondary planner, and only when exiting a feedhold from planner 1. -// It's called from an interrupt, so it only sets a flag. - -static void _sync_to_p1_hold_exit_actions_done(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_P1_EXIT; // penultimate state before transitioning to FEEDHOLD_OFF - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} - -static void _feedhold_p1_exit() -{ - // skip out if not ready to finalize the exit - if (cm1.hold_state != FEEDHOLD_P1_EXIT) { - return; - } - - // return to primary planner (p1) - cm = &cm1; - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; - - // execute this block if a queue flush was performed - // adjust p1 planner positions to runtime positions - if (cm1.flush_state == FLUSH_WAS_RUN) { - cm_reset_position_to_absolute_position(cm); - cm1.flush_state = FLUSH_OFF; - } - - // resume motion from primary planner or end cycle if no moves in planner - if (mp_has_runnable_buffer(&mp1)) { -// cm_set_motion_state(MOTION_RUN); - cm_cycle_start(); - st_request_exec_move(); - } else { -// cm_set_motion_state(MOTION_STOP); - cm_cycle_end(); - } - cm1.hold_state = FEEDHOLD_OFF; -} -*/ -/**************************************************************************************** - * _feedhold_p2_exit() - exit from a feedhold in feedhold (from p2) - * - * Assumes planner is in p2 on entry - */ -/* -static void _feedhold_p2_exit() -{ - float position[AXES]; - copy_vector(position, mr2.position); // save the final position - cm_queue_flush(&cm2); - copy_vector(mr2.position, position); // restore the final position - cm_reset_position_to_absolute_position(&cm2); // propagate position - - cm2.hold_state = FEEDHOLD_OFF; -// cm_set_motion_state(MOTION_STOP); - cm_cycle_end(); - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} -*/ /**************************************************************************************** * _feedhold_abort() - used to exit a feedhold without completing exit actions * @@ -1190,29 +874,3 @@ static void _feedhold_abort() } */ - -/* -typedef enum { // cycle start and feedhold requests - OPERATION_NULL = 0, // no operation; reverts here when complete - OPERATION_CYCLE_START, // perform a cycle start with no other actions - OPERATION_HOLD, // feedhold in p1 or p2 with no entry actions -// OPERATION_HOLD_WITH_ACTIONS,// feedhold into p2 with entry actions -// OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 -// OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush - OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner - OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner - OPERATION_JOB_KILL, // fast hold followed by queue flush and program end - OPERATION_END_JOG, // fast hold followed by program stop - OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit - OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit - OPERATION_SHUTDOWN, // actions to run when a shutdown is received - OPERATION_PANIC, // actions to run when a panic is received - OPERATION_INTERLOCK_START, // enter an interlock state - OPERATION_INTERLOCK_END, // exit interlocked state - OPERATION_DI_FUNC_STOP, // run digital input STOP function - OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function - OPERATION_DI_FUNC_HALT, // run digital input HALT function - OPERATION_TOOL_CHANGE // run a tool change sequence -} cmOperationType; -*/ - From 6198917a4e223c812f649dd0bce5b86599a0d329 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 14 Mar 2017 17:12:16 -0400 Subject: [PATCH 192/283] Passes all regressions except job kill (still working that one) --- g2core/canonical_machine.cpp | 8 +++--- g2core/canonical_machine.h | 3 +- g2core/cycle_feedhold.cpp | 54 ++++++++++++++++++++++++------------ 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 955fdd38..8f113b45 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -292,10 +292,10 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) case MACHINE_READY: case MACHINE_ALARM: case MACHINE_PROGRAM_STOP: - case MACHINE_PROGRAM_END: { return ((cmCombinedState)_cm->machine_state); } - case MACHINE_INTERLOCK: { return (COMBINED_INTERLOCK); } - case MACHINE_SHUTDOWN: { return (COMBINED_SHUTDOWN); } - case MACHINE_PANIC: { return (COMBINED_PANIC); } + case MACHINE_PROGRAM_END: { return ((cmCombinedState)_cm->machine_state); } + case MACHINE_INTERLOCK: { return (COMBINED_INTERLOCK); } + case MACHINE_SHUTDOWN: { return (COMBINED_SHUTDOWN); } + case MACHINE_PANIC: { return (COMBINED_PANIC); } case MACHINE_CYCLE: { switch(_cm->cycle_type) { case CYCLE_NONE: { break; } // CYCLE_NONE cannot ever get here diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 8128e2ca..dcec9472 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -174,8 +174,7 @@ typedef enum { // feed override state machine typedef enum { // queue flush state machine FLUSH_OFF = 0, // no queue flush in effect - FLUSH_REQUESTED, // flush has been requested but not started yet -// FLUSH_WAS_RUN // transient state to note that a queue flush has been run + FLUSH_REQUESTED // flush has been requested but not started yet } cmFlushState; typedef enum { // Motion profiles diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 5a351222..b9eda918 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -38,7 +38,7 @@ #include "util.h" //#include "xio.h" // DIAGNOSTIC -static void _initiate_feedhold(void); +static void _initiate_p1_feedhold(void); static void _initiate_cycle_restart(void); static void _initiate_queue_flush(void); @@ -175,7 +175,7 @@ void cm_operation_init() stat_t cm_operation_sequencing_callback() { if (cm1.hold_state == FEEDHOLD_REQUESTED) { - _initiate_feedhold(); + _initiate_p1_feedhold(); } if (cm1.flush_state == FLUSH_REQUESTED) { _initiate_queue_flush(); @@ -214,9 +214,13 @@ stat_t cm_feedhold_command_blocker() void cm_request_cycle_start() { - if (cm1.hold_state != FEEDHOLD_OFF) { // restart from a feedhold - cm1.cycle_state = CYCLE_START_REQUESTED; - } else { // execute cycle start directly + if (cm1.hold_state != FEEDHOLD_OFF) { // restart from a feedhold + if (cm1.flush_state == FLUSH_REQUESTED) { // possible race condition. Flush wins + cm1.cycle_state = CYCLE_START_OFF; + } else { + cm1.cycle_state = CYCLE_START_REQUESTED; + } + } else { // execute cycle start directly if (mp_has_runnable_buffer(&mp1)) { cm_cycle_start(); st_request_exec_move(); @@ -283,10 +287,10 @@ static void _initiate_cycle_restart() void cm_request_queue_flush() { // Can only initiate a queue flush if in a feedhold - if (cm->hold_state != FEEDHOLD_OFF) { - cm->flush_state = FLUSH_REQUESTED; + if (cm1.hold_state != FEEDHOLD_OFF) { + cm1.flush_state = FLUSH_REQUESTED; } else { - cm->flush_state = FLUSH_OFF; + cm1.flush_state = FLUSH_OFF; } } @@ -357,18 +361,28 @@ static stat_t _run_interlock() void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) { - // Can only initiate a feedhold if you are in a machining cycle not already in a feedhold - if ((cm->hold_state == FEEDHOLD_OFF) && (cm->machine_state == MACHINE_CYCLE)) { - cm->hold_type = type; - cm->hold_final = final; - cm->hold_state = FEEDHOLD_REQUESTED; - _initiate_feedhold(); // attempt to run it immediately - } else { - cm->hold_state = FEEDHOLD_OFF; // reset + // look for p2 feedhold (feedhold in a feedhold) + if ((cm1.hold_state == FEEDHOLD_HOLD) && + (cm2.hold_state == FEEDHOLD_OFF) && + (cm2.machine_state == MACHINE_CYCLE)) { + op.add_action(_feedhold_with_sync); + op.add_action(_run_program_stop); + cm2.hold_state = FEEDHOLD_SYNC; + return; } + + // Can only initiate a feedhold if you are in a machining cycle not already in a feedhold + if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { + cm1.hold_type = type; + cm1.hold_final = final; + cm1.hold_state = FEEDHOLD_REQUESTED; + _initiate_p1_feedhold(); // attempt to run it immediately + return; + } + cm->hold_state = FEEDHOLD_OFF; // cannot honor the feedhold request. reset it } -static void _initiate_feedhold() +static void _initiate_p1_feedhold() { // This function is "safe" and will not initiate a feedhold unless it's OK to. @@ -496,6 +510,10 @@ static stat_t _feedhold_restart_with_no_actions() static stat_t _feedhold_restart_with_actions() // Execute Cases (6) and (7) { + if (cm1.hold_state == FEEDHOLD_OFF) { + return (STAT_OK); // was called erroneously. Can happen for !%~ + } + // Check to run first-time code if (cm1.hold_state == FEEDHOLD_HOLD) { // perform end-hold actions --- while still in secondary machine @@ -523,7 +541,7 @@ static stat_t _feedhold_restart_with_actions() // Execute Cases (6) and (7) return (STAT_OK); } - return (STAT_EAGAIN); // keep the compiler happy. Never executed. + return (STAT_EAGAIN); // still waiting } static stat_t _run_restart_cycle(void) From 957e4fc352c215d7fba4d75b8ff11d761ee6bd59 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 16 Mar 2017 11:26:08 -0400 Subject: [PATCH 193/283] Name changes and comments - no functional changes. Passes all regressions up to job kill --- g2core/canonical_machine.h | 16 +- g2core/cycle_feedhold.cpp | 535 ++++++++++--------------------------- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 4 +- 4 files changed, 156 insertions(+), 403 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index dcec9472..c3f246c0 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -130,7 +130,7 @@ typedef enum { // feedhold final operation FEEDHOLD_EXIT_ALARM, // perform alarm FEEDHOLD_EXIT_SHUTDOWN, // perform shutdown FEEDHOLD_EXIT_INTERLOCK // report as interlock -} cmFeedholdFinal; +} cmFeedholdExit; typedef enum { // feedhold state machine FEEDHOLD_OFF = 0, // no feedhold in effect @@ -141,7 +141,7 @@ typedef enum { // feedhold state machine FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet FEEDHOLD_MOTION_STOPPING, // waiting for motors to have stopped at hold point (motion stop) FEEDHOLD_MOTION_STOPPED, // motion has stopped at hold point - FEEDHOLD_HOLD_ACTIONS_START, + FEEDHOLD_HOLD_POINT_REACHED, // hold point reached and logic run - prepare for next steps FEEDHOLD_HOLD_ACTIONS_PENDING, // wait for feedhold actions to complete FEEDHOLD_HOLD_ACTIONS_COMPLETE, // FEEDHOLD_HOLD, // HOLDING (steady state) @@ -180,7 +180,7 @@ typedef enum { // queue flush state machine typedef enum { // Motion profiles PROFILE_NORMAL = 0, // Normal jerk in effect PROFILE_FAST // High speed jerk in effect -} cmMotion_profile; +} cmMotionProfile; /***************************************************************************** * CANONICAL MACHINE STRUCTURES @@ -279,9 +279,15 @@ typedef struct cmMachine { // struct to manage canonical machin cmCycleType cycle_type; // cycs cmMotionState motion_state; // mots +// cmFeedholdType hold_type; // hold: type of feedhold requested +// cmFeedholdFinal hold_final; // hold: final state of hold +// cmFeedholdState hold_state; // hold: feedhold state machine + cmFeedholdType hold_type; // hold: type of feedhold requested - cmFeedholdFinal hold_final; // hold: final state of hold + cmFeedholdExit hold_exit; // hold: final state of hold on exit + cmMotionProfile hold_profile; // hold: motion profile to use for deceleration cmFeedholdState hold_state; // hold: feedhold state machine + cmFlushState flush_state; // hold: queue flush state machine cmCycleState cycle_state; // used to manage cycle start @@ -487,7 +493,7 @@ stat_t cm_operation_sequencing_callback(void); // operation act void cm_request_alarm(void); void cm_request_fasthold(void); void cm_request_cycle_start(void); -void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final); +void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit); void cm_request_queue_flush(void); stat_t cm_feedhold_sequencing_callback(void); // process feedhold, cycle start and queue flush requests stat_t cm_feedhold_command_blocker(void); diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index b9eda918..fe114488 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -38,16 +38,16 @@ #include "util.h" //#include "xio.h" // DIAGNOSTIC -static void _initiate_p1_feedhold(void); -static void _initiate_cycle_restart(void); -static void _initiate_queue_flush(void); +static void _start_p1_feedhold(void); +static void _start_cycle_restart(void); +static void _start_queue_flush(void); // Feedhold actions static stat_t _feedhold_with_actions(void); -static stat_t _feedhold_with_no_actions(void); +static stat_t _feedhold_no_actions(void); static stat_t _feedhold_with_sync(void); static stat_t _feedhold_restart_with_actions(void); -static stat_t _feedhold_restart_with_no_actions(void); +static stat_t _feedhold_restart_no_actions(void); // Feedhold exits (finalization) static stat_t _run_restart_cycle(void); @@ -61,23 +61,31 @@ static stat_t _run_interlock(void); /**************************************************************************************** * OPERATIONS AND ACTIONS * - * Operations work by queueing a set of actions, then running them in sequence until - * the operation is complete or an error occurs. + * Operations provide a way to assemble a multi-step function from underlying actions, + * then execute the actions in sequence until the operation either completes or returns + * an error. It handles actions that complete immediately (synchronous) as well as long + * running asynchronous operations such as a series of multiple moves. + * + * It works by assembling an operation using a series of add_action() calls, then running + * the operation by one or more run_operation() calls. The cm_operation_sequencing_callback() + * both runs long-running operations, as well as queues operation requests that must + * run sequentially of have other conditions. * * Actions are coded to return: * STAT_OK - successful completion of the action * STAT_EAGAIN - ran to continuation - the action needs to be called again to complete - * STAT_XXXXX - any other status is an error that quits the operation + * STAT_XXXXX - any other status is an error that should quit the operation * - * run_operation returns: + * run_operation() returns: * STAT_NOOP - no operation is set up, but it's OK to call the operation runner * STAT_OK - operation has completed successfully * STAT_EAGAIN - operation needs to be re-entered to complete (via operation callback) * STAT_XXXXX - any other status is an error that quits the operation * - * Constraints: - * - Operations run to completion. They are not preemptable (at this point) + * Current constraints to keep this simple (at least for now): + * - Operations run to completion. They cannot be canceled, or preempted by other operations * - Actions cannot be added to an operation once it is being run + * - Actions do not have parameters. Use the CM context if needed (e.g. hold_type) */ /*** Object Definitions ***/ @@ -153,43 +161,114 @@ void cm_operation_init() } /**************************************************************************************** - * cm_operation_sequencing_callback() - run operations and sequence requests + **** Feedhold and Related Functions **************************************************** + ****************************************************************************************/ +/* + * Feedholds, queue flushes and the various feedhold exits are all related. + * These are performed in this file and in plan_exec.cpp. Feedholds are implemented + * as a state machine (cmFeedholdState) that runs in these files using Operations. * - * The operation callback can hold a set of requests and makes decisions on which to run - * based on priorities and other factors. + * BACKGROUND: There are 2 planners: p1 (primary planner) and p2 (secondary planner). * + * A feedhold (!) received while in p1 stops motion in p1 and optionally transitions to p2, + * where feedhold entry actions such as Z lift, parking moves, spindle and coolant pause + * are run. While in p2 (almost) all machine operations are available. There are different + * Types of feedholds; Feedhold with action and feedholds with no action transition to p2, + * but others do not (e.g. feedhold with sync). + * + * A cycle_start (~) returns to p1 and exits the feedhold, performing exit actions if entry + * actions were performed. Motion resumes in p1 from the held point. + * + * A queue_flush (~) returns to p1 and exits the feedhold, performing exit actions if entry + * actions were performed. The p1 planner is flushed, and motion does not resume. The machine + * executes a program_stop, and ends in the STOP state. + * + * A feedhold (!) received while in p2 (a feedhold within a feedhold - very Inception) + * stops motion in p2 and flushes the p2 planner. Control remains in p2. + * + * Other variants of feedhold and exit exist, but these are invoked internally only to put + * the machine in END, ALARM, SHUTDOWN, INTERLOCK and other states. + */ +/* + * Feedhold State Machine Processing + * + * Feedhold is run as a state machine using the following states: + * FEEDHOLD_OFF - Not in a feedhold. May be in a cycle or not running + * FEEDHOLD_HOLD - Feedhold stable state. Achieved when machine has stopped in the hold. + * FEEDHOLD_XXXX - Any other feedhold state is transient; the machine is headed towards + * FEEDHOLD_HOLD or FEEDHOLD_OFF. + * + * For internal purposes, any state other than FEEDHOLD_OFF is considered to be in a hold. + * + * Feedhold processing performs the following (in rough sequence order): + * + * (0) - Feedhold is request bu calling cm_feedhold_reqeust() + * + * Control transfers to plan_exec.cpp feedhold functions: + * + * (1) - Feedhold arrives while we are in the middle executing of a block + * (1a) - The block is currently accelerating - wait for the end of acceleration + * (1b) - The block is in a head, but has not started execution yet - start deceleration + * (1b1) - The deceleration fits into the current block + * (1b2) - The deceleration does not fit and needs to continue in the next block + * (1c) - The block is in a body - start deceleration + * (1c1) - The deceleration fits into the current block + * (1c2) - The deceleration does not fit and needs to continue in the next block + * (1d) - The block is currently in the tail - wait until the end of the block + * (1e) - We have a new block and a new feedhold request that arrived at EXACTLY the same time + * (unlikely, but handled as 1b). + * + * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block + * (3) - The end of deceleration is detected inline in mp_exec_aline() + * (4) - Finished all runtime work, now wait for motion to stop at HOLD point. When it does: + * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF + * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush + * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute + * + * Control transfers back to cycle_feedhold.cpp feedhold functions: + * + * (5) - Run the P2 entry actions and transition to HOLD state when complete + * (6) - Remove the hold state / there is queued motion - see cycle_feedhold.cpp + * (7) - Remove the hold state / there is no queued motion - see cycle_feedhold.cpp + */ + +/**************************************************************************************** + * cm_operation_sequencing_callback() - run feedhold operations and sequence queued requests + * + * Operations are requested by calling their repective request function, e.g. cm_request_feedhold(). + * The operation callback runs the current operation, and sequences requests that must be queued. * Expected behaviors: (no-hold means machine is not in hold, etc) * * (no-cycle) ! No action. Feedhold is not run (nothing to hold!) * (no-hold) ~ No action. Cannot exit a feedhold that does not exist * (no-hold) % No action. Queue flush is not honored except during a feedhold - * (in-cycle) ! Start a feedhold + * (in-cycle) ! Start a hold to motion in the p1 planner * (in-hold) ~ Wait for feedhold actions to complete, exit feedhold, resume motion * (in-hold) % Wait for feedhold actions to complete, exit feedhold, do not resume motion + * (in-p2) ! If moving in p2 during a p1 hold ! will perform a SYNC type hold in p2 * (in-cycle) !~ Start a feedhold, do enter and exit actions, exit feedhold, resume motion * (in-cycle) !% Start a feedhold, do enter and exit actions, exit feedhold, do not resume motion * (in-cycle) !%~ Same as above * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) + * + * Note that feedholds from p1 are initiated immediately from cm_request_feedhld(), + * and are not triggered here. Only queued p2 feedholds (feedhold in feedhold) are + * handled in the sequencer. */ - stat_t cm_operation_sequencing_callback() { if (cm1.hold_state == FEEDHOLD_REQUESTED) { - _initiate_p1_feedhold(); + _start_p1_feedhold(); } if (cm1.flush_state == FLUSH_REQUESTED) { - _initiate_queue_flush(); + _start_queue_flush(); } if (cm1.cycle_state == CYCLE_START_REQUESTED) { - _initiate_cycle_restart(); + _start_cycle_restart(); } return (op.run_operation()); } -/**************************************************************************************** - **** Functions ************************************************************************* - ****************************************************************************************/ - /* * cm_has_hold() - return true if a hold condition exists (or a pending hold request) */ @@ -199,6 +278,10 @@ bool cm_has_hold() return (cm1.hold_state != FEEDHOLD_OFF); } +/* + * cm_feedhold_command_blocker() - prevents new Gcode commands from reaching the parser while feedhold is in effect + */ + stat_t cm_feedhold_command_blocker() { if (cm1.hold_state != FEEDHOLD_OFF) { @@ -209,7 +292,7 @@ stat_t cm_feedhold_command_blocker() /**************************************************************************************** * cm_request_cycle_start() - set request enum only - * _initiate_cycle_start() - run the cycle start + * _start_cycle_start() - run the cycle start */ void cm_request_cycle_start() @@ -229,17 +312,17 @@ void cm_request_cycle_start() } } -static void _initiate_cycle_restart() +static void _start_cycle_restart() { // Feedhold cycle starts run an operation to complete multiple actions if (cm1.hold_state == FEEDHOLD_HOLD) { cm1.cycle_state = CYCLE_START_OFF; switch (cm1.hold_type) { case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_with_no_actions); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_no_actions); break; } default: {} } - switch (cm1.hold_final) { + switch (cm1.hold_exit) { case FEEDHOLD_EXIT_CYCLE: { op.add_action(_run_restart_cycle); break; @@ -276,12 +359,8 @@ static void _initiate_cycle_restart() /**************************************************************************************** * cm_request_queue_flush() - set request enum only - * _initiate_queue_flush() - run a queue flush from a % + * _start_queue_flush() - run a queue flush from a % * _restart_flush() - run a queue flush from an action - * - * _restart_flush() assumes that the operations sequencing callback has resolved - * all state and timing issues and it's OK to call this now. Do not call this - * function directly. Always call using the operations runner. */ void cm_request_queue_flush() @@ -294,14 +373,14 @@ void cm_request_queue_flush() } } -static void _initiate_queue_flush() +static void _start_queue_flush() { // Don't initiate the queue until in HOLD state (this also means that runtime is idle) if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD)) { if (cm1.hold_type == FEEDHOLD_TYPE_ACTIONS) { op.add_action(_feedhold_restart_with_actions); } else { - op.add_action(_feedhold_restart_with_no_actions); + op.add_action(_feedhold_restart_no_actions); } op.add_action(_run_queue_flush); op.add_action(_run_program_stop); @@ -318,6 +397,10 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner return (STAT_OK); } +/* + * end state functions + */ + static stat_t _run_program_stop() { cm_cycle_end(); // end cycle and run program stop @@ -348,10 +431,10 @@ static stat_t _run_interlock() /**************************************************************************************** * cm_request_feedhold() - request a feedhold - d0 not run it yet - * _initiate_feedhold() - start feedhold of correct type and finalization + * _start_feedhold() - start feedhold of correct type and finalization * _feedhold_sync_to_planner() - planner callback to reach sync point * _feedhold_with_sync() - * _feedhold_with_no_actions() + * _feedhold_no_actions() * _feedhold_with_actions() - perform hold entry actions * * Input arguments @@ -359,7 +442,7 @@ static stat_t _run_interlock() * - See cmFeedholdFinal - the final state when the feedhold is exited */ -void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) +void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) { // look for p2 feedhold (feedhold in a feedhold) if ((cm1.hold_state == FEEDHOLD_HOLD) && @@ -374,26 +457,26 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdFinal final) // Can only initiate a feedhold if you are in a machining cycle not already in a feedhold if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { cm1.hold_type = type; - cm1.hold_final = final; + cm1.hold_exit = exit; cm1.hold_state = FEEDHOLD_REQUESTED; - _initiate_p1_feedhold(); // attempt to run it immediately + _start_p1_feedhold(); // attempt to run it immediately return; } cm->hold_state = FEEDHOLD_OFF; // cannot honor the feedhold request. reset it } -static void _initiate_p1_feedhold() +static void _start_p1_feedhold() { // This function is "safe" and will not initiate a feedhold unless it's OK to. if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { switch (cm1.hold_type) { case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_with_no_actions); break; } + case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_no_actions); break; } case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync); break; } default: { } } - switch (cm1.hold_final) { + switch (cm1.hold_exit) { case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } @@ -412,13 +495,7 @@ static void _initiate_p1_feedhold() } } -static void _feedhold_sync_to_planner(float* vect, bool* flag) -{ - cm1.hold_state = FEEDHOLD_HOLD_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_HOLD - sr_request_status_report(SR_REQUEST_IMMEDIATE); -} - -static stat_t _feedhold_with_no_actions() +static stat_t _feedhold_no_actions() { return (STAT_OK); } @@ -428,10 +505,17 @@ static stat_t _feedhold_with_sync() return (STAT_OK); } +static void _feedhold_actions_done(float* vect, bool* flag) +{ + cm1.hold_state = FEEDHOLD_HOLD_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_HOLD + sr_request_status_report(SR_REQUEST_IMMEDIATE); +} + + static stat_t _feedhold_with_actions() // Execute Case (5) { // Check to run first-time code - if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_START) { + if (cm1.hold_state == FEEDHOLD_HOLD_POINT_REACHED) { cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state // copy the primary canonical machine to the secondary, @@ -473,7 +557,7 @@ static stat_t _feedhold_with_actions() // Execute Case (5) } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - mp_queue_command(_feedhold_sync_to_planner, nullptr, nullptr); + mp_queue_command(_feedhold_actions_done, nullptr, nullptr); return (STAT_EAGAIN); } @@ -492,18 +576,18 @@ static stat_t _feedhold_with_actions() // Execute Case (5) } /**************************************************************************************** - * _feedhold_restart_sync_to_planner() - planner callback to reach sync point - * _feedhold_restart_with_no_actions() - perform hold restart with no actions - * _feedhold_restart_with_actions() - perform hold restart with actions + * _feedhold_restart_actions_done() - planner callback to reach sync point + * _feedhold_restart_no_actions() - perform hold restart with no actions + * _feedhold_restart_with_actions() - perform hold restart with actions */ -static void _feedhold_restart_sync_to_planner(float* vect, bool* flag) +static void _feedhold_restart_actions_done(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_OFF sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _feedhold_restart_with_no_actions() +static stat_t _feedhold_restart_no_actions() { return (STAT_OK); } @@ -523,7 +607,7 @@ static stat_t _feedhold_restart_with_actions() // Execute Cases (6) and (7) // do return move though an intermediate point; queue a wait cm2.return_flags[AXIS_Z] = false; cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); - mp_queue_command(_feedhold_restart_sync_to_planner, nullptr, nullptr); + mp_queue_command(_feedhold_restart_actions_done, nullptr, nullptr); cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_PENDING; return (STAT_EAGAIN); } @@ -555,340 +639,3 @@ static stat_t _run_restart_cycle(void) } return (STAT_OK); } - - - - - - - - - - - - - - - - - - - - - - - - - -/**************************************************************************************** - * Queue Flush operations - * - * This one's complicated. See here first: - * https://github.com/synthetos/g2/wiki/Job-Exception-Handling - * https://github.com/synthetos/g2/wiki/Alarm-Processing - * - * We want to use queue flush for a few different use cases, as per the above wiki pages. - * The % behavior implements Exception Handling cases 1 and 2 - Stop a Single Move and - * Stop Multiple Moves. This is complicated further by the processing in single USB and - * dual USB being different. Also, the state handling is located in xio.cpp / readline(), - * controller.cpp _dispatch_kernel() and cm_request_queue_flush(), below. - * So it's documented here. - * - * Single or Dual USB Channels: - * - If a % is received outside of a feed hold or ALARM state, ignore it. - * Change the % to a ; comment symbol (xio) - * - * Single USB Channel Operation: - * - Enter a feedhold (!) - * - Receive a queue flush (%) Both dispatch it and store a marker (ACK) in the input - * buffer in place of the the % (xio) - * - Execute the feedhold to a hold condition (plan_exec) - * - Execute the dispatched % to flush queues (canonical_machine) - * - Silently reject any commands up to the % in the input queue (controller) - * - When ETX is encountered transition to STOP state (controller/canonical_machine) - * - * Dual USB Channel Operation: - * - Same as above except that we expect the % to arrive on the control channel - * - The system will read and dump all commands in the data channel until either a - * clear is encountered ({clear:n} or $clear), or an ETX is encountered on either - * channel, but it really should be on the data channel to ensure all queued commands - * are dumped. It is the host's responsibility to both write the clear (or ETX), and - * to ensure that it either arrives on the data channel or that the data channel is - * empty before writing it to the control channel. - */ - -/* -static stat_t _parking_move(float *param); -static stat_t _return_move(float *param); -static stat_t _spindle_control(float *param); -static stat_t _coolant_control(float *param); -static stat_t _heater_control(float *param); -static stat_t _output_control(float *param); -static stat_t _queue_flush(float *param); -static stat_t _input_function(float *param); -static stat_t _finalize_program(float *param); -static stat_t _trigger_alarm(float *param); -*/ - -/* -typedef enum { // cycle start and feedhold requests - OPERATION_NULL = 0, // no operation; reverts here when complete - OPERATION_CYCLE_START, // perform a cycle start with no other actions - OPERATION_HOLD, // feedhold in p1 or p2 with no entry actions -// OPERATION_HOLD_WITH_ACTIONS,// feedhold into p2 with entry actions -// OPERATION_P1_FAST_HOLD, // perform a fast hold in p1 -// OPERATION_HOLD_TO_SYNC, // hold in p1 or p2, skip remainder of move; exec SYNC command or flush - OPERATION_EXIT_HOLD_RESUME, // exit p1 or p2 hold and resume motion in p1 planner - OPERATION_EXIT_HOLD_FLUSH, // exit p1 or p2 hold and flush p1 planner - OPERATION_JOB_KILL, // fast hold followed by queue flush and program end - OPERATION_END_JOG, // fast hold followed by program stop - OPERATION_SOFT_LIMIT_HIT, // actions to run when a soft limit is hit - OPERATION_HARD_LIMIT_HIT, // actions to run when a hard limit is hit - OPERATION_SHUTDOWN, // actions to run when a shutdown is received - OPERATION_PANIC, // actions to run when a panic is received - OPERATION_INTERLOCK_START, // enter an interlock state - OPERATION_INTERLOCK_END, // exit interlocked state - OPERATION_DI_FUNC_STOP, // run digital input STOP function - OPERATION_DI_FUNC_FAST_STOP,// run digital input FAST_STOP function - OPERATION_DI_FUNC_HALT, // run digital input HALT function - OPERATION_TOOL_CHANGE // run a tool change sequence -} cmOperationType; -*/ - -/* -typedef enum { // Operation Actions - // Initiation actions - ACTION_NULL = 0, // no pending action; reverts here when complete (read-only; cannot be set) - ACTION_HOLD, // p1/p2 feedhold at selected jerk ending in HOLD state - // ACTION_P1_HOLD, // p1 feedhold at normal jerk ending in HOLD state in p1 - // ACTION_P2_HOLD, // p2 feedhold at normal jerk ending in HOLD state in p2 (not used) - // ACTION_P1_FAST_HOLD, // p1 feedhold at high jerk ending in HOLD state in p1 - // ACTION_P2_FAST_HOLD, // p2 feedhold at high jerk ending in HOLD state in p2 - ACTION_HALT_MOTION, // halt all motion immediately (regardless of p1 or p2) - - // Hold Entry Actions - run when motion has stopped - ACTION_P2_ENTRY, // Z lift, spindle and coolant actions (bundled) - ACTION_PARKING_MOVE, // perform a pre-defined toolhead parking move - ACTION_PAUSE_SPINDLE, - ACTION_PAUSE_COOLANT, - ACTION_PAUSE_HEATERS, - ACTION_PAUSE_OUTPUTS, // programmed special purpose outputs - ACTION_STOP_SPINDLE, - ACTION_STOP_COOLANT, - ACTION_STOP_HEATERS, - ACTION_STOP_OUTPUTS, - - // In-Hold actions - ACTION_TOOL_CHANGE, - - // Feedhold Exit Actions // This set is kept in a separate vector, so the bit shifts start over. - ACTION_P2_EXIT, // coolant, spindle, return move actions (bundled) - ACTION_RESUME_HEATERS, - ACTION_RESUME_COOLANT, - ACTION_RESUME_SPINDLE, - ACTION_RESUME_OUTPUTS, // programmed special purpose outputs - ACTION_RETURN_MOVE, // returns to hold pint an re-enters p1 - - // Cycle start, restart, exit hold - ACTION_SKIP_TO_SYNC, // discard remaining length, execute next block if SYNC command, otherwise flush buffer - ACTION_CYCLE_START, // (~) exit feedhold, perform exit actions if in p2, resume p1 motion - ACTION_QUEUE_FLUSH, // (%) exit feedhold, perform exit actions if in p2, flush planner queue, enter p1 PROGRAM_STOP - - // Finalization actions - ACTION_DI_FUNCTION, // function as assigned by digital input configuration (TBD) - ACTION_PROGRAM_STOP, // invoke PROGRAM_STOP - ACTION_PROGRAM_END, // invoke PROGRAM_END - ACTION_TRIGGER_ALARM, // trigger ALARM - ACTION_TRIGGER_SHUTDOWN, // trigger SHUTDOWN - ACTION_TRIGGER_PANIC, // trigger PANIC state - ACTION_PERFORM_RESET, // defined, but not implemented -} cmOpAction; -*/ - -/**************************************************************************************** - * cm_request_feedhold() - reqeust a feedhold - * cm_request_exit_hold() - reqeust feedhold exit with resume motion - * cm_request_queue_flush() - request feedhold exit with queue flush - * cm_start_hold() - start a feedhhold external to feedhold request equencing - * cm_feedhold_command_blocker() - prevents new Gcode commands from queueing to p2 planner - * - * p1 is the primary planner, p2 is the secondary planner, which is active if the - * primary planner is in hold. IOW p2 can only be in a hold if p1 is already in one. - * Request_feedhold, request_end_hold, and request_queue_flush are contextual: - * - * It's OK to call start_hold directly in order to get a hold quickly (see gpio.cpp) - * - * request_feedhold: - * - If p1 is not in HOLD & is in motion, request_feedhold requests a p1 hold - * - If p1 is in HOLD & p2 is in motion, request_feedhold requests a p2 hold - * - If both p1 and p2 are in HOLD, request_feedhold is ignored - * - * request_end_hold: - * - If p1 is not in HOLD, request_end_hold is ignored - * - If p1 is in HOLD request_end_hold will end p1 hold & resume motion. - * Pre-defined exit actions (coolant, spindle, Z move) are completed first - * Any executing or pending "in-hold" moves are stopped prior to the exit actions - * - * request_queue_flush: - * - If p1 is not in HOLD, request_queue_flush is ignored - * - If p1 is in HOLD request_queue_flush will end p1 hold & queue flush (stop motion). - * Pre-defined exit actions (coolant, spindle, Z move) are completed first - * Any executing or pending "in-hold" moves are stopped prior to the exit actions - */ - -/**************************************************************************************** - * cm_request_operation() - * - * Invoke an operation by calling cm_request_operation(); may require one or more parameters - * - The operation runner must be idle: an operation cannot interrupt a currently running operation - * - Future may need Cancel Operation semantics, but this could get overcomplicated quickly - * - * When a new operation is requested the operations runner object is cleared and one or - * more actions are queued by calling add_action() on the object. - * - * To start the operation immediately call run_action() at the end of the request. - * Otherwise the operation will begin the next time cm_operation_callback(). - * - * It is assumed that all actions are added at once, and that this cannot be interrupted - * by a run request. So no attempt is made at mutual exclusion. Just behave. - * - * Operations are defined as: - * - * - OPERATION_CYCLE_START - start cycle from STOP or restart from hold - * - * - OPERATION_HOLD - initiate a hold of a given form. Parameters: - * - param[0] - p1/p2 0=hold-into-p1, 1=hold-into-p2 (with entry actions) - * - param[1] - jerk 0=normal-jerk, 1=high-jerk (fast hold) - * - param[2] - endstate - */ - -/**************************************************************************************** - **** Feedholds ************************************************************************* - ****************************************************************************************/ -/* - * Feedholds, queue flushes and end_holds are all related and are performed in this - * file and in plan_exec.cpp. Feedholds are implemented as a state machine - * (cmFeedholdState) that runs in these files. - * - * There are 2 planners: p1 (primary planner) and p2 (secondary planner). A feedhold - * received while in p1 stops motion in p1 and transitions to p2, where entry actions - * like Z lift, spindle and coolant pause occur. While in p2 (almost) all machine - * operations are available. - * - * A feedhold received while in p2 (a feedhold within a feedhold - very Inception) - * stops motion in p2 and flushes the p2 planner. Control remains in p2. - * - * A feedhold exit request (~) received while in either p1 or p2 will execute the - * feedhold exit actions: - * - Resume coolant (if paused) - * - Resume spindle (if paused) with spinup delay - * - Move back to starting location in XY, then plunge in Z - * Motion will resume in p1 after the exit actions complete - * - * A feedhold flush request (%) received while in either p1 or p2 will execute the - * exit actions, flush the p1 and p2 queues, then stop motion at the hold point. - */ -/* - * Feedhold Processing - Performs the following cases (listed in rough sequence order): - * - * (0) - Feedhold request arrives or cm_start_hold() is called - * - * Control transfers to plan_exec.cpp feedhold functions: - * - * (1) - Feedhold arrives while we are in the middle executing of a block - * (1a) - The block is currently accelerating - wait for the end of acceleration - * (1b) - The block is in a head, but has not started execution yet - start deceleration - * (1b1) - The deceleration fits into the current block - * (1b2) - The deceleration does not fit and needs to continue in the next block - * (1c) - The block is in a body - start deceleration - * (1c1) - The deceleration fits into the current block - * (1c2) - The deceleration does not fit and needs to continue in the next block - * (1d) - The block is currently in the tail - wait until the end of the block - * (1e) - We have a new block and a new feedhold request that arrived at EXACTLY the same time - * (unlikely, but handled as 1b). - * - * (2) - The block has decelerated to some velocity > zero, so needs continuation into next block - * (3) - The end of deceleration is detected inline in mp_exec_aline() - * (4) - Finished all runtime work, now wait for the motors to stop on HOLD point. When they do: - * (4a) - It's a homing or probing feedhold - ditch the remaining buffer & go directly to OFF - * (4b) - It's a p2 feedhold - ditch the remaining buffer & signal we want a p2 queue flush - * (4c) - It's a normal feedhold - signal we want the p2 entry actions to execute - * - * Control transfers back to cycle_feedhold.cpp feedhold functions: - * - * (5) - Run the P2 entry actions and transition to HOLD state when complete - * (6) - Remove the hold state / there is queued motion - see cycle_feedhold.cpp - * (7) - Remove the hold state / there is no queued motion - see cycle_feedhold.cpp - */ - -/**************************************************************************************** - * cm_feedhold_sequencing_callback() - sequence feedhold, queue_flush, and end_hold requests - * - * Expected behaviors: (no-hold means machine is not in hold, etc) - * - * (no-cycle) ! No action. Feedhold is not run (nothing to hold!) - * (no-hold) ~ No action. Cannot exit a feedhold that does not exist - * (no-hold) % No action. Queue flush is not honored except during a feedhold - * (in-cycle) ! Start a feedhold - * (in-hold) ~ Wait for feedhold actions to complete, exit feedhold, resume motion - * (in-hold) % Wait for feedhold actions to complete, exit feedhold, do not resume motion - * (in-cycle) !~ Start a feedhold, do enter and exit actions, exit feedhold, resume motion - * (in-cycle) !% Start a feedhold, do enter and exit actions, exit feedhold, do not resume motion - * (in-cycle) !%~ Same as above - * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) - */ - -/**************************************************************************************** - * _feedhold_abort() - used to exit a feedhold without completing exit actions - * - * Valid entry states (all must be handled): - * Case (1) Not in a feedhold (FEEDHOLD_OFF). Ignore the request - * - * Case (2) In a feedhold but have not yet hit the hold point. - * Leave the abort request pending to be picked up by p2 entry actions, - * which are not allowed to proceed. - * - * Case (3) In a feedhold and currently executing P2 entry actions - * Case (4) In a feedhold and currently idle in P2 - * Case (5) In a feedhold and currently moving in P2 - * Case (6) In a feedhold and currently executing P2 exit actions - */ -/* -static void _feedhold_abort() -{ - // Exit if not in a feedhold - if (cm1.hold_state == FEEDHOLD_OFF) { - cm1.hold_abort_requested = false; - return; - } - - // No action if waiting for HOLD point - let P2_START run the abort - if ((cm1.hold_state > FEEDHOLD_OFF) && (cm1.hold_state < FEEDHOLD_P2_START)) { - return; - } - - // If in p2 perform the p2 exit first - if (cm == &cm2) { - _feedhold_p2_exit(); - } - - // perform a complete exit from p1 - cm = &cm1; // return to p1 if not already here - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; - - // execute this block if a queue flush was performed - // adjust p1 planner positions to runtime positions - if (cm1.flush_state == FLUSH_WAS_RUN) { - cm_reset_position_to_absolute_position(cm); - cm1.flush_state = FLUSH_OFF; - } - - // end cycle -// cm_set_motion_state(MOTION_STOP); -// cm_cycle_end(); - cm1.hold_state = FEEDHOLD_OFF; - cm1.hold_abort_requested = false; -} -*/ - diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..bb1cf7a0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 1fe32a0d..b115c793 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -485,7 +485,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->hold_state != FEEDHOLD_OFF) { // if running actions, or in HOLD state, or exiting with actions - if (cm->hold_state >= FEEDHOLD_HOLD_ACTIONS_START) { // handles _exec_aline_feedhold_processing case (7) + if (cm->hold_state >= FEEDHOLD_HOLD_POINT_REACHED) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } // STAT_OK terminates aline execution for this move @@ -1059,7 +1059,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Set state to enable transition to p2 and perform entry actions in the p2 planner if (cm->hold_type == FEEDHOLD_TYPE_ACTIONS) { - cm->hold_state = FEEDHOLD_HOLD_ACTIONS_START; // signal to start entry actions + cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; // signal to start entry actions } else { cm->hold_state = FEEDHOLD_HOLD; // achieved hold state } From e956468224cfff971a081d6325635e0e1bcdc0f2 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 16 Mar 2017 12:02:33 -0400 Subject: [PATCH 194/283] Stubbed in job kill changes --- g2core/alarm.cpp | 9 ------ g2core/canonical_machine.cpp | 6 ++-- g2core/canonical_machine.h | 50 +++++++++++++++--------------- g2core/controller.cpp | 2 +- g2core/cycle_feedhold.cpp | 59 ++++++++++++++++++++++++++++-------- 5 files changed, 77 insertions(+), 49 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index c1a22400..3251c6b9 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -242,12 +242,3 @@ stat_t cm_panic(const stat_t status, const char *msg) rpt_exception(status, msg); // send panic report return (status); } - -/**************************************************************************************** - * cm_job_kill() - Control-D handler - */ - -void cm_job_kill() -{ - cm1.request_job_kill = true; -} diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8f113b45..c19860c4 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -191,15 +191,15 @@ void canonical_machine_reset(cmMachine_t *_cm) _cm->homing_state = HOMING_NOT_HOMED; // reset request flags - _cm->flush_state = FLUSH_OFF; + _cm->queue_flush_state = QUEUE_FLUSH_OFF; + _cm->cycle_start_state = CYCLE_START_OFF; + _cm->job_kill_state = JOB_KILL_OFF; _cm->limit_requested = 0; // resets switch closures that occurred during initialization _cm->safety_interlock_disengaged = 0; // ditto _cm->safety_interlock_reengaged = 0; // ditto _cm->shutdown_requested = 0; // ditto - _cm->request_interlock = false; _cm->request_interlock_exit = false; - _cm->request_job_kill = false; // set initial state and signal that the machine is ready for action _cm->cycle_type = CYCLE_NONE; diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index c3f246c0..8a871174 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -98,12 +98,6 @@ typedef enum { MOTION_RUN // machine is in motion: set when the steppers execute an ALINE segment } cmMotionState; -typedef enum { // state machine for cycle start - CYCLE_START_OFF = 0, // not requested - CYCLE_START_REQUESTED, - CYCLE_START_COMPLETE -} cmCycleState; - typedef enum { CYCLE_NONE = 0, // not in a cycle CYCLE_MACHINING, // in normal machining cycle @@ -149,6 +143,22 @@ typedef enum { // feedhold state machine FEEDHOLD_EXIT_ACTIONS_COMPLETE // completed exit actions } cmFeedholdState; +typedef enum { // Motion profiles + PROFILE_NORMAL = 0, // Normal jerk in effect + PROFILE_FAST // High speed jerk in effect +} cmMotionProfile; + +typedef enum { // state machine for cycle start + CYCLE_START_OFF = 0, // not requested + CYCLE_START_REQUESTED, + CYCLE_START_COMPLETE +} cmCycleState; + +typedef enum { // queue flush state machine + QUEUE_FLUSH_OFF = 0, // no queue flush in effect + QUEUE_FLUSH_REQUESTED // flush has been requested but not started yet +} cmFlushState; + typedef enum { // applies to cm->homing_state HOMING_NOT_HOMED = 0, // machine is not homed (0=false) HOMING_HOMED = 1, // machine is homed (1=true) @@ -172,15 +182,11 @@ typedef enum { // feed override state machine MFO_SYNC } cmOverrideState; -typedef enum { // queue flush state machine - FLUSH_OFF = 0, // no queue flush in effect - FLUSH_REQUESTED // flush has been requested but not started yet -} cmFlushState; - -typedef enum { // Motion profiles - PROFILE_NORMAL = 0, // Normal jerk in effect - PROFILE_FAST // High speed jerk in effect -} cmMotionProfile; +typedef enum { // job kill state machine + JOB_KILL_OFF = 0, + JOB_KILL_REQUESTED, + JOB_KILL_RUNNING +} cmJobKillState; /***************************************************************************** * CANONICAL MACHINE STRUCTURES @@ -278,22 +284,18 @@ typedef struct cmMachine { // struct to manage canonical machin cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state cmCycleType cycle_type; // cycs cmMotionState motion_state; // mots - -// cmFeedholdType hold_type; // hold: type of feedhold requested -// cmFeedholdFinal hold_final; // hold: final state of hold -// cmFeedholdState hold_state; // hold: feedhold state machine cmFeedholdType hold_type; // hold: type of feedhold requested cmFeedholdExit hold_exit; // hold: final state of hold on exit cmMotionProfile hold_profile; // hold: motion profile to use for deceleration cmFeedholdState hold_state; // hold: feedhold state machine - cmFlushState flush_state; // hold: queue flush state machine - cmCycleState cycle_state; // used to manage cycle start - + cmFlushState queue_flush_state; // queue flush state machine + cmCycleState cycle_start_state; // used to manage cycle starts and restarts + cmJobKillState job_kill_state; // used to manage job kill transitions + bool request_interlock; // enter interlock bool request_interlock_exit; // exit interlock - bool request_job_kill; // ^d - end hold, flush and alarm cmOverrideState mfo_state; // feed override state machine @@ -530,7 +532,7 @@ void cm_halt_motion(void); // halt motion ( stat_t cm_alarm(const stat_t status, const char *msg); // enter alarm state - preserve Gcode state stat_t cm_shutdown(const stat_t status, const char *msg); // enter shutdown state - dump all state stat_t cm_panic(const stat_t status, const char *msg); // enter panic state - needs RESET -void cm_job_kill(void); // control-D handler +void cm_request_job_kill(void); // control-D handler /**** cfgArray interface functions ****/ diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 882ebede..fa4d9441 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -241,7 +241,7 @@ static void _dispatch_kernel(const devflags_t flags) if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } else if (*cs.bufp == '~') { cm_request_cycle_start(); } - else if (*cs.bufp == EOT) { cm_job_kill(); } + else if (*cs.bufp == EOT) { cm_request_job_kill(); } else if (*cs.bufp == ENQ) { controller_request_enquiry(); } else if (*cs.bufp == CAN) { hw_hard_reset(); } // reset immediately diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index fe114488..9ffa0d0c 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -41,6 +41,7 @@ static void _start_p1_feedhold(void); static void _start_cycle_restart(void); static void _start_queue_flush(void); +static void _start_job_kill(void); // Feedhold actions static stat_t _feedhold_with_actions(void); @@ -257,15 +258,22 @@ void cm_operation_init() */ stat_t cm_operation_sequencing_callback() { + if (cm1.job_kill_state == JOB_KILL_REQUESTED) { // job kill must wait for any active hold to complete + _start_job_kill(); + } if (cm1.hold_state == FEEDHOLD_REQUESTED) { _start_p1_feedhold(); } - if (cm1.flush_state == FLUSH_REQUESTED) { +// if (cm2.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold +// _start_p2_feedhold(); +// } + if (cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) { // look for a queued flush request _start_queue_flush(); } - if (cm1.cycle_state == CYCLE_START_REQUESTED) { + if (cm1.cycle_start_state == CYCLE_START_REQUESTED) { // look for a queued cycle start ot restart _start_cycle_restart(); } + return (op.run_operation()); } @@ -298,17 +306,17 @@ stat_t cm_feedhold_command_blocker() void cm_request_cycle_start() { if (cm1.hold_state != FEEDHOLD_OFF) { // restart from a feedhold - if (cm1.flush_state == FLUSH_REQUESTED) { // possible race condition. Flush wins - cm1.cycle_state = CYCLE_START_OFF; + if (cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) { // possible race condition. Flush wins + cm1.cycle_start_state = CYCLE_START_OFF; } else { - cm1.cycle_state = CYCLE_START_REQUESTED; + cm1.cycle_start_state = CYCLE_START_REQUESTED; } } else { // execute cycle start directly if (mp_has_runnable_buffer(&mp1)) { cm_cycle_start(); st_request_exec_move(); } - cm1.cycle_state = CYCLE_START_OFF; + cm1.cycle_start_state = CYCLE_START_OFF; } } @@ -316,7 +324,7 @@ static void _start_cycle_restart() { // Feedhold cycle starts run an operation to complete multiple actions if (cm1.hold_state == FEEDHOLD_HOLD) { - cm1.cycle_state = CYCLE_START_OFF; + cm1.cycle_start_state = CYCLE_START_OFF; switch (cm1.hold_type) { case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions); break; } case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_no_actions); break; } @@ -367,16 +375,16 @@ void cm_request_queue_flush() { // Can only initiate a queue flush if in a feedhold if (cm1.hold_state != FEEDHOLD_OFF) { - cm1.flush_state = FLUSH_REQUESTED; + cm1.queue_flush_state = QUEUE_FLUSH_REQUESTED; } else { - cm1.flush_state = FLUSH_OFF; + cm1.queue_flush_state = QUEUE_FLUSH_OFF; } } static void _start_queue_flush() { // Don't initiate the queue until in HOLD state (this also means that runtime is idle) - if ((cm1.flush_state == FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD)) { + if ((cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) && (cm1.hold_state == FEEDHOLD_HOLD)) { if (cm1.hold_type == FEEDHOLD_TYPE_ACTIONS) { op.add_action(_feedhold_restart_with_actions); } else { @@ -392,11 +400,38 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner cm_abort_arc(cm); // kill arcs so they don't just create more alines planner_reset((mpPlanner_t *)cm->mp); // reset primary planner. also resets the mr under the planner cm_reset_position_to_absolute_position(cm); - cm1.flush_state = FLUSH_OFF; + cm1.queue_flush_state = QUEUE_FLUSH_OFF; qr_request_queue_report(0); // request a queue report, since we've changed the number of buffers available return (STAT_OK); } +/**************************************************************************************** + * cm_request_job_kill() - Control-D handler - set request flag only by ^d + * _start_job_kill() - invoke the job kill functions + * _run_job_kill() - perform the job kill. queue flush, enter alarm with no movement + */ + +void cm_request_job_kill() +{ + cm1.job_kill_state = JOB_KILL_REQUESTED; +} + +static stat_t _run_job_kill_final() +{ + cm_alarm(STAT_KILL_JOB, "Job killed by ^d"); + return (STAT_OK); +} + +static void _start_job_kill() +{ + if ((cm1.hold_state == FEEDHOLD_OFF) || (cm1.hold_state == FEEDHOLD_HOLD)) { + cm1.job_kill_state = JOB_KILL_RUNNING; +// op.add_action(_feedhold_restart_no_actions); + op.add_action(_run_queue_flush); + op.add_action(_run_job_kill_final); + } +} + /* * end state functions */ @@ -528,7 +563,7 @@ static stat_t _feedhold_with_actions() // Execute Case (5) cm2.hold_state = FEEDHOLD_OFF; cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - cm2.flush_state = FLUSH_OFF; + cm2.queue_flush_state = QUEUE_FLUSH_OFF; cm2.gm.feed_rate = 0; // clear the target and set the positions to the current hold position From 3e9a3e1f81d41cc8fb375ddc4026ee382d3ef944 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 16 Mar 2017 14:16:51 -0400 Subject: [PATCH 195/283] Work on job kill --- g2core/cycle_feedhold.cpp | 113 ++++++++++++++++++++++++-------------- g2core/plan_exec.cpp | 1 + 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 9ffa0d0c..352e467d 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -252,25 +252,27 @@ void cm_operation_init() * (in-cycle) !%~ Same as above * (in-cycle) !~% Same as above (this one's an anomaly, but the intent would be to Q flush) * + * The requests are arranged in priority order, highest priority first. * Note that feedholds from p1 are initiated immediately from cm_request_feedhld(), * and are not triggered here. Only queued p2 feedholds (feedhold in feedhold) are * handled in the sequencer. */ + stat_t cm_operation_sequencing_callback() { - if (cm1.job_kill_state == JOB_KILL_REQUESTED) { // job kill must wait for any active hold to complete + if (cm1.job_kill_state == JOB_KILL_REQUESTED) { // job kill must wait for any active hold to complete _start_job_kill(); } if (cm1.hold_state == FEEDHOLD_REQUESTED) { _start_p1_feedhold(); } -// if (cm2.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold +// if (cm2.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold // _start_p2_feedhold(); // } - if (cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) { // look for a queued flush request + if (cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) { // look for a queued flush request _start_queue_flush(); } - if (cm1.cycle_start_state == CYCLE_START_REQUESTED) { // look for a queued cycle start ot restart + if (cm1.cycle_start_state == CYCLE_START_REQUESTED) { // look for a queued cycle start ot restart _start_cycle_restart(); } @@ -298,6 +300,37 @@ stat_t cm_feedhold_command_blocker() return (STAT_OK); } +/* + * end state functions and helpers + */ + +static stat_t _run_program_stop() +{ + cm_cycle_end(); // end cycle and run program stop +// cm_program_stop(); + return (STAT_OK); +} + +static stat_t _run_program_end() +{ + cm_program_end(); + return (STAT_OK); +} + +static stat_t _run_alarm() +{ + return (STAT_OK); +} + +static stat_t _run_shutdown() +{ + return (STAT_OK); +} + +static stat_t _run_interlock() +{ + return (STAT_OK); +} /**************************************************************************************** * cm_request_cycle_start() - set request enum only * _start_cycle_start() - run the cycle start @@ -407,8 +440,17 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner /**************************************************************************************** * cm_request_job_kill() - Control-D handler - set request flag only by ^d - * _start_job_kill() - invoke the job kill functions - * _run_job_kill() - perform the job kill. queue flush, enter alarm with no movement + * _run_job_kill_final() - perform the job kill. queue flush, enter alarm with no movement + * _start_job_kill() - invoke the job kill function, which may start from various states + * + * Job kill cases: + * Job kill from machining cycle (1) hold, flush and enter ALARM state + * Job kill from PROBE (2) flush and enter ALARM state + * Job kill from HOMING (3) flush and enter ALARM state + * Job kill from JOGGING (4) flush and enter ALARM state + * Job kill from feedhold (5) flush and enter ALARM state + * Job kill from interlock (6) flush and enter ALARM state + * job kill has no action if from: (7) READY, STOP, END, ALARM, SHUTDOWN, PANIC states */ void cm_request_job_kill() @@ -418,50 +460,41 @@ void cm_request_job_kill() static stat_t _run_job_kill_final() { - cm_alarm(STAT_KILL_JOB, "Job killed by ^d"); + + // switch to p1 (may already be in it) + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + + coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); // stop coolant + spindle_control_immediate(SPINDLE_OFF); // stop spindle + + cm->machine_state = MACHINE_ALARM; + rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); + sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); } static void _start_job_kill() { + // Cases (1 - 4) + if (cm1.machine_state == MACHINE_CYCLE) { + if (cm1.hold_state != FEEDHOLD_OFF) { + op.add_action(_feedhold_no_actions); + op.add_action(_run_queue_flush); + } + op.add_action(_run_job_kill_final); // Case (5) + op.run_operation(); + } +/* if ((cm1.hold_state == FEEDHOLD_OFF) || (cm1.hold_state == FEEDHOLD_HOLD)) { cm1.job_kill_state = JOB_KILL_RUNNING; -// op.add_action(_feedhold_restart_no_actions); op.add_action(_run_queue_flush); op.add_action(_run_job_kill_final); + op.run_operation(); } -} - -/* - * end state functions - */ - -static stat_t _run_program_stop() -{ - cm_cycle_end(); // end cycle and run program stop -// cm_program_stop(); - return (STAT_OK); -} - -static stat_t _run_program_end() -{ - cm_program_end(); - return (STAT_OK); -} - -static stat_t _run_alarm() -{ - return (STAT_OK); -} - -static stat_t _run_shutdown() -{ - return (STAT_OK); -} - -static stat_t _run_interlock() -{ - return (STAT_OK); +*/ + cm1.job_kill_state = JOB_KILL_OFF; // nothing to do. turn off the request } /**************************************************************************************** diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index b115c793..8f8ddb62 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1028,6 +1028,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes cm->hold_state = FEEDHOLD_MOTION_STOPPED; + cm_set_motion_state(MOTION_STOP); // we just stopped it +++++ test this // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { From c09cd8983ecd771badc1852ce2e5b6fb4225337e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 17 Mar 2017 10:32:53 -0400 Subject: [PATCH 196/283] Subtle but important changes to where MOTION_RUN and MOTION_STOP are set. Still in testing --- g2core/canonical_machine.h | 20 ++++++------ g2core/cycle_feedhold.cpp | 66 ++++++++++++++++++++++---------------- g2core/plan_exec.cpp | 8 +++-- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 8a871174..1dbd7aed 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -261,7 +261,6 @@ typedef struct cmMachine { // struct to manage canonical machin float feedhold_z_lift; // mm to move Z axis on feedhold, or 0 to disable bool soft_limit_enable; // true to enable soft limit testing on Gcode inputs bool limit_enable; // true to enable limit switches (disabled is same as override) - bool safety_interlock_enable; // true to enable safety interlock system // Coordinate systems and offsets float coord_offset[COORDS+1][AXES]; // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59 @@ -293,22 +292,21 @@ typedef struct cmMachine { // struct to manage canonical machin cmFlushState queue_flush_state; // queue flush state machine cmCycleState cycle_start_state; // used to manage cycle starts and restarts cmJobKillState job_kill_state; // used to manage job kill transitions - - bool request_interlock; // enter interlock - bool request_interlock_exit; // exit interlock - cmOverrideState mfo_state; // feed override state machine - uint8_t safety_interlock_disengaged; // set non-zero to start interlock processing (value is input number) - uint8_t safety_interlock_reengaged; // set non-zero to end interlock processing (value is input number) - cmSafetyState safety_interlock_state; // safety interlock state - uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot + bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move uint8_t limit_requested; // set non-zero to request limit switch processing (value is input number) uint8_t shutdown_requested; // set non-zero to request shutdown in support of external estop (value is input number) bool deferred_write_flag; // G10 data has changed (e.g. offsets) - flag to persist them - - bool return_flags[AXES]; // flags for recording which axes moved - used in feedhold exit move + + bool safety_interlock_enable; // true to enable safety interlock system + bool request_interlock; // enter interlock + bool request_interlock_exit; // exit interlock + uint8_t safety_interlock_disengaged; // set non-zero to start interlock processing (value is input number) + uint8_t safety_interlock_reengaged; // set non-zero to end interlock processing (value is input number) + cmSafetyState safety_interlock_state; // safety interlock state + uint32_t esc_boot_timer; // timer for Electronic Speed Control (Spindle electronics) to boot cmHomingState homing_state; // home: homing cycle sub-state machine uint8_t homed[AXES]; // individual axis homing flags diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 352e467d..dc8d0244 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -460,7 +460,6 @@ void cm_request_job_kill() static stat_t _run_job_kill_final() { - // switch to p1 (may already be in it) cm = &cm1; // return to primary planner (p1) mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer @@ -469,6 +468,7 @@ static stat_t _run_job_kill_final() coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); // stop coolant spindle_control_immediate(SPINDLE_OFF); // stop spindle + cm->hold_state = FEEDHOLD_OFF; cm->machine_state = MACHINE_ALARM; rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -479,31 +479,23 @@ static void _start_job_kill() { // Cases (1 - 4) if (cm1.machine_state == MACHINE_CYCLE) { - if (cm1.hold_state != FEEDHOLD_OFF) { + if (cm1.hold_state == FEEDHOLD_OFF) { op.add_action(_feedhold_no_actions); - op.add_action(_run_queue_flush); } + op.add_action(_run_queue_flush); op.add_action(_run_job_kill_final); // Case (5) op.run_operation(); } -/* - if ((cm1.hold_state == FEEDHOLD_OFF) || (cm1.hold_state == FEEDHOLD_HOLD)) { - cm1.job_kill_state = JOB_KILL_RUNNING; - op.add_action(_run_queue_flush); - op.add_action(_run_job_kill_final); - op.run_operation(); - } -*/ cm1.job_kill_state = JOB_KILL_OFF; // nothing to do. turn off the request } /**************************************************************************************** - * cm_request_feedhold() - request a feedhold - d0 not run it yet - * _start_feedhold() - start feedhold of correct type and finalization - * _feedhold_sync_to_planner() - planner callback to reach sync point - * _feedhold_with_sync() - * _feedhold_no_actions() + * cm_request_feedhold() - request a feedhold - do not run it yet + * _start_p1_feedhold() - start feedhold of correct type and finalization + * _feedhold_with_sync() - perform feedhold that will end in a sync callback + * _feedhold_no_actions() - perform feedhold with no entry actions * _feedhold_with_actions() - perform hold entry actions + * _feedhold_actions_done_callback() - planner callback to reach sync point * * Input arguments * - See cmFeedholdType - how the feedhold will execute @@ -563,17 +555,31 @@ static void _start_p1_feedhold() } } -static stat_t _feedhold_no_actions() -{ - return (STAT_OK); -} - static stat_t _feedhold_with_sync() { + if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold + cm1.hold_state = FEEDHOLD_SYNC; + } + if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { + return (STAT_EAGAIN); + } + cm1.hold_state = FEEDHOLD_HOLD; return (STAT_OK); } -static void _feedhold_actions_done(float* vect, bool* flag) +static stat_t _feedhold_no_actions() +{ + if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold + cm1.hold_state = FEEDHOLD_SYNC; + } + if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { // wait until it reaches the hold point + return (STAT_EAGAIN); + } + cm1.hold_state = FEEDHOLD_HOLD; + return (STAT_OK); +} + +static void _feedhold_actions_done_callback(float* vect, bool* flag) { cm1.hold_state = FEEDHOLD_HOLD_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_HOLD sr_request_status_report(SR_REQUEST_IMMEDIATE); @@ -625,7 +631,7 @@ static stat_t _feedhold_with_actions() // Execute Case (5) } spindle_control_sync(SPINDLE_PAUSE); // optional spindle pause coolant_control_sync(COOLANT_PAUSE, COOLANT_BOTH); // optional coolant pause - mp_queue_command(_feedhold_actions_done, nullptr, nullptr); + mp_queue_command(_feedhold_actions_done_callback, nullptr, nullptr); return (STAT_EAGAIN); } @@ -644,19 +650,25 @@ static stat_t _feedhold_with_actions() // Execute Case (5) } /**************************************************************************************** - * _feedhold_restart_actions_done() - planner callback to reach sync point * _feedhold_restart_no_actions() - perform hold restart with no actions * _feedhold_restart_with_actions() - perform hold restart with actions + * _feedhold_restart_actions_done_callback() */ -static void _feedhold_restart_actions_done(float* vect, bool* flag) +static void _feedhold_restart_actions_done_callback(float* vect, bool* flag) { - cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_OFF + cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_OFF sr_request_status_report(SR_REQUEST_IMMEDIATE); } static stat_t _feedhold_restart_no_actions() { + if (cm1.hold_state == FEEDHOLD_OFF) { + return (STAT_OK); // was called erroneously. Can happen for !%~ + } + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; return (STAT_OK); } @@ -675,7 +687,7 @@ static stat_t _feedhold_restart_with_actions() // Execute Cases (6) and (7) // do return move though an intermediate point; queue a wait cm2.return_flags[AXIS_Z] = false; cm_goto_g30_position(cm2.gmx.g30_position, cm2.return_flags); - mp_queue_command(_feedhold_restart_actions_done, nullptr, nullptr); + mp_queue_command(_feedhold_restart_actions_done_callback, nullptr, nullptr); cm1.hold_state = FEEDHOLD_EXIT_ACTIONS_PENDING; return (STAT_EAGAIN); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 8f8ddb62..990a1793 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -307,7 +307,7 @@ stat_t mp_exec_move() } // Perform motion state transition. Also sets active model to RUNTIME - if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); } +// if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); } } if (bf->bf_func == NULL) { return(cm_panic(STAT_INTERNAL_ERROR, "mp_exec_move()")); // never supposed to get here @@ -527,8 +527,12 @@ stat_t mp_exec_aline(mpBuf_t *bf) if ((status == STAT_OK) || (status == STAT_NOOP)) { cm->hold_state = FEEDHOLD_DECEL_COMPLETE; bf->block_state = BLOCK_INITIAL_ACTION; // reset bf so it can restart the rest of the move + cm_set_motion_state(MOTION_STOP); } } + + // Perform motion state transition. Also sets active model to RUNTIME + if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); } // There are 4 things that can happen here depending on return conditions: // status bf->block_state Description @@ -1027,8 +1031,8 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes +// cm_set_motion_state(MOTION_STOP); // we just stopped it +++++ test this cm->hold_state = FEEDHOLD_MOTION_STOPPED; - cm_set_motion_state(MOTION_STOP); // we just stopped it +++++ test this // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { From d29150b50b2a34c55682b725d7af69f8e2393240 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 17 Mar 2017 12:53:57 -0400 Subject: [PATCH 197/283] Better final states from job kill. Tests better --- g2core/config_app.cpp | 3 +-- g2core/cycle_feedhold.cpp | 3 +++ g2core/gcode.h | 38 +++++++++++++++++++------------------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 19bc13ec..baf1eebe 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -133,9 +133,8 @@ const cfgItem_t cfgArray[] = { { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled - #ifdef TEMPORARY_HAS_LEDS - { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds,(float *)&cs.null, 0 }, // TEMPORARY - change LEDs + { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds, (float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index dc8d0244..ed0b7ab0 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -470,6 +470,9 @@ static stat_t _run_job_kill_final() cm->hold_state = FEEDHOLD_OFF; cm->machine_state = MACHINE_ALARM; + cm->cycle_type = CYCLE_NONE; + cm_set_motion_state(MOTION_STOP); // set to stop and set the active model + rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); diff --git a/g2core/gcode.h b/g2core/gcode.h index bf915bd4..f3dede09 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -179,19 +179,19 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) /**************************************************************************************** * GCODE MODEL - The following GCodeModel/GCodeInput structs are used: * - * - gm is the core Gcode model state. It keeps the internal gcode state model in - * normalized, canonical form. All values are unit converted (to mm) and in the - * machine coordinate system (absolute coordinate system). Gm is owned by the + * - gm is the core Gcode model state. It keeps the internal gcode state model in + * normalized canonical form. All values are unit converted (to mm) and in the + * machine coordinate system (absolute coordinate system). Gm is owned by the * canonical machine layer and should be accessed only through cm_ routines. * - * The gm core struct is copied and passed as context to the runtime where it is - * used for planning, move execution, feedholds, and reporting. + * The gm core struct is copied and passed as context to the runtime where it is used + * for planning, move execution, feedholds, and reporting. * * - gmx is the extended gcode model variables that are only used by the canonical - * machine and do not need to be passed further down. It keeps "global" gcode - * state that does not change when you go down through the planner to the runtime. - * Other Gcode model state is kept in the singletons for various sub-systems, such - * as arcs, spindle, coolant, and others (i.e. not ALL gcode global state is in gmx) + * machine and do not need to be passed further down. It keeps "global" gcode state + * that does not change when you go down through the planner to the runtime. Other + * Gcode model state is kept in the singletons for various sub-systems, such as arcs + * spindle, coolant, and others (i.e. not ALL gcode global state is in gmx) * * - gn is used by the gcode interpreter and is re-initialized for each gcode block. * It accepts data in the new gcode block in the formats present in the block @@ -199,21 +199,21 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) * restored from gm. * * - gf is used by the gcode parser interpreter to hold flags for any data that has - * changed in gn during the parse. gf.target[] values are also used by the - * canonical machine during set_target(). + * changed in gn during the parse. gf.target[] values are also used by the canonical + * machine during set_target(). * - * - cfg (config struct in config.h) is also used heavily and contains some values - * that might be considered to be Gcode model values. The distinction is that all - * values in the config are persisted and restored, whereas the gm structs are - * transient. So cfg has the G54 - G59 offsets, but gm has the G92 offsets. - * cfg has the power-on / reset gcode default values, but gm has the operating - * state for the values (which may have changed). + * - cfg (config struct in config.h) is also used heavily and contains some values that + * might be considered to be Gcode model values. The distinction is that all values + * in the config are persisted and restored, whereas the gm structs are transient. + * So cfg has the G54 - G59 offsets, but gm has the G92 offsets. cfg has the power-on / + * reset gcode default values, but gm has the operating state for the values + * (which may have changed). */ typedef struct GCodeState { // Gcode model state - used by model, planning and runtime uint32_t linenum; // Gcode block line number - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, - // G82, G83 G84, G85, G86, G87, G88, G89 + cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 + // G83, G84, G85, G86, G87, G88, G89 float target[AXES]; // XYZABC target where the move should go float target_comp[AXES]; // summation compensation (Kahan) overflow value From 76924d8e80da0e2802325c92c47b7b64aaba6b44 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 17 Mar 2017 13:06:18 -0400 Subject: [PATCH 198/283] Minor commit --- g2core/cycle_feedhold.cpp | 6 +++--- g2core/plan_exec.cpp | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index ed0b7ab0..ccc0e563 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -468,10 +468,10 @@ static stat_t _run_job_kill_final() coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); // stop coolant spindle_control_immediate(SPINDLE_OFF); // stop spindle - cm->hold_state = FEEDHOLD_OFF; - cm->machine_state = MACHINE_ALARM; - cm->cycle_type = CYCLE_NONE; cm_set_motion_state(MOTION_STOP); // set to stop and set the active model + cm->hold_state = FEEDHOLD_OFF; + cm->cycle_type = CYCLE_NONE; + cm->machine_state = MACHINE_ALARM; rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); sr_request_status_report(SR_REQUEST_IMMEDIATE); diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 990a1793..9cb7fb66 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1031,12 +1031,10 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes -// cm_set_motion_state(MOTION_STOP); // we just stopped it +++++ test this cm->hold_state = FEEDHOLD_MOTION_STOPPED; // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue if (cm == &cm2) { -// cm->hold_type = FEEDHOLD_TYPE_SYNC; // force to a sync hold cm->hold_state = FEEDHOLD_HOLD; return (STAT_OK); // will end this exec_aline() with no more movement } From 4fbaad1c33d952b5aa0ff41c15af8e5faf60b6b8 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 05:39:16 -0400 Subject: [PATCH 199/283] Testing for feedhold type instead if cycle type; corrected bug in gpio edge detection for probe mode; changed feedhold with sync to feedhold with command; --- g2core/canonical_machine.h | 2 +- g2core/cycle_feedhold.cpp | 16 +++---- g2core/cycle_probing.cpp | 46 +++++++++--------- g2core/gpio.cpp | 12 +++-- g2core/plan_exec.cpp | 14 ++++-- g2core/plan_line.cpp | 1 - g2core/planner.cpp | 98 +++++++++++++++++++------------------- 7 files changed, 98 insertions(+), 91 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 1dbd7aed..564b48ec 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -111,7 +111,7 @@ typedef enum { typedef enum { // feedhold type parameter FEEDHOLD_TYPE_ACTIONS = 0, // feedhold at max jerk with actions FEEDHOLD_TYPE_NO_ACTIONS, // feedhold at max jerk with no actions - FEEDHOLD_TYPE_SYNC, // feedhold at max jerk with queue flush and sync command + FEEDHOLD_TYPE_COMMAND, // feedhold at max jerk with queue flush and sync command FEEDHOLD_TYPE_FAST, // feedhold at high jerk with no actions. Can resume FEEDHOLD_TYPE_SCRAM // feedhold at high jerk and stop all active devices } cmFeedholdType; diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index ccc0e563..d77cabf0 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -44,9 +44,9 @@ static void _start_queue_flush(void); static void _start_job_kill(void); // Feedhold actions -static stat_t _feedhold_with_actions(void); +static stat_t _feedhold_with_command(void); static stat_t _feedhold_no_actions(void); -static stat_t _feedhold_with_sync(void); +static stat_t _feedhold_with_actions(void); static stat_t _feedhold_restart_with_actions(void); static stat_t _feedhold_restart_no_actions(void); @@ -508,10 +508,9 @@ static void _start_job_kill() void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) { // look for p2 feedhold (feedhold in a feedhold) - if ((cm1.hold_state == FEEDHOLD_HOLD) && - (cm2.hold_state == FEEDHOLD_OFF) && + if ((cm1.hold_state == FEEDHOLD_HOLD) && (cm2.hold_state == FEEDHOLD_OFF) && (cm2.machine_state == MACHINE_CYCLE)) { - op.add_action(_feedhold_with_sync); + op.add_action(_feedhold_with_command); op.add_action(_run_program_stop); cm2.hold_state = FEEDHOLD_SYNC; return; @@ -536,7 +535,7 @@ static void _start_p1_feedhold() switch (cm1.hold_type) { case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions); break; } case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_no_actions); break; } - case FEEDHOLD_TYPE_SYNC: { op.add_action(_feedhold_with_sync); break; } + case FEEDHOLD_TYPE_COMMAND: { op.add_action(_feedhold_with_command); break; } default: { } } switch (cm1.hold_exit) { @@ -553,12 +552,12 @@ static void _start_p1_feedhold() // P2 feedholds only allow feedhold sync types if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { - op.add_action(_feedhold_with_sync); + op.add_action(_feedhold_with_command); cm2.hold_state = FEEDHOLD_SYNC; } } -static stat_t _feedhold_with_sync() +static stat_t _feedhold_with_command() { if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold cm1.hold_state = FEEDHOLD_SYNC; @@ -567,6 +566,7 @@ static stat_t _feedhold_with_sync() return (STAT_EAGAIN); } cm1.hold_state = FEEDHOLD_HOLD; + st_request_exec_move(); return (STAT_OK); } diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 87181a07..08ec8843 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -36,6 +36,7 @@ #include "report.h" #include "gpio.h" #include "planner.h" +#include "stepper.h" #include "util.h" #include "xio.h" @@ -193,6 +194,29 @@ uint8_t cm_probing_cycle_callback(void) return (pb.func()); // execute the current probing move } +/*********************************************************************************** + * _probe_move() - function to execute probing moves + * _motion_end_callback() - callback completes when motion has stopped + * + * target[] must be provided in machine canonical coordinates (absolute, mm) + * cm_set_absolute_override() also zeros work offsets, which are restored on exit. + */ + +static void _motion_end_callback(float* vect, bool* flag) +{ + pb.wait_for_motion_end = false; +} + +static stat_t _probe_move(const float target[], const bool flags[]) +{ + cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); + pb.wait_for_motion_end = true; // set this BEFORE the motion starts + cm_straight_feed(target, flags, PROFILE_FAST); // NB: feed rate was set earlier, so it's OK + mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway + st_request_forward_plan(); //+++++ + return (STAT_EAGAIN); +} + /*********************************************************************************** * _probing_start() - start the probe or skip it if contact is already active */ @@ -268,28 +292,6 @@ static stat_t _probing_backoff() return (STAT_EAGAIN); } -/*********************************************************************************** - * _probe_move() - function to execute probing moves - * _motion_end_callback() - callback completes when motion has stopped - * - * target[] must be provided in machine canonical coordinates (absolute, mm) - * cm_set_absolute_override() also zeros work offsets, which are restored on exit. - */ - -static void _motion_end_callback(float* vect, bool* flag) -{ - pb.wait_for_motion_end = false; -} - -static stat_t _probe_move(const float target[], const bool flags[]) -{ - cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); - pb.wait_for_motion_end = true; // set this BEFORE the motion starts - cm_straight_feed(target, flags, PROFILE_FAST); // NB: feed rate was set earlier, so it's OK - mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway - return (STAT_EAGAIN); -} - /*********************************************************************************** * _probe_restore_settings() - helper for both exits * _probing_exception_exit() - exit for probes that hit an exception diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 00cb39e6..418c6a6e 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -143,7 +143,7 @@ struct ioDigitalInputExt { if (in->homing_mode) { if (in->edge == INPUT_EDGE_LEADING) { // we only want the leading edge to fire en_take_encoder_snapshot(); - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); } return; } @@ -153,8 +153,10 @@ struct ioDigitalInputExt { // We want to capture either way. // Probing tests the start condition for the correct direction ahead of time. // If we see any edge, it's the right one. - en_take_encoder_snapshot(); - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); + if ((in->edge == INPUT_EDGE_LEADING) || (in->edge == INPUT_EDGE_TRAILING)) { + en_take_encoder_snapshot(); + cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); + } return; } @@ -163,10 +165,10 @@ struct ioDigitalInputExt { // trigger the action on leading edges if (in->edge == INPUT_EDGE_LEADING) { if (in->action == INPUT_ACTION_STOP) { - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); } if (in->action == INPUT_ACTION_FAST_STOP) { - cm_request_feedhold(FEEDHOLD_TYPE_SYNC, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); } if (in->action == INPUT_ACTION_HALT) { cm_halt(); // hard stop, including spindle, coolant and heaters diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 9cb7fb66..bb170678 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -247,7 +247,7 @@ stat_t mp_exec_move() // It is possible to try to try to exec from a priming planner if coming off a hold // This occurs if new p1 commands (and were held back) arrived while in a hold -// if (mp->planner_state <= PLANNER_PRIMING) { +// if (mp->planner_state <= MP_BUFFER_BACK_PLANNED) { // st_prep_null(); // return (STAT_NOOP); // } @@ -266,7 +266,7 @@ stat_t mp_exec_move() } if (bf->block_type == BLOCK_TYPE_ALINE) { // cycle auto-start for lines only - +// if ((bf->block_type == BLOCK_TYPE_ALINE) || (bf->block_type == BLOCK_TYPE_COMMAND)) { // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_BACK_PLANNED) && (cm->motion_state == MOTION_RUN)) { @@ -1042,11 +1042,15 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // If probing or homing, exit the move and advance to the _motion_end_callback()'s. // Stop the runtime, clear the run buffer and do not transition to p2 planner. - else if ((cm->cycle_type == CYCLE_HOMING) || (cm->cycle_type == CYCLE_PROBE)) { -// else if (cm->hold_type == FEEDHOLD_TYPE_SYNC) { +// else if ((cm->cycle_type == CYCLE_HOMING) || (cm->cycle_type == CYCLE_PROBE)) { + else if (cm->hold_type == FEEDHOLD_TYPE_COMMAND) { mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement mp_free_run_buffer(); // free buffer and enable finalization move to get loaded - cm->hold_state = FEEDHOLD_OFF; + copy_vector(mp->position, mr->position); + cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; + +// mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks +// st_request_forward_plan(); // replan the current bf buffer } // In a regular p1 hold. Motion has stopped, so we can rely on positions and other values to be stable diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 3d814c1b..350c6295 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -262,7 +262,6 @@ void mp_plan_block_list() mp->p = mp->p->nx; return; } - bf = _plan_block(bf); // returns next block to plan planned_something = true; mp->p = bf; // DIAGNOSTIC - this is not needed but is set here for debugging purposes diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 943cf30d..9c20f43b 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -66,16 +66,32 @@ // Allocate planner structures -mpPlanner_t *mp; // currently active planner (global variable) -mpPlanner_t mp1; // primary planning context -mpPlanner_t mp2; // secondary planning context +mpPlanner_t *mp; // currently active planner (global variable) +mpPlanner_t mp1; // primary planning context +mpPlanner_t mp2; // secondary planning context -mpPlannerRuntime_t *mr; // context for planner block runtime -mpPlannerRuntime_t mr1; // primary planner runtime context -mpPlannerRuntime_t mr2; // secondary planner runtime context +mpPlannerRuntime_t *mr; // context for planner block runtime +mpPlannerRuntime_t mr1; // primary planner runtime context +mpPlannerRuntime_t mr2; // secondary planner runtime context -mpBuf_t mp1_queue[PLANNER_QUEUE_SIZE]; // storage allocation for primary planner queue buffers -mpBuf_t mp2_queue[SECONDARY_QUEUE_SIZE]; // storage allocation for secondary planner queue buffers +mpBuf_t mp1_queue[PLANNER_QUEUE_SIZE]; // storage allocation for primary planner queue buffers +mpBuf_t mp2_queue[SECONDARY_QUEUE_SIZE]; // storage allocation for secondary planner queue buffers + +// Local Scope Data and Functions +#define value_vector gm.target // alias for vector of values + +// Execution routines (NB: These are called from the LO interrupt) +static stat_t _exec_dwell(mpBuf_t *bf); +static stat_t _exec_command(mpBuf_t *bf); +static stat_t _exec_json_wait(mpBuf_t *bf); + +// DIAGNOSTICS +//static void _planner_time_accounting(); +static void _audit_buffers(); + +/**************************************************************************************** + * JSON planner objects + */ #define JSON_COMMAND_BUFFER_SIZE 3 @@ -124,23 +140,9 @@ struct _json_commands_t { available++; } }; - _json_commands_t jc; -// Local Scope Data and Functions -#define spindle_speed block_time // local alias for spindle_speed to the time variable -#define value_vector gm.target // alias for vector of values - -//static void _planner_time_accounting(); -static void _audit_buffers(); - -// Execution routines (NB: These are called from the LO interrupt) -static void _exec_json_command(float *value, bool *flag); -static stat_t _exec_dwell(mpBuf_t *bf); -static stat_t _exec_command(mpBuf_t *bf); -static stat_t _exec_json_wait(mpBuf_t *bf); - -/* +/**************************************************************************************** * planner_init() - initialize MP, MR and planner queue buffers * planner_reset() - selective reset MP and MR structures * planner_assert() - test planner assertions, PANIC if violation exists @@ -222,7 +224,7 @@ stat_t planner_assert(const mpPlanner_t *_mp) return (STAT_OK); } -/* +/**************************************************************************************** * mp_halt_runtime() - stop runtime movement immediately */ void mp_halt_runtime() @@ -231,18 +233,18 @@ void mp_halt_runtime() planner_reset(mp); // reset the active planner } -/* +/**************************************************************************************** * mp_set_planner_position() - set planner position for a single axis * mp_set_runtime_position() - set runtime position for a single axis * mp_set_steps_to_runtime_position() - set encoder counts to the runtime position * * Since steps are in motor space you have to run the position vector through inverse - * kinematics to get the right numbers. This means that in a non-Cartesian robot changing - * any position can result in changes to multiple step values. So this operation is provided - * as a single function and always uses the new position vector as an input. + * kinematics to get the right numbers. This means that in a non-Cartesian robot + * changing any position can result in changes to multiple step values. So this operation + * is provided as a single function and always uses the new position vector as an input. * - * Keeping track of position is complicated by the fact that moves exist in several reference - * frames. The scheme to keep this straight is: + * Keeping track of position is complicated by the fact that moves exist in several + * reference frames. The scheme to keep this straight is: * * - mp->position - start and end position for planning * - mr->position - current position of runtime segment @@ -251,9 +253,9 @@ void mp_halt_runtime() * The runtime keeps a lot more data, such as waypoints, step vectors, etc. * See struct mpMoveRuntimeSingleton for details. * - * Note that position is set immediately when called and may not be not an accurate representation - * of the tool position. The motors are still processing the action and the real tool position is - * still close to the starting point. + * Note that position is set immediately when called and may not be not an accurate + * representation of the tool position. The motors are still processing the action + * and the real tool position is still close to the starting point. */ void mp_set_planner_position(uint8_t axis, const float position) { mp->position[axis] = position; } @@ -276,7 +278,7 @@ void mp_set_steps_to_runtime_position() } } -/*********************************************************************************** +/**************************************************************************************** * mp_queue_command() - queue a synchronous Mcode, program control, or other command * _exec_command() - callback to execute command * @@ -332,11 +334,18 @@ stat_t mp_runtime_command(mpBuf_t *bf) return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * mp_json_command() - queue a json command * _exec_json_command() - execute json string */ +static void _exec_json_command(float *value, bool *flag) +{ + char *json_string = jc.read_buffer(); + json_parse_for_exec(json_string, true); // process it + jc.free_buffer(); +} + stat_t mp_json_command(char *json_string) { // Never supposed to fail, since we stopped parsing when we were full @@ -345,15 +354,7 @@ stat_t mp_json_command(char *json_string) return (STAT_OK); } -static void _exec_json_command(float *value, bool *flag) -{ - char *json_string = jc.read_buffer(); - json_parse_for_exec(json_string, true); // process it - jc.free_buffer(); -} - - -/*********************************************************************************** +/**************************************************************************************** * mp_json_wait() - queue a json wait command * _exec_json_wait() - execute json wait string */ @@ -406,8 +407,7 @@ static stat_t _exec_json_wait(mpBuf_t *bf) return (STAT_OK); } - -/*********************************************************************************** +/**************************************************************************************** * mp_dwell() - queue a dwell * _exec_dwell() - dwell execution * @@ -439,7 +439,7 @@ static stat_t _exec_dwell(mpBuf_t *bf) return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * mp_request_out_of_band_dwell() - request a dwell outside of the planner queue * * This command is used to request that a dwell be run outside of the planner. @@ -457,7 +457,7 @@ void mp_request_out_of_band_dwell(float seconds) } } -/*********************************************************************************** +/**************************************************************************************** * Planner helpers * * mp_get_planner_buffers() - return # of available planner buffers @@ -490,7 +490,7 @@ bool mp_is_phat_city_time() return ((mp->plannable_time <= 0.0) || (PHAT_CITY_TIME < mp->plannable_time)); } -/*********************************************************************************** +/**************************************************************************************** * mp_planner_callback() * * mp_planner_callback()'s job is to invoke backward planning intelligently. From 24d0fdb421dc0c20ee59b77685e92b4da755253b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 06:40:29 -0400 Subject: [PATCH 200/283] Updated request_feedhold --- g2core/cycle_feedhold.cpp | 58 +++++++++++++++++++-------------------- g2core/g2core.cppproj | 4 +-- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index d77cabf0..76f89625 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -355,7 +355,7 @@ void cm_request_cycle_start() static void _start_cycle_restart() { - // Feedhold cycle starts run an operation to complete multiple actions + // Feedhold cycle restart builds an operation to complete multiple actions if (cm1.hold_state == FEEDHOLD_HOLD) { cm1.cycle_start_state = CYCLE_START_OFF; switch (cm1.hold_type) { @@ -506,50 +506,48 @@ static void _start_job_kill() */ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) -{ - // look for p2 feedhold (feedhold in a feedhold) - if ((cm1.hold_state == FEEDHOLD_HOLD) && (cm2.hold_state == FEEDHOLD_OFF) && - (cm2.machine_state == MACHINE_CYCLE)) { - op.add_action(_feedhold_with_command); - op.add_action(_run_program_stop); - cm2.hold_state = FEEDHOLD_SYNC; - return; - } - +{ // Can only initiate a feedhold if you are in a machining cycle not already in a feedhold if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { cm1.hold_type = type; cm1.hold_exit = exit; - cm1.hold_state = FEEDHOLD_REQUESTED; - _start_p1_feedhold(); // attempt to run it immediately - return; - } - cm->hold_state = FEEDHOLD_OFF; // cannot honor the feedhold request. reset it -} + cm1.hold_profile = ((type == FEEDHOLD_TYPE_ACTIONS) || (type == FEEDHOLD_TYPE_NO_ACTIONS)) ? + PROFILE_NORMAL : PROFILE_FAST; -static void _start_p1_feedhold() -{ - // This function is "safe" and will not initiate a feedhold unless it's OK to. - - if ((cm1.hold_state == FEEDHOLD_REQUESTED) && (cm1.motion_state == MOTION_RUN)) { switch (cm1.hold_type) { case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions); break; } case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_no_actions); break; } case FEEDHOLD_TYPE_COMMAND: { op.add_action(_feedhold_with_command); break; } - default: { } + default: {} } switch (cm1.hold_exit) { - case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } - case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } - case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } - case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } - case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } - default: { } + case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } + case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } + case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } + case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } + case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } + default: {} } cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec return; - } + } + + // Look for p2 feedhold (feedhold in a feedhold) + if ((cm1.hold_state == FEEDHOLD_HOLD) && + (cm2.hold_state == FEEDHOLD_OFF) && (cm2.machine_state == MACHINE_CYCLE)) { + cm2.hold_state = FEEDHOLD_REQUESTED; + return; + } + // Reset the request if it's invalid + if ((cm1.machine_state != MACHINE_CYCLE) || (cm1.motion_state == MOTION_STOP)) { + cm->hold_state = FEEDHOLD_OFF; // cannot honor the feedhold request. reset it + } + +} + +static void _start_p1_feedhold() +{ // P2 feedholds only allow feedhold sync types if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { op.add_action(_feedhold_with_command); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index bb1cf7a0..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 From 3dc69f4f0220ceb7fe72ffeed1d426d5fc27e40b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 08:38:11 -0400 Subject: [PATCH 201/283] Got probing working; moved command values from gm.target to the unit vector; some name changes; --- g2core/canonical_machine.cpp | 4 +-- g2core/canonical_machine.h | 2 +- g2core/controller.cpp | 9 ++++--- g2core/cycle_feedhold.cpp | 11 +++++--- g2core/cycle_probing.cpp | 16 +++++------ g2core/plan_exec.cpp | 52 ++++++++++++++++++++++++------------ g2core/planner.cpp | 7 ++--- g2core/planner.h | 2 ++ g2core/util.h | 11 +++++--- 9 files changed, 70 insertions(+), 44 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index c19860c4..8294fe57 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1094,7 +1094,6 @@ stat_t cm_resume_origin_offsets() * cm_straight_traverse() - G0 linear rapid */ -//stat_t cm_straight_traverse(const float target[], const bool flags[]) stat_t cm_straight_traverse(const float *target, const bool *flags, const uint8_t motion_profile) { cm->gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; @@ -1247,8 +1246,7 @@ stat_t cm_dwell(const float seconds) /**************************************************************************************** * cm_straight_feed() - G1 */ -//stat_t cm_straight_feed(const float target[], const bool flags[]) -//stat_t cm_straight_feed(const float *target, const bool *flags) + stat_t cm_straight_feed(const float *target, const bool *flags, const uint8_t motion_profile) { // trap zero feed rate condition diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 564b48ec..431e04d3 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -488,7 +488,7 @@ stat_t cm_json_wait(char *json_string); // M102 // Feedhold and related functions (cycle_feedhold.cpp) void cm_operation_init(void); -stat_t cm_operation_sequencing_callback(void); // operation action runner +stat_t cm_operation_runner_callback(void); // operation action runner void cm_request_alarm(void); void cm_request_fasthold(void); diff --git a/g2core/controller.cpp b/g2core/controller.cpp index fa4d9441..68343740 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -142,7 +142,9 @@ static void _controller_HSM() // See hardware.h for a list of ISRs and their priorities. // //----- kernel level ISR handlers ----(flags are set in ISRs)------------------------// - // Order is important: + + // Order is important, and line breaks indicate dependency groups + DISPATCH(hardware_periodic()); // give the hardware a chance to do stuff DISPATCH(_led_indicator()); // blink LEDs at the current rate DISPATCH(_shutdown_handler()); // invoke shutdown @@ -159,15 +161,16 @@ static void _controller_HSM() DISPATCH(sr_status_report_callback()); // conditionally send status report DISPATCH(qr_queue_report_callback()); // conditionally send queue report -// DISPATCH(cm_feedhold_sequencing_callback());// feedhold state machine runner +++++ DISPATCH(mp_planner_callback()); // motion planner + DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines - DISPATCH(cm_operation_sequencing_callback());// operation action runner + DISPATCH(cm_operation_runner_callback()); // operation action runner DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) DISPATCH(cm_jogging_cycle_callback()); // jog cycle operation DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle + DISPATCH(cm_feedhold_command_blocker()); // blocks new Gcode from arriving while in feedhold //----- command readers and parsers --------------------------------------------------// diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 76f89625..16d51161 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -234,7 +234,7 @@ void cm_operation_init() */ /**************************************************************************************** - * cm_operation_sequencing_callback() - run feedhold operations and sequence queued requests + * cm_operation_runner_callback() - run feedhold operations and sequence queued requests * * Operations are requested by calling their repective request function, e.g. cm_request_feedhold(). * The operation callback runs the current operation, and sequences requests that must be queued. @@ -258,7 +258,7 @@ void cm_operation_init() * handled in the sequencer. */ -stat_t cm_operation_sequencing_callback() +stat_t cm_operation_runner_callback() { if (cm1.job_kill_state == JOB_KILL_REQUESTED) { // job kill must wait for any active hold to complete _start_job_kill(); @@ -563,8 +563,11 @@ static stat_t _feedhold_with_command() if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { return (STAT_EAGAIN); } - cm1.hold_state = FEEDHOLD_HOLD; - st_request_exec_move(); +// cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't run (see mp_plan_block_list()) + cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't run (see mp_plan_block_list()) + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks + st_request_forward_plan(); // replan from the new bf buffer +// st_request_exec_move(); return (STAT_OK); } diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 08ec8843..93d300e5 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -55,7 +55,7 @@ struct pbProbingSingleton { // persistent probing runtime variables int8_t probe_input; // digital input to read bool trip_sense; // true if contact CLOSURE trips probe (true for G38.2 and G38.3) bool alarm_flag; // true if failure triggers alarm (true for G38.2 and G38.4) - bool wait_for_motion_end; // flag to know when the motion has ended + bool waiting_for_motion_complete; // true if waiting for a motion to complete stat_t (*func)(); // binding for callback function state machine // saved gcode model state @@ -170,7 +170,7 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool trip_sense, bool al // queue a function to let us know when we can start probing cm->probe_state[0] = PROBE_WAITING; // wait until planner queue empties before starting movement - pb.wait_for_motion_end = true; + pb.waiting_for_motion_complete = true; mp_queue_command(_motion_end_callback, nullptr, nullptr); // note: these args are ignored return (STAT_OK); } @@ -186,12 +186,12 @@ uint8_t cm_straight_probe(float target[], bool flags[], bool trip_sense, bool al uint8_t cm_probing_cycle_callback(void) { if ((cm->cycle_type != CYCLE_PROBE) && (cm->probe_state[0] != PROBE_WAITING)) { - return (STAT_NOOP); // exit if not in a probing cycle + return (STAT_NOOP); // exit if not in a probing cycle } - if (pb.wait_for_motion_end) { // sync to planner move ends (using callback) + if (pb.waiting_for_motion_complete) { // sync to planner move ends (using callback) return (STAT_EAGAIN); } - return (pb.func()); // execute the current probing move + return (pb.func()); // execute the current probing move } /*********************************************************************************** @@ -204,16 +204,16 @@ uint8_t cm_probing_cycle_callback(void) static void _motion_end_callback(float* vect, bool* flag) { - pb.wait_for_motion_end = false; + pb.waiting_for_motion_complete = false; } static stat_t _probe_move(const float target[], const bool flags[]) { cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); - pb.wait_for_motion_end = true; // set this BEFORE the motion starts + pb.waiting_for_motion_complete = true; // set this BEFORE the motion starts cm_straight_feed(target, flags, PROFILE_FAST); // NB: feed rate was set earlier, so it's OK mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway - st_request_forward_plan(); //+++++ +// st_request_forward_plan(); //+++++ return (STAT_EAGAIN); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index bb170678..823c9651 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -184,11 +184,23 @@ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) return (STAT_OK); // report that we planned something... } +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ + stat_t mp_forward_plan() { mpBuf_t *bf = mp_get_run_buffer(); float entry_velocity; + if (bf->buffer_number == 15) { + if (bf->buffer_state == MP_BUFFER_BACK_PLANNED) { + bf->hint = ZERO_VELOCITY; + } + } + if (bf->buffer_number == 17) { + bf->hint = ZERO_VELOCITY; + } + // Case 0: Examine current running buffer for early exit conditions if (bf == NULL) { // case 0a: NULL means nothing is running - this is OK st_prep_null(); @@ -234,6 +246,9 @@ stat_t mp_forward_plan() return (planned_something ? STAT_OK : STAT_NOOP); } +// insert function here +#pragma GCC reset_options + /************************************************************************* * mp_exec_move() - execute runtime functions to prep move for steppers * @@ -1032,31 +1047,34 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish mp_zero_segment_velocity(); // finalize velocity for reporting purposes cm->hold_state = FEEDHOLD_MOTION_STOPPED; + cm_set_motion_state(MOTION_STOP); + // Motion has stopped, so we can rely on positions and other values to be stable // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue - if (cm == &cm2) { - cm->hold_state = FEEDHOLD_HOLD; - return (STAT_OK); // will end this exec_aline() with no more movement - } - // At this point we know we are in a p1 hold +// if (cm == &cm2) { +// cm->hold_state = FEEDHOLD_HOLD; +// return (STAT_OK); // will end this exec_aline() with no more movement +// } +// // At this point we know we are in a p1 hold // If probing or homing, exit the move and advance to the _motion_end_callback()'s. // Stop the runtime, clear the run buffer and do not transition to p2 planner. // else if ((cm->cycle_type == CYCLE_HOMING) || (cm->cycle_type == CYCLE_PROBE)) { - else if (cm->hold_type == FEEDHOLD_TYPE_COMMAND) { - mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement - mp_free_run_buffer(); // free buffer and enable finalization move to get loaded - copy_vector(mp->position, mr->position); +// else + // In COMMAND type, discard the remainder of the block and position to the next block + if (cm->hold_type == FEEDHOLD_TYPE_COMMAND) { + float next_entry_velocity = bf->exit_velocity; + mp_free_run_buffer(); // advance to next block, discarding the rest of the move + if (next_entry_velocity > 0) { // only need to replan if new block dis not plan from zero + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks + st_request_forward_plan(); // replan from the new bf buffer + } + copy_vector(mp->position, mr->position); // update planner position to the final runtime position +// mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement + mr->reset(); // disable the rest of the runtime movement cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; - -// mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks -// st_request_forward_plan(); // replan the current bf buffer } - - // In a regular p1 hold. Motion has stopped, so we can rely on positions and other values to be stable - else { - - // Reset the state of the p1 planner regardless of how hold will ultimately be exited. + else { // Reset the state of the planner regardless of how hold will ultimately be exited. bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 9c20f43b..77775fcb 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -77,9 +77,6 @@ mpPlannerRuntime_t mr2; // secondary planner runtime context mpBuf_t mp1_queue[PLANNER_QUEUE_SIZE]; // storage allocation for primary planner queue buffers mpBuf_t mp2_queue[SECONDARY_QUEUE_SIZE]; // storage allocation for secondary planner queue buffers -// Local Scope Data and Functions -#define value_vector gm.target // alias for vector of values - // Execution routines (NB: These are called from the LO interrupt) static stat_t _exec_dwell(mpBuf_t *bf); static stat_t _exec_command(mpBuf_t *bf); @@ -313,7 +310,7 @@ void mp_queue_command(void(*cm_exec)(float *, bool *), float *value, bool *flag) bf->cm_func = cm_exec; // callback to canonical machine exec function for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - bf->value_vector[axis] = value[axis]; + bf->unit[axis] = value[axis]; // use the unit vector to store command values bf->axis_flags[axis] = flag[axis]; } mp_commit_write_buffer(BLOCK_TYPE_COMMAND); // must be final operation before exit @@ -327,7 +324,7 @@ static stat_t _exec_command(mpBuf_t *bf) stat_t mp_runtime_command(mpBuf_t *bf) { - bf->cm_func(bf->value_vector, bf->axis_flags); // 2 vectors used by callbacks + bf->cm_func(bf->unit, bf->axis_flags); // 2 vectors used by callbacks if (mp_free_run_buffer()) { cm_cycle_end(); // free buffer & perform cycle_end if planner is empty } diff --git a/g2core/planner.h b/g2core/planner.h index e5cd9b68..905b5037 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -491,6 +491,8 @@ typedef struct mpPlannerRuntime { // persistent runtime variables block_state = BLOCK_INACTIVE; section = SECTION_HEAD; section_state = SECTION_OFF; + entry_velocity = 0; // needed to ensure next block in forward planning starts from 0 velocity + r->exit_velocity = 0; // ditto } } mpPlannerRuntime_t; diff --git a/g2core/util.h b/g2core/util.h index b69b7c7e..b97d8479 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -25,9 +25,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* util.c/.h contains a dog's breakfast of supporting functions that are - * not specific to g2core: including: - * +/* util.c/.h contains a dog's breakfast of supporting functions that are not specific + * to g2core: including: * - math and min/max utilities and extensions * - vector manipulation utilities * - support for debugging routines @@ -49,6 +48,12 @@ using Motate::SysTickTimer; #include // isnan, isinf /****** Global Scope Variables and Functions ******/ +/* +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +// insert function here +#pragma GCC reset_options // DIAGNOSTIC +++++ +*/ //*** vector utilities *** From 283b7d65cfe7bf4c9b597ef079bdb6434428478a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 09:49:42 -0400 Subject: [PATCH 202/283] Adjustments in testing --- g2core/canonical_machine.h | 7 +++-- g2core/cycle_feedhold.cpp | 55 ++++++++++++++++++-------------------- g2core/gpio.cpp | 8 +++--- g2core/plan_exec.cpp | 42 ++++------------------------- 4 files changed, 38 insertions(+), 74 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 431e04d3..5c3998d8 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -109,10 +109,9 @@ typedef enum { } cmCycleType; typedef enum { // feedhold type parameter - FEEDHOLD_TYPE_ACTIONS = 0, // feedhold at max jerk with actions - FEEDHOLD_TYPE_NO_ACTIONS, // feedhold at max jerk with no actions - FEEDHOLD_TYPE_COMMAND, // feedhold at max jerk with queue flush and sync command - FEEDHOLD_TYPE_FAST, // feedhold at high jerk with no actions. Can resume + FEEDHOLD_TYPE_HOLD, // simple feedhold at max jerk with no actions + FEEDHOLD_TYPE_ACTIONS, // feedhold at max jerk with hold entry actions + FEEDHOLD_TYPE_SKIP, // feedhold at max jerk with queue flush and sync command FEEDHOLD_TYPE_SCRAM // feedhold at high jerk and stop all active devices } cmFeedholdType; diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 16d51161..b7444027 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -38,13 +38,13 @@ #include "util.h" //#include "xio.h" // DIAGNOSTIC -static void _start_p1_feedhold(void); +static void _start_feedhold(void); static void _start_cycle_restart(void); static void _start_queue_flush(void); static void _start_job_kill(void); // Feedhold actions -static stat_t _feedhold_with_command(void); +static stat_t _feedhold_skip(void); static stat_t _feedhold_no_actions(void); static stat_t _feedhold_with_actions(void); static stat_t _feedhold_restart_with_actions(void); @@ -263,12 +263,9 @@ stat_t cm_operation_runner_callback() if (cm1.job_kill_state == JOB_KILL_REQUESTED) { // job kill must wait for any active hold to complete _start_job_kill(); } - if (cm1.hold_state == FEEDHOLD_REQUESTED) { - _start_p1_feedhold(); + if (cm1.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold + _start_feedhold(); } -// if (cm2.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold -// _start_p2_feedhold(); -// } if (cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) { // look for a queued flush request _start_queue_flush(); } @@ -276,6 +273,7 @@ stat_t cm_operation_runner_callback() _start_cycle_restart(); } + // run the operation or operation continuation return (op.run_operation()); } @@ -331,6 +329,7 @@ static stat_t _run_interlock() { return (STAT_OK); } + /**************************************************************************************** * cm_request_cycle_start() - set request enum only * _start_cycle_start() - run the cycle start @@ -359,8 +358,8 @@ static void _start_cycle_restart() if (cm1.hold_state == FEEDHOLD_HOLD) { cm1.cycle_start_state = CYCLE_START_OFF; switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_restart_no_actions); break; } + case FEEDHOLD_TYPE_HOLD: { op.add_action(_feedhold_restart_no_actions); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_restart_with_actions); break; } default: {} } switch (cm1.hold_exit) { @@ -511,21 +510,21 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { cm1.hold_type = type; cm1.hold_exit = exit; - cm1.hold_profile = ((type == FEEDHOLD_TYPE_ACTIONS) || (type == FEEDHOLD_TYPE_NO_ACTIONS)) ? + cm1.hold_profile = ((type == FEEDHOLD_TYPE_ACTIONS) || (type == FEEDHOLD_TYPE_HOLD)) ? PROFILE_NORMAL : PROFILE_FAST; switch (cm1.hold_type) { - case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions); break; } - case FEEDHOLD_TYPE_NO_ACTIONS: { op.add_action(_feedhold_no_actions); break; } - case FEEDHOLD_TYPE_COMMAND: { op.add_action(_feedhold_with_command); break; } + case FEEDHOLD_TYPE_HOLD: { op.add_action(_feedhold_no_actions); break; } + case FEEDHOLD_TYPE_ACTIONS: { op.add_action(_feedhold_with_actions); break; } + case FEEDHOLD_TYPE_SKIP: { op.add_action(_feedhold_skip); break; } default: {} } switch (cm1.hold_exit) { - case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } - case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } - case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } - case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } - case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } + case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } + case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } + case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } + case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } + case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } default: {} } cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec @@ -546,34 +545,32 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) } -static void _start_p1_feedhold() +static void _start_feedhold() { - // P2 feedholds only allow feedhold sync types + // P2 feedholds only allow skip types if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { - op.add_action(_feedhold_with_command); + op.add_action(_feedhold_skip); cm2.hold_state = FEEDHOLD_SYNC; } } -static stat_t _feedhold_with_command() +static stat_t _feedhold_skip() { - if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold + if (cm1.hold_state == FEEDHOLD_OFF) { // if entered while OFF start a feedhold cm1.hold_state = FEEDHOLD_SYNC; } if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { return (STAT_EAGAIN); } -// cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't run (see mp_plan_block_list()) - cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't run (see mp_plan_block_list()) - mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks - st_request_forward_plan(); // replan from the new bf buffer -// st_request_exec_move(); + cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't plan (see mp_plan_block_list()) + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks + st_request_forward_plan(); // replan from the new bf buffer return (STAT_OK); } static stat_t _feedhold_no_actions() { - if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold + if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold cm1.hold_state = FEEDHOLD_SYNC; } if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { // wait until it reaches the hold point diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 418c6a6e..c0bdc313 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -143,7 +143,7 @@ struct ioDigitalInputExt { if (in->homing_mode) { if (in->edge == INPUT_EDGE_LEADING) { // we only want the leading edge to fire en_take_encoder_snapshot(); - cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SKIP, FEEDHOLD_EXIT_STOP); } return; } @@ -155,7 +155,7 @@ struct ioDigitalInputExt { // If we see any edge, it's the right one. if ((in->edge == INPUT_EDGE_LEADING) || (in->edge == INPUT_EDGE_TRAILING)) { en_take_encoder_snapshot(); - cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SKIP, FEEDHOLD_EXIT_STOP); } return; } @@ -165,10 +165,10 @@ struct ioDigitalInputExt { // trigger the action on leading edges if (in->edge == INPUT_EDGE_LEADING) { if (in->action == INPUT_ACTION_STOP) { - cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_HOLD, FEEDHOLD_EXIT_STOP); } if (in->action == INPUT_ACTION_FAST_STOP) { - cm_request_feedhold(FEEDHOLD_TYPE_COMMAND, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_HOLD, FEEDHOLD_EXIT_STOP); } if (in->action == INPUT_ACTION_HALT) { cm_halt(); // hard stop, including spindle, coolant and heaters diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 823c9651..d86f5264 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -184,23 +184,11 @@ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) return (STAT_OK); // report that we planned something... } -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ - stat_t mp_forward_plan() { mpBuf_t *bf = mp_get_run_buffer(); float entry_velocity; - - if (bf->buffer_number == 15) { - if (bf->buffer_state == MP_BUFFER_BACK_PLANNED) { - bf->hint = ZERO_VELOCITY; - } - } - if (bf->buffer_number == 17) { - bf->hint = ZERO_VELOCITY; - } - + // Case 0: Examine current running buffer for early exit conditions if (bf == NULL) { // case 0a: NULL means nothing is running - this is OK st_prep_null(); @@ -246,9 +234,6 @@ stat_t mp_forward_plan() return (planned_something ? STAT_OK : STAT_NOOP); } -// insert function here -#pragma GCC reset_options - /************************************************************************* * mp_exec_move() - execute runtime functions to prep move for steppers * @@ -1050,27 +1035,10 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) cm_set_motion_state(MOTION_STOP); // Motion has stopped, so we can rely on positions and other values to be stable - // If in a p2 hold, exit the p2 hold immediately set up a flush of the p2 planner queue -// if (cm == &cm2) { -// cm->hold_state = FEEDHOLD_HOLD; -// return (STAT_OK); // will end this exec_aline() with no more movement -// } -// // At this point we know we are in a p1 hold - - // If probing or homing, exit the move and advance to the _motion_end_callback()'s. - // Stop the runtime, clear the run buffer and do not transition to p2 planner. -// else if ((cm->cycle_type == CYCLE_HOMING) || (cm->cycle_type == CYCLE_PROBE)) { -// else - // In COMMAND type, discard the remainder of the block and position to the next block - if (cm->hold_type == FEEDHOLD_TYPE_COMMAND) { - float next_entry_velocity = bf->exit_velocity; - mp_free_run_buffer(); // advance to next block, discarding the rest of the move - if (next_entry_velocity > 0) { // only need to replan if new block dis not plan from zero - mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks - st_request_forward_plan(); // replan from the new bf buffer - } + // If SKIP type, discard the remainder of the block and position to the next block + if (cm->hold_type == FEEDHOLD_TYPE_SKIP) { copy_vector(mp->position, mr->position); // update planner position to the final runtime position -// mr->block_state = BLOCK_INACTIVE; // disable the rest of the runtime movement + mp_free_run_buffer(); // advance to next block, discarding the rest of the move mr->reset(); // disable the rest of the runtime movement cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; } @@ -1078,7 +1046,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->plannable = true; // needed so black can be adjusted + bf->plannable = true; // needed so block can be adjusted mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks st_request_forward_plan(); // replan the current bf buffer From 8c8be02735e5bb4c3f320c736c6b9f98442502ca Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 10:18:41 -0400 Subject: [PATCH 203/283] Cleanup --- g2core/cycle_feedhold.cpp | 14 +++++++------- g2core/plan_exec.cpp | 17 +++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index b7444027..7a79e93c 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -38,7 +38,7 @@ #include "util.h" //#include "xio.h" // DIAGNOSTIC -static void _start_feedhold(void); +//static void _start_feedhold(void); static void _start_cycle_restart(void); static void _start_queue_flush(void); static void _start_job_kill(void); @@ -263,9 +263,9 @@ stat_t cm_operation_runner_callback() if (cm1.job_kill_state == JOB_KILL_REQUESTED) { // job kill must wait for any active hold to complete _start_job_kill(); } - if (cm1.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold - _start_feedhold(); - } +// if (cm1.hold_state == FEEDHOLD_REQUESTED) { // look for a queued p2 feedhold +// _start_feedhold(); +// } if (cm1.queue_flush_state == QUEUE_FLUSH_REQUESTED) { // look for a queued flush request _start_queue_flush(); } @@ -533,7 +533,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) // Look for p2 feedhold (feedhold in a feedhold) if ((cm1.hold_state == FEEDHOLD_HOLD) && - (cm2.hold_state == FEEDHOLD_OFF) && (cm2.machine_state == MACHINE_CYCLE)) { + (cm2.hold_state == FEEDHOLD_OFF) && (cm2.machine_state == MACHINE_CYCLE)) { cm2.hold_state = FEEDHOLD_REQUESTED; return; } @@ -544,7 +544,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) } } - +/* static void _start_feedhold() { // P2 feedholds only allow skip types @@ -553,7 +553,7 @@ static void _start_feedhold() cm2.hold_state = FEEDHOLD_SYNC; } } - +*/ static stat_t _feedhold_skip() { if (cm1.hold_state == FEEDHOLD_OFF) { // if entered while OFF start a feedhold diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index d86f5264..f6e3e2d9 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1030,17 +1030,17 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Case (4) - Completing the feedhold - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish - mp_zero_segment_velocity(); // finalize velocity for reporting purposes - cm->hold_state = FEEDHOLD_MOTION_STOPPED; - cm_set_motion_state(MOTION_STOP); // Motion has stopped, so we can rely on positions and other values to be stable + mp_zero_segment_velocity(); // finalize velocity for reporting purposes +// cm->hold_state = FEEDHOLD_MOTION_STOPPED; + cm_set_motion_state(MOTION_STOP); + // If SKIP type, discard the remainder of the block and position to the next block if (cm->hold_type == FEEDHOLD_TYPE_SKIP) { copy_vector(mp->position, mr->position); // update planner position to the final runtime position mp_free_run_buffer(); // advance to next block, discarding the rest of the move mr->reset(); // disable the rest of the runtime movement - cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; } else { // Reset the state of the planner regardless of how hold will ultimately be exited. bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move @@ -1049,15 +1049,8 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) bf->plannable = true; // needed so block can be adjusted mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks st_request_forward_plan(); // replan the current bf buffer - - // Set state to enable transition to p2 and perform entry actions in the p2 planner - if (cm->hold_type == FEEDHOLD_TYPE_ACTIONS) { - cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; // signal to start entry actions - } else { - cm->hold_state = FEEDHOLD_HOLD; // achieved hold state - } } - + cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } From 94939ee72d93e4b71cb25afc13048fde5330f94c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 10:51:54 -0400 Subject: [PATCH 204/283] Cleanup and comments --- g2core/canonical_machine.h | 1 - g2core/cycle_feedhold.cpp | 8 +++++--- g2core/plan_exec.cpp | 24 ++++++++---------------- g2core/planner.h | 3 ++- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 5c3998d8..f686a30d 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -134,7 +134,6 @@ typedef enum { // feedhold state machine FEEDHOLD_DECEL_COMPLETE, // feedhold deceleration has completed, but motors may not have stopped yet FEEDHOLD_MOTION_STOPPING, // waiting for motors to have stopped at hold point (motion stop) FEEDHOLD_MOTION_STOPPED, // motion has stopped at hold point - FEEDHOLD_HOLD_POINT_REACHED, // hold point reached and logic run - prepare for next steps FEEDHOLD_HOLD_ACTIONS_PENDING, // wait for feedhold actions to complete FEEDHOLD_HOLD_ACTIONS_COMPLETE, // FEEDHOLD_HOLD, // HOLDING (steady state) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 7a79e93c..e5e84179 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -559,7 +559,7 @@ static stat_t _feedhold_skip() if (cm1.hold_state == FEEDHOLD_OFF) { // if entered while OFF start a feedhold cm1.hold_state = FEEDHOLD_SYNC; } - if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { + if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { return (STAT_EAGAIN); } cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't plan (see mp_plan_block_list()) @@ -573,9 +573,11 @@ static stat_t _feedhold_no_actions() if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold cm1.hold_state = FEEDHOLD_SYNC; } - if (cm1.hold_state < FEEDHOLD_HOLD_POINT_REACHED) { // wait until it reaches the hold point + if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { // wait until it reaches the hold point return (STAT_EAGAIN); } + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks + st_request_forward_plan(); // replan from the new bf buffer cm1.hold_state = FEEDHOLD_HOLD; return (STAT_OK); } @@ -590,7 +592,7 @@ static void _feedhold_actions_done_callback(float* vect, bool* flag) static stat_t _feedhold_with_actions() // Execute Case (5) { // Check to run first-time code - if (cm1.hold_state == FEEDHOLD_HOLD_POINT_REACHED) { + if (cm1.hold_state == FEEDHOLD_MOTION_STOPPED) { cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state // copy the primary canonical machine to the secondary, diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index f6e3e2d9..d6d55fec 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -485,7 +485,7 @@ stat_t mp_exec_aline(mpBuf_t *bf) // Feedhold Processing - We need to handle the following cases (listed in rough sequence order): if (cm->hold_state != FEEDHOLD_OFF) { // if running actions, or in HOLD state, or exiting with actions - if (cm->hold_state >= FEEDHOLD_HOLD_POINT_REACHED) { // handles _exec_aline_feedhold_processing case (7) + if (cm->hold_state >= FEEDHOLD_MOTION_STOPPED) { // handles _exec_aline_feedhold_processing case (7) return (STAT_NOOP); // VERY IMPORTANT to exit as a NOOP. Do not load another move } // STAT_OK terminates aline execution for this move @@ -1030,27 +1030,20 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) // Case (4) - Completing the feedhold - Wait for the steppers to stop if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish - // Motion has stopped, so we can rely on positions and other values to be stable - - mp_zero_segment_velocity(); // finalize velocity for reporting purposes -// cm->hold_state = FEEDHOLD_MOTION_STOPPED; - cm_set_motion_state(MOTION_STOP); + // Motion has stopped, so we can rely on positions and other values to be stable // If SKIP type, discard the remainder of the block and position to the next block if (cm->hold_type == FEEDHOLD_TYPE_SKIP) { copy_vector(mp->position, mr->position); // update planner position to the final runtime position mp_free_run_buffer(); // advance to next block, discarding the rest of the move - mr->reset(); // disable the rest of the runtime movement - } - else { // Reset the state of the planner regardless of how hold will ultimately be exited. + } else { // Otherwise setup the block to complete motion (regardless of how hold will ultimately be exited) bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - mr->block_state = BLOCK_INACTIVE; // invalidate mr buffer to reset the new move - bf->plannable = true; // needed so block can be adjusted - mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks - st_request_forward_plan(); // replan the current bf buffer + bf->plannable = true; // needed so block can be replanned } - cm->hold_state = FEEDHOLD_HOLD_POINT_REACHED; + mr->reset(); // reset MR for next use and for forward planning + cm_set_motion_state(MOTION_STOP); + cm->hold_state = FEEDHOLD_MOTION_STOPPED; sr_request_status_report(SR_REQUEST_IMMEDIATE); cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE } @@ -1058,8 +1051,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) } // Case (3') - Decelerated to zero. See also Feedhold Case (3) in mp_exec_aline() - // Update the run buffer then force a replan of the whole planner queue. Replans from zero velocity - // This state might not appear necessary, but it is to handle closely packed !~ and other cases + // This state is needed to return an OK to complete the aline exec before transitioning to case (4). if (cm->hold_state == FEEDHOLD_DECEL_COMPLETE) { cm->hold_state = FEEDHOLD_MOTION_STOPPING; // wait for motion to come to a complete stop return (STAT_OK); // exit from mp_exec_aline() diff --git a/g2core/planner.h b/g2core/planner.h index 905b5037..29f87744 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -493,8 +493,9 @@ typedef struct mpPlannerRuntime { // persistent runtime variables section_state = SECTION_OFF; entry_velocity = 0; // needed to ensure next block in forward planning starts from 0 velocity r->exit_velocity = 0; // ditto + segment_velocity = 0; } - + } mpPlannerRuntime_t; //**** Master Planner Structure *** From d3789652cf3f3f8976823c745749af41119dd5a1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 13:22:20 -0400 Subject: [PATCH 205/283] Testing --- g2core/controller.cpp | 4 ++-- g2core/cycle_feedhold.cpp | 9 +++------ g2core/plan_exec.cpp | 20 ++++++++++++-------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 68343740..ec84eb6a 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -161,10 +161,10 @@ static void _controller_HSM() DISPATCH(sr_status_report_callback()); // conditionally send status report DISPATCH(qr_queue_report_callback()); // conditionally send queue report + // these 3 must be in this exact order: DISPATCH(mp_planner_callback()); // motion planner - - DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_operation_runner_callback()); // operation action runner + DISPATCH(cm_arc_callback(cm)); // arc generation runs as a cycle above lines DISPATCH(cm_homing_cycle_callback()); // homing cycle operation (G28.2) DISPATCH(cm_probing_cycle_callback()); // probing cycle operation (G38.2) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index e5e84179..df085f33 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -493,10 +493,9 @@ static void _start_job_kill() /**************************************************************************************** * cm_request_feedhold() - request a feedhold - do not run it yet - * _start_p1_feedhold() - start feedhold of correct type and finalization - * _feedhold_with_sync() - perform feedhold that will end in a sync callback - * _feedhold_no_actions() - perform feedhold with no entry actions - * _feedhold_with_actions() - perform hold entry actions + * _feedhold_skip() - run feedhold that will skip remaining unused buffer length + * _feedhold_no_actions() - run feedhold with no entry actions + * _feedhold_with_actions() - run feedhold entry actions * _feedhold_actions_done_callback() - planner callback to reach sync point * * Input arguments @@ -588,7 +587,6 @@ static void _feedhold_actions_done_callback(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } - static stat_t _feedhold_with_actions() // Execute Case (5) { // Check to run first-time code @@ -648,7 +646,6 @@ static stat_t _feedhold_with_actions() // Execute Case (5) cm1.hold_state = FEEDHOLD_HOLD; return (STAT_OK); } - return (STAT_EAGAIN); // keep the compiler happy. Never executed. } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index d6d55fec..84ea6211 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -527,12 +527,13 @@ stat_t mp_exec_aline(mpBuf_t *bf) if ((status == STAT_OK) || (status == STAT_NOOP)) { cm->hold_state = FEEDHOLD_DECEL_COMPLETE; bf->block_state = BLOCK_INITIAL_ACTION; // reset bf so it can restart the rest of the move - cm_set_motion_state(MOTION_STOP); } } // Perform motion state transition. Also sets active model to RUNTIME - if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); } + if (cm->motion_state != MOTION_RUN) { + cm_set_motion_state(MOTION_RUN); + } // There are 4 things that can happen here depending on return conditions: // status bf->block_state Description @@ -766,8 +767,9 @@ static stat_t _exec_aline_head(mpBuf_t *bf) debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)"); return (STAT_OK); // exit without advancing position, say we're done } + // If this trap ever fires put this statement back in: mr->section = SECTION_HEAD; debug_trap_if_true(mr->section != SECTION_HEAD, "exec_aline() Not section head"); -// mr->section = SECTION_HEAD; // +++++ Redundant??? + mr->section_state = SECTION_RUNNING; } else { mr->segment_velocity += mr->forward_diff_5; @@ -811,8 +813,9 @@ static stat_t _exec_aline_body(mpBuf_t *bf) debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)"); return (STAT_OK); // exit without advancing position, say we're done } + // If this trap ever fires put this statement back in: mr->section = SECTION_BODY; debug_trap_if_true(mr->section != SECTION_BODY, "exec_aline() Not section body"); -// mr->section = SECTION_BODY; // +++++ Redundant??? + mr->section_state = SECTION_RUNNING; // uses PERIOD_2 so last segment detection works } if (_exec_aline_segment() == STAT_OK) { // OK means this section is done @@ -852,8 +855,9 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)"); return (STAT_OK); // exit without advancing position, say we're done } + // If this trap ever fires put this statement back in: mr->section = SECTION_TAIL; debug_trap_if_true(mr->section != SECTION_TAIL, "exec_aline() Not section tail"); -// mr->section = SECTION_TAIL; // +++++ Redundant??? + mr->section_state = SECTION_RUNNING; } else { mr->segment_velocity += mr->forward_diff_5; @@ -979,7 +983,7 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) // We'll add the time to either the head or the tail or split it if (b->tail_length > 0) { - if (b->head_length > 0) { // Split the body to the head and tail + if (b->head_length > 0) { // Split the body to the head and tail b->head_length += b->body_length * 0.5; b->tail_length += b->body_length * 0.5; // let the compiler optimize out one of these * b->head_time = (2.0 * b->head_length) / (mr->entry_velocity + b->cruise_velocity); @@ -993,7 +997,7 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) b->body_time = 0; } } - else if (b->head_length > 0) { // Put it all in the head + else if (b->head_length > 0) { // Put it all in the head b->head_length += b->body_length; b->head_time = (2.0 * b->head_length) / (mr->entry_velocity + b->cruise_velocity); b->body_length = 0; @@ -1045,7 +1049,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) cm_set_motion_state(MOTION_STOP); cm->hold_state = FEEDHOLD_MOTION_STOPPED; sr_request_status_report(SR_REQUEST_IMMEDIATE); - cs.controller_state = CONTROLLER_READY; // remove controller readline() PAUSE +// cs.controller_state = CONTROLLER_READY; // Can this be removed? +++++ // remove controller readline() PAUSE } return (STAT_NOOP); // hold here. leave with a NOOP so it does not attempt another load and exec. } From e31be2ae0d9d4624cc7efefb640d83b1bf7a1f8e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 18 Mar 2017 20:05:48 -0400 Subject: [PATCH 206/283] Line number validation --- g2core/canonical_machine.cpp | 14 +++++++++++--- g2core/canonical_machine.h | 13 +++++++------ g2core/config.cpp | 2 +- g2core/gcode_parser.cpp | 6 ++++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 8294fe57..54e4d7bc 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -348,8 +348,16 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ cm_set_display_offsets(MODEL); // must reset offsets if you change absolute override } -void cm_set_model_linenum(const uint32_t linenum) +void cm_set_model_linenum(uint32_t linenum) { + if (linenum < 0) { + linenum = 0; + rpt_exception(STAT_INPUT_LESS_THAN_MIN_VALUE, "line number is negative"); + } else + if (linenum > MAX_LINENUM) { // about 100m + linenum = 0; + rpt_exception(STAT_INPUT_EXCEEDS_MAX_VALUE, "line number exceeds 100,000,000"); + } cm->gm.linenum = linenum; // you must first set the model line number, nv_add_object((const char *)"n"); // then add the line number to the nv list } @@ -1975,8 +1983,8 @@ stat_t cm_get_admo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_admo, cm_get_ar stat_t cm_get_frmo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_frmo, cm_get_feed_rate_mode(ACTIVE_MODEL)));} stat_t cm_get_toolv(nvObj_t *nv) { return(get_int(nv, cm_get_tool(ACTIVE_MODEL))); } -stat_t cm_get_mline(nvObj_t *nv) { return(get_int(nv, cm_get_linenum(MODEL))); } -stat_t cm_get_line(nvObj_t *nv) { return(get_int(nv, cm_get_linenum(ACTIVE_MODEL))); } +stat_t cm_get_mline(nvObj_t *nv) { return(get_int32(nv, cm_get_linenum(MODEL))); } +stat_t cm_get_line(nvObj_t *nv) { return(get_int32(nv, cm_get_linenum(ACTIVE_MODEL))); } stat_t cm_get_vel(nvObj_t *nv) { diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index f686a30d..4b46add5 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -45,11 +45,12 @@ #define _to_millimeters(a) ((cm->gm.units_mode == INCHES) ? ((float)a * (float)MM_PER_INCH) : (float)a) #define _to_inches(a) ((cm->gm.units_mode == INCHES) ? ((float)a * (float)(1/MM_PER_INCH)) : (float)a) -#define DISABLE_SOFT_LIMIT (999999) -#define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3 -#define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3 -#define PROBES_STORED 3 // we store three probes for coordinate rotation computation -#define RADIUS_MIN (0.0001) // minimum value for ABC radius settings +#define DISABLE_SOFT_LIMIT (999999) +#define JERK_INPUT_MIN (0.01) // minimum allowable jerk setting in millions mm/min^3 +#define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3 +#define PROBES_STORED 3 // we store three probes for coordinate rotation computation +#define RADIUS_MIN (0.0001) // minimum value for ABC radius settings +#define MAX_LINENUM (50000000) // 50m is about where float craps out /***************************************************************************** * MACHINE STATE MODEL @@ -375,7 +376,7 @@ float cm_get_feed_rate(const GCodeState_t *gcode_state); void cm_set_motion_mode(GCodeState_t *gcode_state, const uint8_t motion_mode); void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool); void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override); -void cm_set_model_linenum(const uint32_t linenum); +void cm_set_model_linenum(uint32_t linenum); // Coordinate systems and offsets float cm_get_combined_offset(const uint8_t axis); diff --git a/g2core/config.cpp b/g2core/config.cpp index 761d1b33..123a6952 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -710,7 +710,7 @@ nvObj_t *nv_add_string(const char *token, const char *string) // add a string ob } /* - * cm_conditional_message() - queue a RAM string as a message in the response (conditionally) + * nv_add__conditional_message() - queue a RAM string as a message in the response (conditionally) */ nvObj_t *nv_add_conditional_message(const char *string) // conditionally add a message object to the body diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 67252900..4d6983a7 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -732,8 +732,10 @@ static stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; - cm_set_model_linenum(gv.linenum); - + if (gf.linenum) { + cm_set_model_linenum(gv.linenum); + } + EXEC_FUNC(cm_m48_enable, m48_enable); if (gf.fro_control) { // feedrate override From fc2ed0097d4e476146d8f95b88c85e2787c61916 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Mar 2017 05:36:17 -0400 Subject: [PATCH 207/283] Fixed line numbers, but max reliable line number is ~8.3 million given floating point representation --- g2core/canonical_machine.cpp | 7 +++---- g2core/canonical_machine.h | 1 - g2core/util.h | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 54e4d7bc..36cc8d64 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -352,11 +352,10 @@ void cm_set_model_linenum(uint32_t linenum) { if (linenum < 0) { linenum = 0; - rpt_exception(STAT_INPUT_LESS_THAN_MIN_VALUE, "line number is negative"); + rpt_exception(STAT_INPUT_LESS_THAN_MIN_VALUE, "line number is negative; set of zero"); } else - if (linenum > MAX_LINENUM) { // about 100m - linenum = 0; - rpt_exception(STAT_INPUT_EXCEEDS_MAX_VALUE, "line number exceeds 100,000,000"); + if (linenum > MAX_FP_INTEGER) { // see util.h + rpt_exception(STAT_INPUT_EXCEEDS_MAX_VALUE, "line number > 8,388,608; may be inexact"); } cm->gm.linenum = linenum; // you must first set the model line number, nv_add_object((const char *)"n"); // then add the line number to the nv list diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 4b46add5..4c29f513 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -50,7 +50,6 @@ #define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3 #define PROBES_STORED 3 // we store three probes for coordinate rotation computation #define RADIUS_MIN (0.0001) // minimum value for ABC radius settings -#define MAX_LINENUM (50000000) // 50m is about where float craps out /***************************************************************************** * MACHINE STATE MODEL diff --git a/g2core/util.h b/g2core/util.h index b97d8479..81f472a5 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -139,6 +139,7 @@ inline T avg(const T a,const T b) {return (a+b)/2; } // Constants #define MAX_LONG (2147483647) #define MAX_ULONG (4294967295) +#define MAX_FP_INTEGER (8388608) // maximum integer 32 bit FP will represent exactly (23 bits) #define MM_PER_INCH (25.4) #define INCHES_PER_MM (1/25.4) #define MICROSECONDS_PER_MINUTE ((float)60000000) From e22f5099c570a8728109ca6d2fba7350828883a7 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Mar 2017 07:14:33 -0400 Subject: [PATCH 208/283] Installed union for value --- g2core/config.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/g2core/config.h b/g2core/config.h index 0ab584dd..fc305c11 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -258,7 +258,11 @@ typedef struct nvObject { // depending on use, not all elements ma int8_t depth; // depth of object in the tree. 0 is root (-1 is invalid) valueType valuetype; // see valueType enum int8_t precision; // decimal precision for reporting (JSON) - float value; // numeric value +// float value; // numeric value + union { + float value; // float values + uint32_t value_int; // uint32 values + }; char group[GROUP_LEN+1]; // group prefix or NUL if not in a group char token[TOKEN_LEN+1]; // full mnemonic token for lookup char (*stringp)[]; // pointer to array of characters from shared character array From 36f8b9a9cc1e82a2f333edf596dea3391bb49a40 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Mar 2017 14:33:14 -0400 Subject: [PATCH 209/283] Checkpoint --- g2core/config.cpp | 12 +++++++++--- g2core/config.h | 29 ++++++++++++++++++++++------- g2core/config_app.cpp | 20 ++++++++++++-------- g2core/gcode.h | 2 +- g2core/json_parser.cpp | 27 +++++++++++++++++++++++---- g2core/report.h | 2 +- 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/g2core/config.cpp b/g2core/config.cpp index 123a6952..db429f53 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -131,7 +131,11 @@ static void _set_defa(nvObj_t *nv, bool print) if (cfgArray[nv->index].flags & F_ZERO) { nv->value = 0; } else { - nv->value = cfgArray[nv->index].def_value; + if (cfgArray[nv->index].flags & F_INT32) { + nv->value_int = cfgArray[nv->index].def_value; + } else { + nv->value = cfgArray[nv->index].def_value; + } } strncpy(nv->token, cfgArray[nv->index].token, TOKEN_LEN); cfgArray[nv->index].set(nv); // run the set method, nv_set(nv); @@ -222,7 +226,8 @@ stat_t get_int8(nvObj_t *nv) stat_t get_int32(nvObj_t *nv) { - nv->value = *((uint32_t *)GET_TABLE_WORD(target)); +//+++++ nv->value = *((uint32_t *)GET_TABLE_WORD(target)); + nv->value_int = *((uint32_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_INT; return (STAT_OK); } @@ -331,7 +336,8 @@ stat_t set_0123(nvObj_t *nv) stat_t set_int32(nvObj_t *nv) { - *((uint32_t *)GET_TABLE_WORD(target)) = (uint32_t)nv->value; +// *((uint32_t *)GET_TABLE_WORD(target)) = (uint32_t)nv->value; +++++ + *((uint32_t *)GET_TABLE_WORD(target)) = nv->value_int; nv->valuetype = TYPE_INT; return(STAT_OK); } diff --git a/g2core/config.h b/g2core/config.h index fc305c11..c1ad4b29 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -208,7 +208,8 @@ typedef enum { // value typing for config and JSON TYPE_NULL = 0, // value is 'null' (meaning the JSON null value) TYPE_PARENT, // object is a parent to a sub-object TYPE_FLOAT, // value is a floating point number - TYPE_INT, // value is a signed or unsigned integer or any size + TYPE_INT, // value is a signed or unsigned integer < 32 bits + TYPE_INT32, // value is a 32 bit signed integer TYPE_STRING, // value is in string field TYPE_BOOL, // value is "true" (1) or "false"(0) TYPE_DATA, // value is blind cast to uint32_t @@ -223,6 +224,7 @@ typedef enum { // value typing for config and JSON #define F_CONVERT 0x08 // set if unit conversion is required #define F_ICONVERT 0x10 // set if unit conversion is required AND value is an inverse quantity #define F_ZERO 0x20 // initialize to zero (requires F_INITIALIZE set as well) +#define F_INT32 0x40 // treat as int32 #define _f0 0x00 #define _fi (F_INITIALIZE) @@ -238,6 +240,20 @@ typedef enum { // value typing for config and JSON #define _fipi (F_INITIALIZE | F_PERSIST | F_ICONVERT) #define _fipnc (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) +#define _i0 (F_INT32) +#define _ii (F_INT32) | (F_INITIALIZE) +#define _ip (F_INT32) | (F_PERSIST) +#define _in (F_INT32) | (F_NOSTRIP) +#define _ic (F_INT32) | (F_CONVERT) +#define _iic (F_INT32) | (F_INITIALIZE | F_CONVERT) +#define _iip (F_INT32) | (F_INITIALIZE | F_PERSIST) +#define _iiz (F_INT32) | (F_INITIALIZE | F_ZERO) +#define _iizc (F_INT32) | (F_INITIALIZE | F_ZERO | F_CONVERT) +#define _iipc (F_INT32) | (F_INITIALIZE | F_PERSIST | F_CONVERT) +#define _iipn (F_INT32) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP) +#define _iipi (F_INT32) | (F_INITIALIZE | F_PERSIST | F_ICONVERT) +#define _iipnc (F_INT32) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) + /**** Structures ****/ typedef struct nvString { // shared string object @@ -258,10 +274,9 @@ typedef struct nvObject { // depending on use, not all elements ma int8_t depth; // depth of object in the tree. 0 is root (-1 is invalid) valueType valuetype; // see valueType enum int8_t precision; // decimal precision for reporting (JSON) -// float value; // numeric value union { float value; // float values - uint32_t value_int; // uint32 values + int32_t value_int; // int32 values }; char group[GROUP_LEN+1]; // group prefix or NUL if not in a group char token[TOKEN_LEN+1]; // full mnemonic token for lookup @@ -331,7 +346,7 @@ stat_t set_int8(nvObj_t *nv); // set signed 8 bit integer stat_t set_01(nvObj_t *nv); // set a 0 or 1 value with validation stat_t set_012(nvObj_t *nv); // set a 0, 1 or 2 value with validation stat_t set_0123(nvObj_t *nv); // set a 0, 1, 2 or 3 value with validation -stat_t set_int32(nvObj_t *nv); // set uint32_t integer value +stat_t set_int32(nvObj_t *nv); // set int32_t integer value stat_t set_data(nvObj_t *nv); // set uint32_t integer value blind cast stat_t set_flt(nvObj_t *nv); // set floating point value @@ -339,7 +354,7 @@ stat_t get_nul(nvObj_t *nv); // get null value type stat_t get_bool(nvObj_t *nv); // get boolean value stat_t get_ui8(nvObj_t *nv); // get uint8_t value stat_t get_int8(nvObj_t *nv); // get signed 8 bit integer -stat_t get_int32(nvObj_t *nv); // get uint32_t integer value +stat_t get_int32(nvObj_t *nv); // get int32_t integer value stat_t get_data(nvObj_t *nv); // get uint32_t integer value blind cast stat_t get_flt(nvObj_t *nv); // get floating point value @@ -372,8 +387,8 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving 8 bit integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); -stat_t get_int32(nvObj_t *nv, const uint32_t value); // boilerplate for retrieving 32 bit integer value -stat_t set_int32(nvObj_t *nv, uint32_t &value, uint32_t low, uint32_t high); +stat_t get_int32(nvObj_t *nv, const int32_t value); // boilerplate for retrieving 32 bit integer value +stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high); stat_t get_string(nvObj_t *nv, const char *str); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index baf1eebe..b27dea30 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -648,7 +648,7 @@ const cfgItem_t cfgArray[] = { { "sys","jv", _fipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, { "sys","qv", _fipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, { "sys","sv", _fipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, - { "sys","si", _fipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, + { "sys","si", _iipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco @@ -1397,30 +1397,34 @@ stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { return (STAT_OK); } -stat_t get_int32(nvObj_t *nv, const uint32_t value) { - nv->value = value; +stat_t get_int32(nvObj_t *nv, const int32_t value) { +//+++++ nv->value = value; + nv->value_int = value; nv->valuetype = TYPE_INT; return STAT_OK; } -stat_t set_int32(nvObj_t *nv, uint32_t &value, uint32_t low, uint32_t high) { +stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high) { char msg[64]; - if (nv->value < low) { +//+++++ if (nv->value < low) { + if (nv->value_int < low) { sprintf(msg, "Input is less than minimum value %lu", low); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > high) { +//+++++ if (nv->value > high) { + if (nv->value_int > high) { sprintf(msg, "Input is more than maximum value %lu", high); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - value = nv->value; // note: valuetype = TYPE_INT already set - nv->valuetype = TYPE_INT; +// value = nv->value; // note: valuetype = TYPE_INT already set + value = nv->value_int; // note: valuetype = TYPE_INT already set + nv->valuetype = TYPE_INT32; return (STAT_OK); } diff --git a/g2core/gcode.h b/g2core/gcode.h index f3dede09..0a0e9e9f 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -211,7 +211,7 @@ typedef enum { // axis modes (ordered: see _cm_get_feed_time()) */ typedef struct GCodeState { // Gcode model state - used by model, planning and runtime - uint32_t linenum; // Gcode block line number + int32_t linenum; // Gcode block line number cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82 // G83, G84, G85, G86, G87, G88, G89 diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index cfd04bc5..f1fbb941 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -45,7 +45,7 @@ jsSingleton_t js; static stat_t _json_parser_kernal(nvObj_t *nv, char *str); static stat_t _json_parser_execute(nvObj_t *nv); static stat_t _normalize_json_string(char *str, uint16_t size); -static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth); +static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *value_int); /**************************************************************************** * json_parser() - exposed part of JSON parser @@ -97,7 +97,6 @@ void json_parser(char *str) return; } nv_print_list(status, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT); -// nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_FORMAT); sr_request_status_report(SR_REQUEST_TIMED); // generate incremental status report to show any changes } @@ -135,10 +134,22 @@ static stat_t _json_parser_execute(nvObj_t *nv) { return (STAT_OK); // only successful commands exit through this point } +// Return valueType defined for this variable. +// Currently just (f)loat and (int) + +static valueType _value_type_defined(index_t i) +{ + if (cfgArray[i].flags & F_INT32) { + return (TYPE_INT32); + } + return (TYPE_FLOAT); +} + static stat_t _json_parser_kernal(nvObj_t *nv, char *str) { stat_t status; int8_t depth; + uint32_t value_int = 0; char group[GROUP_LEN+1] = {""}; // group identifier - starts as NUL int8_t i = NV_BODY_LEN; @@ -155,7 +166,7 @@ static stat_t _json_parser_kernal(nvObj_t *nv, char *str) } // Use relaxed parser. Will read either strict or relaxed mode. To use strict-only parser refer // to build earlier than 407.03. Substitute _get_nv_pair_strict() for _get_nv_pair() - if ((status = _get_nv_pair(nv, &str, &depth)) > STAT_EAGAIN) { // erred out + if ((status = _get_nv_pair(nv, &str, &depth, &value_int)) > STAT_EAGAIN) { // erred out nv->valuetype = TYPE_NULL; return (status); } @@ -171,6 +182,10 @@ static stat_t _json_parser_kernal(nvObj_t *nv, char *str) if ((nv_index_is_group(nv->index)) && (nv_group_is_prefixed(nv->token))) { strncpy(group, nv->token, GROUP_LEN); // record the group ID } + if (_value_type_defined(nv->index) == TYPE_INT32) { // change out the float for an int32 + nv->value_int = value_int; + nv->valuetype = TYPE_INT32; + } if ((nv = nv->nx) == NULL) { return (STAT_JSON_TOO_MANY_PAIRS); // Not supposed to encounter a NULL } @@ -236,7 +251,7 @@ static stat_t _normalize_json_string(char *str, uint16_t size) * See build 406.xx or earlier for strict JSON parser - deleted in 407.03 */ -static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth) +static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *value_int) { uint8_t i; char *tmp; @@ -290,6 +305,7 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth) // numbers } else if (isdigit(**pstr) || (**pstr == '-')) { // value is a number + *value_int = atol(*pstr); // get number as an integer first (non destructive) nv->value = (float)strtod(*pstr, &tmp); // tmp is the end pointer if ((tmp == *pstr) || // if start pointer equals end the conversion failed @@ -428,6 +444,9 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) str += sprintf(str, "%d", (int)nv->value); break; } + case (TYPE_INT32): { str += sprintf(str, "%d", (int)nv->value_int); + break; + } case (TYPE_STRING): { *str++ = '"'; strcpy(str, *nv->stringp); str += strlen(*nv->stringp); diff --git a/g2core/report.h b/g2core/report.h index 31514a73..197a32e8 100644 --- a/g2core/report.h +++ b/g2core/report.h @@ -61,7 +61,7 @@ typedef struct srSingleton { /*** config values (PUBLIC) ***/ srVerbosity status_report_verbosity; - uint32_t status_report_interval; // in milliseconds + int32_t status_report_interval; // in milliseconds /*** runtime values (PRIVATE) ***/ srVerbosity status_report_request; // flag that SR has been requested, and what type From 5f306e1657754e6a6b0a5d97a3c5e97cf9c997f0 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 19 Mar 2017 20:27:53 -0400 Subject: [PATCH 210/283] Big commit. Added nv->value_int, and changed nv_value to nv->value_flt. Many many things changed. Passes smoke test. Now on to some real regressions. --- g2core/canonical_machine.cpp | 82 ++-- g2core/config.cpp | 102 +++-- g2core/config.h | 138 +++++-- g2core/config_app.cpp | 781 +++++++++++++++++------------------ g2core/coolant.cpp | 4 +- g2core/cycle_probing.cpp | 6 +- g2core/gpio.cpp | 79 ++-- g2core/json_parser.cpp | 72 ++-- g2core/persistence.cpp | 2 +- g2core/planner.cpp | 8 +- g2core/report.cpp | 39 +- g2core/spindle.cpp | 4 +- g2core/stepper.cpp | 46 +-- g2core/temperature.cpp | 258 ++++++------ g2core/text_parser.cpp | 31 +- 15 files changed, 841 insertions(+), 811 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 36cc8d64..0d00b671 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -513,8 +513,8 @@ void cm_update_model_position() /**************************************************************************************** * cm_deferred_write_callback() - write any changed G10 values back to persistence * - * Only runs if there is G10 data to write, there is no movement, and the serial queues are quiescent - * This could be made tighter by issuing an XOFF or ~CTS beforehand and releasing it afterwards. + * Only runs if there is G10 data to write, there is no movement, and the serial queues + * are quiescent. */ stat_t cm_deferred_write_callback() @@ -526,8 +526,8 @@ stat_t cm_deferred_write_callback() for (uint8_t j=0; jcoord_offset[i][j]; - nv_persist(&nv); // Note: only writes values that have changed + nv.value_flt = cm->coord_offset[i][j]; + nv_persist(&nv); // Note: nv_persist() only writes values that have changed } } } @@ -543,11 +543,10 @@ stat_t cm_deferred_write_callback() stat_t cm_set_tram(nvObj_t *nv) { - if ((nv->valuetype == TYPE_BOOL) || - (nv->valuetype == TYPE_INT) || - (nv->valuetype == TYPE_FLOAT)) - { - bool do_set = !!((uint32_t)nv->value); + // Ah yes. If you call {tram:true} or any non-zero it will tram. Anything falsey will clear the tram. + if ((nv->valuetype == TYPE_BOOLEAN) || (nv->valuetype == TYPE_INTEGER) || (nv->valuetype == TYPE_FLOAT)) { + + bool do_set = !!(nv->value_int); // if passed false/0, we will clear the rotation matrix if (!do_set) { @@ -641,7 +640,7 @@ stat_t cm_set_tram(nvObj_t *nv) stat_t cm_get_tram(nvObj_t *nv) { - nv->value = true; + nv->value_int = true; if (fp_NOT_ZERO(cm->rotation_z_offset) || fp_NOT_ZERO(cm->rotation_matrix[0][1]) || @@ -654,9 +653,9 @@ stat_t cm_get_tram(nvObj_t *nv) fp_NE(1.0, cm->rotation_matrix[1][1]) || fp_NE(1.0, cm->rotation_matrix[2][2])) { - nv->value = false; + nv->value_int = false; } - nv->valuetype = TYPE_BOOL; + nv->valuetype = TYPE_BOOLEAN; return (STAT_OK); } @@ -1736,20 +1735,12 @@ char cm_get_axis_char(const int8_t axis) /*********************************************************************************** * Run Commands * - * cm_run_qf() - flush planner queue * cm_run_home() - run homing sequence */ -/* -stat_t cm_run_qf(nvObj_t *nv) -{ - cm_request_queue_flush(); - return (STAT_OK); -} -*/ stat_t cm_run_home(nvObj_t *nv) { - if (fp_TRUE(nv->value)) { + if (nv->value_int) { // if true float axes[] = { 1,1,1,1,1,1 }; bool flags[] = { 1,1,1,1,1,1 }; cm_homing_cycle_start(axes, flags); @@ -1958,10 +1949,10 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; #endif // __TEXT_MODE // Add the string for the enum to the nv, but leave it as a TYPE_INT -stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], uint8_t value) +stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], int32_t value) { - nv->value = (float)value; - nv->valuetype = TYPE_INT; + nv->value_int = value; + nv->valuetype = TYPE_INTEGER; return(nv_copy_string(nv, (const char *)GET_TEXT_ITEM(msg_array, value))); } @@ -1988,11 +1979,11 @@ stat_t cm_get_line(nvObj_t *nv) { return(get_int32(nv, cm_get_linenum(ACTIVE_MO stat_t cm_get_vel(nvObj_t *nv) { if (cm_get_motion_state() == MOTION_STOP) { - nv->value = 0; + nv->value_flt = 0; } else { - nv->value = mp_get_runtime_velocity(); + nv->value_flt = mp_get_runtime_velocity(); if (cm_get_units_mode(RUNTIME) == INCHES) { - nv->value *= INCHES_PER_MM; + nv->value_flt *= INCHES_PER_MM; } } nv->precision = GET_TABLE_WORD(precision); @@ -2070,25 +2061,25 @@ stat_t cm_set_tt(nvObj_t *nv) stat_t cm_get_am(nvObj_t *nv) { int8_t axis = _axis(nv); - nv->value = (float)cm->a[axis].axis_mode; - return(_get_msg_helper(nv, msg_am, nv->value)); + nv->value_int = cm->a[axis].axis_mode; + return(_get_msg_helper(nv, msg_am, nv->value_int)); } stat_t cm_set_am(nvObj_t *nv) // axis mode { if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { - if (nv->value > AXIS_MODE_LINEAR_MAX) { + if (nv->value_int > AXIS_MODE_LINEAR_MAX) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } } else { - if (nv->value > AXIS_MODE_ROTARY_MAX) { + if (nv->value_int > AXIS_MODE_ROTARY_MAX) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } } - nv->valuetype = TYPE_INT; - cm->a[_axis(nv)].axis_mode = (cmAxisMode)nv->value; + nv->valuetype = TYPE_INTEGER; + cm->a[_axis(nv)].axis_mode = (cmAxisMode)nv->value_int; return(STAT_OK); } @@ -2155,7 +2146,7 @@ stat_t cm_set_vm(nvObj_t *nv) { uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].velocity_max, 0, MAX_LONG)); - cm->a[axis].recip_velocity_max = 1/nv->value; + cm->a[axis].recip_velocity_max = 1/nv->value_flt; return(STAT_OK); } @@ -2164,7 +2155,7 @@ stat_t cm_set_fr(nvObj_t *nv) { uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].feedrate_max, 0, MAX_LONG)); - cm->a[axis].recip_feedrate_max = 1/nv->value; + cm->a[axis].recip_feedrate_max = 1/nv->value_flt; return(STAT_OK); } @@ -2173,17 +2164,16 @@ stat_t cm_set_jm(nvObj_t *nv) { uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].jerk_max, JERK_INPUT_MIN, JERK_INPUT_MAX)); - cm_set_axis_max_jerk(axis, nv->value); + cm_set_axis_max_jerk(axis, nv->value_flt); return(STAT_OK); } stat_t cm_get_jh(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].jerk_high)); } -stat_t cm_set_jh(nvObj_t *nv) -// { return (set_float_range(nv, cm->a[_axis(nv)].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); } +stat_t cm_set_jh(nvObj_t *nv) { uint8_t axis = _axis(nv); ritorno(set_float_range(nv, cm->a[axis].jerk_high, JERK_INPUT_MIN, JERK_INPUT_MAX)); - cm_set_axis_high_jerk(axis, nv->value); + cm_set_axis_high_jerk(axis, nv->value_flt); return(STAT_OK); } @@ -2458,7 +2448,7 @@ static const char fmt_hom[] = "%c axis homing state:%2.0f\n"; static void _print_axis_ui8(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, (uint8_t)nv->value); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value_int); xio_writeline(cs.out_buf); } @@ -2470,7 +2460,7 @@ static void _print_axis_flt(nvObj_t *nv, const char *format) } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); } - sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value, units); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value_flt, units); xio_writeline(cs.out_buf); } @@ -2482,7 +2472,7 @@ static void _print_axis_coord_flt(nvObj_t *nv, const char *format) } else { units = (char *)GET_TEXT_ITEM(msg_units, DEGREE_INDEX); } - sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->token, nv->value, units); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->token, nv->value_flt, units); xio_writeline(cs.out_buf); } @@ -2491,7 +2481,7 @@ static void _print_pos(nvObj_t *nv, const char *format, uint8_t units) char axes[] = {"XYZABC"}; uint8_t axis = _axis(nv); if (axis >= AXIS_A) { units = DEGREES;} - sprintf(cs.out_buf, format, axes[axis], nv->value, GET_TEXT_ITEM(msg_units, units)); + sprintf(cs.out_buf, format, axes[axis], nv->value_flt, GET_TEXT_ITEM(msg_units, units)); xio_writeline(cs.out_buf); } @@ -2499,14 +2489,14 @@ static void _print_hom(nvObj_t *nv, const char *format) { char axes[] = {"XYZABC"}; uint8_t axis = _axis(nv); - sprintf(cs.out_buf, format, axes[axis], nv->value); + sprintf(cs.out_buf, format, axes[axis], nv->value_int); xio_writeline(cs.out_buf); } void cm_print_am(nvObj_t *nv) // print axis mode with enumeration string { - sprintf(cs.out_buf, fmt_Xam, nv->group, nv->token, nv->group, (uint8_t)nv->value, - GET_TEXT_ITEM(msg_am, (uint8_t)nv->value)); + sprintf(cs.out_buf, fmt_Xam, nv->group, nv->token, nv->group, nv->value_int, + GET_TEXT_ITEM(msg_am, nv->value_int)); xio_writeline(cs.out_buf); } diff --git a/g2core/config.cpp b/g2core/config.cpp index db429f53..272caf82 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -128,15 +128,15 @@ static void _set_defa(nvObj_t *nv, bool print) cm_set_units_mode(MILLIMETERS); // must do inits in MM mode for (nv->index=0; nv_index_is_single(nv->index); nv->index++) { if (cfgArray[nv->index].flags & F_INITIALIZE) { - if (cfgArray[nv->index].flags & F_ZERO) { - nv->value = 0; +// if (cfgArray[nv->index].flags & F_ZERO) { +// nv->value = 0; +// } else { + if ((cfgArray[nv->index].flags & F_TYPE_MASK) == TYPE_INTEGER) { + nv->value_int = cfgArray[nv->index].def_value; } else { - if (cfgArray[nv->index].flags & F_INT32) { - nv->value_int = cfgArray[nv->index].def_value; - } else { - nv->value = cfgArray[nv->index].def_value; - } + nv->value_flt = cfgArray[nv->index].def_value; } +// } strncpy(nv->token, cfgArray[nv->index].token, TOKEN_LEN); cfgArray[nv->index].set(nv); // run the set method, nv_set(nv); if (cfgArray[nv->index].flags & F_PERSIST) { @@ -152,8 +152,10 @@ static void _set_defa(nvObj_t *nv, bool print) stat_t set_defaults(nvObj_t *nv) { - // failsafe. nv->value must be true or no action occurs - if (fp_FALSE(nv->value)) return(help_defa(nv)); + // failsafe. nv->value_int must be true or no action occurs + if (!nv->value_int) { + return(help_defa(nv)); + } _set_defa(nv, true); // The nvlist was used for the initialize message so the values are all garbage @@ -161,8 +163,8 @@ stat_t set_defaults(nvObj_t *nv) nv_reset_nv_list(); strncpy(nv->token, "defa", TOKEN_LEN); // nv->index = nv_get_index("", nv->token); // correct, but not required - nv->valuetype = TYPE_INT; - nv->value = 1; + nv->valuetype = TYPE_INTEGER; // ++++ probably should be TYPE_BOOLEAN + nv->value_int = true; return (STAT_OK); } @@ -212,29 +214,31 @@ stat_t get_nul(nvObj_t *nv) stat_t get_ui8(nvObj_t *nv) { - nv->value = (float)*((uint8_t *)GET_TABLE_WORD(target)); - nv->valuetype = TYPE_INT; +// nv->value = (float)*((uint8_t *)GET_TABLE_WORD(target)); + nv->value_int = *((uint8_t *)GET_TABLE_WORD(target)); + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } stat_t get_int8(nvObj_t *nv) { - nv->value = (float)*((int8_t *)GET_TABLE_WORD(target)); - nv->valuetype = TYPE_INT; +// nv->value = (float)*((int8_t *)GET_TABLE_WORD(target)); + nv->value_int = *((int8_t *)GET_TABLE_WORD(target)); + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } stat_t get_int32(nvObj_t *nv) { -//+++++ nv->value = *((uint32_t *)GET_TABLE_WORD(target)); +// nv->value = *((uint32_t *)GET_TABLE_WORD(target)); nv->value_int = *((uint32_t *)GET_TABLE_WORD(target)); - nv->valuetype = TYPE_INT; + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } stat_t get_data(nvObj_t *nv) { - uint32_t *v = (uint32_t*)&nv->value; + uint32_t *v = (uint32_t*)&nv->value_flt; *v = *((uint32_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_DATA; return (STAT_OK); @@ -242,7 +246,7 @@ stat_t get_data(nvObj_t *nv) stat_t get_flt(nvObj_t *nv) { - nv->value = *((float *)GET_TABLE_WORD(target)); + nv->value_flt= *((float *)GET_TABLE_WORD(target)); nv->precision = (int8_t)GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return (STAT_OK); @@ -283,25 +287,25 @@ stat_t set_ro(nvObj_t *nv) { stat_t set_ui8(nvObj_t *nv) { - *((uint8_t *)GET_TABLE_WORD(target)) = nv->value; - nv->valuetype = TYPE_INT; + *((uint8_t *)GET_TABLE_WORD(target)) = nv->value_int; + nv->valuetype = TYPE_INTEGER; return(STAT_OK); } stat_t set_int8(nvObj_t *nv) { - *((int8_t *)GET_TABLE_WORD(target)) = (int8_t)nv->value; - nv->valuetype = TYPE_INT; + *((int8_t *)GET_TABLE_WORD(target)) = (int8_t)nv->value_int; + nv->valuetype = TYPE_INTEGER; return(STAT_OK); } stat_t set_01(nvObj_t *nv) { - if (nv->value < 0) { + if (nv->value_int < 0) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > 1) { + if (nv->value_int > 1) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } @@ -310,11 +314,11 @@ stat_t set_01(nvObj_t *nv) stat_t set_012(nvObj_t *nv) { - if (nv->value < 0) { + if (nv->value_int < 0) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > 2) { + if (nv->value_int > 2) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } @@ -323,11 +327,11 @@ stat_t set_012(nvObj_t *nv) stat_t set_0123(nvObj_t *nv) { - if (nv->value < 0) { + if (nv->value_int < 0) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > 3) { + if (nv->value_int > 3) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } @@ -338,13 +342,13 @@ stat_t set_int32(nvObj_t *nv) { // *((uint32_t *)GET_TABLE_WORD(target)) = (uint32_t)nv->value; +++++ *((uint32_t *)GET_TABLE_WORD(target)) = nv->value_int; - nv->valuetype = TYPE_INT; + nv->valuetype = TYPE_INTEGER; return(STAT_OK); } stat_t set_data(nvObj_t *nv) { - uint32_t *v = (uint32_t*)&nv->value; + uint32_t *v = (uint32_t*)&nv->value_flt; *((uint32_t *)GET_TABLE_WORD(target)) = *v; nv->valuetype = TYPE_DATA; return(STAT_OK); @@ -352,7 +356,7 @@ stat_t set_data(nvObj_t *nv) stat_t set_flt(nvObj_t *nv) { - *((float *)GET_TABLE_WORD(target)) = nv->value; + *((float *)GET_TABLE_WORD(target)) = nv->value_flt; nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return(STAT_OK); @@ -499,6 +503,25 @@ uint8_t nv_get_type(nvObj_t *nv) return (NV_TYPE_CONFIG); } +/* + * nv_coerce_types() - change types based on type field in configApp table + */ +void nv_coerce_types(nvObj_t *nv) +{ + valueType type = (valueType)(cfgArray[nv->index].flags & F_TYPE_MASK); + if (type == TYPE_INTEGER) { + nv->valuetype = TYPE_INTEGER; // will pay attention to the int value, not the float + } else if (type == TYPE_BOOLEAN) { // it may have been marked as a boolean, but if it's not... + nv->valuetype = TYPE_BOOLEAN; + if (nv->valuetype == TYPE_INTEGER) { + nv->value_int = nv->value_int ? true : false; + } else + if (nv->valuetype == TYPE_FLOAT) { + nv->value_int = (fp_ZERO(nv->value_flt)) ? true : false; + } + } +} + /****************************************************************************** * nvObj low-level object and list operations * nv_get_nvObj() - setup a nv object by providing the index @@ -550,7 +573,8 @@ nvObj_t *nv_reset_nv(nvObj_t *nv) // clear a single nvObj structur { nv->valuetype = TYPE_EMPTY; // selective clear is much faster than calling memset nv->index = 0; - nv->value = 0; + nv->value_int = 0; + nv->value_flt = 0; nv->precision = 0; nv->token[0] = NUL; nv->group[0] = NUL; @@ -639,7 +663,7 @@ nvObj_t *nv_add_object(const char *token) // add an object to the body usi return (NULL); } -nvObj_t *nv_add_integer(const char *token, const uint32_t value)// add an integer object to the body +nvObj_t *nv_add_integer(const char *token, const int32_t value) // add an integer object to the body { nvObj_t *nv = nv_body; for (uint8_t i=0; itoken, token, TOKEN_LEN); - nv->value = (float) value; - nv->valuetype = TYPE_INT; + nv->value_int = value; + nv->valuetype = TYPE_INTEGER; return (nv); } return (NULL); @@ -669,7 +693,7 @@ nvObj_t *nv_add_data(const char *token, const uint32_t value)// add an integer o } strcpy(nv->token, token); float *v = (float*)&value; - nv->value = *v; + nv->value_flt = *v; nv->valuetype = TYPE_DATA; return (nv); } @@ -687,7 +711,7 @@ nvObj_t *nv_add_float(const char *token, const float value) // add a float ob continue; } strncpy(nv->token, token, TOKEN_LEN); - nv->value = value; + nv->value_flt = value; nv->valuetype = TYPE_FLOAT; return (nv); } @@ -761,7 +785,7 @@ void nv_dump_nv(nvObj_t *nv) nv->depth, nv->valuetype, nv->precision, - (double)nv->value, + (double)nv->value_flt, // would need to add in value_int to be complete nv->group, nv->token, (char *)nv->stringp); diff --git a/g2core/config.h b/g2core/config.h index c1ad4b29..65b793a9 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -203,29 +203,85 @@ typedef enum { FLOW_CONTROL_RTS // flow control uses RTS/CTS } flowControl; -typedef enum { // value typing for config and JSON - TYPE_EMPTY = -1, // value struct is empty (which is not the same as "NULL") - TYPE_NULL = 0, // value is 'null' (meaning the JSON null value) - TYPE_PARENT, // object is a parent to a sub-object - TYPE_FLOAT, // value is a floating point number - TYPE_INT, // value is a signed or unsigned integer < 32 bits - TYPE_INT32, // value is a 32 bit signed integer - TYPE_STRING, // value is in string field - TYPE_BOOL, // value is "true" (1) or "false"(0) - TYPE_DATA, // value is blind cast to uint32_t - TYPE_ARRAY // value is array element count, values are CSV ASCII in string field +typedef enum { // value typing for config and JSON + // exception types + TYPE_SKIP = -2, // do not serialize this object (used for filtering) + TYPE_EMPTY = -1, // value struct is empty (which is not the same as "NULL") + + // fundamental JSON types // must be 0-3. Do not change. Used by F_'s and JSON decoding + TYPE_NULL = 0, // value is 'null' (meaning the JSON null value) + TYPE_BOOLEAN = 1, // value is "true" (1) or "false"(0) + TYPE_INTEGER = 2, // value is an 8 or 32 bit signed integer + TYPE_STRING = 3, // value is in string field + + // derived data types // must be 4-7. Do not change. + TYPE_FLOAT = 4, // value is a floating point number + TYPE_UINT32 = 5, // unsigned 32 bit integer (unused) + TYPE_ARRAY = 6, // value is array element count, values are CSV ASCII in string field + TYPE_DATA = 7, // value is blind cast to uint32_t (willbe removed) + + // transient types and types used during JSON processing + TYPE_PARENT // object is a parent to a sub-object +// TYPE_NEW_LEVEL, // 'value' is actually child key at new nesting level +// TYPE_NULL_STRING, // empty string - treated as null +// TYPE_TYPE_ERROR // none of the above } valueType; /**** operations flags and shorthand ****/ -#define F_INITIALIZE 0x01 // initialize this item (run set during initialization) -#define F_PERSIST 0x02 // persist this item when set is run -#define F_NOSTRIP 0x04 // do not strip the group prefix from the token -#define F_CONVERT 0x08 // set if unit conversion is required -#define F_ICONVERT 0x10 // set if unit conversion is required AND value is an inverse quantity -#define F_ZERO 0x20 // initialize to zero (requires F_INITIALIZE set as well) -#define F_INT32 0x40 // treat as int32 +#define F_TYPE_MASK 0x00000007 // 3 LSB's used for data type +#define F_INITIALIZE 0x08 // initialize this item (run set during initialization) +#define F_PERSIST 0x10 // persist this item when set is run +#define F_NOSTRIP 0x20 // do not strip the group prefix from the token +#define F_CONVERT 0x40 // set if unit conversion is required +#define F_ICONVERT 0x80 // set if unit conversion is required AND value is an inverse quantity + +// Shorthand +// _n(ull) (used by commands or other case where there is no target data) +// _b(oolean) +// _s(tring) +// _i(nteger) +// _f(loat) +// _t(ext container) +// _d(ata) + +#define _n0 (TYPE_NULL) +#define _nn (TYPE_NULL | F_NOSTRIP) + +#define _s0 (TYPE_STRING) +#define _sn (TYPE_STRING | F_NOSTRIP) + +#define _d0 (TYPE_DATA) +#define _dip (TYPE_DATA | F_INITIALIZE | F_PERSIST) + +#define _b0 (TYPE_BOOLEAN) // boolean data types (only listing the ones we use) +#define _bip (TYPE_BOOLEAN | F_INITIALIZE | F_PERSIST) +#define _bin (TYPE_BOOLEAN | F_INITIALIZE | F_NOSTRIP) +#define _bipn (TYPE_BOOLEAN | F_INITIALIZE | F_PERSIST | F_NOSTRIP) + +#define _i0 (TYPE_INTEGER) // integer data types (only listing the ones we use) +#define _ii (TYPE_INTEGER | F_INITIALIZE) +#define _ip (TYPE_INTEGER | F_PERSIST) +#define _in (TYPE_INTEGER | F_NOSTRIP) +#define _iip (TYPE_INTEGER | F_INITIALIZE | F_PERSIST) +#define _iipn (TYPE_INTEGER | F_INITIALIZE | F_PERSIST | F_NOSTRIP) + +#define _f0 (TYPE_FLOAT) // floating point data types (only listing the ones we use) +#define _fi (TYPE_FLOAT | F_INITIALIZE) +#define _fp (TYPE_FLOAT | F_PERSIST) +#define _fn (TYPE_FLOAT | F_NOSTRIP) +#define _fip (TYPE_FLOAT | F_INITIALIZE | F_PERSIST) +#define _fic (TYPE_FLOAT | F_INITIALIZE | F_CONVERT) +#define _fin (TYPE_FLOAT | F_INITIALIZE | F_NOSTRIP) +#define _fipc (TYPE_FLOAT | F_INITIALIZE | F_PERSIST | F_CONVERT) +#define _fipn (TYPE_FLOAT | F_INITIALIZE | F_PERSIST | F_NOSTRIP) +#define _fipi (TYPE_FLOAT | F_INITIALIZE | F_PERSIST | F_ICONVERT) +#define _fipnc (TYPE_FLOAT | F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) + +#define _t0 (TYPE_TXTCON) + +/* #define _f0 0x00 #define _fi (F_INITIALIZE) #define _fp (F_PERSIST) @@ -233,26 +289,27 @@ typedef enum { // value typing for config and JSON #define _fc (F_CONVERT) #define _fic (F_INITIALIZE | F_CONVERT) #define _fip (F_INITIALIZE | F_PERSIST) -#define _fiz (F_INITIALIZE | F_ZERO) -#define _fizc (F_INITIALIZE | F_ZERO | F_CONVERT) +//#define _fiz (F_INITIALIZE | F_ZERO) +//#define _fizc (F_INITIALIZE | F_ZERO | F_CONVERT) #define _fipc (F_INITIALIZE | F_PERSIST | F_CONVERT) #define _fipn (F_INITIALIZE | F_PERSIST | F_NOSTRIP) #define _fipi (F_INITIALIZE | F_PERSIST | F_ICONVERT) #define _fipnc (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) -#define _i0 (F_INT32) -#define _ii (F_INT32) | (F_INITIALIZE) -#define _ip (F_INT32) | (F_PERSIST) -#define _in (F_INT32) | (F_NOSTRIP) -#define _ic (F_INT32) | (F_CONVERT) -#define _iic (F_INT32) | (F_INITIALIZE | F_CONVERT) -#define _iip (F_INT32) | (F_INITIALIZE | F_PERSIST) -#define _iiz (F_INT32) | (F_INITIALIZE | F_ZERO) -#define _iizc (F_INT32) | (F_INITIALIZE | F_ZERO | F_CONVERT) -#define _iipc (F_INT32) | (F_INITIALIZE | F_PERSIST | F_CONVERT) -#define _iipn (F_INT32) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP) -#define _iipi (F_INT32) | (F_INITIALIZE | F_PERSIST | F_ICONVERT) -#define _iipnc (F_INT32) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) +#define _i0 (F_TYPE_INTEGER) +#define _ii (F_TYPE_INTEGER) | (F_INITIALIZE) +#define _ip (F_TYPE_INTEGER) | (F_PERSIST) +#define _in (F_TYPE_INTEGER) | (F_NOSTRIP) +#define _ic (F_TYPE_INTEGER) | (F_CONVERT) +#define _iic (F_TYPE_INTEGER) | (F_INITIALIZE | F_CONVERT) +#define _iip (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST) +#define _iiz (F_TYPE_INTEGER) | (F_INITIALIZE | F_ZERO) +#define _iizc (F_TYPE_INTEGER) | (F_INITIALIZE | F_ZERO | F_CONVERT) +#define _iipc (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_CONVERT) +#define _iipn (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP) +#define _iipi (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_ICONVERT) +#define _iipnc (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) +*/ /**** Structures ****/ @@ -270,17 +327,15 @@ typedef struct nvString { // shared string object typedef struct nvObject { // depending on use, not all elements may be populated struct nvObject *pv; // pointer to previous object or NULL if first object struct nvObject *nx; // pointer to next object or NULL if last object - index_t index; // index of tokenized name, or -1 if no token (optional) int8_t depth; // depth of object in the tree. 0 is root (-1 is invalid) - valueType valuetype; // see valueType enum - int8_t precision; // decimal precision for reporting (JSON) - union { - float value; // float values - int32_t value_int; // int32 values - }; char group[GROUP_LEN+1]; // group prefix or NUL if not in a group char token[TOKEN_LEN+1]; // full mnemonic token for lookup - char (*stringp)[]; // pointer to array of characters from shared character array + index_t index; // index of tokenized name, or -1 if no token (optional) + valueType valuetype; // type of value that follows: see valueType enum + int8_t precision; // decimal precision for reporting floating point numbers (JSON only) + float value_flt; // floating point values + int32_t value_int; // signed integer values and booleans + char (*stringp)[]; // string value: pointer to array of characters from shared character array } nvObj_t; // OK, so it's not REALLY an object typedef uint8_t (*fptrCmd)(nvObj_t *nv);// required for cfg table access @@ -330,6 +385,7 @@ stat_t nv_persist(nvObj_t *nv); // main entry point for persistence // helpers uint8_t nv_get_type(nvObj_t *nv); +void nv_coerce_types(nvObj_t *nv); index_t nv_get_index(const char *group, const char *token); index_t nv_index_max(void); // (see config_app.c) bool nv_index_is_single(index_t index); // (see config_app.c) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index b27dea30..d2ed99f3 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -106,35 +106,35 @@ const cfgItem_t cfgArray[] = { // group token flags p, print_func, get_func, set_func, get/set target, default value { "sys", "fb", _fn, 2, hw_print_fb, hw_get_fb, set_ro, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! { "sys", "fv", _fn, 2, hw_print_fv, hw_get_fv, set_ro, (float *)&cs.null, 0 }, - { "sys", "fbs",_fn, 0, hw_print_fbs, hw_get_fbs, set_ro, (float *)&cs.null, 0 }, - { "sys", "fbc",_fn, 0, hw_print_fbc, hw_get_fbc, set_ro, (float *)&cs.null, 0 }, - { "sys", "hp", _fn, 0, hw_print_hp, hw_get_hp, set_ro, (float *)&cs.null, 0 }, - { "sys", "hv", _fn, 0, hw_print_hv, hw_get_hv, set_ro, (float *)&cs.null, 0 }, - { "sys", "id", _fn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) + { "sys", "fbs",_sn, 0, hw_print_fbs, hw_get_fbs, set_ro, (float *)&cs.null, 0 }, + { "sys", "fbc",_sn, 0, hw_print_fbc, hw_get_fbc, set_ro, (float *)&cs.null, 0 }, + { "sys", "hp", _sn, 0, hw_print_hp, hw_get_hp, set_ro, (float *)&cs.null, 0 }, + { "sys", "hv", _sn, 0, hw_print_hv, hw_get_hv, set_ro, (float *)&cs.null, 0 }, + { "sys", "id", _sn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) - { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "stat2",_f0,0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null, 0 }, // Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number + { "", "stat",_i0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state + { "","stat2",_i0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state + { "", "n", _ii, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null,0 }, // Model line number + { "", "line",_ii, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool - { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "macs",_i0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state + { "", "cycs",_i0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state + { "", "mots",_i0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state + { "", "hold",_i0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state + { "", "unit",_i0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode + { "", "coor",_i0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system + { "", "momo",_i0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode + { "", "plan",_i0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select + { "", "path",_i0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode + { "", "dist",_i0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode + { "", "admo",_i0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode + { "", "frmo",_i0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode + { "", "tool",_i0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool + { "", "g92e",_i0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS - { "", "_leds",_f0, 0, tx_print_nul, _get_leds,_set_leds, (float *)&cs.null, 0 }, // TEMPORARY - change LEDs + { "", "_leds",_i0, 0, tx_print_nul, _get_leds,_set_leds, (float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position @@ -158,15 +158,15 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsb",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset { "ofs","ofsc",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset - { "hom","home",_f0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed + { "hom","home",_i0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle + { "hom","homx",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group + { "hom","homy",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Y homed + { "hom","homz",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Z homed + { "hom","homa",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // A homed + { "hom","homb",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // B homed + { "hom","homc",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed - { "prb","prbe",_f0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state + { "prb","prbe",_i0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results @@ -197,121 +197,121 @@ const cfgItem_t cfgArray[] = { #endif // Motor parameters - { "1","1ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, + { "1","1ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, { "1","1tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M1_STEPS_PER_UNIT }, - { "1","1mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, - { "1","1po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M1_POLARITY }, - { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, + { "1","1mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, + { "1","1po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M1_POLARITY }, + { "1","1pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, { "1","1pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M1_POWER_LEVEL }, // { "1","1pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, // { "1","1mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, #if (MOTORS >= 2) - { "2","2ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, + { "2","2ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, { "2","2tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M2_STEPS_PER_UNIT }, - { "2","2mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, - { "2","2po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M2_POLARITY }, - { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, + { "2","2mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, + { "2","2po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M2_POLARITY }, + { "2","2pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, { "2","2pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M2_POWER_LEVEL}, // { "2","2pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, // { "2","2mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 3) - { "3","3ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, + { "3","3ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, { "3","3tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M3_STEPS_PER_UNIT }, - { "3","3mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, - { "3","3po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M3_POLARITY }, - { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, + { "3","3mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, + { "3","3po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M3_POLARITY }, + { "3","3pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, { "3","3pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M3_POWER_LEVEL }, // { "3","3pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, // { "3","3mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 4) - { "4","4ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, + { "4","4ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, { "4","4tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M4_STEPS_PER_UNIT }, - { "4","4mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, - { "4","4po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M4_POLARITY }, - { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, + { "4","4mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, + { "4","4po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M4_POLARITY }, + { "4","4pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, { "4","4pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M4_POWER_LEVEL }, // { "4","4pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, // { "4","4mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 5) - { "5","5ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, + { "5","5ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, { "5","5tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M5_STEPS_PER_UNIT }, - { "5","5mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, - { "5","5po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M5_POLARITY }, - { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, + { "5","5mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, + { "5","5po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M5_POLARITY }, + { "5","5pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, { "5","5pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M5_POWER_LEVEL }, // { "5","5pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, // { "5","5mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_5].motor_timeout, M5_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 6) - { "6","6ma",_fip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, + { "6","6ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, { "6","6tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M6_STEPS_PER_UNIT }, - { "6","6mi",_fip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, - { "6","6po",_fip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M6_POLARITY }, - { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, + { "6","6mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, + { "6","6po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M6_POLARITY }, + { "6","6pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M6_POWER_LEVEL }, // { "6","6pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, // { "6","6mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, #endif // Axis parameters - { "x","xam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, + { "x","xam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, X_VELOCITY_MAX }, { "x","xfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, X_FEEDRATE_MAX }, { "x","xtn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, { "x","xtm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, { "x","xjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, X_JERK_MAX }, { "x","xjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, X_JERK_HIGH_SPEED }, - { "x","xhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, X_HOMING_INPUT }, - { "x","xhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, X_HOMING_DIRECTION }, + { "x","xhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, X_HOMING_INPUT }, + { "x","xhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, X_HOMING_DIRECTION }, { "x","xsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, X_SEARCH_VELOCITY }, { "x","xlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, X_LATCH_VELOCITY }, { "x","xlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, X_LATCH_BACKOFF }, { "x","xzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, X_ZERO_BACKOFF }, - { "y","yam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, + { "y","yam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Y_VELOCITY_MAX }, { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Y_FEEDRATE_MAX }, { "y","ytn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Y_TRAVEL_MIN }, { "y","ytm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Y_TRAVEL_MAX }, { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Y_JERK_MAX }, { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, Y_JERK_HIGH_SPEED }, - { "y","yhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Y_HOMING_INPUT }, - { "y","yhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Y_HOMING_DIRECTION }, + { "y","yhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Y_HOMING_INPUT }, + { "y","yhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Y_HOMING_DIRECTION }, { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Y_SEARCH_VELOCITY }, { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Y_LATCH_VELOCITY }, { "y","ylb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Y_LATCH_BACKOFF }, { "y","yzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, Y_ZERO_BACKOFF }, - { "z","zam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, + { "z","zam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, { "z","zvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Z_VELOCITY_MAX }, { "z","zfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Z_FEEDRATE_MAX }, { "z","ztn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Z_TRAVEL_MIN }, { "z","ztm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Z_TRAVEL_MAX }, { "z","zjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Z_JERK_MAX }, { "z","zjh",_fipc, 0, cm_print_jh, cm_get_jm, cm_set_jh, (float *)&cs.null, Z_JERK_HIGH_SPEED }, - { "z","zhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Z_HOMING_INPUT }, - { "z","zhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Z_HOMING_DIRECTION }, + { "z","zhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Z_HOMING_INPUT }, + { "z","zhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Z_HOMING_DIRECTION }, { "z","zsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Z_SEARCH_VELOCITY }, { "z","zlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Z_LATCH_VELOCITY }, { "z","zlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Z_LATCH_BACKOFF }, { "z","zzb",_fipc, 5, cm_print_zb, cm_get_lb, cm_set_zb, (float *)&cs.null, Z_ZERO_BACKOFF }, - { "a","aam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, + { "a","aam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, { "a","avm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, A_VELOCITY_MAX }, { "a","afr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, A_FEEDRATE_MAX }, { "a","atn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, @@ -319,14 +319,14 @@ const cfgItem_t cfgArray[] = { { "a","ajm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, A_JERK_MAX }, { "a","ajh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, A_JERK_HIGH_SPEED }, { "a","ara",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, A_RADIUS}, - { "a","ahi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, A_HOMING_INPUT }, - { "a","ahd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, A_HOMING_DIRECTION }, + { "a","ahi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, A_HOMING_INPUT }, + { "a","ahd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, A_HOMING_DIRECTION }, { "a","asv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, A_SEARCH_VELOCITY }, { "a","alv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, A_LATCH_VELOCITY }, { "a","alb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, { "a","azb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, - { "b","bam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, + { "b","bam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, { "b","bvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, B_VELOCITY_MAX }, { "b","bfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, B_FEEDRATE_MAX }, { "b","btn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, @@ -334,14 +334,14 @@ const cfgItem_t cfgArray[] = { { "b","bjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, B_JERK_MAX }, { "b","bjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, B_JERK_HIGH_SPEED }, { "b","bra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, B_RADIUS }, - { "b","bhi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, B_HOMING_INPUT }, - { "b","bhd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, B_HOMING_DIRECTION }, + { "b","bhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, B_HOMING_INPUT }, + { "b","bhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, B_HOMING_DIRECTION }, { "b","bsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, B_SEARCH_VELOCITY }, { "b","blv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, B_LATCH_VELOCITY }, { "b","blb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, { "b","bzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, - { "c","cam",_fip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, + { "c","cam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, { "c","cvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, C_VELOCITY_MAX }, { "c","cfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, C_FEEDRATE_MAX }, { "c","ctn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, @@ -349,116 +349,116 @@ const cfgItem_t cfgArray[] = { { "c","cjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, C_JERK_MAX }, { "c","cjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, C_JERK_HIGH_SPEED }, { "c","cra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, C_RADIUS }, - { "c","chi",_fip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, C_HOMING_INPUT }, - { "c","chd",_fip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, C_HOMING_DIRECTION }, + { "c","chi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, C_HOMING_INPUT }, + { "c","chd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, C_HOMING_DIRECTION }, { "c","csv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, C_SEARCH_VELOCITY }, { "c","clv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, C_LATCH_VELOCITY }, { "c","clb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, { "c","czb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, // Digital input configs - { "di1","di1mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, - { "di1","di1ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[0].action, DI1_ACTION }, - { "di1","di1fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[0].function, DI1_FUNCTION }, + { "di1","di1mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, + { "di1","di1ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[0].action, DI1_ACTION }, + { "di1","di1fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[0].function, DI1_FUNCTION }, - { "di2","di2mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[1].mode, DI2_MODE }, - { "di2","di2ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[1].action, DI2_ACTION }, - { "di2","di2fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[1].function, DI2_FUNCTION }, + { "di2","di2mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[1].mode, DI2_MODE }, + { "di2","di2ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[1].action, DI2_ACTION }, + { "di2","di2fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[1].function, DI2_FUNCTION }, - { "di3","di3mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[2].mode, DI3_MODE }, - { "di3","di3ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[2].action, DI3_ACTION }, - { "di3","di3fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[2].function, DI3_FUNCTION }, + { "di3","di3mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[2].mode, DI3_MODE }, + { "di3","di3ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[2].action, DI3_ACTION }, + { "di3","di3fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[2].function, DI3_FUNCTION }, - { "di4","di4mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[3].mode, DI4_MODE }, - { "di4","di4ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[3].action, DI4_ACTION }, - { "di4","di4fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[3].function, DI4_FUNCTION }, + { "di4","di4mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[3].mode, DI4_MODE }, + { "di4","di4ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[3].action, DI4_ACTION }, + { "di4","di4fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[3].function, DI4_FUNCTION }, - { "di5","di5mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[4].mode, DI5_MODE }, - { "di5","di5ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[4].action, DI5_ACTION }, - { "di5","di5fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[4].function, DI5_FUNCTION }, + { "di5","di5mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[4].mode, DI5_MODE }, + { "di5","di5ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[4].action, DI5_ACTION }, + { "di5","di5fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[4].function, DI5_FUNCTION }, - { "di6","di6mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[5].mode, DI6_MODE }, - { "di6","di6ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[5].action, DI6_ACTION }, - { "di6","di6fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[5].function, DI6_FUNCTION }, + { "di6","di6mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[5].mode, DI6_MODE }, + { "di6","di6ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[5].action, DI6_ACTION }, + { "di6","di6fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[5].function, DI6_FUNCTION }, - { "di7","di7mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[6].mode, DI7_MODE }, - { "di7","di7ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[6].action, DI7_ACTION }, - { "di7","di7fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[6].function, DI7_FUNCTION }, + { "di7","di7mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[6].mode, DI7_MODE }, + { "di7","di7ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[6].action, DI7_ACTION }, + { "di7","di7fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[6].function, DI7_FUNCTION }, - { "di8","di8mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[7].mode, DI8_MODE }, - { "di8","di8ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[7].action, DI8_ACTION }, - { "di8","di8fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[7].function, DI8_FUNCTION }, + { "di8","di8mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[7].mode, DI8_MODE }, + { "di8","di8ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[7].action, DI8_ACTION }, + { "di8","di8fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[7].function, DI8_FUNCTION }, #if (D_IN_CHANNELS >= 9) - { "di9","di9mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[8].mode, DI9_MODE }, - { "di9","di9ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[8].action, DI9_ACTION }, - { "di9","di9fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[8].function, DI9_FUNCTION }, + { "di9","di9mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[8].mode, DI9_MODE }, + { "di9","di9ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[8].action, DI9_ACTION }, + { "di9","di9fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[8].function, DI9_FUNCTION }, #endif #if (D_IN_CHANNELS >= 10) - { "di10","di10mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[9].mode, DI10_MODE }, - { "di10","di10ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[9].action, DI10_ACTION }, - { "di10","di10fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[9].function, DI10_FUNCTION }, + { "di10","di10mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[9].mode, DI10_MODE }, + { "di10","di10ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[9].action, DI10_ACTION }, + { "di10","di10fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[9].function, DI10_FUNCTION }, #endif #if (D_IN_CHANNELS >= 11) - { "di11","di11mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[10].mode, DI11_MODE }, - { "di11","di11ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[10].action, DI11_ACTION }, - { "di11","di11fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[10].function, DI11_FUNCTION }, + { "di11","di11mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[10].mode, DI11_MODE }, + { "di11","di11ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[10].action, DI11_ACTION }, + { "di11","di11fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[10].function, DI11_FUNCTION }, #endif #if (D_IN_CHANNELS >= 12) - { "di12","di12mo",_fip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[11].mode, DI12_MODE }, - { "di12","di12ac",_fip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[11].action, DI12_ACTION }, - { "di12","di12fn",_fip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[11].function, DI12_FUNCTION }, + { "di12","di12mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[11].mode, DI12_MODE }, + { "di12","di12ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[11].action, DI12_ACTION }, + { "di12","di12fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[11].function, DI12_FUNCTION }, #endif // Digital input state readers - { "in","in1", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in2", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in3", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in4", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in5", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in6", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in7", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in8", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in1", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in2", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in3", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in4", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in5", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in6", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in7", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in8", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #if (D_IN_CHANNELS >= 9) - { "in","in9", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in9", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif #if (D_IN_CHANNELS >= 10) - { "in","in10", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in10", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif #if (D_IN_CHANNELS >= 11) - { "in","in11", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in11", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif #if (D_IN_CHANNELS >= 12) - { "in","in12", _f0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in12", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, #endif // digital output configs - { "do1", "do1mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[0].mode, DO1_MODE }, - { "do2", "do2mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[1].mode, DO2_MODE }, - { "do3", "do3mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[2].mode, DO3_MODE }, - { "do4", "do4mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[3].mode, DO4_MODE }, - { "do5", "do5mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[4].mode, DO5_MODE }, - { "do6", "do6mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[5].mode, DO6_MODE }, - { "do7", "do7mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[6].mode, DO7_MODE }, - { "do8", "do8mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[7].mode, DO8_MODE }, - { "do9", "do9mo", _fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[8].mode, DO9_MODE }, - { "do10","do10mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[9].mode, DO10_MODE }, - { "do11","do11mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[10].mode, DO11_MODE }, - { "do12","do12mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[11].mode, DO12_MODE }, - { "do13","do13mo",_fip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[12].mode, DO13_MODE }, + { "do1", "do1mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[0].mode, DO1_MODE }, + { "do2", "do2mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[1].mode, DO2_MODE }, + { "do3", "do3mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[2].mode, DO3_MODE }, + { "do4", "do4mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[3].mode, DO4_MODE }, + { "do5", "do5mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[4].mode, DO5_MODE }, + { "do6", "do6mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[5].mode, DO6_MODE }, + { "do7", "do7mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[6].mode, DO7_MODE }, + { "do8", "do8mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[7].mode, DO8_MODE }, + { "do9", "do9mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[8].mode, DO9_MODE }, + { "do10","do10mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[9].mode, DO10_MODE }, + { "do11","do11mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[10].mode, DO11_MODE }, + { "do12","do12mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[11].mode, DO12_MODE }, + { "do13","do13mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[12].mode, DO13_MODE }, // Digital output state readers (default to non-active) - { "out","out1", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out2", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out3", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out4", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out5", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out6", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out7", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out8", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out9", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out10", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out11", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out12", _f0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out1", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out2", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out3", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out4", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out5", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out6", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out7", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out8", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out9", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out10", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out11", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out12", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, // PWM settings { "p1","p1frq",_fip, 0, pwm_print_p1frq, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].frequency, P1_PWM_FREQUENCY }, @@ -473,65 +473,65 @@ const cfgItem_t cfgArray[] = { { "p1","p1pof",_fip, 3, pwm_print_p1pof, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].phase_off, P1_PWM_PHASE_OFF }, // temperature configs - pid active values (read-only) - // NOTICE: If you change these PID group keys, you MUST change the get/set functions too!! - { "pid1","pid1p",_fiz, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid1","pid1i",_fiz, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid1","pid1d",_fiz, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + // NOTICE: If you change these PID group keys, you MUST change the get/set functions too! + { "pid1","pid1p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, + { "pid1","pid1i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, + { "pid1","pid1d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2p",_fiz, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2i",_fiz, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2d",_fiz, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3p",_fiz, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3i",_fiz, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3d",_fiz, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, // temperature configs - heater set values (read-write) - // NOTICE: If you change these heater group keys, you MUST change the get/set functions too!! - { "he1","he1e", _fip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H1_DEFAULT_ENABLE }, - { "he1","he1p", _fi, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H1_DEFAULT_P }, - { "he1","he1i", _fi, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H1_DEFAULT_I }, - { "he1","he1d", _fi, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H1_DEFAULT_D }, - { "he1","he1st",_fiz, 1, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he1","he1t", _fiz, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he1","he1op",_fiz, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he1","he1tr",_fiz, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he1","he1at",_fiz, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he1","he1an",_fiz, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he1","he1fp",_fiz, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he1","he1fm",_fiz, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he1","he1fl",_fiz, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he1","he1fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + // NOTICE: If you change these heater group keys, you MUST change the get/set functions too! + { "he1","he1e", _bip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H1_DEFAULT_ENABLE }, + { "he1","he1at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, + { "he1","he1p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H1_DEFAULT_P }, + { "he1","he1i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H1_DEFAULT_I }, + { "he1","he1d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H1_DEFAULT_D }, + { "he1","he1st",_fi, 1, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, + { "he1","he1t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, + { "he1","he1op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, + { "he1","he1tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, + { "he1","he1an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, + { "he1","he1fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, + { "he1","he1fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, + { "he1","he1fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, + { "he1","he1fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, - { "he2","he2e", _fip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H2_DEFAULT_ENABLE }, - { "he2","he2p", _fi, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H2_DEFAULT_P }, - { "he2","he2i", _fi, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H2_DEFAULT_I }, - { "he2","he2d", _fi, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H2_DEFAULT_D }, - { "he2","he2st",_fiz, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he2","he2t", _fiz, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he2","he2op",_fiz, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he2","he2tr",_fiz, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he2","he2at",_fiz, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he2","he2an",_fiz, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he2","he2fp",_fiz, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he2","he2fm",_fiz, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he2","he2fl",_fiz, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he2","he2fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he2","he2e", _iip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H2_DEFAULT_ENABLE }, + { "he2","he2at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, + { "he2","he2p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H2_DEFAULT_P }, + { "he2","he2i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H2_DEFAULT_I }, + { "he2","he2d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H2_DEFAULT_D }, + { "he2","he2st",_fi, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, + { "he2","he2t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, + { "he2","he2op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, + { "he2","he2tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, + { "he2","he2an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, + { "he2","he2fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, + { "he2","he2fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, + { "he2","he2fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, + { "he2","he2fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, - { "he3","he3e", _fip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H3_DEFAULT_ENABLE }, - { "he3","he3p", _fi, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H3_DEFAULT_P }, - { "he3","he3i", _fi, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H3_DEFAULT_I }, - { "he3","he3d", _fi, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H3_DEFAULT_D }, - { "he3","he3st",_fiz, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he3","he3t", _fiz, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he3","he3op",_fiz, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he3","he3tr",_fiz, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he3","he3at",_fiz, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he3","he3an",_fiz, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he3","he3fp",_fiz, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he3","he3fm",_fiz, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he3","he3fl",_fiz, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he3","he3fh",_fiz, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he3","he3e", _iip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H3_DEFAULT_ENABLE }, + { "he3","he3at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, + { "he3","he3p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H3_DEFAULT_P }, + { "he3","he3i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H3_DEFAULT_I }, + { "he3","he3d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H3_DEFAULT_D }, + { "he3","he3st",_fi, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, + { "he3","he3t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, + { "he3","he3op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, + { "he3","he3tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, + { "he3","he3an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, + { "he3","he3fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, + { "he3","he3fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, + { "he3","he3fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, + { "he3","he3fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, // Coordinate system offsets (G54-G59 and G92) { "g54","g54x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_X_OFFSET }, @@ -576,136 +576,135 @@ const cfgItem_t cfgArray[] = { { "g59","g59b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, { "g59","g59c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, - { "g92","g92x",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently - { "g92","g92y",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92z",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92a",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92b",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92c",_fizc, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92x",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently + { "g92","g92y",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92z",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92a",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92b",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92c",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently - { "g28","g28y",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28z",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28a",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28b",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28c",_fizc, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28x",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently + { "g28","g28y",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28z",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28a",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28b",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28c",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g30","g30x",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently - { "g30","g30y",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30z",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30a",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30b",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30c",_fizc, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30x",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently + { "g30","g30y",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30z",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30a",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30b",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30c",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, // this is a 128bit UUID for identifying a previously committed job state - { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, - { "jid","jidb",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0}, - { "jid","jidc",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, - { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, + { "jid","jida",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, + { "jid","jidb",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0}, + { "jid","jidc",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, + { "jid","jidd",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, // Spindle functions - { "sp","spmo", _fip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, - { "sp","spph", _fip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, + { "sp","spmo", _iip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, + { "sp","spph", _bip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, - { "sp","spep", _fip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, - { "sp","spdp", _fip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, - { "sp","spoe", _fip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, + { "sp","spep", _iip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, + { "sp","spdp", _iip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, + { "sp","spoe", _bip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, - { "sp","spc", _f0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state + { "sp","spc", _i0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed // Coolant functions - { "co","coph", _fip, 0, co_print_coph, co_get_coph, co_set_coph, (float *)&cs.null, COOLANT_PAUSE_ON_HOLD }, - { "co","comp", _fip, 0, co_print_comp, co_get_comp, co_set_comp, (float *)&cs.null, COOLANT_MIST_POLARITY }, - { "co","cofp", _fip, 0, co_print_cofp, co_get_cofp, co_set_cofp, (float *)&cs.null, COOLANT_FLOOD_POLARITY }, - { "co","com", _f0, 0, co_print_com, co_get_com, co_set_com, (float *)&cs.null, 0 }, // mist coolant enable - { "co","cof", _f0, 0, co_print_cof, co_get_cof, co_set_cof, (float *)&cs.null, 0 }, // flood coolant enable + { "co","coph", _bip, 0, co_print_coph, co_get_coph, co_set_coph, (float *)&cs.null, COOLANT_PAUSE_ON_HOLD }, + { "co","comp", _iip, 0, co_print_comp, co_get_comp, co_set_comp, (float *)&cs.null, COOLANT_MIST_POLARITY }, + { "co","cofp", _iip, 0, co_print_cofp, co_get_cofp, co_set_cofp, (float *)&cs.null, COOLANT_FLOOD_POLARITY }, + { "co","com", _i0, 0, co_print_com, co_get_com, co_set_com, (float *)&cs.null, 0 }, // mist coolant enable + { "co","cof", _i0, 0, co_print_cof, co_get_cof, co_set_cof, (float *)&cs.null, 0 }, // flood coolant enable // General system parameters { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT }, - { "sys","sl", _fipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, - { "sys","lim", _fipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, - { "sys","saf", _fipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48", _fipn, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 0 }, // M48/M49 feedrate & spindle override enable - { "sys","froe",_fipn, 0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, - { "sys","fro", _fipn, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, - { "sys","troe",_fipn, 0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","tro", _fipn, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, - { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, + { "sys","sl", _bipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, + { "sys","lim", _bipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, + { "sys","saf", _bipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, + { "sys","m48", _bin, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 1 }, // M48/M49 feedrate & spindle override enable + { "sys","froe",_bin, 0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, + { "sys","fro", _fin, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, + { "sys","troe",_bin, 0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","tro", _fin, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, // N is seconds of timeout { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors // Communications and reporting parameters #ifdef __TEXT_MODE - { "sys","tv", _fipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, + { "sys","tv", _iipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, #endif - { "sys","ej", _fipn, 0, js_print_ej, js_get_ej, js_set_ej, (float *)&cs.null, COMM_MODE }, - { "sys","jv", _fipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, - { "sys","qv", _fipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, - { "sys","sv", _fipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, + { "sys","ej", _iipn, 0, js_print_ej, js_get_ej, js_set_ej, (float *)&cs.null, COMM_MODE }, + { "sys","jv", _iipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, + { "sys","qv", _iipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, + { "sys","sv", _iipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, { "sys","si", _iipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco - { "sys","gpl", _fipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, (float *)&cs.null, GCODE_DEFAULT_PLANE }, - { "sys","gun", _fipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, (float *)&cs.null, GCODE_DEFAULT_UNITS }, - { "sys","gco", _fipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, - { "sys","gpa", _fipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, - { "sys","gdi", _fipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, - { "", "gc2", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // send gcode to secondary planner - { "", "gc", _f0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group + { "sys","gpl", _iipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, (float *)&cs.null, GCODE_DEFAULT_PLANE }, + { "sys","gun", _iipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, (float *)&cs.null, GCODE_DEFAULT_UNITS }, + { "sys","gco", _iipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, + { "sys","gpa", _iipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, + { "sys","gdi", _iipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, + { "", "gc2", _s0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // send gcode to secondary planner + { "", "gc", _s0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group // Actions and Reports - { "", "sr", _f0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports - { "", "qr", _f0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available - { "", "qi", _f0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue - { "", "qo", _f0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue - { "", "er", _f0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing -// { "", "qf", _f0, 0, tx_print_nul, get_nul, cm_run_qf, (float *)&cs.null, 0 }, // SET to invoke queue flush - { "", "rx", _f0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets - { "", "dw", _f0, 0, tx_print_int, st_get_dw, set_noop, (float *)&cs.null, 0 }, // get dwell time remaining - { "", "msg", _f0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages - { "", "alarm",_f0,0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm - { "", "panic",_f0,0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic - { "", "shutd",_f0,0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown - { "", "clear",_f0,0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state - { "", "clr", _f0, 0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" - { "", "tick",_f0, 0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic - { "", "tram",_f0, 0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes - { "", "defa",_f0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen - { "", "flash",_f0,0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, + { "", "sr", _n0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports + { "", "qr", _n0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available + { "", "qi", _n0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue + { "", "qo", _n0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue + { "", "er", _n0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing + { "", "rx", _n0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets + { "", "dw", _i0, 0, tx_print_int, st_get_dw, set_noop, (float *)&cs.null, 0 }, // get dwell time remaining + { "", "msg", _s0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages + { "", "alarm",_n0, 0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm + { "", "panic",_n0, 0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic + { "", "shutd",_n0, 0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown + { "", "clear",_n0, 0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state + { "", "clr", _n0, 0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" + { "", "tick", _n0, 0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic + { "", "tram", _b0, 0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes + { "", "defa", _b0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen + { "", "flash",_b0, 0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, #ifdef __HELP_SCREENS - { "", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen - { "", "h", _f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // alias for "help" + { "", "help",_b0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen + { "", "h", _b0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // alias for "help" #endif #ifdef __USER_DATA // User defined data groups - { "uda","uda0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[0], USER_DATA_A0 }, - { "uda","uda1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[1], USER_DATA_A1 }, - { "uda","uda2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[2], USER_DATA_A2 }, - { "uda","uda3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[3], USER_DATA_A3 }, + { "uda","uda0", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[0], USER_DATA_A0 }, + { "uda","uda1", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[1], USER_DATA_A1 }, + { "uda","uda2", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[2], USER_DATA_A2 }, + { "uda","uda3", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_a[3], USER_DATA_A3 }, - { "udb","udb0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[0], USER_DATA_B0 }, - { "udb","udb1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[1], USER_DATA_B1 }, - { "udb","udb2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[2], USER_DATA_B2 }, - { "udb","udb3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[3], USER_DATA_B3 }, + { "udb","udb0", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[0], USER_DATA_B0 }, + { "udb","udb1", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[1], USER_DATA_B1 }, + { "udb","udb2", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[2], USER_DATA_B2 }, + { "udb","udb3", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_b[3], USER_DATA_B3 }, - { "udc","udc0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[0], USER_DATA_C0 }, - { "udc","udc1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[1], USER_DATA_C1 }, - { "udc","udc2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[2], USER_DATA_C2 }, - { "udc","udc3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[3], USER_DATA_C3 }, + { "udc","udc0", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[0], USER_DATA_C0 }, + { "udc","udc1", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[1], USER_DATA_C1 }, + { "udc","udc2", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[2], USER_DATA_C2 }, + { "udc","udc3", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_c[3], USER_DATA_C3 }, - { "udd","udd0", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[0], USER_DATA_D0 }, - { "udd","udd1", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[1], USER_DATA_D1 }, - { "udd","udd2", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[2], USER_DATA_D2 }, - { "udd","udd3", _fip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[3], USER_DATA_D3 }, + { "udd","udd0", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[0], USER_DATA_D0 }, + { "udd","udd1", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[1], USER_DATA_D1 }, + { "udd","udd2", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[2], USER_DATA_D2 }, + { "udd","udd3", _dip, 0, tx_print_int, get_data, set_data,(float *)&cfg.user_data_d[3], USER_DATA_D3 }, #endif // Tool table offsets @@ -961,97 +960,97 @@ const cfgItem_t cfgArray[] = { { "_tr","_trc",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_C], 0 }, #if (MOTORS >= 1) - { "_ts","_ts1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_1], 0 }, // Motor 1 target steps - { "_ps","_ps1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_1], 0 }, // Motor 1 position steps - { "_cs","_cs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_1], 0 }, // Motor 1 commanded steps (delayed steps) - { "_es","_es1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_1], 0 }, // Motor 1 encoder steps - { "_xs","_xs1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_1].corrected_steps, 0 }, // Motor 1 correction steps applied - { "_fe","_fe1",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_1], 0 }, // Motor 1 following error in steps + { "_ts","_ts1",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_1], 0 }, // Motor 1 target steps + { "_ps","_ps1",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_1], 0 }, // Motor 1 position steps + { "_cs","_cs1",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_1], 0 }, // Motor 1 commanded steps (delayed steps) + { "_es","_es1",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_1], 0 }, // Motor 1 encoder steps + { "_xs","_xs1",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_1].corrected_steps, 0 }, // Motor 1 correction steps applied + { "_fe","_fe1",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_1], 0 }, // Motor 1 following error in steps #endif #if (MOTORS >= 2) - { "_ts","_ts2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_2], 0 }, - { "_ps","_ps2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_2], 0 }, - { "_cs","_cs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_2], 0 }, - { "_es","_es2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_2], 0 }, - { "_xs","_xs2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_2].corrected_steps, 0 }, - { "_fe","_fe2",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_2], 0 }, + { "_ts","_ts2",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_2], 0 }, + { "_ps","_ps2",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_2], 0 }, + { "_cs","_cs2",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_2], 0 }, + { "_es","_es2",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_2], 0 }, + { "_xs","_xs2",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_2].corrected_steps, 0 }, + { "_fe","_fe2",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_2], 0 }, #endif #if (MOTORS >= 3) - { "_ts","_ts3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_3], 0 }, - { "_ps","_ps3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_3], 0 }, - { "_cs","_cs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_3], 0 }, - { "_es","_es3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_3], 0 }, - { "_xs","_xs3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_3].corrected_steps, 0 }, - { "_fe","_fe3",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_3], 0 }, + { "_ts","_ts3",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_3], 0 }, + { "_ps","_ps3",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_3], 0 }, + { "_cs","_cs3",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_3], 0 }, + { "_es","_es3",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_3], 0 }, + { "_xs","_xs3",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_3].corrected_steps, 0 }, + { "_fe","_fe3",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_3], 0 }, #endif #if (MOTORS >= 4) - { "_ts","_ts4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_4], 0 }, - { "_ps","_ps4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_4], 0 }, - { "_cs","_cs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_4], 0 }, - { "_es","_es4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_4], 0 }, - { "_xs","_xs4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_4].corrected_steps, 0 }, - { "_fe","_fe4",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_4], 0 }, + { "_ts","_ts4",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_4], 0 }, + { "_ps","_ps4",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_4], 0 }, + { "_cs","_cs4",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_4], 0 }, + { "_es","_es4",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_4], 0 }, + { "_xs","_xs4",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_4].corrected_steps, 0 }, + { "_fe","_fe4",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_4], 0 }, #endif #if (MOTORS >= 5) - { "_ts","_ts5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_5], 0 }, - { "_ps","_ps5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_5], 0 }, - { "_cs","_cs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_5], 0 }, - { "_es","_es5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_5], 0 }, - { "_xs","_xs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_5].corrected_steps, 0 }, - { "_fe","_fe5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_5], 0 }, + { "_ts","_ts5",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_5], 0 }, + { "_ps","_ps5",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_5], 0 }, + { "_cs","_cs5",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_5], 0 }, + { "_es","_es5",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_5], 0 }, + { "_xs","_xs6",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_5].corrected_steps, 0 }, + { "_fe","_fe5",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_5], 0 }, #endif #if (MOTORS >= 6) - { "_ts","_ts6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_6], 0 }, - { "_ps","_ps6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_6], 0 }, - { "_cs","_cs6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_6], 0 }, - { "_es","_es6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_6], 0 }, - { "_xs","_xs5",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_6].corrected_steps, 0 }, - { "_fe","_fe6",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_6], 0 }, + { "_ts","_ts6",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target_steps[MOTOR_6], 0 }, + { "_ps","_ps6",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->position_steps[MOTOR_6], 0 }, + { "_cs","_cs6",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->commanded_steps[MOTOR_6], 0 }, + { "_es","_es6",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->encoder_steps[MOTOR_6], 0 }, + { "_xs","_xs5",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&st_pre.mot[MOTOR_6].corrected_steps, 0 }, + { "_fe","_fe6",_i0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->following_error[MOTOR_6], 0 }, #endif #endif // __DIAGNOSTIC_PARAMETERS // Persistence for status report - must be in sequence // *** Count must agree with NV_STATUS_REPORT_LEN in report.h *** - { "","se00",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[0],0 }, - { "","se01",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[1],0 }, - { "","se02",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[2],0 }, - { "","se03",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[3],0 }, - { "","se04",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[4],0 }, - { "","se05",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[5],0 }, - { "","se06",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[6],0 }, - { "","se07",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[7],0 }, - { "","se08",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[8],0 }, - { "","se09",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[9],0 }, - { "","se10",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[10],0 }, - { "","se11",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[11],0 }, - { "","se12",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[12],0 }, - { "","se13",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[13],0 }, - { "","se14",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[14],0 }, - { "","se15",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[15],0 }, - { "","se16",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[16],0 }, - { "","se17",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[17],0 }, - { "","se18",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[18],0 }, - { "","se19",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[19],0 }, - { "","se20",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[20],0 }, - { "","se21",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[21],0 }, - { "","se22",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[22],0 }, - { "","se23",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[23],0 }, - { "","se24",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[24],0 }, - { "","se25",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[25],0 }, - { "","se26",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[26],0 }, - { "","se27",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[27],0 }, - { "","se28",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[28],0 }, - { "","se29",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[29],0 }, - { "","se30",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[30],0 }, - { "","se31",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[31],0 }, - { "","se32",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[32],0 }, - { "","se33",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[33],0 }, - { "","se34",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[34],0 }, - { "","se35",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[35],0 }, - { "","se36",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[36],0 }, - { "","se37",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[37],0 }, - { "","se38",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[38],0 }, - { "","se39",_fp, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[39],0 }, + { "","se00",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[0],0 }, + { "","se01",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[1],0 }, + { "","se02",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[2],0 }, + { "","se03",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[3],0 }, + { "","se04",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[4],0 }, + { "","se05",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[5],0 }, + { "","se06",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[6],0 }, + { "","se07",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[7],0 }, + { "","se08",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[8],0 }, + { "","se09",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[9],0 }, + { "","se10",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[10],0 }, + { "","se11",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[11],0 }, + { "","se12",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[12],0 }, + { "","se13",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[13],0 }, + { "","se14",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[14],0 }, + { "","se15",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[15],0 }, + { "","se16",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[16],0 }, + { "","se17",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[17],0 }, + { "","se18",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[18],0 }, + { "","se19",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[19],0 }, + { "","se20",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[20],0 }, + { "","se21",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[21],0 }, + { "","se22",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[22],0 }, + { "","se23",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[23],0 }, + { "","se24",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[24],0 }, + { "","se25",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[25],0 }, + { "","se26",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[26],0 }, + { "","se27",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[27],0 }, + { "","se28",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[28],0 }, + { "","se29",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[29],0 }, + { "","se30",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[30],0 }, + { "","se31",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[31],0 }, + { "","se32",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[32],0 }, + { "","se33",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[33],0 }, + { "","se34",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[34],0 }, + { "","se35",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[35],0 }, + { "","se36",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[36],0 }, + { "","se37",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[37],0 }, + { "","se38",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[38],0 }, + { "","se39",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[39],0 }, // Count is 40, since se00 counts as one. // Group lookups - must follow the single-valued entries for proper sub-string matching @@ -1248,8 +1247,6 @@ bool nv_index_lt_groups(index_t index) { return ((index <= NV_INDEX_START_GROUPS /* * set_flu() - set floating point number with G20/G21 units conversion - * set_flup() - set positive floating point number with G20/G21 units conversion - * set_fltp() - set positive floating point number with no units conversion * * The number 'setted' will have been delivered in external units (inches or mm). * It is written to the target memory location in internal canonical units (mm). @@ -1262,9 +1259,9 @@ bool nv_index_lt_groups(index_t index) { return ((index <= NV_INDEX_START_GROUPS stat_t set_flu(nvObj_t *nv) { if (cm_get_units_mode(MODEL) == INCHES) { // if in inches... - nv->value *= MM_PER_INCH; // convert to canonical millimeter units + nv->value_flt *= MM_PER_INCH; // convert to canonical millimeter units } - *((float *)GET_TABLE_WORD(target)) = nv->value; // write value as millimeters or degrees + *((float *)GET_TABLE_WORD(target)) = nv->value_flt; // write value as millimeters or degrees nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; return(STAT_OK); @@ -1294,17 +1291,17 @@ stat_t set_flu(nvObj_t *nv) static void _convert(nvObj_t *nv, float conversion_factor) { if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type - if (isnan((double)nv->value) || isinf((double)nv->value)) { return; } // trap illegal float values + if (isnan((double)nv->value_flt) || isinf((double)nv->value_flt)) { return; } // trap illegal float values ///+++ transform these checks into NaN or INF strings with an error return? if (cm_get_units_mode(MODEL) == INCHES) { cmAxisType axis_type = cm_get_axis_type(nv); // linear, rotary, global or error if ((axis_type == AXIS_TYPE_LINEAR) || (axis_type == AXIS_TYPE_SYSTEM)) { if (cfgArray[nv->index].flags & F_CONVERT) { // standard units conversion - nv->value *= conversion_factor; + nv->value_flt *= conversion_factor; } else if (cfgArray[nv->index].flags & F_ICONVERT) { // inverse units conversion - nv->value /= conversion_factor; + nv->value_flt /= conversion_factor; } } } @@ -1330,7 +1327,7 @@ void convert_outgoing_float(nvObj_t *nv) { return(_convert (nv, INCHES_PER_MM)); */ stat_t get_float(nvObj_t *nv, const float value) { - nv->value = value; + nv->value_flt = value; nv->valuetype = TYPE_FLOAT; nv->precision = GET_TABLE_WORD(precision); return STAT_OK; @@ -1338,7 +1335,7 @@ stat_t get_float(nvObj_t *nv, const float value) { stat_t set_float(nvObj_t *nv, float &value) { convert_incoming_float(nv); - value = nv->value; + value = nv->value_flt; return (STAT_OK); } @@ -1347,19 +1344,19 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { char msg[64]; convert_incoming_float(nv); // conditional unit conversion - if (nv->value < low) { + if (nv->value_flt < low) { sprintf(msg, "Input is less than minimum value %0.4f", low); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > high) { + if (nv->value_flt > high) { sprintf(msg, "Input is more than maximum value %0.4f", high); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - value = nv->value; + value = nv->value_flt; return (STAT_OK); } @@ -1371,8 +1368,8 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { */ stat_t get_int(nvObj_t *nv, const uint8_t value) { - nv->value = value; - nv->valuetype = TYPE_INT; + nv->value_int = value; + nv->valuetype = TYPE_INTEGER; return STAT_OK; } @@ -1380,27 +1377,26 @@ stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { char msg[64]; - if (nv->value < low) { + if (nv->value_int < low) { sprintf(msg, "Input is less than minimum value %d", low); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > high) { + if (nv->value_int > high) { sprintf(msg, "Input is more than maximum value %d", high); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - value = nv->value; - nv->valuetype = TYPE_INT; + value = nv->value_int; + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } stat_t get_int32(nvObj_t *nv, const int32_t value) { -//+++++ nv->value = value; nv->value_int = value; - nv->valuetype = TYPE_INT; + nv->valuetype = TYPE_INTEGER; return STAT_OK; } @@ -1408,23 +1404,20 @@ stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high) { char msg[64]; -//+++++ if (nv->value < low) { if (nv->value_int < low) { sprintf(msg, "Input is less than minimum value %lu", low); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } -//+++++ if (nv->value > high) { if (nv->value_int > high) { sprintf(msg, "Input is more than maximum value %lu", high); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } -// value = nv->value; // note: valuetype = TYPE_INT already set value = nv->value_int; // note: valuetype = TYPE_INT already set - nv->valuetype = TYPE_INT32; + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } @@ -1570,15 +1563,15 @@ static stat_t _do_all(nvObj_t *nv) // print all parameters static stat_t get_rx(nvObj_t *nv) { - nv->value = (float)254; // ARM always says the serial buffer is available (max) - nv->valuetype = TYPE_INT; + nv->value_int = (float)254; // ARM always says the serial buffer is available (max) + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } static stat_t get_tick(nvObj_t *nv) { - nv->value = (float)SysTickTimer.getValue(); - nv->valuetype = TYPE_INT; + nv->value_int = (float)SysTickTimer.getValue(); + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index 23a57829..f0db9b52 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -154,9 +154,9 @@ static void _exec_coolant_control(float* value, bool* flag) { ***********************************************************************************/ stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.mist.state)); } -stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_MIST)); } +stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value_int, COOLANT_MIST)); } stat_t co_get_cof(nvObj_t *nv) { return(get_int(nv, coolant.flood.state)); } -stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value, COOLANT_FLOOD)); } +stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value_int, COOLANT_FLOOD)); } stat_t co_get_coph(nvObj_t *nv) { return(get_int(nv, coolant.mist.pause_enable)); } stat_t co_set_coph(nvObj_t *nv) { diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 93d300e5..af0ff3a6 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -379,13 +379,13 @@ static void _send_probe_report() { stat_t cm_get_prbr(nvObj_t *nv) { - nv->value = (float)cm->probe_report_enable; - nv->valuetype = TYPE_INT; + nv->value_int = cm->probe_report_enable; + nv->valuetype = TYPE_INTEGER; // ++++ should probably be type boolean return (STAT_OK); } stat_t cm_set_prbr(nvObj_t *nv) { - cm->probe_report_enable = fp_NOT_ZERO(nv->value); + cm->probe_report_enable = nv->value_int; return (STAT_OK); } diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index c0bdc313..ecae09d9 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -481,7 +481,7 @@ bool gpio_read_input(const uint8_t input_num_ext) static stat_t _input_set_helper(nvObj_t *nv, const int8_t lower_bound, const int8_t upper_bound) { - if ((nv->value < lower_bound) || (nv->value >= upper_bound)) { + if ((nv->value_int < lower_bound) || (nv->value_int >= upper_bound)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } set_ui8(nv); // will this work if -1 is a valid value? @@ -493,7 +493,7 @@ static stat_t _input_set_helper(nvObj_t *nv, const int8_t lower_bound, const int static stat_t _output_set_helper(nvObj_t *nv, const int8_t lower_bound, const int8_t upper_bound) { - if ((nv->value < lower_bound) || (nv->value >= upper_bound)) { + if ((nv->value_int < lower_bound) || (nv->value_int >= upper_bound)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } set_ui8(nv); // will this work in -1 is a valid value? @@ -529,12 +529,12 @@ stat_t io_get_input(nvObj_t *nv) // skip over "in" num_start+=2; } - nv->value = d_in[strtol(num_start, NULL, 10)-1].state; + nv->value_int = d_in[strtol(num_start, NULL, 10)-1].state; - if (nv->value > 1.1) { + if (nv->value_int > 1.1) { nv->valuetype = TYPE_NULL; } else { - nv->valuetype = TYPE_BOOL; + nv->valuetype = TYPE_BOOLEAN; } return (STAT_OK); } @@ -557,19 +557,19 @@ stat_t io_set_domode(nvObj_t *nv) // output function // Force pins that aren't available to be "disabled" switch (output_num) { - case 1: if (output_1_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 2: if (output_2_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 3: if (output_3_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 4: if (output_4_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 5: if (output_5_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 6: if (output_6_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 7: if (output_7_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 8: if (output_8_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 9: if (output_9_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 10: if (output_10_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 11: if (output_11_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 12: if (output_12_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; - case 13: if (output_13_pin.isNull()) { nv->value = IO_MODE_DISABLED; } break; + case 1: if (output_1_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 2: if (output_2_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 3: if (output_3_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 4: if (output_4_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 5: if (output_5_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 6: if (output_6_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 7: if (output_7_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 8: if (output_8_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 9: if (output_9_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 10: if (output_10_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 11: if (output_11_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 12: if (output_12_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; + case 13: if (output_13_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; default: break; @@ -599,7 +599,7 @@ stat_t io_get_output(nvObj_t *nv) ioMode outMode = d_out[output_num-1].mode; if (outMode == IO_MODE_DISABLED) { -// nv->value = 0; +// nv->value_int = 0; nv->valuetype = TYPE_NULL; // reports back as NULL } else { nv->valuetype = TYPE_FLOAT; @@ -607,19 +607,19 @@ stat_t io_get_output(nvObj_t *nv) bool invert = (outMode == 0); // Note: !! forces a value to boolean 0 or 1 switch (output_num) { - case 1: { nv->value = (float)output_1_pin; } break; - case 2: { nv->value = (float)output_2_pin; } break; - case 3: { nv->value = (float)output_3_pin; } break; - case 4: { nv->value = (float)output_4_pin; } break; - case 5: { nv->value = (float)output_5_pin; } break; - case 6: { nv->value = (float)output_6_pin; } break; - case 7: { nv->value = (float)output_7_pin; } break; - case 8: { nv->value = (float)output_8_pin; } break; - case 9: { nv->value = (float)output_9_pin; } break; - case 10: { nv->value = (float)output_10_pin; } break; - case 11: { nv->value = (float)output_11_pin; } break; - case 12: { nv->value = (float)output_12_pin; } break; - case 13: { nv->value = (float)output_13_pin; } break; + case 1: { nv->value_flt = (float)output_1_pin; } break; + case 2: { nv->value_flt = (float)output_2_pin; } break; + case 3: { nv->value_flt = (float)output_3_pin; } break; + case 4: { nv->value_flt = (float)output_4_pin; } break; + case 5: { nv->value_flt = (float)output_5_pin; } break; + case 6: { nv->value_flt = (float)output_6_pin; } break; + case 7: { nv->value_flt = (float)output_7_pin; } break; + case 8: { nv->value_flt = (float)output_8_pin; } break; + case 9: { nv->value_flt = (float)output_9_pin; } break; + case 10: { nv->value_flt = (float)output_10_pin; } break; + case 11: { nv->value_flt = (float)output_11_pin; } break; + case 12: { nv->value_flt = (float)output_12_pin; } break; + case 13: { nv->value_flt = (float)output_13_pin; } break; default: { @@ -628,7 +628,7 @@ stat_t io_get_output(nvObj_t *nv) } } if (invert) { - nv->value = 1.0 - nv->value; + nv->value_flt = 1.0 - nv->value_flt; } } return (STAT_OK); @@ -637,6 +637,7 @@ stat_t io_get_output(nvObj_t *nv) /* * io_set_output() - return output state given an nv object */ + stat_t io_set_output(nvObj_t *nv) { char *num_start = nv->token; @@ -650,10 +651,10 @@ stat_t io_set_output(nvObj_t *nv) ioMode outMode = d_out[output_num-1].mode; if (outMode == IO_MODE_DISABLED) { - nv->value = 0; // Inactive? + nv->value_flt = 0; // Inactive? } else { bool invert = (outMode == 0); - float value = nv->value; + float value = nv->value_flt; if (invert) { value = 1.0 - value; } @@ -675,7 +676,7 @@ stat_t io_set_output(nvObj_t *nv) case 12: { output_12_pin = value; } break; case 13: { output_13_pin = value; } break; // END generated - default: { nv->value = 0; } // inactive + default: { nv->value_flt = 0; } // inactive } } return (STAT_OK); @@ -698,20 +699,20 @@ stat_t io_set_output(nvObj_t *nv) static void _print_di(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, nv->group, (int)nv->value); + sprintf(cs.out_buf, format, nv->group, nv->value_int); xio_writeline(cs.out_buf); } void io_print_mo(nvObj_t *nv) {_print_di(nv, fmt_gpio_mo);} void io_print_ac(nvObj_t *nv) {_print_di(nv, fmt_gpio_ac);} void io_print_fn(nvObj_t *nv) {_print_di(nv, fmt_gpio_fn);} void io_print_in(nvObj_t *nv) { - sprintf(cs.out_buf, fmt_gpio_in, nv->token, (int)nv->value); + sprintf(cs.out_buf, fmt_gpio_in, nv->token, (int)nv->value_int); xio_writeline(cs.out_buf); } void io_print_domode(nvObj_t *nv) {_print_di(nv, fmt_gpio_domode);} void io_print_out(nvObj_t *nv) { - sprintf(cs.out_buf, fmt_gpio_out, nv->token, (int)nv->value); + sprintf(cs.out_buf, fmt_gpio_out, nv->token, nv->value_int); xio_writeline(cs.out_buf); } #endif diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index f1fbb941..74cbb538 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -45,7 +45,7 @@ jsSingleton_t js; static stat_t _json_parser_kernal(nvObj_t *nv, char *str); static stat_t _json_parser_execute(nvObj_t *nv); static stat_t _normalize_json_string(char *str, uint16_t size); -static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *value_int); +static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth); /**************************************************************************** * json_parser() - exposed part of JSON parser @@ -134,22 +134,10 @@ static stat_t _json_parser_execute(nvObj_t *nv) { return (STAT_OK); // only successful commands exit through this point } -// Return valueType defined for this variable. -// Currently just (f)loat and (int) - -static valueType _value_type_defined(index_t i) -{ - if (cfgArray[i].flags & F_INT32) { - return (TYPE_INT32); - } - return (TYPE_FLOAT); -} - static stat_t _json_parser_kernal(nvObj_t *nv, char *str) { stat_t status; int8_t depth; - uint32_t value_int = 0; char group[GROUP_LEN+1] = {""}; // group identifier - starts as NUL int8_t i = NV_BODY_LEN; @@ -166,7 +154,7 @@ static stat_t _json_parser_kernal(nvObj_t *nv, char *str) } // Use relaxed parser. Will read either strict or relaxed mode. To use strict-only parser refer // to build earlier than 407.03. Substitute _get_nv_pair_strict() for _get_nv_pair() - if ((status = _get_nv_pair(nv, &str, &depth, &value_int)) > STAT_EAGAIN) { // erred out + if ((status = _get_nv_pair(nv, &str, &depth)) > STAT_EAGAIN) { // erred out nv->valuetype = TYPE_NULL; return (status); } @@ -182,10 +170,7 @@ static stat_t _json_parser_kernal(nvObj_t *nv, char *str) if ((nv_index_is_group(nv->index)) && (nv_group_is_prefixed(nv->token))) { strncpy(group, nv->token, GROUP_LEN); // record the group ID } - if (_value_type_defined(nv->index) == TYPE_INT32) { // change out the float for an int32 - nv->value_int = value_int; - nv->valuetype = TYPE_INT32; - } + nv_coerce_types(nv); // set final types following _get_nv_pair if ((nv = nv->nx) == NULL) { return (STAT_JSON_TOO_MANY_PAIRS); // Not supposed to encounter a NULL } @@ -251,7 +236,7 @@ static stat_t _normalize_json_string(char *str, uint16_t size) * See build 406.xx or earlier for strict JSON parser - deleted in 407.03 */ -static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *value_int) +static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth) { uint8_t i; char *tmp; @@ -301,12 +286,12 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *va // nulls (gets) if ((**pstr == 'n') || ((**pstr == '\"') && (*(*pstr+1) == '\"'))) { // process null value nv->valuetype = TYPE_NULL; - nv->value = TYPE_NULL; + nv->value_int = TYPE_NULL; // numbers } else if (isdigit(**pstr) || (**pstr == '-')) { // value is a number - *value_int = atol(*pstr); // get number as an integer first (non destructive) - nv->value = (float)strtod(*pstr, &tmp); // tmp is the end pointer + nv->value_int = atol(*pstr); // get the number as an integer + nv->value_flt = (float)strtod(*pstr, &tmp); // get the number as a float - tmp is the end pointer if ((tmp == *pstr) || // if start pointer equals end the conversion failed (strchr(terminators, *tmp) == NULL)) { // terminators are the only legal chars at the end of a number @@ -334,7 +319,7 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *va // if string begins with 0x it might be data, needs to be at least 3 chars long if( strlen(*pstr)>=3 && (*pstr)[0]=='0' && (*pstr)[1]=='x') { - uint32_t *v = (uint32_t*)&nv->value; + uint32_t *v = (uint32_t*)&nv->value_flt; *v = strtoul((const char *)*pstr, 0L, 0); nv->valuetype = TYPE_DATA; } else { @@ -344,11 +329,11 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth, uint32_t *va // boolean true/false } else if (**pstr == 't') { - nv->valuetype = TYPE_BOOL; - nv->value = true; + nv->valuetype = TYPE_BOOLEAN; + nv->value_int = true; } else if (**pstr == 'f') { - nv->valuetype = TYPE_BOOL; - nv->value = false; + nv->valuetype = TYPE_BOOLEAN; + nv->value_int = false; // arrays } else if (**pstr == '[') { @@ -437,23 +422,23 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) break; } case (TYPE_FLOAT): { convert_outgoing_float(nv); - str += floattoa(str, nv->value, nv->precision); + str += floattoa(str, nv->value_flt, nv->precision); break; } - case (TYPE_INT): { // str += inttoa(str, (int)nv->value); // doesn't handle negative numbers - str += sprintf(str, "%d", (int)nv->value); +// case (TYPE_INT): { // str += inttoa(str, (int)nv->value); // doesn't handle negative numbers +// str += sprintf(str, "%d", (int)nv->value); +// break; +// } + case (TYPE_INTEGER):{ str += sprintf(str, "%d", (int)nv->value_int); break; } - case (TYPE_INT32): { str += sprintf(str, "%d", (int)nv->value_int); - break; - } case (TYPE_STRING): { *str++ = '"'; strcpy(str, *nv->stringp); str += strlen(*nv->stringp); *str++ = '"'; break; } - case (TYPE_BOOL): { if (fp_FALSE(nv->value)) { + case (TYPE_BOOLEAN):{ if (nv->value_int) { strcpy(str, "false"); str += 5; } else { @@ -462,7 +447,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) } break; } - case (TYPE_DATA): { uint32_t *v = (uint32_t*)&nv->value; + case (TYPE_DATA): { uint32_t *v = (uint32_t*)&nv->value_flt; str += sprintf(str, "\"0x%lx\"", *v); break; } @@ -472,6 +457,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size) strcpy(str++, "]"); break; } + default: {} } } if (str >= str_max) { return (-1);} // signal buffer overrun @@ -582,7 +568,7 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/) } } else if (nv_type == NV_TYPE_LINENUM) { // kill line number echo if not enabled - if ((js.echo_json_linenum == false) || (fp_ZERO(nv->value))) { // do not report line# 0 + if ((js.echo_json_linenum == false) || (fp_ZERO(nv->value_int))) { // do not report line# 0 nv->valuetype = TYPE_EMPTY; } } @@ -647,8 +633,8 @@ stat_t js_get_ej(nvObj_t *nv) { return(get_int(nv, cs.comm_mode)); } stat_t js_set_ej(nvObj_t *nv) { ritorno (set_int(nv, (uint8_t &)cs.comm_mode, TEXT_MODE, AUTO_MODE)); - if (commMode(nv->value) < AUTO_MODE) { // set json_mode to 0 or 1, but don't change it if comm_mode == 2 - js.json_mode = commMode(nv->value); + if (commMode(nv->value_int) < AUTO_MODE) { // set json_mode to 0 or 1, but don't change it if comm_mode == 2 + js.json_mode = commMode(nv->value_int); } return (STAT_OK); } @@ -674,11 +660,11 @@ stat_t js_set_jv(nvObj_t *nv) js.echo_json_messages = true; js.echo_json_configs = true; } else { - if (nv->value >= JV_FOOTER) js.echo_json_footer = true; - if (nv->value >= JV_MESSAGES) js.echo_json_messages = true; - if (nv->value >= JV_CONFIGS) js.echo_json_configs = true; - if (nv->value >= JV_LINENUM) js.echo_json_linenum = true; - if (nv->value >= JV_VERBOSE) js.echo_json_gcode_block = true; + if (nv->value_int >= JV_FOOTER) js.echo_json_footer = true; + if (nv->value_int >= JV_MESSAGES) js.echo_json_messages = true; + if (nv->value_int >= JV_CONFIGS) js.echo_json_configs = true; + if (nv->value_int >= JV_LINENUM) js.echo_json_linenum = true; + if (nv->value_int >= JV_VERBOSE) js.echo_json_gcode_block = true; } return(STAT_OK); } diff --git a/g2core/persistence.cpp b/g2core/persistence.cpp index 00bd37e6..362070a7 100644 --- a/g2core/persistence.cpp +++ b/g2core/persistence.cpp @@ -58,7 +58,7 @@ void persistence_init() stat_t read_persistent_value(nvObj_t *nv) { - nv->value = 0; + nv->value_flt = 0; return (STAT_OK); } diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 77775fcb..53a02916 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -384,11 +384,13 @@ static stat_t _exec_json_wait(mpBuf_t *bf) nvObj_t *nv = nv_exec; while ((nv != NULL) && (nv->valuetype != TYPE_EMPTY)) { // For now we ignore non-BOOL - if (nv->valuetype == TYPE_BOOL) { - bool old_value = !fp_ZERO(nv->value); // force it to bool + if (nv->valuetype == TYPE_BOOLEAN) { +// bool old_value = !fp_ZERO(nv->value); // force it to bool + bool old_value = (bool)nv->value_int; // force it to bool nv_get_nvObj(nv); - bool new_value = !fp_ZERO(nv->value); +// bool new_value = !fp_ZERO(nv->value); + bool new_value = (bool)nv->value_int; if (old_value != new_value) { st_prep_dwell((uint32_t)(0.1 * 1000000.0));// 1ms converted to uSec return STAT_OK; diff --git a/g2core/report.cpp b/g2core/report.cpp index b0a0ae87..9bbaa05b 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -163,10 +163,10 @@ static uint8_t _populate_filtered_status_report(void); uint8_t _is_stat(nvObj_t *nv) { - char tok[TOKEN_LEN+1]; + char token[TOKEN_LEN+1]; - GET_TOKEN_STRING(nv->value, tok); - if (strcmp(tok, "stat") == 0) { return (true);} + GET_TOKEN_STRING(nv->value_int, token); // pass in index, get back token + if (strcmp(token, "stat") == 0) { return (true);} return (false); } @@ -188,8 +188,9 @@ void sr_init_status_report() for (uint8_t i=0; i < NV_STATUS_REPORT_LEN ; i++) { if (sr_defaults[i][0] == NUL) break; // quit on first blank array entry sr.status_report_value[i] = -1234567; // pre-load values with an unlikely number - nv->value = nv_get_index((const char *)"", sr_defaults[i]);// load the index for the SR element - if (fp_EQ(nv->value, NO_MATCH)) { + nv->value_int = nv_get_index((const char *)"", sr_defaults[i]);// load the index for the SR element +// if (fp_EQ(nv->value, NO_MATCH)) { + if (nv->value_int == NO_MATCH) { rpt_exception(STAT_BAD_STATUS_REPORT_SETTING, "sr_init_status_report() encountered bad SR setting"); // trap mis-configured profile settings return; } @@ -220,9 +221,9 @@ stat_t sr_set_status_report(nvObj_t *nv) if (((nv = nv->nx) == NULL) || (nv->valuetype == TYPE_EMPTY)) { break; } - if ((nv->valuetype == TYPE_BOOL) && (fp_TRUE(nv->value))) { + if ((nv->valuetype == TYPE_BOOLEAN) && nv->value_int) { status_report_list[i] = nv->index; - nv->value = nv->index; // persist the index as the value + nv->value_int = nv->index; // persist the index as the value nv->index = sr_start + i; // index of the SR persistence location nv_persist(nv); elements++; @@ -386,14 +387,14 @@ static uint8_t _populate_filtered_status_report() nv_get_nvObj(nv); // report values that have changed by more than 0.0001, but always stops and ends - if ((fabs(nv->value - sr.status_report_value[i]) > precision[cfgArray[nv->index].precision]) || - ((nv->index == sr.stat_index) && fp_EQ(nv->value, COMBINED_PROGRAM_STOP)) || - ((nv->index == sr.stat_index) && fp_EQ(nv->value, COMBINED_PROGRAM_END))) { + if ((fabs(nv->value_int - sr.status_report_value[i]) > precision[cfgArray[nv->index].precision]) || + ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_STOP)) || + ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_END))) { strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here... strcat(tmp, nv->token); strcpy(nv->token, tmp); //...or here. - sr.status_report_value[i] = nv->value; + sr.status_report_value[i] = nv->value_int; if ((nv = nv->nx) == NULL) return (false); // should never be NULL unless SR length exceeds available buffer array has_data = true; @@ -572,23 +573,23 @@ stat_t qr_queue_report_callback() // called by controller dispatcher */ stat_t qr_get(nvObj_t *nv) { - nv->value = (float)mp_get_planner_buffers(mp); // ensure that manually requested QR count is always up to date - nv->valuetype = TYPE_INT; + nv->value_int = mp_get_planner_buffers(mp); // ensure that manually requested QR count is always up to date + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } stat_t qi_get(nvObj_t *nv) { - nv->value = (float)qr.buffers_added; - nv->valuetype = TYPE_INT; + nv->value_int = qr.buffers_added; + nv->valuetype = TYPE_INTEGER; qr.buffers_added = 0; // reset it return (STAT_OK); } stat_t qo_get(nvObj_t *nv) { - nv->value = (float)qr.buffers_removed; - nv->valuetype = TYPE_INT; + nv->value_int = qr.buffers_removed; + nv->valuetype = TYPE_INTEGER; qr.buffers_removed = 0; // reset it return (STAT_OK); } @@ -640,8 +641,8 @@ stat_t job_set_job_report(nvObj_t *nv) for (uint8_t i=0; i<4; i++) { if (((nv = nv->nx) == NULL) || (nv->valuetype == TYPE_EMPTY)) { break;} - if (nv->valuetype == TYPE_INT) { - cfg.job_id[i] = nv->value; + if (nv->valuetype == TYPE_INTEGER) { + cfg.job_id[i] = nv->value_int; nv->index = job_start + i; // index of the SR persistence location nv_persist(nv); } else { diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index 2ff03bb8..dba5eae5 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -414,9 +414,9 @@ stat_t sp_set_spo(nvObj_t *nv) { return(set_float_range(nv, spindle.override_fac // These are provided as a way to view and control spindles without using M commands stat_t sp_get_spc(nvObj_t *nv) { return(get_int(nv, spindle.state)); } -stat_t sp_set_spc(nvObj_t *nv) { return(spindle_control_immediate((spControl)nv->value)); } +stat_t sp_set_spc(nvObj_t *nv) { return(spindle_control_immediate((spControl)nv->value_int)); } stat_t sp_get_sps(nvObj_t *nv) { return(get_float(nv, spindle.speed)); } -stat_t sp_set_sps(nvObj_t *nv) { return(spindle_speed_immediate(nv->value)); } +stat_t sp_set_sps(nvObj_t *nv) { return(spindle_speed_immediate(nv->value_flt)); } /*********************************************************************************** * TEXT MODE SUPPORT diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 870072d0..b01868ac 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -841,19 +841,19 @@ stat_t st_set_tr(nvObj_t *nv) stat_t st_get_mi(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].microsteps)); } stat_t st_set_mi(nvObj_t *nv) { - if (nv->value <= 0) { + if (nv->value_int <= 0) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - uint8_t mi = (uint8_t)nv->value; + uint8_t mi = (uint8_t)nv->value_int; if ((mi != 1) && (mi != 2) && (mi != 4) && (mi != 8) && (mi != 16) && (mi != 32)) { nv_add_conditional_message((const char *)"*** WARNING *** Setting non-standard microstep value"); } // set it anyway, even if it's unsupported ritorno(set_int(nv, st_cfg.mot[_motor(nv->index)].microsteps, 1, 255)); _set_motor_steps_per_unit(nv); - _set_hw_microsteps(_motor(nv->index), (uint8_t)nv->value); + _set_hw_microsteps(_motor(nv->index), nv->value_int); return (STAT_OK); } @@ -867,19 +867,19 @@ stat_t st_set_su(nvObj_t *nv) { // Don't set a zero or negative value - just calculate based on sa, tr, and mi // This way, if STEPS_PER_UNIT is set to 0 it is unused and we get the computed value - if(nv->value <= 0) { - nv->value = _set_motor_steps_per_unit(nv); + if(nv->value_flt <= 0) { + nv->value_flt = _set_motor_steps_per_unit(nv); return(STAT_OK); } // Do unit conversion here because it's a reciprocal value (rather than process_incoming_float()) if (cm_get_units_mode(MODEL) == INCHES) { if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { - nv->value *= INCHES_PER_MM; + nv->value_flt *= INCHES_PER_MM; } } uint8_t m = _motor(nv->index); - st_cfg.mot[m].steps_per_unit = nv->value; + st_cfg.mot[m].steps_per_unit = nv->value_flt; st_cfg.mot[m].units_per_step = 1.0/st_cfg.mot[m].steps_per_unit; // Scale TR so all the other values make sense @@ -896,8 +896,8 @@ stat_t st_set_po(nvObj_t *nv) { return(set_int(nv, st_cfg.mot[_motor(nv->index)] // power management mode stat_t st_get_pm(nvObj_t *nv) { - nv->value = (float)Motors[_motor(nv->index)]->getPowerMode(); - nv->valuetype = TYPE_INT; + nv->value_int = (float)Motors[_motor(nv->index)]->getPowerMode(); + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } @@ -906,7 +906,7 @@ stat_t st_set_pm(nvObj_t *nv) // Test the value without setting it, then setPowerMode() now // to both set and take effect immediately. ritorno(set_int(nv, (uint8_t &)cs.null, 0, MOTOR_POWER_MODE_MAX_VALUE )); - Motors[_motor(nv->index)]->setPowerMode((stPowerMode)nv->value); + Motors[_motor(nv->index)]->setPowerMode((stPowerMode)nv->value_int); return (STAT_OK); } @@ -923,7 +923,7 @@ stat_t st_set_pl(nvObj_t *nv) { uint8_t m = _motor(nv->index); ritorno(set_float_range(nv, st_cfg.mot[m].power_level, 0.0, 1.0)); - st_cfg.mot[m].power_level_scaled = (nv->value * POWER_LEVEL_SCALE_FACTOR); + st_cfg.mot[m].power_level_scaled = (nv->value_flt * POWER_LEVEL_SCALE_FACTOR); st_run.mot[m].power_level_dynamic = (st_cfg.mot[m].power_level_scaled); Motors[m]->setPowerLevel(st_cfg.mot[m].power_level_scaled); return(STAT_OK); @@ -942,7 +942,7 @@ stat_t st_get_pwr(nvObj_t *nv) uint8_t motor = (cfgArray[nv->index].token[3] & 0x0F) - 1; if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; - nv->value = Motors[motor]->getCurrentPowerLevel(motor); + nv->value_flt = Motors[motor]->getCurrentPowerLevel(motor); nv->valuetype = TYPE_FLOAT; nv->precision = cfgArray[nv->index].precision; return (STAT_OK); @@ -972,7 +972,7 @@ stat_t st_set_mt(nvObj_t *nv) { return(set_float_range(nv, st_cfg.motor_power_ti stat_t st_set_me(nvObj_t *nv) { for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { - Motors[motor]->enable(nv->value); // nv->value is the timeout or 0 for default + Motors[motor]->enable(nv->value_int); // nv->value is the timeout or 0 for default } return (STAT_OK); } @@ -981,29 +981,29 @@ stat_t st_set_me(nvObj_t *nv) // nv-value is motor to disable, or 0 for all motors stat_t st_set_md(nvObj_t *nv) { - if (nv->value < 0) { + if (nv->value_int < 0) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > MOTORS) { + if (nv->value_int > MOTORS) { nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } // de-energize all motors - if ((uint8_t)nv->value == 0) { // 0 means all motors + if ((uint8_t)nv->value_int == 0) { // 0 means all motors for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { Motors[motor]->disable(); } } else { // otherwise it's just one motor - Motors[(uint8_t)nv->value -1]->disable(); + Motors[(uint8_t)nv->value_int -1]->disable(); } return (STAT_OK); } stat_t st_get_dw(nvObj_t *nv) { - nv->value = st_run.dwell_ticks_downcount; - nv->valuetype = TYPE_INT; + nv->value_int = st_run.dwell_ticks_downcount; + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } @@ -1039,25 +1039,25 @@ void st_print_mt(nvObj_t *nv) { text_print(nv, fmt_mt);} // TYPE_FLOAT static void _print_motor_int(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, (int)nv->value); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, (int)nv->value_int); xio_writeline(cs.out_buf); } static void _print_motor_flt(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value_flt); xio_writeline(cs.out_buf); } static void _print_motor_flt_units(nvObj_t *nv, const char *format, uint8_t units) { - sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value, GET_TEXT_ITEM(msg_units, units)); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->group, nv->value_flt, GET_TEXT_ITEM(msg_units, units)); xio_writeline(cs.out_buf); } static void _print_motor_pwr(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, nv->group, nv->token, nv->token[0], nv->value); + sprintf(cs.out_buf, format, nv->group, nv->token, nv->token[0], nv->value_flt); xio_writeline(cs.out_buf); } diff --git a/g2core/temperature.cpp b/g2core/temperature.cpp index 09af8221..8539e78e 100644 --- a/g2core/temperature.cpp +++ b/g2core/temperature.cpp @@ -602,18 +602,19 @@ char _get_heater_number(nvObj_t *nv) { stat_t cm_get_heater_enable(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._enable; break; } - case '2': { nv->value = pid2._enable; break; } - case '3': { nv->value = pid3._enable; break; } + case '1': { nv->value_int = pid1._enable; break; } + case '2': { nv->value_int = pid2._enable; break; } + case '3': { nv->value_int = pid3._enable; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. default: { return(STAT_INPUT_VALUE_RANGE_ERROR); break; } } - nv->valuetype = TYPE_BOOL; + nv->valuetype = TYPE_BOOLEAN; return (STAT_OK); } stat_t cm_set_heater_enable(nvObj_t *nv) { +/* bool enable = false; if (nv->value > 1) { // testing a boolean value return (STAT_INPUT_VALUE_RANGE_ERROR); @@ -621,16 +622,20 @@ stat_t cm_set_heater_enable(nvObj_t *nv) if (nv->value > 0.1) { enable = true; } +*/ // The above manipulation of 'enable' was necessary because the compiler won't accept this cast: // pid1._enable = (bool)nv->value; // says it's unsafe to compare ==, != an FP number switch(_get_heater_number(nv)) { - // case '1': { pid1._enable = (bool)nv->value; break; } - // case '2': { pid2._enable = (bool)nv->value; break; } - // case '3': { pid3._enable = (bool)nv->value; break; } - case '1': { pid1._enable = enable; break; } - case '2': { pid2._enable = enable; break; } - case '3': { pid3._enable = enable; break; } + // case '1': { pid1._enable = (bool)nv->value; break; } + // case '2': { pid2._enable = (bool)nv->value; break; } + // case '3': { pid3._enable = (bool)nv->value; break; } +// case '1': { pid1._enable = enable; break; } +// case '2': { pid2._enable = enable; break; } +// case '3': { pid3._enable = enable; break; } + case '1': { pid1._enable = nv->value_int; break; } + case '2': { pid2._enable = nv->value_int; break; } + case '3': { pid3._enable = nv->value_int; break; } default: { return(STAT_INPUT_VALUE_RANGE_ERROR); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. } return (STAT_OK); @@ -643,29 +648,27 @@ stat_t cm_get_heater_p(nvObj_t *nv) { // there are three of them, so we can use a simple switch switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._p_factor * 100.0; break; } - case '2': { nv->value = pid2._p_factor * 100.0; break; } - case '3': { nv->value = pid3._p_factor * 100.0; break; } + case '1': { nv->value_flt = pid1._p_factor * 100.0; break; } + case '2': { nv->value_flt = pid2._p_factor * 100.0; break; } + case '3': { nv->value_flt = pid3._p_factor * 100.0; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } stat_t cm_set_heater_p(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { pid1._p_factor = nv->value / 100.0; break; } - case '2': { pid2._p_factor = nv->value / 100.0; break; } - case '3': { pid3._p_factor = nv->value / 100.0; break; } + case '1': { pid1._p_factor = nv->value_flt / 100.0; break; } + case '2': { pid2._p_factor = nv->value_flt / 100.0; break; } + case '3': { pid3._p_factor = nv->value_flt / 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. + // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -676,30 +679,27 @@ stat_t cm_get_heater_i(nvObj_t *nv) { // there are three of them, so we can use a simple switch switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._i_factor * 100.0; break; } - case '2': { nv->value = pid2._i_factor * 100.0; break; } - case '3': { nv->value = pid3._i_factor * 100.0; break; } + case '1': { nv->value_flt = pid1._i_factor * 100.0; break; } + case '2': { nv->value_flt = pid2._i_factor * 100.0; break; } + case '3': { nv->value_flt = pid3._i_factor * 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + // Failsafe. We can only get here if we set it up in config_app, but not here. + default: { nv->value_flt = 0.0; break; } } - nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } stat_t cm_set_heater_i(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { pid1._i_factor = nv->value / 100.0; break; } - case '2': { pid2._i_factor = nv->value / 100.0; break; } - case '3': { pid3._i_factor = nv->value / 100.0; break; } + case '1': { pid1._i_factor = nv->value_flt / 100.0; break; } + case '2': { pid2._i_factor = nv->value_flt / 100.0; break; } + case '3': { pid3._i_factor = nv->value_flt / 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. + // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -709,26 +709,25 @@ stat_t cm_set_heater_i(nvObj_t *nv) stat_t cm_get_heater_d(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._d_factor * 100.0; break; } - case '2': { nv->value = pid2._d_factor * 100.0; break; } - case '3': { nv->value = pid3._d_factor * 100.0; break; } + case '1': { nv->value_flt = pid1._d_factor * 100.0; break; } + case '2': { nv->value_flt = pid2._d_factor * 100.0; break; } + case '3': { nv->value_flt = pid3._d_factor * 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + // Failsafe. We can only get here if we set it up in config_app, but not here. + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } stat_t cm_set_heater_d(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { pid1._d_factor = nv->value / 100.0; break; } - case '2': { pid2._d_factor = nv->value / 100.0; break; } - case '3': { pid3._d_factor = nv->value / 100.0; break; } + case '1': { pid1._d_factor = nv->value_flt / 100.0; break; } + case '2': { pid2._d_factor = nv->value_flt / 100.0; break; } + case '3': { pid3._d_factor = nv->value_flt / 100.0; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. + // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } return (STAT_OK); @@ -740,30 +739,27 @@ stat_t cm_set_heater_d(nvObj_t *nv) stat_t cm_get_set_temperature(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._set_point; break; } - case '2': { nv->value = pid2._set_point; break; } - case '3': { nv->value = pid3._set_point; break; } + case '1': { nv->value_flt = pid1._set_point; break; } + case '2': { nv->value_flt = pid2._set_point; break; } + case '3': { nv->value_flt = pid3._set_point; break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + // Failsafe. We can only get here if we set it up in config_app, but not here. + default: { nv->value_flt = 0.0; break; } } - nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } stat_t cm_set_set_temperature(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { pid1._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; } - case '2': { pid2._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; } - case '3': { pid3._set_point = min(TEMP_MAX_SETPOINT, nv->value); break; } + case '1': { pid1._set_point = min(TEMP_MAX_SETPOINT, nv->value_flt); break; } + case '2': { pid2._set_point = min(TEMP_MAX_SETPOINT, nv->value_flt); break; } + case '3': { pid3._set_point = min(TEMP_MAX_SETPOINT, nv->value_flt); break; } - // Failsafe. We can only get here if we set it up in config_app, but not here. + // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -773,30 +769,28 @@ stat_t cm_set_set_temperature(nvObj_t *nv) stat_t cm_get_fan_power(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = min(1.0f, heater_fan1.max_value); break; } -// case '2': { nv->value = min(1.0f, heater_fan2.max_value); break; } -// case '3': { nv->value = min(1.0f, heater_fan3.max_value); break; } + case '1': { nv->value_flt = min(1.0f, heater_fan1.max_value); break; } +// case '2': { nv->value_flt = min(1.0f, heater_fan2.max_value); break; } +// case '3': { nv->value_flt = min(1.0f, heater_fan3.max_value); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } - nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } + stat_t cm_set_fan_power(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { heater_fan1.max_value = max(0.0f, nv->value); break; } -// case '2': { heater_fan2.max_value = max(0.0, nv->value); break; } -// case '3': { heater_fan3.max_value = max(0.0, nv->value); break; } + case '1': { heater_fan1.max_value = max(0.0f, nv->value_flt); break; } +// case '2': { heater_fan2.max_value = max(0.0, nv->value_flt); break; } +// case '3': { heater_fan3.max_value = max(0.0, nv->value_flt); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -806,30 +800,28 @@ stat_t cm_set_fan_power(nvObj_t *nv) stat_t cm_get_fan_min_power(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = heater_fan1.min_value; break; } -// case '2': { nv->value = heater_fan2.min_value; break; } -// case '3': { nv->value = heater_fan3.min_value; break; } + case '1': { nv->value_flt = heater_fan1.min_value; break; } +// case '2': { nv->value_flt = heater_fan2.min_value; break; } +// case '3': { nv->value_flt = heater_fan3.min_value; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } - nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } + stat_t cm_set_fan_min_power(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { heater_fan1.max_value = min(0.0f, nv->value); break; } -// case '2': { heater_fan2.min_value = min(0.0, nv->value); break; } -// case '3': { heater_fan3.min_value = min(0.0, nv->value); break; } + case '1': { heater_fan1.max_value = min(0.0f, nv->value_flt); break; } +// case '2': { heater_fan2.min_value = min(0.0, nv->value_flt); break; } +// case '3': { heater_fan3.min_value = min(0.0, nv->value_flt); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -839,30 +831,28 @@ stat_t cm_set_fan_min_power(nvObj_t *nv) stat_t cm_get_fan_low_temp(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = heater_fan1.low_temp; break; } -// case '2': { nv->value = heater_fan2.low_temp; break; } -// case '3': { nv->value = heater_fan3.low_temp; break; } + case '1': { nv->value_flt = heater_fan1.low_temp; break; } +// case '2': { nv->value_flt = heater_fan2.low_temp; break; } +// case '3': { nv->value_flt = heater_fan3.low_temp; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } - } - + default: { nv->value_flt = 0.0; break; } + } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } + stat_t cm_set_fan_low_temp(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { heater_fan1.low_temp = min(0.0f, nv->value); break; } -// case '2': { heater_fan2.low_temp = min(0.0f, nv->value); break; } -// case '3': { heater_fan3.low_temp = min(0.0f, nv->value); break; } + case '1': { heater_fan1.low_temp = min(0.0f, nv->value_flt); break; } +// case '2': { heater_fan2.low_temp = min(0.0f, nv->value_flt); break; } +// case '3': { heater_fan3.low_temp = min(0.0f, nv->value_flt); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -872,30 +862,28 @@ stat_t cm_set_fan_low_temp(nvObj_t *nv) stat_t cm_get_fan_high_temp(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = heater_fan1.high_temp; break; } -// case '2': { nv->value = heater_fan2.high_temp; break; } -// case '3': { nv->value = heater_fan3.high_temp; break; } + case '1': { nv->value_flt = heater_fan1.high_temp; break; } +// case '2': { nv->value_flt = heater_fan2.high_temp; break; } +// case '3': { nv->value_flt = heater_fan3.high_temp; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } - nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } + stat_t cm_set_fan_high_temp(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { heater_fan1.high_temp = min(0.0f, nv->value); break; } -// case '2': { heater_fan2.high_temp = min(0.0f, nv->value); break; } -// case '3': { heater_fan3.high_temp = min(0.0f, nv->value); break; } + case '1': { heater_fan1.high_temp = min(0.0f, nv->value_flt); break; } +// case '2': { heater_fan2.high_temp = min(0.0f, nv->value_flt); break; } +// case '3': { heater_fan3.high_temp = min(0.0f, nv->value_flt); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. default: { break; } } - return (STAT_OK); } @@ -905,37 +893,32 @@ stat_t cm_set_fan_high_temp(nvObj_t *nv) stat_t cm_get_at_temperature(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = pid1._at_set_point; break; } - case '2': { nv->value = pid2._at_set_point; break; } - case '3': { nv->value = pid3._at_set_point; break; } + case '1': { nv->value_int = pid1._at_set_point; break; } + case '2': { nv->value_int = pid2._at_set_point; break; } + case '3': { nv->value_int = pid3._at_set_point; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_int = 0; break; } } - - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_BOOL; - + nv->valuetype = TYPE_BOOLEAN; return (STAT_OK); } - /* * cm_get_heater_output() - get the output value (PWM duty cycle) of the PID */ stat_t cm_get_heater_output(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = (float)fet_pin1; break; } - case '2': { nv->value = (float)fet_pin2; break; } - case '3': { nv->value = (float)fet_pin3; break; } + case '1': { nv->value_flt = (float)fet_pin1; break; } + case '2': { nv->value_flt = (float)fet_pin2; break; } + case '3': { nv->value_flt = (float)fet_pin3; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } @@ -945,16 +928,15 @@ stat_t cm_get_heater_output(nvObj_t *nv) stat_t cm_get_heater_adc(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = (float)thermistor1.raw_adc_value; break; } - case '2': { nv->value = (float)thermistor2.raw_adc_value; break; } - case '3': { nv->value = (float)thermistor3.raw_adc_value; break; } + case '1': { nv->value_flt = (float)thermistor1.raw_adc_value; break; } + case '2': { nv->value_flt = (float)thermistor2.raw_adc_value; break; } + case '3': { nv->value_flt = (float)thermistor3.raw_adc_value; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } @@ -964,17 +946,15 @@ stat_t cm_get_heater_adc(nvObj_t *nv) stat_t cm_get_temperature(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = last_reported_temp1 = thermistor1.temperature_exact(); break; } - case '2': { nv->value = last_reported_temp2 = thermistor2.temperature_exact(); break; } - case '3': { nv->value = last_reported_temp3 = thermistor3.temperature_exact(); break; } + case '1': { nv->value_flt = last_reported_temp1 = thermistor1.temperature_exact(); break; } + case '2': { nv->value_flt = last_reported_temp2 = thermistor2.temperature_exact(); break; } + case '3': { nv->value_flt = last_reported_temp3 = thermistor3.temperature_exact(); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } - nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } @@ -984,21 +964,18 @@ stat_t cm_get_temperature(nvObj_t *nv) stat_t cm_get_thermistor_resistance(nvObj_t *nv) { switch(_get_heater_number(nv)) { - case '1': { nv->value = thermistor1.get_resistance(); break; } - case '2': { nv->value = thermistor2.get_resistance(); break; } - case '3': { nv->value = thermistor3.get_resistance(); break; } + case '1': { nv->value_flt = thermistor1.get_resistance(); break; } + case '2': { nv->value_flt = thermistor2.get_resistance(); break; } + case '3': { nv->value_flt = thermistor3.get_resistance(); break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } - - // In these functions, nv->group == "pid1", "pid2", or "pid3" char _get_pid_number(nvObj_t *nv) { if (!nv->group[0]) { @@ -1014,16 +991,15 @@ char _get_pid_number(nvObj_t *nv) { stat_t cm_get_pid_p(nvObj_t *nv) { switch(_get_pid_number(nv)) { - case '1': { nv->value = pid1._proportional; break; } - case '2': { nv->value = pid2._proportional; break; } - case '3': { nv->value = pid3._proportional; break; } + case '1': { nv->value_flt = pid1._proportional; break; } + case '2': { nv->value_flt = pid2._proportional; break; } + case '3': { nv->value_flt = pid3._proportional; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } @@ -1033,16 +1009,15 @@ stat_t cm_get_pid_p(nvObj_t *nv) stat_t cm_get_pid_i(nvObj_t *nv) { switch(_get_pid_number(nv)) { - case '1': { nv->value = pid1._integral; break; } - case '2': { nv->value = pid2._integral; break; } - case '3': { nv->value = pid3._integral; break; } + case '1': { nv->value_flt = pid1._integral; break; } + case '2': { nv->value_flt = pid2._integral; break; } + case '3': { nv->value_flt = pid3._integral; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } @@ -1052,16 +1027,15 @@ stat_t cm_get_pid_i(nvObj_t *nv) stat_t cm_get_pid_d(nvObj_t *nv) { switch(_get_pid_number(nv)) { - case '1': { nv->value = pid1._derivative; break; } - case '2': { nv->value = pid2._derivative; break; } - case '3': { nv->value = pid3._derivative; break; } + case '1': { nv->value_flt = pid1._derivative; break; } + case '2': { nv->value_flt = pid2._derivative; break; } + case '3': { nv->value_flt = pid3._derivative; break; } // Failsafe. We can only get here if we set it up in config_app, but not here. - default: { nv->value = 0.0; break; } + default: { nv->value_flt = 0.0; break; } } nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; - return (STAT_OK); } diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index 2757f0fa..7dd2f844 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -121,9 +121,10 @@ static stat_t _text_parser_kernal(char *str, nvObj_t *nv) *rd = NUL; // terminate at end of name strncpy(nv->token, str, TOKEN_LEN); str = ++rd; - nv->value = strtof(str, &rd); // rd used as end pointer + nv->value_int = atol(str); // collect the number as an integer + nv->value_flt = strtof(str, &rd); // collect the number as a float - rd used as end pointer if (rd != str) { - nv->valuetype = TYPE_FLOAT; + nv->valuetype = TYPE_FLOAT; // provisionally set it as a float } } @@ -132,6 +133,7 @@ static stat_t _text_parser_kernal(char *str, nvObj_t *nv) return (STAT_UNRECOGNIZED_NAME); } strcpy(nv->group, cfgArray[nv->index].group); // capture the group string if there is one + nv_coerce_types(nv); // adjust types based on type fields in configApp table // see if you need to strip the token - but only if in text mode if ((cs.comm_request_mode == TEXT_MODE) && (nv_group_is_prefixed(nv->group))) { @@ -218,9 +220,9 @@ void tx_print_flt(nvObj_t *nv) { text_print_flt(nv, fmt_flt);} void tx_print(nvObj_t *nv) { switch ((int8_t)nv->valuetype) { - case TYPE_FLOAT: { text_print_flt(nv, fmt_flt); break;} - case TYPE_INT: { text_print_int(nv, fmt_int); break;} - case TYPE_STRING:{ text_print_str(nv, fmt_str); break;} + case TYPE_FLOAT: { text_print_flt(nv, fmt_flt); break;} + case TYPE_INTEGER: { text_print_int(nv, fmt_int); break;} + case TYPE_STRING: { text_print_str(nv, fmt_str); break;} // TYPE_NULL is not needed in this list as it does nothing } } @@ -244,35 +246,36 @@ void text_print_str(nvObj_t *nv, const char *format) void text_print_int(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, (uint32_t)nv->value); + sprintf(cs.out_buf, format, nv->value_int); xio_writeline(cs.out_buf); } void text_print_flt(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, nv->value); + sprintf(cs.out_buf, format, nv->value_flt); xio_writeline(cs.out_buf); } void text_print_flt_units(nvObj_t *nv, const char *format, const char *units) { - sprintf(cs.out_buf, format, nv->value, units); + sprintf(cs.out_buf, format, nv->value_flt, units); xio_writeline(cs.out_buf); } void text_print_bool(nvObj_t *nv, const char *format) { - sprintf(cs.out_buf, format, !!((uint32_t)nv->value)?"True":"False"); +// sprintf(cs.out_buf, format, !!((uint32_t)nv->value)?"True":"False"); + sprintf(cs.out_buf, format, (nv->value_int ? "True" : "False")); xio_writeline(cs.out_buf); } void text_print(nvObj_t *nv, const char *format) { switch ((int8_t)nv->valuetype) { - case TYPE_NULL: { text_print_nul(nv, format); break;} - case TYPE_FLOAT: { text_print_flt(nv, format); break;} - case TYPE_INT: { text_print_int(nv, format); break;} - case TYPE_STRING:{ text_print_str(nv, format); break;} - case TYPE_BOOL: { text_print_bool(nv, format); break;} + case TYPE_NULL: { text_print_nul(nv, format); break;} + case TYPE_FLOAT: { text_print_flt(nv, format); break;} + case TYPE_INTEGER: { text_print_int(nv, format); break;} + case TYPE_STRING: { text_print_str(nv, format); break;} + case TYPE_BOOLEAN: { text_print_bool(nv, format); break;} } } From d7334e8a2dde6799478813e910f8720ed4170883 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 06:31:38 -0400 Subject: [PATCH 211/283] Fixed problem in sr_set_status_report(); fixed some compiler cast warnings --- g2core/canonical_machine.cpp | 2 +- g2core/config.h | 34 +--------------------------------- g2core/gpio.cpp | 2 +- g2core/report.cpp | 11 ++++++----- g2core/report.h | 1 - 5 files changed, 9 insertions(+), 41 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0d00b671..630c545c 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2495,7 +2495,7 @@ static void _print_hom(nvObj_t *nv, const char *format) void cm_print_am(nvObj_t *nv) // print axis mode with enumeration string { - sprintf(cs.out_buf, fmt_Xam, nv->group, nv->token, nv->group, nv->value_int, + sprintf(cs.out_buf, fmt_Xam, nv->group, nv->token, nv->group, (int)nv->value_int, GET_TEXT_ITEM(msg_am, nv->value_int)); xio_writeline(cs.out_buf); } diff --git a/g2core/config.h b/g2core/config.h index 65b793a9..38d3ce01 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -279,38 +279,6 @@ typedef enum { // value typing for config and JSON #define _fipi (TYPE_FLOAT | F_INITIALIZE | F_PERSIST | F_ICONVERT) #define _fipnc (TYPE_FLOAT | F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) -#define _t0 (TYPE_TXTCON) - -/* -#define _f0 0x00 -#define _fi (F_INITIALIZE) -#define _fp (F_PERSIST) -#define _fn (F_NOSTRIP) -#define _fc (F_CONVERT) -#define _fic (F_INITIALIZE | F_CONVERT) -#define _fip (F_INITIALIZE | F_PERSIST) -//#define _fiz (F_INITIALIZE | F_ZERO) -//#define _fizc (F_INITIALIZE | F_ZERO | F_CONVERT) -#define _fipc (F_INITIALIZE | F_PERSIST | F_CONVERT) -#define _fipn (F_INITIALIZE | F_PERSIST | F_NOSTRIP) -#define _fipi (F_INITIALIZE | F_PERSIST | F_ICONVERT) -#define _fipnc (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) - -#define _i0 (F_TYPE_INTEGER) -#define _ii (F_TYPE_INTEGER) | (F_INITIALIZE) -#define _ip (F_TYPE_INTEGER) | (F_PERSIST) -#define _in (F_TYPE_INTEGER) | (F_NOSTRIP) -#define _ic (F_TYPE_INTEGER) | (F_CONVERT) -#define _iic (F_TYPE_INTEGER) | (F_INITIALIZE | F_CONVERT) -#define _iip (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST) -#define _iiz (F_TYPE_INTEGER) | (F_INITIALIZE | F_ZERO) -#define _iizc (F_TYPE_INTEGER) | (F_INITIALIZE | F_ZERO | F_CONVERT) -#define _iipc (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_CONVERT) -#define _iipn (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP) -#define _iipi (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_ICONVERT) -#define _iipnc (F_TYPE_INTEGER) | (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT) -*/ - /**** Structures ****/ typedef struct nvString { // shared string object @@ -443,7 +411,7 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving 8 bit integer value stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); -stat_t get_int32(nvObj_t *nv, const int32_t value); // boilerplate for retrieving 32 bit integer value +stat_t get_int32(nvObj_t *nv, const int32_t value); // boilerplate for retrieving 32 bit integer value stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high); stat_t get_string(nvObj_t *nv, const char *str); diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index ecae09d9..de6f04df 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -712,7 +712,7 @@ stat_t io_set_output(nvObj_t *nv) void io_print_domode(nvObj_t *nv) {_print_di(nv, fmt_gpio_domode);} void io_print_out(nvObj_t *nv) { - sprintf(cs.out_buf, fmt_gpio_out, nv->token, nv->value_int); + sprintf(cs.out_buf, fmt_gpio_out, nv->token, (int)nv->value_int); xio_writeline(cs.out_buf); } #endif diff --git a/g2core/report.cpp b/g2core/report.cpp index 9bbaa05b..e165b690 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -183,13 +183,15 @@ void sr_init_status_report() sr.status_report_request = SR_OFF; char sr_defaults[NV_STATUS_REPORT_LEN][TOKEN_LEN+1] = { STATUS_REPORT_DEFAULTS }; nv->index = nv_get_index((const char *)"", (char *)"se00"); // set first SR persistence index + + // record the index of the "stat" variable so we can use it during reporting sr.stat_index = nv_get_index((const char *)"", (const char *)"stat"); + // setup the status report array for (uint8_t i=0; i < NV_STATUS_REPORT_LEN ; i++) { if (sr_defaults[i][0] == NUL) break; // quit on first blank array entry sr.status_report_value[i] = -1234567; // pre-load values with an unlikely number nv->value_int = nv_get_index((const char *)"", sr_defaults[i]);// load the index for the SR element -// if (fp_EQ(nv->value, NO_MATCH)) { if (nv->value_int == NO_MATCH) { rpt_exception(STAT_BAD_STATUS_REPORT_SETTING, "sr_init_status_report() encountered bad SR setting"); // trap mis-configured profile settings return; @@ -198,12 +200,10 @@ void sr_init_status_report() nv_persist(nv); // conditionally persist - automatic by nv_persist() nv->index++; // increment SR NVM index } - // record the index of the "stat" variable so we can use it during reporting - sr.index_of_stat_variable = nv_get_index((const char *)"", (const char *)"stat"); } /* - * sr_set_status_report() - interpret an SR setup string and return current report + * sr_set_status_report() - read a list of NV pairs to set up SRs and return a report * * Note: By the time this function is called any unrecognized tokens have been detected and * rejected by the JSON or text parser. In other words, it should never get to here if @@ -221,7 +221,8 @@ stat_t sr_set_status_report(nvObj_t *nv) if (((nv = nv->nx) == NULL) || (nv->valuetype == TYPE_EMPTY)) { break; } - if ((nv->valuetype == TYPE_BOOLEAN) && nv->value_int) { + // Note: valuetype may have been coerced from boolean to something else, so just treat value_int as a bool + if (nv->value_int) { status_report_list[i] = nv->index; nv->value_int = nv->index; // persist the index as the value nv->index = sr_start + i; // index of the SR persistence location diff --git a/g2core/report.h b/g2core/report.h index 197a32e8..3cd72805 100644 --- a/g2core/report.h +++ b/g2core/report.h @@ -66,7 +66,6 @@ typedef struct srSingleton { /*** runtime values (PRIVATE) ***/ srVerbosity status_report_request; // flag that SR has been requested, and what type uint32_t status_report_systick; // SysTick value for next status report - index_t index_of_stat_variable; // like it says, the index of the "stat" variable index_t stat_index; // table index value for stat - determined during initialization uint8_t throttle_counter; // slow down SRs when in a constrained time (not phat_city) index_t status_report_list[NV_STATUS_REPORT_LEN]; // status report elements to report From 5c451cfcb4641c533b6b833b896928aa314ba042 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 07:18:26 -0400 Subject: [PATCH 212/283] Fixed Gcode parser to preserve large line numbers --- g2core/canonical_machine.cpp | 7 ++++--- g2core/gcode_parser.cpp | 16 +++++++++------- g2core/json_parser.cpp | 3 +-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 630c545c..9c9f6ca2 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -352,10 +352,11 @@ void cm_set_model_linenum(uint32_t linenum) { if (linenum < 0) { linenum = 0; - rpt_exception(STAT_INPUT_LESS_THAN_MIN_VALUE, "line number is negative; set of zero"); + rpt_exception(STAT_INPUT_LESS_THAN_MIN_VALUE, "line number is negative; set to zero"); } else - if (linenum > MAX_FP_INTEGER) { // see util.h - rpt_exception(STAT_INPUT_EXCEEDS_MAX_VALUE, "line number > 8,388,608; may be inexact"); + if (linenum >= MAX_LONG) { // see util.h + linenum = 0; + rpt_exception(STAT_INPUT_EXCEEDS_MAX_VALUE, "line number > 2.1 billion; set to zero"); } cm->gm.linenum = linenum; // you must first set the model line number, nv_add_object((const char *)"n"); // then add the line number to the nv list diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 4d6983a7..8564dc50 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -34,7 +34,7 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context uint8_t next_action; // handles G modal group 1 moves & non-modals cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89 uint8_t program_flow; // used only by the gcode_parser - uint32_t linenum; // N word + int32_t linenum; // N word float target[AXES]; // XYZABC where the move should go float arc_offset[3]; // IJK - used by arc commands @@ -119,7 +119,7 @@ GCodeFlag_t gf; // gcode input flags // local helper functions and macros static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); -static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value); +static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value, int32_t *value_int); static stat_t _point(float value); static stat_t _validate_gcode_block(char *active_comment); static stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs @@ -435,7 +435,7 @@ static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *bl * G0X... is not interpreted as hexadecimal. This is trapped. */ -static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value) +static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value, int32_t *value_int) { if (**pstr == NUL) { return (STAT_COMPLETE); } // no more words @@ -450,17 +450,18 @@ static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value) if ((**pstr == '0') && (*(*pstr+1) == 'X')) { *value = 0; (*pstr)++; - return (STAT_OK); // pointer points to X + return (STAT_OK); // pointer points to X } // get-value general case char *end; + *value_int = atol(*pstr); // needed to get an accurate line number for N > 8,388,608 *value = strtof(*pstr, &end); if(end == *pstr) { return(STAT_BAD_NUMBER_FORMAT); } // more robust test then checking for value=0; *pstr = end; - return (STAT_OK); // pointer points to next character after the word + return (STAT_OK); // pointer points to next character after the word } /* @@ -510,6 +511,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) char *pstr = (char *)buf; // persistent pointer into gcode block for parsing words char letter; // parsed letter, eg.g. G or X or Y float value = 0; // value parsed from letter (e.g. 2 for G2) + int32_t value_int = 0; // integer value parsed from letter - needed for line numbers stat_t status = STAT_OK; // set initial state for new move @@ -526,7 +528,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) } // extract commands and parameters - while((status = _get_next_gcode_word(&pstr, &letter, &value)) == STAT_OK) { + while((status = _get_next_gcode_word(&pstr, &letter, &value, &value_int)) == STAT_OK) { switch(letter) { case 'G': switch((uint8_t)value) { @@ -678,7 +680,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 'K': SET_NON_MODAL (arc_offset[2], value); case 'L': SET_NON_MODAL (L_word, value); case 'R': SET_NON_MODAL (arc_radius, value); - case 'N': SET_NON_MODAL (linenum,(uint32_t)value); // line number + case 'N': SET_NON_MODAL (linenum, value_int); // line number handled as special case to preserve integer value default: status = STAT_GCODE_COMMAND_UNSUPPORTED; } if(status != STAT_OK) break; diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 74cbb538..3627d96a 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -106,9 +106,8 @@ void json_parse_for_exec(char *str, bool execute) nvObj_t *nv = nv_reset_exec_nv_list(); // get a fresh nvObj list stat_t status = _json_parser_kernal(nv, str); if ((status == STAT_OK) && (execute)) { - // execute the command nv = nv_exec; - status = _json_parser_execute(nv); + status = _json_parser_execute(nv); // execute the command } } From dfbcc3f05078387cd84db6aece1b75d39af47407 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 08:22:08 -0400 Subject: [PATCH 213/283] Set max line number to 2,000,000,000; Passes all line number functional tests --- g2core/canonical_machine.cpp | 10 +++------- g2core/canonical_machine.h | 3 ++- g2core/g2core.cppproj | 4 ++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 9c9f6ca2..a95d86a2 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -348,15 +348,11 @@ void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_ cm_set_display_offsets(MODEL); // must reset offsets if you change absolute override } -void cm_set_model_linenum(uint32_t linenum) +void cm_set_model_linenum(int32_t linenum) { - if (linenum < 0) { + if ((linenum < 0) || (linenum > MAX_LINENUM)) { linenum = 0; - rpt_exception(STAT_INPUT_LESS_THAN_MIN_VALUE, "line number is negative; set to zero"); - } else - if (linenum >= MAX_LONG) { // see util.h - linenum = 0; - rpt_exception(STAT_INPUT_EXCEEDS_MAX_VALUE, "line number > 2.1 billion; set to zero"); + rpt_exception(STAT_INPUT_VALUE_RANGE_ERROR, "line number > 2B or negative; set to zero"); } cm->gm.linenum = linenum; // you must first set the model line number, nv_add_object((const char *)"n"); // then add the line number to the nv list diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 4c29f513..3cf2b4ef 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -50,6 +50,7 @@ #define JERK_INPUT_MAX (1000000) // maximum allowable jerk setting in millions mm/min^3 #define PROBES_STORED 3 // we store three probes for coordinate rotation computation #define RADIUS_MIN (0.0001) // minimum value for ABC radius settings +#define MAX_LINENUM 2000000000 // set 2 billion as max line number /***************************************************************************** * MACHINE STATE MODEL @@ -375,7 +376,7 @@ float cm_get_feed_rate(const GCodeState_t *gcode_state); void cm_set_motion_mode(GCodeState_t *gcode_state, const uint8_t motion_mode); void cm_set_tool_number(GCodeState_t *gcode_state, const uint8_t tool); void cm_set_absolute_override(GCodeState_t *gcode_state, const uint8_t absolute_override); -void cm_set_model_linenum(uint32_t linenum); +void cm_set_model_linenum(int32_t linenum); // Coordinate systems and offsets float cm_get_combined_offset(const uint8_t axis); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0014b2ec..bb1cf7a0 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 From 2a7a65efa5fbd4c535b9fbf0f1f9d39cab68bef9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 09:23:54 -0400 Subject: [PATCH 214/283] Passes all get/set regressions. Fixed type coercion on GETS (not supposed to happen); Failing digital inputs for some reason; re-organized cm_set_tram() to use the nv->value_int boolean value --- g2core/alarm.cpp | 1 - g2core/canonical_machine.cpp | 173 ++++++++++++++++------------------- g2core/config.cpp | 7 +- g2core/cycle_probing.cpp | 1 - g2core/json_parser.cpp | 2 +- g2core/text_parser.cpp | 4 +- 6 files changed, 87 insertions(+), 101 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 3251c6b9..975a6e48 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -235,7 +235,6 @@ stat_t cm_panic(const stat_t status, const char *msg) spindle_reset(); // stop spindle immediately and set speed to 0 RPM coolant_reset(); // stop coolant immediately temperature_reset(); // turn off heaters and fans -//+++++ cm_queue_flush(&cm1); // flush all queues and reset positions cm1.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable cm2.machine_state = MACHINE_PANIC; // don't reset anything. Panics are not recoverable diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a95d86a2..f74a5f9a 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -540,104 +540,93 @@ stat_t cm_deferred_write_callback() stat_t cm_set_tram(nvObj_t *nv) { - // Ah yes. If you call {tram:true} or any non-zero it will tram. Anything falsey will clear the tram. - if ((nv->valuetype == TYPE_BOOLEAN) || (nv->valuetype == TYPE_INTEGER) || (nv->valuetype == TYPE_FLOAT)) { - - bool do_set = !!(nv->value_int); - - // if passed false/0, we will clear the rotation matrix - if (!do_set) { - canonical_machine_reset_rotation(cm); - return (STAT_OK); - } - - // check to make sure we have three valid probes in a row - if ((cm->probe_state[0] == PROBE_SUCCEEDED) && - (cm->probe_state[1] == PROBE_SUCCEEDED) && - (cm->probe_state[2] == PROBE_SUCCEEDED)) - { - - // Step 1: Get the normal of the plane formed by the three probes. Naming: - // d0_{xyz} is the delta between point 0 and point 1 - // d2_{xyz} is the delta between point 2 and point 1 - // n_{xyz} is the unit normal - - // Step 1a: get the deltas - float d0_x = cm->probe_results[0][0] - cm->probe_results[1][0]; - float d0_y = cm->probe_results[0][1] - cm->probe_results[1][1]; - float d0_z = cm->probe_results[0][2] - cm->probe_results[1][2]; - float d2_x = cm->probe_results[2][0] - cm->probe_results[1][0]; - float d2_y = cm->probe_results[2][1] - cm->probe_results[1][1]; - float d2_z = cm->probe_results[2][2] - cm->probe_results[1][2]; - - // Step 1b: compute the combined magnitude - // since sqrt(a)*sqrt(b) = sqrt(a*b), we can save a sqrt in making the unit normal - float combined_magnitude_inv = 1.0/sqrt((d0_x*d0_x + d0_y*d0_y + d0_z*d0_z) * - (d2_x*d2_x + d2_y*d2_y + d2_z*d2_z)); - - // Step 1c: compute the cross product and normalize - float n_x = (d0_z*d2_y - d0_y*d2_z)*combined_magnitude_inv; - float n_y = (d0_x*d2_z - d0_z*d2_x)*combined_magnitude_inv; - float n_z = (d0_y*d2_x - d0_x*d2_y)*combined_magnitude_inv; - - // Step 1d: flip the normal if it's negative - if (n_z < 0.0) { - n_x = -n_x; - n_y = -n_y; - n_z = -n_z; - } - - // Step 2: make the quaternion for the rotation to {0,0,1} - float p = sqrt(n_x*n_x + n_y*n_y + n_z*n_z); - float m = sqrt(2.0)*sqrt(p*(p+n_z)); - float q_w = (n_z + p) / m; - float q_x = -n_y / m; - float q_y = n_x / m; - //float q_z = 0; // already optimized out - - // Step 3: compute the rotation matrix - float q_wx_2 = q_w * q_x * 2.0; - float q_wy_2 = q_w * q_y * 2.0; - float q_xx_2 = q_x * q_x * 2.0; - float q_xy_2 = q_x * q_y * 2.0; - float q_yy_2 = q_y * q_y * 2.0; - - /* - matrix = { - {1 - q_yy_2, q_xy_2, q_wy_2, 0}, - {q_xy_2, 1 - q_xx_2, -q_wx_2, 0}, - {-q_wy_2, q_wx_2, 1 - q_xx_2 - q_yy_2, i}, - {0, 0, 0, 1} - } - */ - cm->rotation_matrix[0][0] = 1 - q_yy_2; - cm->rotation_matrix[0][1] = q_xy_2; - cm->rotation_matrix[0][2] = q_wy_2; - - cm->rotation_matrix[1][0] = q_xy_2; - cm->rotation_matrix[1][1] = 1 - q_xx_2; - cm->rotation_matrix[1][2] = -q_wx_2; - - cm->rotation_matrix[2][0] = -q_wy_2; - cm->rotation_matrix[2][1] = q_wx_2; - cm->rotation_matrix[2][2] = 1 - q_xx_2 - q_yy_2; - - // Step 4: compute the z-offset - cm->rotation_z_offset = (n_x*cm->probe_results[1][0] + - n_y*cm->probe_results[1][1]) / - n_z + cm->probe_results[1][2]; - } else { - return (STAT_COMMAND_NOT_ACCEPTED); - } - } else { - return (STAT_INPUT_VALUE_RANGE_ERROR); + if (!nv->value_int) { // if false, reset the matrix and return + canonical_machine_reset_rotation(cm); + return (STAT_OK); } + + // check to make sure we have three valid probes in a row + if (!((cm->probe_state[0] == PROBE_SUCCEEDED) && + (cm->probe_state[1] == PROBE_SUCCEEDED) && + (cm->probe_state[2] == PROBE_SUCCEEDED))) { + return (STAT_COMMAND_NOT_ACCEPTED); // do not have 3 valid probes + } + + // Step 1: Get the normal of the plane formed by the three probes. Naming: + // d0_{xyz} is the delta between point 0 and point 1 + // d2_{xyz} is the delta between point 2 and point 1 + // n_{xyz} is the unit normal + + // Step 1a: get the deltas + float d0_x = cm->probe_results[0][0] - cm->probe_results[1][0]; + float d0_y = cm->probe_results[0][1] - cm->probe_results[1][1]; + float d0_z = cm->probe_results[0][2] - cm->probe_results[1][2]; + float d2_x = cm->probe_results[2][0] - cm->probe_results[1][0]; + float d2_y = cm->probe_results[2][1] - cm->probe_results[1][1]; + float d2_z = cm->probe_results[2][2] - cm->probe_results[1][2]; + + // Step 1b: compute the combined magnitude + // since sqrt(a)*sqrt(b) = sqrt(a*b), we can save a sqrt in making the unit normal + float combined_magnitude_inv = 1.0/sqrt((d0_x*d0_x + d0_y*d0_y + d0_z*d0_z) * + (d2_x*d2_x + d2_y*d2_y + d2_z*d2_z)); + + // Step 1c: compute the cross product and normalize + float n_x = (d0_z*d2_y - d0_y*d2_z)*combined_magnitude_inv; + float n_y = (d0_x*d2_z - d0_z*d2_x)*combined_magnitude_inv; + float n_z = (d0_y*d2_x - d0_x*d2_y)*combined_magnitude_inv; + + // Step 1d: flip the normal if it's negative + if (n_z < 0.0) { + n_x = -n_x; + n_y = -n_y; + n_z = -n_z; + } + + // Step 2: make the quaternion for the rotation to {0,0,1} + float p = sqrt(n_x*n_x + n_y*n_y + n_z*n_z); + float m = sqrt(2.0)*sqrt(p*(p+n_z)); + float q_w = (n_z + p) / m; + float q_x = -n_y / m; + float q_y = n_x / m; + //float q_z = 0; // already optimized out + + // Step 3: compute the rotation matrix + float q_wx_2 = q_w * q_x * 2.0; + float q_wy_2 = q_w * q_y * 2.0; + float q_xx_2 = q_x * q_x * 2.0; + float q_xy_2 = q_x * q_y * 2.0; + float q_yy_2 = q_y * q_y * 2.0; + + /* + matrix = { + {1 - q_yy_2, q_xy_2, q_wy_2, 0}, + {q_xy_2, 1 - q_xx_2, -q_wx_2, 0}, + {-q_wy_2, q_wx_2, 1 - q_xx_2 - q_yy_2, i}, + {0, 0, 0, 1} + } + */ + cm->rotation_matrix[0][0] = 1 - q_yy_2; + cm->rotation_matrix[0][1] = q_xy_2; + cm->rotation_matrix[0][2] = q_wy_2; + + cm->rotation_matrix[1][0] = q_xy_2; + cm->rotation_matrix[1][1] = 1 - q_xx_2; + cm->rotation_matrix[1][2] = -q_wx_2; + + cm->rotation_matrix[2][0] = -q_wy_2; + cm->rotation_matrix[2][1] = q_wx_2; + cm->rotation_matrix[2][2] = 1 - q_xx_2 - q_yy_2; + + // Step 4: compute the z-offset + cm->rotation_z_offset = (n_x*cm->probe_results[1][0] + + n_y*cm->probe_results[1][1]) / + n_z + cm->probe_results[1][2]; return (STAT_OK); } stat_t cm_get_tram(nvObj_t *nv) { - nv->value_int = true; + nv->value_int = true; // believe it or not, the compiler likes this form best - most efficient code if (fp_NOT_ZERO(cm->rotation_z_offset) || fp_NOT_ZERO(cm->rotation_matrix[0][1]) || diff --git a/g2core/config.cpp b/g2core/config.cpp index 272caf82..fe5f5906 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -214,7 +214,6 @@ stat_t get_nul(nvObj_t *nv) stat_t get_ui8(nvObj_t *nv) { -// nv->value = (float)*((uint8_t *)GET_TABLE_WORD(target)); nv->value_int = *((uint8_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_INTEGER; return (STAT_OK); @@ -222,7 +221,6 @@ stat_t get_ui8(nvObj_t *nv) stat_t get_int8(nvObj_t *nv) { -// nv->value = (float)*((int8_t *)GET_TABLE_WORD(target)); nv->value_int = *((int8_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_INTEGER; return (STAT_OK); @@ -230,7 +228,6 @@ stat_t get_int8(nvObj_t *nv) stat_t get_int32(nvObj_t *nv) { -// nv->value = *((uint32_t *)GET_TABLE_WORD(target)); nv->value_int = *((uint32_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_INTEGER; return (STAT_OK); @@ -340,7 +337,6 @@ stat_t set_0123(nvObj_t *nv) stat_t set_int32(nvObj_t *nv) { -// *((uint32_t *)GET_TABLE_WORD(target)) = (uint32_t)nv->value; +++++ *((uint32_t *)GET_TABLE_WORD(target)) = nv->value_int; nv->valuetype = TYPE_INTEGER; return(STAT_OK); @@ -508,6 +504,9 @@ uint8_t nv_get_type(nvObj_t *nv) */ void nv_coerce_types(nvObj_t *nv) { + if (nv->valuetype == TYPE_NULL) { // don't change type if it's a GET query + return; + } valueType type = (valueType)(cfgArray[nv->index].flags & F_TYPE_MASK); if (type == TYPE_INTEGER) { nv->valuetype = TYPE_INTEGER; // will pay attention to the int value, not the float diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index af0ff3a6..1fd4fda4 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -213,7 +213,6 @@ static stat_t _probe_move(const float target[], const bool flags[]) pb.waiting_for_motion_complete = true; // set this BEFORE the motion starts cm_straight_feed(target, flags, PROFILE_FAST); // NB: feed rate was set earlier, so it's OK mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway -// st_request_forward_plan(); //+++++ return (STAT_EAGAIN); } diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 3627d96a..65ebd177 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -169,7 +169,7 @@ static stat_t _json_parser_kernal(nvObj_t *nv, char *str) if ((nv_index_is_group(nv->index)) && (nv_group_is_prefixed(nv->token))) { strncpy(group, nv->token, GROUP_LEN); // record the group ID } - nv_coerce_types(nv); // set final types following _get_nv_pair + nv_coerce_types(nv); // adjust types based on type fields in configApp table if ((nv = nv->nx) == NULL) { return (STAT_JSON_TOO_MANY_PAIRS); // Not supposed to encounter a NULL } diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index 7dd2f844..8720109a 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -133,8 +133,8 @@ static stat_t _text_parser_kernal(char *str, nvObj_t *nv) return (STAT_UNRECOGNIZED_NAME); } strcpy(nv->group, cfgArray[nv->index].group); // capture the group string if there is one - nv_coerce_types(nv); // adjust types based on type fields in configApp table - + nv_coerce_types(nv); // adjust types based on type fields in configApp table + // see if you need to strip the token - but only if in text mode if ((cs.comm_request_mode == TEXT_MODE) && (nv_group_is_prefixed(nv->group))) { wr = nv->token; From fc209a4cf29dcfda4ea2f92e9854975c129f3f62 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 16:20:23 -0400 Subject: [PATCH 215/283] Gpio changes and updates; removed some unused getters and setters --- g2core/board/G2v9/G2v9k-pinout.h | 6 +- g2core/canonical_machine.cpp | 1 + g2core/canonical_machine.h | 1 + g2core/config.cpp | 133 +++++------------------ g2core/config.h | 20 ++-- g2core/config_app.cpp | 111 +++++++++---------- g2core/gpio.cpp | 177 +++++++++++++------------------ g2core/gpio.h | 17 +-- g2core/report.cpp | 2 +- 9 files changed, 179 insertions(+), 289 deletions(-) diff --git a/g2core/board/G2v9/G2v9k-pinout.h b/g2core/board/G2v9/G2v9k-pinout.h index b41aa851..047bf9a2 100644 --- a/g2core/board/G2v9/G2v9k-pinout.h +++ b/g2core/board/G2v9/G2v9k-pinout.h @@ -3,8 +3,8 @@ * For: /board/g2v9 * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2017 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -95,7 +95,7 @@ #define TEMPERATURE_OUTPUT_ON 0 // Some pins, if the PWM capability is turned on, it will cause timer conflicts. -// So we have to explicity enable them as PWM pins. +// So we have to explicitly enable them as PWM pins. // Generated with: // perl -e 'for($i=1;$i<14;$i++) { print "#define OUTPUT${i}_PWM 0\n";}' #define OUTPUT1_PWM 0 diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f74a5f9a..c940f8ae 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1992,6 +1992,7 @@ stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_ax stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } +stat_t cm_get_g92e(nvObj_t *nv) { return (get_int(nv, cm->gmx.origin_offset_enable)); } stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv)])); } stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv)])); } stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv)])); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 3cf2b4ef..de1909eb 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -571,6 +571,7 @@ stat_t cm_get_ofs(nvObj_t *nv); // get runtime work offset stat_t cm_get_coord(nvObj_t *nv); // get coordinate offset stat_t cm_set_coord(nvObj_t *nv); // set coordinate offset +stat_t cm_get_g92e(nvObj_t *nv); // get g92 enable state stat_t cm_get_g92(nvObj_t *nv); // get g92 offset stat_t cm_get_g28(nvObj_t *nv); // get g28 offset stat_t cm_get_g30(nvObj_t *nv); // get g30 offset diff --git a/g2core/config.cpp b/g2core/config.cpp index fe5f5906..a8b9bad1 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -125,20 +125,16 @@ void config_init() static void _set_defa(nvObj_t *nv, bool print) { - cm_set_units_mode(MILLIMETERS); // must do inits in MM mode + cm_set_units_mode(MILLIMETERS); // must do inits in MM mode for (nv->index=0; nv_index_is_single(nv->index); nv->index++) { if (cfgArray[nv->index].flags & F_INITIALIZE) { -// if (cfgArray[nv->index].flags & F_ZERO) { -// nv->value = 0; -// } else { if ((cfgArray[nv->index].flags & F_TYPE_MASK) == TYPE_INTEGER) { nv->value_int = cfgArray[nv->index].def_value; } else { nv->value_flt = cfgArray[nv->index].def_value; } -// } strncpy(nv->token, cfgArray[nv->index].token, TOKEN_LEN); - cfgArray[nv->index].set(nv); // run the set method, nv_set(nv); + cfgArray[nv->index].set(nv); // run the set method, nv_set(nv); if (cfgArray[nv->index].flags & F_PERSIST) { nv_persist(nv); } @@ -162,7 +158,7 @@ stat_t set_defaults(nvObj_t *nv) // Mark the nv as $defa so it displays nicely in the response nv_reset_nv_list(); strncpy(nv->token, "defa", TOKEN_LEN); -// nv->index = nv_get_index("", nv->token); // correct, but not required +// nv->index = nv_get_index("", nv->token); // correct, but not required nv->valuetype = TYPE_INTEGER; // ++++ probably should be TYPE_BOOLEAN nv->value_int = true; return (STAT_OK); @@ -200,8 +196,6 @@ stat_t config_test_assertions() /* Generic gets() * get_nul() - get nothing (returns STAT_NOOP) - * get_ui8() - get value as 8 bit uint8_t (use uint8 for booleans) - * get_int8() - get value as 8 bit int8_t * get_int32() - get value as 32 bit integer * get_data() - get value as 32 bit integer blind cast * get_flt() - get value as float @@ -212,35 +206,13 @@ stat_t get_nul(nvObj_t *nv) return (STAT_NOOP); } -stat_t get_ui8(nvObj_t *nv) -{ - nv->value_int = *((uint8_t *)GET_TABLE_WORD(target)); - nv->valuetype = TYPE_INTEGER; - return (STAT_OK); -} - -stat_t get_int8(nvObj_t *nv) -{ - nv->value_int = *((int8_t *)GET_TABLE_WORD(target)); - nv->valuetype = TYPE_INTEGER; - return (STAT_OK); -} - stat_t get_int32(nvObj_t *nv) { - nv->value_int = *((uint32_t *)GET_TABLE_WORD(target)); + nv->value_int = *((int32_t *)GET_TABLE_WORD(target)); nv->valuetype = TYPE_INTEGER; return (STAT_OK); } -stat_t get_data(nvObj_t *nv) -{ - uint32_t *v = (uint32_t*)&nv->value_flt; - *v = *((uint32_t *)GET_TABLE_WORD(target)); - nv->valuetype = TYPE_DATA; - return (STAT_OK); -} - stat_t get_flt(nvObj_t *nv) { nv->value_flt= *((float *)GET_TABLE_WORD(target)); @@ -249,18 +221,21 @@ stat_t get_flt(nvObj_t *nv) return (STAT_OK); } +stat_t get_data(nvObj_t *nv) +{ + uint32_t *v = (uint32_t*)&nv->value_flt; + *v = *((uint32_t *)GET_TABLE_WORD(target)); + nv->valuetype = TYPE_DATA; + return (STAT_OK); +} + /* Generic sets() - * set_noop() - set nothing and return OK - * set_nul() - set nothing and return READ_ONLY error - * set_ro() - set nothing, return read-only error - * set_ui8() - set value as 8 bit uint8_t value - * set_int8() - set value as an 8 bit int8_t value - * set_01() - set a 0 or 1 uint8_t value with validation - * set_012() - set a 0, 1 or 2 uint8_t value with validation - * set_0123() - set a 0, 1, 2 or 3 uint8_t value with validation - * set_uint() - set value as 32 bit unsigned integer - * set_data() - set value as 32 bit integer blind cast - * set_flt() - set value as float + * set_noop() - set nothing and return OK + * set_nul() - set nothing and return READ_ONLY error + * set_ro() - set nothing, return read-only error + * set_int32() - set value as 32 bit unsigned integer + * set_flt() - set value as float + * set_data() - set value as 32 bit integer blind cast */ stat_t set_noop(nvObj_t *nv) { @@ -271,7 +246,6 @@ stat_t set_noop(nvObj_t *nv) { stat_t set_nul(nvObj_t *nv) { nv->valuetype = TYPE_NULL; return (STAT_PARAMETER_IS_READ_ONLY); // this is what it should be -// return (STAT_OK); // hack until JSON is refactored } stat_t set_ro(nvObj_t *nv) { @@ -282,74 +256,13 @@ stat_t set_ro(nvObj_t *nv) { return (STAT_PARAMETER_IS_READ_ONLY); } -stat_t set_ui8(nvObj_t *nv) -{ - *((uint8_t *)GET_TABLE_WORD(target)) = nv->value_int; - nv->valuetype = TYPE_INTEGER; - return(STAT_OK); -} - -stat_t set_int8(nvObj_t *nv) -{ - *((int8_t *)GET_TABLE_WORD(target)) = (int8_t)nv->value_int; - nv->valuetype = TYPE_INTEGER; - return(STAT_OK); -} - -stat_t set_01(nvObj_t *nv) -{ - if (nv->value_int < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value_int > 1) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - return (set_ui8(nv)); -} - -stat_t set_012(nvObj_t *nv) -{ - if (nv->value_int < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value_int > 2) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - return (set_ui8(nv)); -} - -stat_t set_0123(nvObj_t *nv) -{ - if (nv->value_int < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value_int > 3) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - return (set_ui8(nv)); -} - stat_t set_int32(nvObj_t *nv) { - *((uint32_t *)GET_TABLE_WORD(target)) = nv->value_int; + *((int32_t *)GET_TABLE_WORD(target)) = nv->value_int; nv->valuetype = TYPE_INTEGER; return(STAT_OK); } -stat_t set_data(nvObj_t *nv) -{ - uint32_t *v = (uint32_t*)&nv->value_flt; - *((uint32_t *)GET_TABLE_WORD(target)) = *v; - nv->valuetype = TYPE_DATA; - return(STAT_OK); -} - stat_t set_flt(nvObj_t *nv) { *((float *)GET_TABLE_WORD(target)) = nv->value_flt; @@ -358,6 +271,14 @@ stat_t set_flt(nvObj_t *nv) return(STAT_OK); } +stat_t set_data(nvObj_t *nv) +{ + uint32_t *v = (uint32_t*)&nv->value_flt; + *((uint32_t *)GET_TABLE_WORD(target)) = *v; + nv->valuetype = TYPE_DATA; + return(STAT_OK); +} + /************************************************************************************ * Group operations * diff --git a/g2core/config.h b/g2core/config.h index 38d3ce01..30c34e54 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -362,25 +362,17 @@ bool nv_index_lt_groups(index_t index); // (see config_app.c) bool nv_group_is_prefixed(char *group); // generic internal functions and accessors +stat_t get_nul(nvObj_t *nv); // get null value type +stat_t get_int32(nvObj_t *nv); // get int32_t integer value +stat_t get_flt(nvObj_t *nv); // get floating point value +stat_t get_data(nvObj_t *nv); // get uint32_t integer value blind cast + stat_t set_noop(nvObj_t *nv); // set nothing and return OK stat_t set_nul(nvObj_t *nv); // set nothing and return READ_ONLY error stat_t set_ro(nvObj_t *nv); // set nothing, return read-only error -stat_t set_ui8(nvObj_t *nv); // set uint8_t value -stat_t set_int8(nvObj_t *nv); // set signed 8 bit integer -stat_t set_01(nvObj_t *nv); // set a 0 or 1 value with validation -stat_t set_012(nvObj_t *nv); // set a 0, 1 or 2 value with validation -stat_t set_0123(nvObj_t *nv); // set a 0, 1, 2 or 3 value with validation stat_t set_int32(nvObj_t *nv); // set int32_t integer value -stat_t set_data(nvObj_t *nv); // set uint32_t integer value blind cast stat_t set_flt(nvObj_t *nv); // set floating point value - -stat_t get_nul(nvObj_t *nv); // get null value type -stat_t get_bool(nvObj_t *nv); // get boolean value -stat_t get_ui8(nvObj_t *nv); // get uint8_t value -stat_t get_int8(nvObj_t *nv); // get signed 8 bit integer -stat_t get_int32(nvObj_t *nv); // get int32_t integer value -stat_t get_data(nvObj_t *nv); // get uint32_t integer value blind cast -stat_t get_flt(nvObj_t *nv); // get floating point value +stat_t set_data(nvObj_t *nv); // set uint32_t integer value blind cast stat_t set_grp(nvObj_t *nv); // set data for a group stat_t get_grp(nvObj_t *nv); // get data for a group diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index d2ed99f3..2d143ab8 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -132,7 +132,8 @@ const cfgItem_t cfgArray[] = { { "", "admo",_i0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode { "", "frmo",_i0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode { "", "tool",_i0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool - { "", "g92e",_i0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "g92e",_i0, 0, cm_print_g92e, cm_get_g92e, set_ro, nullptr, 0 }, // G92 enable state +// { "", "g92e",_i0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled #ifdef TEMPORARY_HAS_LEDS { "", "_leds",_i0, 0, tx_print_nul, _get_leds,_set_leds, (float *)&cs.null, 0 }, // TEMPORARY - change LEDs #endif @@ -357,56 +358,56 @@ const cfgItem_t cfgArray[] = { { "c","czb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, // Digital input configs - { "di1","di1mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[0].mode, DI1_MODE }, - { "di1","di1ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[0].action, DI1_ACTION }, - { "di1","di1fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[0].function, DI1_FUNCTION }, + { "di1","di1mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI1_MODE }, + { "di1","di1ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI1_ACTION }, + { "di1","di1fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI1_FUNCTION }, - { "di2","di2mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[1].mode, DI2_MODE }, - { "di2","di2ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[1].action, DI2_ACTION }, - { "di2","di2fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[1].function, DI2_FUNCTION }, + { "di2","di2mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI2_MODE }, + { "di2","di2ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI2_ACTION }, + { "di2","di2fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI2_FUNCTION }, - { "di3","di3mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[2].mode, DI3_MODE }, - { "di3","di3ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[2].action, DI3_ACTION }, - { "di3","di3fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[2].function, DI3_FUNCTION }, + { "di3","di3mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI3_MODE }, + { "di3","di3ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI3_ACTION }, + { "di3","di3fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI3_FUNCTION }, - { "di4","di4mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[3].mode, DI4_MODE }, - { "di4","di4ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[3].action, DI4_ACTION }, - { "di4","di4fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[3].function, DI4_FUNCTION }, + { "di4","di4mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI4_MODE }, + { "di4","di4ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI4_ACTION }, + { "di4","di4fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI4_FUNCTION }, - { "di5","di5mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[4].mode, DI5_MODE }, - { "di5","di5ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[4].action, DI5_ACTION }, - { "di5","di5fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[4].function, DI5_FUNCTION }, + { "di5","di5mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI5_MODE }, + { "di5","di5ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI5_ACTION }, + { "di5","di5fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI5_FUNCTION }, - { "di6","di6mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[5].mode, DI6_MODE }, - { "di6","di6ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[5].action, DI6_ACTION }, - { "di6","di6fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[5].function, DI6_FUNCTION }, + { "di6","di6mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI6_MODE }, + { "di6","di6ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI6_ACTION }, + { "di6","di6fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI6_FUNCTION }, - { "di7","di7mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[6].mode, DI7_MODE }, - { "di7","di7ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[6].action, DI7_ACTION }, - { "di7","di7fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[6].function, DI7_FUNCTION }, + { "di7","di7mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI7_MODE }, + { "di7","di7ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI7_ACTION }, + { "di7","di7fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI7_FUNCTION }, - { "di8","di8mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[7].mode, DI8_MODE }, - { "di8","di8ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[7].action, DI8_ACTION }, - { "di8","di8fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[7].function, DI8_FUNCTION }, + { "di8","di8mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI8_MODE }, + { "di8","di8ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI8_ACTION }, + { "di8","di8fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI8_FUNCTION }, #if (D_IN_CHANNELS >= 9) - { "di9","di9mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[8].mode, DI9_MODE }, - { "di9","di9ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[8].action, DI9_ACTION }, - { "di9","di9fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[8].function, DI9_FUNCTION }, + { "di9","di9mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI9_MODE }, + { "di9","di9ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI9_ACTION }, + { "di9","di9fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI9_FUNCTION }, #endif #if (D_IN_CHANNELS >= 10) - { "di10","di10mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[9].mode, DI10_MODE }, - { "di10","di10ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[9].action, DI10_ACTION }, - { "di10","di10fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[9].function, DI10_FUNCTION }, + { "di10","di10mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI10_MODE }, + { "di10","di10ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI10_ACTION }, + { "di10","di10fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI10_FUNCTION }, #endif #if (D_IN_CHANNELS >= 11) - { "di11","di11mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[10].mode, DI11_MODE }, - { "di11","di11ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[10].action, DI11_ACTION }, - { "di11","di11fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[10].function, DI11_FUNCTION }, + { "di11","di11mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI1_MODE }, + { "di11","di11ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI11_ACTION }, + { "di11","di11fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI11_FUNCTION }, #endif #if (D_IN_CHANNELS >= 12) - { "di12","di12mo",_iip, 0, io_print_mo, get_int8,io_set_mo, (float *)&d_in[11].mode, DI12_MODE }, - { "di12","di12ac",_iip, 0, io_print_ac, get_ui8, io_set_ac, (float *)&d_in[11].action, DI12_ACTION }, - { "di12","di12fn",_iip, 0, io_print_fn, get_ui8, io_set_fn, (float *)&d_in[11].function, DI12_FUNCTION }, + { "di12","di12mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI12_MODE }, + { "di12","di12ac",_iip, 0, io_print_ac, io_get_ac, io_set_ac, nullptr, DI12_ACTION }, + { "di12","di12fn",_iip, 0, io_print_fn, io_get_fn, io_set_fn, nullptr, DI12_FUNCTION }, #endif // Digital input state readers @@ -432,19 +433,19 @@ const cfgItem_t cfgArray[] = { #endif // digital output configs - { "do1", "do1mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[0].mode, DO1_MODE }, - { "do2", "do2mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[1].mode, DO2_MODE }, - { "do3", "do3mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[2].mode, DO3_MODE }, - { "do4", "do4mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[3].mode, DO4_MODE }, - { "do5", "do5mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[4].mode, DO5_MODE }, - { "do6", "do6mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[5].mode, DO6_MODE }, - { "do7", "do7mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[6].mode, DO7_MODE }, - { "do8", "do8mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[7].mode, DO8_MODE }, - { "do9", "do9mo", _iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[8].mode, DO9_MODE }, - { "do10","do10mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[9].mode, DO10_MODE }, - { "do11","do11mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[10].mode, DO11_MODE }, - { "do12","do12mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[11].mode, DO12_MODE }, - { "do13","do13mo",_iip, 0, io_print_domode, get_int8, io_set_domode, (float *)&d_out[12].mode, DO13_MODE }, + { "do1", "do1mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO1_MODE }, + { "do2", "do2mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO2_MODE }, + { "do3", "do3mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO3_MODE }, + { "do4", "do4mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO4_MODE }, + { "do5", "do5mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO5_MODE }, + { "do6", "do6mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO6_MODE }, + { "do7", "do7mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO7_MODE }, + { "do8", "do8mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO8_MODE }, + { "do9", "do9mo", _iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO9_MODE }, + { "do10","do10mo",_iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO10_MODE }, + { "do11","do11mo",_iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO11_MODE }, + { "do12","do12mo",_iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO12_MODE }, + { "do13","do13mo",_iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO13_MODE }, // Digital output state readers (default to non-active) { "out","out1", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, @@ -631,11 +632,11 @@ const cfgItem_t cfgArray[] = { { "sys","sl", _bipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, { "sys","lim", _bipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, { "sys","saf", _bipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48", _bin, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 1 }, // M48/M49 feedrate & spindle override enable - { "sys","froe",_bin, 0, cm_print_froe,cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, - { "sys","fro", _fin, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, - { "sys","troe",_bin, 0, cm_print_troe,cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","tro", _fin, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","m48", _bin, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 1 }, // M48/M49 feedrate & spindle override enable + { "sys","froe",_bin, 0, cm_print_froe, cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, + { "sys","fro", _fin, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, + { "sys","troe",_bin, 0, cm_print_troe, cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","tro", _fin, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, // N is seconds of timeout { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index de6f04df..8ec12408 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -479,43 +479,59 @@ bool gpio_read_input(const uint8_t input_num_ext) * These functions are not part of the NIST defined functions ***********************************************************************************/ -static stat_t _input_set_helper(nvObj_t *nv, const int8_t lower_bound, const int8_t upper_bound) +/* HELPERS + * _io() - get IO number from the token as an array index (reduce by one) + */ + +static uint8_t _io(const index_t index) { - if ((nv->value_int < lower_bound) || (nv->value_int >= upper_bound)) { - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - set_ui8(nv); // will this work if -1 is a valid value? + const char *ptr = cfgArray[index].token; + + do { + if (isdigit(*ptr)) { + return (atoi(ptr)-1); // need to reduce by 1 for internal 0-based arrays + } + } while (++ptr != NUL); + + return (0); +} + +/* + * io_get_mo() - get input mode + * io_set_mo() - set input mode + * io_get_ac() - get input action + * io_set_ac() - set input action + * io_get_fn() - get input function + * io_set_fn() - set input function + */ +stat_t io_get_mo(nvObj_t *nv) { return(get_int(nv, d_in[_io(nv->index)].mode)); } +stat_t io_set_mo(nvObj_t *nv) +{ + ritorno(set_int(nv, (uint8_t &)d_in[_io(nv->index)].mode, 0, IO_MODE_MAX)); if (cm_get_machine_state() != MACHINE_INITIALIZING) { inputs_reset(); } return (STAT_OK); } -static stat_t _output_set_helper(nvObj_t *nv, const int8_t lower_bound, const int8_t upper_bound) +stat_t io_get_ac(nvObj_t *nv) { return(get_int(nv, d_in[_io(nv->index)].action)); } +stat_t io_set_ac(nvObj_t *nv) { - if ((nv->value_int < lower_bound) || (nv->value_int >= upper_bound)) { - return (STAT_INPUT_VALUE_RANGE_ERROR); - } - set_ui8(nv); // will this work in -1 is a valid value? + ritorno(set_int(nv, (uint8_t &)d_in[_io(nv->index)].action, 0, INPUT_ACTION_MAX)); if (cm_get_machine_state() != MACHINE_INITIALIZING) { - outputs_reset(); + inputs_reset(); } return (STAT_OK); } -stat_t io_set_mo(nvObj_t *nv) // input type or disabled +stat_t io_get_fn(nvObj_t *nv) { return(get_int(nv, d_in[_io(nv->index)].function)); } +stat_t io_set_fn(nvObj_t *nv) { - return (_input_set_helper(nv, IO_ACTIVE_LOW, IO_MODE_MAX)); -} - -stat_t io_set_ac(nvObj_t *nv) // input action -{ - return (_input_set_helper(nv, INPUT_ACTION_NONE, INPUT_ACTION_MAX)); -} - -stat_t io_set_fn(nvObj_t *nv) // input function -{ - return (_input_set_helper(nv, INPUT_FUNCTION_NONE, INPUT_FUNCTION_MAX)); + ritorno(set_int(nv, (uint8_t &)d_in[_io(nv->index)].function, 0, INPUT_FUNCTION_MAX)); + if (cm_get_machine_state() != MACHINE_INITIALIZING) { + inputs_reset(); + } + return (STAT_OK); } /* @@ -523,40 +539,22 @@ stat_t io_set_fn(nvObj_t *nv) // input function */ stat_t io_get_input(nvObj_t *nv) { - char *num_start = nv->token; - if (*(nv->group) == 0) { - // if we don't have a group, then the group name is in the token - // skip over "in" - num_start+=2; - } - nv->value_int = d_in[strtol(num_start, NULL, 10)-1].state; - - if (nv->value_int > 1.1) { - nv->valuetype = TYPE_NULL; - } else { - nv->valuetype = TYPE_BOOLEAN; - } + nv->value_int = d_in[_io(nv->index)].state; + nv->valuetype = TYPE_INTEGER; return (STAT_OK); } -stat_t io_set_domode(nvObj_t *nv) // output function +/* + * io_get_domode() - get digital output mode + * io_set_domode() - set digital output mode + */ +stat_t io_get_domode(nvObj_t *nv) { return(get_int(nv, d_out[_io(nv->index)].mode)); } +stat_t io_set_domode(nvObj_t *nv) // output function { - char *num_start = nv->token; - if (*(nv->group) == 0) { - // if we don't have a group, then the group name is in the token - // skip over "out" - num_start+=3; - } - // the token has been stripped down to an ASCII digit string - use it as an index - uint8_t output_num = strtol(num_start, NULL, 10); - - if (output_num > D_OUT_CHANNELS) { - nv->valuetype = TYPE_NULL; - return(STAT_NO_GPIO); - } + uint8_t output_num = _io(nv->index); // returns 1 based output number (arrays) // Force pins that aren't available to be "disabled" - switch (output_num) { + switch (output_num+1) { // add 1 to get logical pin numbers case 1: if (output_1_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; case 2: if (output_2_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; case 3: if (output_3_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; @@ -570,12 +568,14 @@ stat_t io_set_domode(nvObj_t *nv) // output function case 11: if (output_11_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; case 12: if (output_12_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; case 13: if (output_13_pin.isNull()) { nv->value_int = IO_MODE_DISABLED; } break; - - default: - break; + default: {} } - return (_output_set_helper(nv, IO_ACTIVE_LOW, IO_MODE_MAX)); + ritorno(set_int(nv, (uint8_t &)d_out[output_num].mode, 0, IO_MODE_MAX)); + if (cm_get_machine_state() != MACHINE_INITIALIZING) { + outputs_reset(); + } + return (STAT_OK); } /* @@ -583,30 +583,16 @@ stat_t io_set_domode(nvObj_t *nv) // output function */ stat_t io_get_output(nvObj_t *nv) { - char *num_start = nv->token; - if (*(nv->group) == 0) { - // if we don't have a group, then the group name is in the token - // skip over "out" - num_start+=3; - } - // the token has been stripped down to an ASCII digit string - use it as an index - uint8_t output_num = strtol(num_start, NULL, 10); + uint8_t output_num = _io(nv->index); - if (output_num > D_OUT_CHANNELS) { - nv->valuetype = TYPE_NULL; - return(STAT_NO_GPIO); - } - - ioMode outMode = d_out[output_num-1].mode; + ioMode outMode = d_out[output_num].mode; if (outMode == IO_MODE_DISABLED) { -// nv->value_int = 0; nv->valuetype = TYPE_NULL; // reports back as NULL } else { nv->valuetype = TYPE_FLOAT; nv->precision = 2; - bool invert = (outMode == 0); - // Note: !! forces a value to boolean 0 or 1 - switch (output_num) { + + switch (output_num+1) { // add 1 to get logical pin numbers case 1: { nv->value_flt = (float)output_1_pin; } break; case 2: { nv->value_flt = (float)output_2_pin; } break; case 3: { nv->value_flt = (float)output_3_pin; } break; @@ -620,45 +606,31 @@ stat_t io_get_output(nvObj_t *nv) case 11: { nv->value_flt = (float)output_11_pin; } break; case 12: { nv->value_flt = (float)output_12_pin; } break; case 13: { nv->value_flt = (float)output_13_pin; } break; - - default: - { -// nv->value = 0; // inactive - nv->valuetype = TYPE_NULL; // reports back as NULL - } + default: { nv->valuetype = TYPE_NULL; } // reports back as NULL } - if (invert) { - nv->value_flt = 1.0 - nv->value_flt; + if (outMode == IO_ACTIVE_LOW) { + nv->value_flt = 1.0 - nv->value_flt; // invert output sense } } return (STAT_OK); } /* - * io_set_output() - return output state given an nv object + * io_set_output() - read and return output state given an nv object */ stat_t io_set_output(nvObj_t *nv) { - char *num_start = nv->token; - if (*(nv->group) == 0) { - // if we don't have a group, then the group name is in the token - // skip over "out" - num_start+=3; - } - // the token has been stripped down to an ASCII digit string - use it as an index - uint8_t output_num = strtol(num_start, NULL, 10); + uint8_t output_num = _io(nv->index); ioMode outMode = d_out[output_num-1].mode; if (outMode == IO_MODE_DISABLED) { - nv->value_flt = 0; // Inactive? + nv->valuetype = TYPE_NULL; // reports back as NULL + } else { - bool invert = (outMode == 0); - float value = nv->value_flt; - if (invert) { - value = 1.0 - value; - } - switch (output_num) { + // send normal or inverted value to output + float value = (outMode == IO_ACTIVE_HIGH) ? nv->value_flt : 1.0 - nv->value_flt; + switch (output_num+1) { // add 1 to get logical pin numbers // Generated with: // perl -e 'for($i=1;$i<14;$i++) { print "case ${i}: { output_${i}_pin = value; } break;\n";}' // BEGIN generated @@ -671,12 +643,11 @@ stat_t io_set_output(nvObj_t *nv) case 7: { output_7_pin = value; } break; case 8: { output_8_pin = value; } break; case 9: { output_9_pin = value; } break; - case 10: { output_10_pin = value; } break; - case 11: { output_11_pin = value; } break; - case 12: { output_12_pin = value; } break; - case 13: { output_13_pin = value; } break; - // END generated - default: { nv->value_flt = 0; } // inactive + case 10: { output_10_pin = value; } break; + case 11: { output_11_pin = value; } break; + case 12: { output_12_pin = value; } break; + case 13: { output_13_pin = value; } break; // END generated + default: { nv->value_flt = 0; } // inactive } } return (STAT_OK); diff --git a/g2core/gpio.h b/g2core/gpio.h index 0afb26dc..1c437d39 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -47,9 +47,9 @@ typedef enum { IO_ACTIVE_LOW = 0, // input is active low (aka normally open) IO_ACTIVE_HIGH = 1, // input is active high (aka normally closed) - IO_MODE_DISABLED = 2, // input is disabled - IO_MODE_MAX // unused. Just for range checking + IO_MODE_DISABLED = 2 // input is disabled } ioMode; +#define IO_MODE_MAX IO_MODE_DISABLED #define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent #define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent @@ -80,18 +80,18 @@ typedef enum { // actions are initiated from within the INPUT_ACTION_ALARM, // initiate an alarm. stops everything immediately - preserves position INPUT_ACTION_SHUTDOWN, // initiate a shutdown. stops everything immediately - does not preserve position INPUT_ACTION_PANIC, // initiate a panic. stops everything immediately - does not preserve position - INPUT_ACTION_RESET, // reset system - INPUT_ACTION_MAX // unused. Just for range checking + INPUT_ACTION_RESET // reset system } inputAction; +#define INPUT_ACTION_MAX INPUT_ACTION_RESET typedef enum { // functions are requested from the ISR, run from the main loop INPUT_FUNCTION_NONE = 0, INPUT_FUNCTION_LIMIT = 1, // limit switch processing INPUT_FUNCTION_INTERLOCK = 2, // interlock processing INPUT_FUNCTION_SHUTDOWN = 3, // shutdown in support of external emergency stop - INPUT_FUNCTION_PROBE = 4, // assign input as probe input - INPUT_FUNCTION_MAX // unused. Just for range checking + INPUT_FUNCTION_PROBE = 4 // assign input as probe input } inputFunc; +#define INPUT_FUNCTION_MAX INPUT_FUNCTION_PROBE typedef enum { INPUT_INACTIVE = 0, // aka switch open, also read as 'false' @@ -151,13 +151,16 @@ void gpio_set_homing_mode(const uint8_t input_num, const bool is_homing); void gpio_set_probing_mode(const uint8_t input_num, const bool is_probing); int8_t gpio_get_probing_input(void); +stat_t io_get_mo(nvObj_t *nv); stat_t io_set_mo(nvObj_t *nv); +stat_t io_get_ac(nvObj_t *nv); stat_t io_set_ac(nvObj_t *nv); +stat_t io_get_fn(nvObj_t *nv); stat_t io_set_fn(nvObj_t *nv); stat_t io_get_input(nvObj_t *nv); - +stat_t io_get_domode(nvObj_t *nv); // output sense stat_t io_set_domode(nvObj_t *nv); // output sense stat_t io_get_output(nvObj_t *nv); stat_t io_set_output(nvObj_t *nv); diff --git a/g2core/report.cpp b/g2core/report.cpp index e165b690..55c17f1d 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -61,7 +61,7 @@ stat_t rpt_exception(stat_t status, const char *msg) if (cs.controller_state >= CONTROLLER_READY) { char buffer[128]; sprintf(buffer, "{\"er\":{\"fb\":%0.2f,\"st\":%d,\"msg\":\"%s - %s\"}}\n", - G2CORE_FIRMWARE_BUILD, status, get_status_message(status), msg); + G2CORE_FIRMWARE_BUILD, status, get_status_message(status), msg); xio_writeline(buffer); } } From 76361a60b3365ab515c419111b819f095d4ab3a3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 17:09:18 -0400 Subject: [PATCH 216/283] Removed overloading on get_int; shared some code on set_ints; removed set_flu() --- g2core/canonical_machine.cpp | 64 ++++++++++++++-------------- g2core/config.h | 7 +-- g2core/config_app.cpp | 82 ++++++++++-------------------------- g2core/coolant.cpp | 18 ++++---- g2core/gpio.cpp | 16 +++---- g2core/json_parser.cpp | 8 ++-- g2core/report.cpp | 10 ++--- g2core/spindle.cpp | 22 +++++----- g2core/stepper.cpp | 14 +++--- g2core/text_parser.cpp | 4 +- 10 files changed, 103 insertions(+), 142 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index c940f8ae..f045b6f0 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1958,9 +1958,9 @@ stat_t cm_get_dist(nvObj_t *nv) { return(_get_msg_helper(nv, msg_dist, cm_get_di stat_t cm_get_admo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_admo, cm_get_arc_distance_mode(ACTIVE_MODEL)));} stat_t cm_get_frmo(nvObj_t *nv) { return(_get_msg_helper(nv, msg_frmo, cm_get_feed_rate_mode(ACTIVE_MODEL)));} -stat_t cm_get_toolv(nvObj_t *nv) { return(get_int(nv, cm_get_tool(ACTIVE_MODEL))); } -stat_t cm_get_mline(nvObj_t *nv) { return(get_int32(nv, cm_get_linenum(MODEL))); } -stat_t cm_get_line(nvObj_t *nv) { return(get_int32(nv, cm_get_linenum(ACTIVE_MODEL))); } +stat_t cm_get_toolv(nvObj_t *nv) { return(get_integer(nv, cm_get_tool(ACTIVE_MODEL))); } +stat_t cm_get_mline(nvObj_t *nv) { return(get_integer(nv, cm_get_linenum(MODEL))); } +stat_t cm_get_line(nvObj_t *nv) { return(get_integer(nv, cm_get_linenum(ACTIVE_MODEL))); } stat_t cm_get_vel(nvObj_t *nv) { @@ -1983,8 +1983,8 @@ stat_t cm_get_mpo(nvObj_t *nv) { return (get_float(nv, cm_get_absolute_position stat_t cm_get_ofs(nvObj_t *nv) { return (get_float(nv, cm_get_display_offset(ACTIVE_MODEL, _axis(nv)))); } stat_t cm_get_home(nvObj_t *nv) { return(_get_msg_helper(nv, msg_home, cm_get_homing_state())); } -stat_t cm_set_home(nvObj_t *nv) { return (set_int(nv, ((uint8_t &)(cm->homing_state)), false, true)); } -stat_t cm_get_hom(nvObj_t *nv) { return (get_int(nv, cm->homed[_axis(nv)])); } +stat_t cm_set_home(nvObj_t *nv) { return (set_integer(nv, ((uint8_t &)(cm->homing_state)), false, true)); } +stat_t cm_get_hom(nvObj_t *nv) { return (get_integer(nv, cm->homed[_axis(nv)])); } stat_t cm_get_prob(nvObj_t *nv) { return(_get_msg_helper(nv, msg_probe, cm_get_probe_state())); } stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_axis(nv)])); } @@ -1992,7 +1992,7 @@ stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_ax stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } -stat_t cm_get_g92e(nvObj_t *nv) { return (get_int(nv, cm->gmx.origin_offset_enable)); } +stat_t cm_get_g92e(nvObj_t *nv) { return (get_integer(nv, cm->gmx.origin_offset_enable)); } stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv)])); } stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv)])); } stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv)])); } @@ -2179,10 +2179,10 @@ stat_t cm_set_jh(nvObj_t *nv) * cm_set_zb() - set homing zero backoff */ -stat_t cm_get_hi(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv)].homing_input)); } -stat_t cm_set_hi(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv)].homing_input, 0, D_IN_CHANNELS)); } -stat_t cm_get_hd(nvObj_t *nv) { return (get_int(nv, cm->a[_axis(nv)].homing_dir)); } -stat_t cm_set_hd(nvObj_t *nv) { return (set_int(nv, cm->a[_axis(nv)].homing_dir, 0, 1)); } +stat_t cm_get_hi(nvObj_t *nv) { return (get_integer(nv, cm->a[_axis(nv)].homing_input)); } +stat_t cm_set_hi(nvObj_t *nv) { return (set_integer(nv, cm->a[_axis(nv)].homing_input, 0, D_IN_CHANNELS)); } +stat_t cm_get_hd(nvObj_t *nv) { return (get_integer(nv, cm->a[_axis(nv)].homing_dir)); } +stat_t cm_set_hd(nvObj_t *nv) { return (set_integer(nv, cm->a[_axis(nv)].homing_dir, 0, 1)); } stat_t cm_get_sv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].search_velocity)); } stat_t cm_set_sv(nvObj_t *nv) { return (set_float_range(nv, cm->a[_axis(nv)].search_velocity, 0, MAX_LONG)); } stat_t cm_get_lv(nvObj_t *nv) { return (get_float(nv, cm->a[_axis(nv)].latch_velocity)); } @@ -2225,42 +2225,42 @@ stat_t cm_set_ct(nvObj_t *nv) { return(set_float_range(nv, cm->chordal_tolerance stat_t cm_get_zl(nvObj_t *nv) { return(get_float(nv, cm->feedhold_z_lift)); } stat_t cm_set_zl(nvObj_t *nv) { return(set_float(nv, cm->feedhold_z_lift)); } -stat_t cm_get_sl(nvObj_t *nv) { return(get_int(nv, cm->soft_limit_enable)); } -stat_t cm_set_sl(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->soft_limit_enable, 0, 1)); } +stat_t cm_get_sl(nvObj_t *nv) { return(get_integer(nv, cm->soft_limit_enable)); } +stat_t cm_set_sl(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->soft_limit_enable, 0, 1)); } -stat_t cm_get_lim(nvObj_t *nv) { return(get_int(nv, cm->limit_enable)); } -stat_t cm_set_lim(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->limit_enable, 0, 1)); } +stat_t cm_get_lim(nvObj_t *nv) { return(get_integer(nv, cm->limit_enable)); } +stat_t cm_set_lim(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->limit_enable, 0, 1)); } -stat_t cm_get_saf(nvObj_t *nv) { return(get_int(nv, cm->safety_interlock_enable)); } -stat_t cm_set_saf(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->safety_interlock_enable, 0, 1)); } +stat_t cm_get_saf(nvObj_t *nv) { return(get_integer(nv, cm->safety_interlock_enable)); } +stat_t cm_set_saf(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->safety_interlock_enable, 0, 1)); } -stat_t cm_get_m48(nvObj_t *nv) { return(get_int(nv, cm->gmx.m48_enable)); } -stat_t cm_set_m48(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.m48_enable, 0, 1)); } +stat_t cm_get_m48(nvObj_t *nv) { return(get_integer(nv, cm->gmx.m48_enable)); } +stat_t cm_set_m48(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->gmx.m48_enable, 0, 1)); } -stat_t cm_get_froe(nvObj_t *nv) { return(get_int(nv, cm->gmx.mfo_enable)); } -stat_t cm_set_froe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.mfo_enable, 0, 1)); } +stat_t cm_get_froe(nvObj_t *nv) { return(get_integer(nv, cm->gmx.mfo_enable)); } +stat_t cm_set_froe(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->gmx.mfo_enable, 0, 1)); } stat_t cm_get_fro(nvObj_t *nv) { return(get_float(nv, cm->gmx.mfo_factor)); } stat_t cm_set_fro(nvObj_t *nv) { return(set_float_range(nv, cm->gmx.mfo_factor, FEED_OVERRIDE_MIN, FEED_OVERRIDE_MAX)); } -stat_t cm_get_troe(nvObj_t *nv) { return(get_int(nv, cm->gmx.mto_enable)); } -stat_t cm_set_troe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->gmx.mto_enable, 0, 1)); } +stat_t cm_get_troe(nvObj_t *nv) { return(get_integer(nv, cm->gmx.mto_enable)); } +stat_t cm_set_troe(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->gmx.mto_enable, 0, 1)); } stat_t cm_get_tro(nvObj_t *nv) { return(get_float(nv, cm->gmx.mto_factor)); } stat_t cm_set_tro(nvObj_t *nv) { return(set_float_range(nv, cm->gmx.mto_factor, TRAVERSE_OVERRIDE_MIN, TRAVERSE_OVERRIDE_MAX)); } -stat_t cm_get_gpl(nvObj_t *nv) { return(get_int(nv, cm->default_select_plane)); } -stat_t cm_set_gpl(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_select_plane, CANON_PLANE_XY, CANON_PLANE_YZ)); } +stat_t cm_get_gpl(nvObj_t *nv) { return(get_integer(nv, cm->default_select_plane)); } +stat_t cm_set_gpl(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->default_select_plane, CANON_PLANE_XY, CANON_PLANE_YZ)); } -stat_t cm_get_gun(nvObj_t *nv) { return(get_int(nv, cm->default_units_mode)); } -stat_t cm_set_gun(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_units_mode, INCHES, MILLIMETERS)); } +stat_t cm_get_gun(nvObj_t *nv) { return(get_integer(nv, cm->default_units_mode)); } +stat_t cm_set_gun(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->default_units_mode, INCHES, MILLIMETERS)); } -stat_t cm_get_gco(nvObj_t *nv) { return(get_int(nv, cm->default_coord_system)); } -stat_t cm_set_gco(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_coord_system, G54, G59)); } +stat_t cm_get_gco(nvObj_t *nv) { return(get_integer(nv, cm->default_coord_system)); } +stat_t cm_set_gco(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->default_coord_system, G54, G59)); } -stat_t cm_get_gpa(nvObj_t *nv) { return(get_int(nv, cm->default_path_control)); } -stat_t cm_set_gpa(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_path_control, PATH_EXACT_PATH, PATH_CONTINUOUS)); } +stat_t cm_get_gpa(nvObj_t *nv) { return(get_integer(nv, cm->default_path_control)); } +stat_t cm_set_gpa(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->default_path_control, PATH_EXACT_PATH, PATH_CONTINUOUS)); } -stat_t cm_get_gdi(nvObj_t *nv) { return(get_int(nv, cm->default_distance_mode)); } -stat_t cm_set_gdi(nvObj_t *nv) { return(set_int(nv, (uint8_t &)cm->default_distance_mode, ABSOLUTE_DISTANCE_MODE, INCREMENTAL_DISTANCE_MODE)); } +stat_t cm_get_gdi(nvObj_t *nv) { return(get_integer(nv, cm->default_distance_mode)); } +stat_t cm_set_gdi(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->default_distance_mode, ABSOLUTE_DISTANCE_MODE, INCREMENTAL_DISTANCE_MODE)); } /*********************************************************************************** * Debugging Commands diff --git a/g2core/config.h b/g2core/config.h index 30c34e54..5be86054 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -392,8 +392,6 @@ void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags); // application specific helpers and functions (config_app.c) -stat_t set_flu(nvObj_t *nv); // set floating point number with G20/G21 units conversion - void convert_incoming_float(nvObj_t *nv); // pre-process outgoing float values for units and illegal values void convert_outgoing_float(nvObj_t *nv); // pre-process incoming float values for canonical units @@ -401,9 +399,8 @@ stat_t get_float(nvObj_t *nv, const float value); // boilerplate for retrievin stat_t set_float(nvObj_t *nv, float &value); // boilerplate for setting a floating point value w/conversion stat_t set_float_range(nvObj_t *nv, float &value, float low, float high); -stat_t get_int(nvObj_t *nv, const uint8_t value); // boilerplate for retrieving 8 bit integer value -stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); -stat_t get_int32(nvObj_t *nv, const int32_t value); // boilerplate for retrieving 32 bit integer value +stat_t get_integer(nvObj_t *nv, const int32_t value); // boilerplate for retrieving 8 bit integer value +stat_t set_integer(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high); stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high); stat_t get_string(nvObj_t *nv, const char *str); diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 2d143ab8..333d887c 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1245,29 +1245,6 @@ bool nv_index_is_group(index_t index) { return (((index >= NV_INDEX_START_GROUPS bool nv_index_lt_groups(index_t index) { return ((index <= NV_INDEX_START_GROUPS) ? true : false);} /***** APPLICATION SPECIFIC CONFIGS AND EXTENSIONS TO GENERIC FUNCTIONS *****/ - -/* - * set_flu() - set floating point number with G20/G21 units conversion - * - * The number 'setted' will have been delivered in external units (inches or mm). - * It is written to the target memory location in internal canonical units (mm). - * The original nv->value is also changed so persistence works correctly. - * Displays should convert back from internal canonical form to external form. - * - * !!!! WARNING !!!! set_flu() doesn't care about axes, so make sure you aren't passing it ABC axes - */ - -stat_t set_flu(nvObj_t *nv) -{ - if (cm_get_units_mode(MODEL) == INCHES) { // if in inches... - nv->value_flt *= MM_PER_INCH; // convert to canonical millimeter units - } - *((float *)GET_TABLE_WORD(target)) = nv->value_flt; // write value as millimeters or degrees - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; - return(STAT_OK); -} - /* * convert_incoming_float() - pre-process an incoming floating point number for canonical units * convert_outgoing_float() - pre-process an outgoing floating point number for units display @@ -1362,61 +1339,48 @@ stat_t set_float_range(nvObj_t *nv, float &value, float low, float high) { } /* - * get_int() - boilerplate for retrieving 8 bit integer value - * set_int() - boilerplate for setting 8 bit integer value with range checking - * get_int32() - boilerplate for retrieving 32 bit integer value - * set_int32() - boilerplate for setting 32 bit integer value with range checking + * get_integer() - boilerplate for retrieving 8 and 32 bit integer values + * set_integer() - boilerplate for setting 8 bit integer value with range checking + * set_int32() - boilerplate for setting 32 bit integer value with range checking */ -stat_t get_int(nvObj_t *nv, const uint8_t value) { - nv->value_int = value; - nv->valuetype = TYPE_INTEGER; - return STAT_OK; -} - -stat_t set_int(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) { - +static stat_t _set_int_tests(nvObj_t *nv, int32_t low, int32_t high) +{ char msg[64]; if (nv->value_int < low) { - sprintf(msg, "Input is less than minimum value %d", low); + sprintf(msg, "Input less than minimum value %d", (int)low); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_LESS_THAN_MIN_VALUE); } if (nv->value_int > high) { - sprintf(msg, "Input is more than maximum value %d", high); + sprintf(msg, "Input more than maximum value %d", (int)high); nv_add_conditional_message(msg); nv->valuetype = TYPE_NULL; return (STAT_INPUT_EXCEEDS_MAX_VALUE); } + return (STAT_OK); +} + +stat_t get_integer(nvObj_t *nv, const int32_t value) +{ + nv->value_int = value; + nv->valuetype = TYPE_INTEGER; + return STAT_OK; +} + +stat_t set_integer(nvObj_t *nv, uint8_t &value, uint8_t low, uint8_t high) +{ + ritorno(_set_int_tests(nv, low, high)) value = nv->value_int; nv->valuetype = TYPE_INTEGER; return (STAT_OK); } -stat_t get_int32(nvObj_t *nv, const int32_t value) { - nv->value_int = value; - nv->valuetype = TYPE_INTEGER; - return STAT_OK; -} - -stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high) { - - char msg[64]; - - if (nv->value_int < low) { - sprintf(msg, "Input is less than minimum value %lu", low); - nv_add_conditional_message(msg); - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value_int > high) { - sprintf(msg, "Input is more than maximum value %lu", high); - nv_add_conditional_message(msg); - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } +stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high) +{ + ritorno(_set_int_tests(nv, low, high)) value = nv->value_int; // note: valuetype = TYPE_INT already set nv->valuetype = TYPE_INTEGER; return (STAT_OK); diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index f0db9b52..fc813202 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -153,21 +153,21 @@ static void _exec_coolant_control(float* value, bool* flag) { **** Coolant Settings ************************************************************* ***********************************************************************************/ -stat_t co_get_com(nvObj_t *nv) { return(get_int(nv, coolant.mist.state)); } +stat_t co_get_com(nvObj_t *nv) { return(get_integer(nv, coolant.mist.state)); } stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value_int, COOLANT_MIST)); } -stat_t co_get_cof(nvObj_t *nv) { return(get_int(nv, coolant.flood.state)); } +stat_t co_get_cof(nvObj_t *nv) { return(get_integer(nv, coolant.flood.state)); } stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value_int, COOLANT_FLOOD)); } -stat_t co_get_coph(nvObj_t *nv) { return(get_int(nv, coolant.mist.pause_enable)); } +stat_t co_get_coph(nvObj_t *nv) { return(get_integer(nv, coolant.mist.pause_enable)); } stat_t co_set_coph(nvObj_t *nv) { - ritorno(set_int(nv, (uint8_t &)coolant.mist.pause_enable, 0, 1)); - return (set_int(nv, (uint8_t &)coolant.flood.pause_enable, 0, 1)); + ritorno(set_integer(nv, (uint8_t &)coolant.mist.pause_enable, 0, 1)); + return (set_integer(nv, (uint8_t &)coolant.flood.pause_enable, 0, 1)); } -stat_t co_get_comp(nvObj_t *nv) { return(get_int(nv, coolant.mist.polarity)); } -stat_t co_set_comp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.mist.polarity, 0, 1)); } -stat_t co_get_cofp(nvObj_t *nv) { return(get_int(nv, coolant.flood.polarity)); } -stat_t co_set_cofp(nvObj_t *nv) { return(set_int(nv, (uint8_t &)coolant.flood.polarity, 0, 1)); } +stat_t co_get_comp(nvObj_t *nv) { return(get_integer(nv, coolant.mist.polarity)); } +stat_t co_set_comp(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)coolant.mist.polarity, 0, 1)); } +stat_t co_get_cofp(nvObj_t *nv) { return(get_integer(nv, coolant.flood.polarity)); } +stat_t co_set_cofp(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)coolant.flood.polarity, 0, 1)); } /*********************************************************************************** * TEXT MODE SUPPORT diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 8ec12408..fdd857c5 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -504,30 +504,30 @@ static uint8_t _io(const index_t index) * io_get_fn() - get input function * io_set_fn() - set input function */ -stat_t io_get_mo(nvObj_t *nv) { return(get_int(nv, d_in[_io(nv->index)].mode)); } +stat_t io_get_mo(nvObj_t *nv) { return(get_integer(nv, d_in[_io(nv->index)].mode)); } stat_t io_set_mo(nvObj_t *nv) { - ritorno(set_int(nv, (uint8_t &)d_in[_io(nv->index)].mode, 0, IO_MODE_MAX)); + ritorno(set_integer(nv, (uint8_t &)d_in[_io(nv->index)].mode, 0, IO_MODE_MAX)); if (cm_get_machine_state() != MACHINE_INITIALIZING) { inputs_reset(); } return (STAT_OK); } -stat_t io_get_ac(nvObj_t *nv) { return(get_int(nv, d_in[_io(nv->index)].action)); } +stat_t io_get_ac(nvObj_t *nv) { return(get_integer(nv, d_in[_io(nv->index)].action)); } stat_t io_set_ac(nvObj_t *nv) { - ritorno(set_int(nv, (uint8_t &)d_in[_io(nv->index)].action, 0, INPUT_ACTION_MAX)); + ritorno(set_integer(nv, (uint8_t &)d_in[_io(nv->index)].action, 0, INPUT_ACTION_MAX)); if (cm_get_machine_state() != MACHINE_INITIALIZING) { inputs_reset(); } return (STAT_OK); } -stat_t io_get_fn(nvObj_t *nv) { return(get_int(nv, d_in[_io(nv->index)].function)); } +stat_t io_get_fn(nvObj_t *nv) { return(get_integer(nv, d_in[_io(nv->index)].function)); } stat_t io_set_fn(nvObj_t *nv) { - ritorno(set_int(nv, (uint8_t &)d_in[_io(nv->index)].function, 0, INPUT_FUNCTION_MAX)); + ritorno(set_integer(nv, (uint8_t &)d_in[_io(nv->index)].function, 0, INPUT_FUNCTION_MAX)); if (cm_get_machine_state() != MACHINE_INITIALIZING) { inputs_reset(); } @@ -548,7 +548,7 @@ stat_t io_get_input(nvObj_t *nv) * io_get_domode() - get digital output mode * io_set_domode() - set digital output mode */ -stat_t io_get_domode(nvObj_t *nv) { return(get_int(nv, d_out[_io(nv->index)].mode)); } +stat_t io_get_domode(nvObj_t *nv) { return(get_integer(nv, d_out[_io(nv->index)].mode)); } stat_t io_set_domode(nvObj_t *nv) // output function { uint8_t output_num = _io(nv->index); // returns 1 based output number (arrays) @@ -571,7 +571,7 @@ stat_t io_set_domode(nvObj_t *nv) // output function default: {} } - ritorno(set_int(nv, (uint8_t &)d_out[output_num].mode, 0, IO_MODE_MAX)); + ritorno(set_integer(nv, (uint8_t &)d_out[output_num].mode, 0, IO_MODE_MAX)); if (cm_get_machine_state() != MACHINE_INITIALIZING) { outputs_reset(); } diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 65ebd177..b3d53a3d 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -628,10 +628,10 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/) * If comm_mode is set to AUTO_MORE (0) then json_mode should not be changed */ -stat_t js_get_ej(nvObj_t *nv) { return(get_int(nv, cs.comm_mode)); } +stat_t js_get_ej(nvObj_t *nv) { return(get_integer(nv, cs.comm_mode)); } stat_t js_set_ej(nvObj_t *nv) { - ritorno (set_int(nv, (uint8_t &)cs.comm_mode, TEXT_MODE, AUTO_MODE)); + ritorno (set_integer(nv, (uint8_t &)cs.comm_mode, TEXT_MODE, AUTO_MODE)); if (commMode(nv->value_int) < AUTO_MODE) { // set json_mode to 0 or 1, but don't change it if comm_mode == 2 js.json_mode = commMode(nv->value_int); } @@ -643,10 +643,10 @@ stat_t js_set_ej(nvObj_t *nv) * js_set_jv() - set JSON verbosity and related flags */ -stat_t js_get_jv(nvObj_t *nv) { return(get_int(nv, js.json_verbosity)); } +stat_t js_get_jv(nvObj_t *nv) { return(get_integer(nv, js.json_verbosity)); } stat_t js_set_jv(nvObj_t *nv) { - ritorno (set_int(nv, (uint8_t &)js.json_verbosity, JV_SILENT, JV_MAX_VALUE)); + ritorno (set_integer(nv, (uint8_t &)js.json_verbosity, JV_SILENT, JV_MAX_VALUE)); js.echo_json_footer = false; js.echo_json_messages = false; diff --git a/g2core/report.cpp b/g2core/report.cpp index 55c17f1d..d9131733 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -430,9 +430,9 @@ static uint8_t _populate_filtered_status_report() stat_t sr_get(nvObj_t *nv) { return (_populate_unfiltered_status_report()); } stat_t sr_set(nvObj_t *nv) { return (sr_set_status_report(nv)); } -stat_t sr_get_sv(nvObj_t *nv) { return(get_int(nv, (uint8_t &)sr.status_report_verbosity)); } -stat_t sr_set_sv(nvObj_t *nv) { return(set_int(nv, (uint8_t &)sr.status_report_verbosity, SR_OFF, SR_VERBOSE)); } -stat_t sr_get_si(nvObj_t *nv) { return(get_int32(nv, sr.status_report_interval)); } +stat_t sr_get_sv(nvObj_t *nv) { return(get_integer(nv, (uint8_t &)sr.status_report_verbosity)); } +stat_t sr_set_sv(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)sr.status_report_verbosity, SR_OFF, SR_VERBOSE)); } +stat_t sr_get_si(nvObj_t *nv) { return(get_integer(nv, sr.status_report_interval)); } stat_t sr_set_si(nvObj_t *nv) { return(set_int32(nv, sr.status_report_interval, STATUS_REPORT_MIN_MS, STATUS_REPORT_MAX_MS)); } /********************* @@ -595,8 +595,8 @@ stat_t qo_get(nvObj_t *nv) return (STAT_OK); } -stat_t qr_get_qv(nvObj_t *nv) { return(get_int(nv, (uint8_t &)qr.queue_report_verbosity)); } -stat_t qr_set_qv(nvObj_t *nv) { return(set_int(nv, (uint8_t &)qr.queue_report_verbosity, QR_OFF, QR_TRIPLE)); } +stat_t qr_get_qv(nvObj_t *nv) { return(get_integer(nv, (uint8_t &)qr.queue_report_verbosity)); } +stat_t qr_set_qv(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)qr.queue_report_verbosity, QR_OFF, QR_TRIPLE)); } /***************************************************************************** * JOB ID REPORTS diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index dba5eae5..c5f42a26 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -380,25 +380,25 @@ void spindle_end_override(const float ramp_time) **** Spindle Settings ************************************************************* ***********************************************************************************/ -stat_t sp_get_spmo(nvObj_t *nv) { return(get_int(nv, spindle.mode)); } -stat_t sp_set_spmo(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.mode, SPINDLE_DISABLED, SPINDLE_MODE_MAX)); } +stat_t sp_get_spmo(nvObj_t *nv) { return(get_integer(nv, spindle.mode)); } +stat_t sp_set_spmo(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)spindle.mode, SPINDLE_DISABLED, SPINDLE_MODE_MAX)); } -stat_t sp_get_spep(nvObj_t *nv) { return(get_int(nv, spindle.enable_polarity)); } +stat_t sp_get_spep(nvObj_t *nv) { return(get_integer(nv, spindle.enable_polarity)); } stat_t sp_set_spep(nvObj_t *nv) { - stat_t status = set_int(nv, (uint8_t &)spindle.enable_polarity, 0, 1); + stat_t status = set_integer(nv, (uint8_t &)spindle.enable_polarity, 0, 1); spindle_control_immediate(SPINDLE_OFF); // stop spindle and apply new settings return (status); } -stat_t sp_get_spdp(nvObj_t *nv) { return(get_int(nv, spindle.dir_polarity)); } +stat_t sp_get_spdp(nvObj_t *nv) { return(get_integer(nv, spindle.dir_polarity)); } stat_t sp_set_spdp(nvObj_t *nv) { - stat_t status = set_int(nv, (uint8_t &)spindle.dir_polarity, 0, 1); + stat_t status = set_integer(nv, (uint8_t &)spindle.dir_polarity, 0, 1); spindle_control_immediate(SPINDLE_OFF); // stop spindle and apply new settings return (status); } -stat_t sp_get_spph(nvObj_t *nv) { return(get_int(nv, spindle.pause_enable)); } -stat_t sp_set_spph(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.pause_enable, 0, 1)); } +stat_t sp_get_spph(nvObj_t *nv) { return(get_integer(nv, spindle.pause_enable)); } +stat_t sp_set_spph(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)spindle.pause_enable, 0, 1)); } stat_t sp_get_spde(nvObj_t *nv) { return(get_float(nv, spindle.spinup_delay)); } stat_t sp_set_spde(nvObj_t *nv) { return(set_float_range(nv, spindle.spinup_delay, 0, SPINDLE_DWELL_MAX)); } @@ -407,13 +407,13 @@ stat_t sp_set_spsn(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_min, stat_t sp_get_spsm(nvObj_t *nv) { return(get_float(nv, spindle.speed_max)); } stat_t sp_set_spsm(nvObj_t *nv) { return(set_float_range(nv, spindle.speed_max, SPINDLE_SPEED_MIN, SPINDLE_SPEED_MAX)); } -stat_t sp_get_spoe(nvObj_t *nv) { return(get_int(nv, spindle.override_enable)); } -stat_t sp_set_spoe(nvObj_t *nv) { return(set_int(nv, (uint8_t &)spindle.override_enable, 0, 1)); } +stat_t sp_get_spoe(nvObj_t *nv) { return(get_integer(nv, spindle.override_enable)); } +stat_t sp_set_spoe(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)spindle.override_enable, 0, 1)); } stat_t sp_get_spo(nvObj_t *nv) { return(get_float(nv, spindle.override_factor)); } stat_t sp_set_spo(nvObj_t *nv) { return(set_float_range(nv, spindle.override_factor, SPINDLE_OVERRIDE_MIN, SPINDLE_OVERRIDE_MAX)); } // These are provided as a way to view and control spindles without using M commands -stat_t sp_get_spc(nvObj_t *nv) { return(get_int(nv, spindle.state)); } +stat_t sp_get_spc(nvObj_t *nv) { return(get_integer(nv, spindle.state)); } stat_t sp_set_spc(nvObj_t *nv) { return(spindle_control_immediate((spControl)nv->value_int)); } stat_t sp_get_sps(nvObj_t *nv) { return(get_float(nv, spindle.speed)); } stat_t sp_set_sps(nvObj_t *nv) { return(spindle_speed_immediate(nv->value_flt)); } diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index b01868ac..81f570cc 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -816,8 +816,8 @@ static float _set_motor_steps_per_unit(nvObj_t *nv) */ // motor axis mapping -stat_t st_get_ma(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].motor_map)); } -stat_t st_set_ma(nvObj_t *nv) { return(set_int(nv, st_cfg.mot[_motor(nv->index)].motor_map, 0, AXES)); } +stat_t st_get_ma(nvObj_t *nv) { return(get_integer(nv, st_cfg.mot[_motor(nv->index)].motor_map)); } +stat_t st_set_ma(nvObj_t *nv) { return(set_integer(nv, st_cfg.mot[_motor(nv->index)].motor_map, 0, AXES)); } // step angle stat_t st_get_sa(nvObj_t *nv) { return(get_float(nv, st_cfg.mot[_motor(nv->index)].step_angle)); } @@ -838,7 +838,7 @@ stat_t st_set_tr(nvObj_t *nv) } // microsteps -stat_t st_get_mi(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].microsteps)); } +stat_t st_get_mi(nvObj_t *nv) { return(get_integer(nv, st_cfg.mot[_motor(nv->index)].microsteps)); } stat_t st_set_mi(nvObj_t *nv) { if (nv->value_int <= 0) { @@ -851,7 +851,7 @@ stat_t st_set_mi(nvObj_t *nv) nv_add_conditional_message((const char *)"*** WARNING *** Setting non-standard microstep value"); } // set it anyway, even if it's unsupported - ritorno(set_int(nv, st_cfg.mot[_motor(nv->index)].microsteps, 1, 255)); + ritorno(set_integer(nv, st_cfg.mot[_motor(nv->index)].microsteps, 1, 255)); _set_motor_steps_per_unit(nv); _set_hw_microsteps(_motor(nv->index), nv->value_int); return (STAT_OK); @@ -890,8 +890,8 @@ stat_t st_set_su(nvObj_t *nv) } // polarity -stat_t st_get_po(nvObj_t *nv) { return(get_int(nv, st_cfg.mot[_motor(nv->index)].polarity)); } -stat_t st_set_po(nvObj_t *nv) { return(set_int(nv, st_cfg.mot[_motor(nv->index)].polarity, 0, 1)); } +stat_t st_get_po(nvObj_t *nv) { return(get_integer(nv, st_cfg.mot[_motor(nv->index)].polarity)); } +stat_t st_set_po(nvObj_t *nv) { return(set_integer(nv, st_cfg.mot[_motor(nv->index)].polarity, 0, 1)); } // power management mode stat_t st_get_pm(nvObj_t *nv) @@ -905,7 +905,7 @@ stat_t st_set_pm(nvObj_t *nv) { // Test the value without setting it, then setPowerMode() now // to both set and take effect immediately. - ritorno(set_int(nv, (uint8_t &)cs.null, 0, MOTOR_POWER_MODE_MAX_VALUE )); + ritorno(set_integer(nv, (uint8_t &)cs.null, 0, MOTOR_POWER_MODE_MAX_VALUE )); Motors[_motor(nv->index)]->setPowerMode((stPowerMode)nv->value_int); return (STAT_OK); } diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index 8720109a..56723673 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -296,7 +296,7 @@ void tx_print_tv(nvObj_t *nv) { text_print(nv, fmt_tv);} // TYPE_INT * txt_set_tv() - set text verbosity */ -stat_t txt_get_tv(nvObj_t *nv) { return (get_int(nv, txt.text_verbosity)); } -stat_t txt_set_tv(nvObj_t *nv) { return (set_int(nv, txt.text_verbosity, TV_SILENT, TV_VERBOSE)); } +stat_t txt_get_tv(nvObj_t *nv) { return (get_integer(nv, txt.text_verbosity)); } +stat_t txt_set_tv(nvObj_t *nv) { return (set_integer(nv, txt.text_verbosity, TV_SILENT, TV_VERBOSE)); } #endif // __TEXT_MODE From 647d9e60b3cf803b74a9ecc7a227ec9fe68deb3c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 19:47:51 -0400 Subject: [PATCH 217/283] Job kill ends with END (not alarm) --- g2core/cycle_feedhold.cpp | 5 +++-- g2core/g2core.cppproj | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index df085f33..13ce7d2b 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -469,9 +469,10 @@ static stat_t _run_job_kill_final() cm_set_motion_state(MOTION_STOP); // set to stop and set the active model cm->hold_state = FEEDHOLD_OFF; - cm->cycle_type = CYCLE_NONE; - cm->machine_state = MACHINE_ALARM; +// cm->cycle_type = CYCLE_NONE; +// cm->machine_state = MACHINE_ALARM; + cm_program_end(); rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index bb1cf7a0..0014b2ec 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 From 486b118458d36597a2edfcf6f738317a118490a3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 20 Mar 2017 20:02:20 -0400 Subject: [PATCH 218/283] A little cleanup. No functional changes --- g2core/config_app.cpp | 1501 ++++++++++++++++++------------------- g2core/cycle_feedhold.cpp | 4 +- 2 files changed, 751 insertions(+), 754 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 333d887c..71fd2f47 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -104,258 +104,257 @@ static stat_t get_tick(nvObj_t *nv); // get system tick count */ const cfgItem_t cfgArray[] = { // group token flags p, print_func, get_func, set_func, get/set target, default value - { "sys", "fb", _fn, 2, hw_print_fb, hw_get_fb, set_ro, (float *)&cs.null, 0 }, // MUST BE FIRST for persistence checking! - { "sys", "fv", _fn, 2, hw_print_fv, hw_get_fv, set_ro, (float *)&cs.null, 0 }, - { "sys", "fbs",_sn, 0, hw_print_fbs, hw_get_fbs, set_ro, (float *)&cs.null, 0 }, - { "sys", "fbc",_sn, 0, hw_print_fbc, hw_get_fbc, set_ro, (float *)&cs.null, 0 }, - { "sys", "hp", _sn, 0, hw_print_hp, hw_get_hp, set_ro, (float *)&cs.null, 0 }, - { "sys", "hv", _sn, 0, hw_print_hv, hw_get_hv, set_ro, (float *)&cs.null, 0 }, - { "sys", "id", _sn, 0, hw_print_id, hw_get_id, set_ro, (float *)&cs.null, 0 }, // device ID (ASCII signature) + { "sys", "fb", _fn, 2, hw_print_fb, hw_get_fb, set_ro, nullptr, 0 }, // MUST BE FIRST for persistence checking! + { "sys", "fv", _fn, 2, hw_print_fv, hw_get_fv, set_ro, nullptr, 0 }, + { "sys", "fbs",_sn, 0, hw_print_fbs, hw_get_fbs, set_ro, nullptr, 0 }, + { "sys", "fbc",_sn, 0, hw_print_fbc, hw_get_fbc, set_ro, nullptr, 0 }, + { "sys", "hp", _sn, 0, hw_print_hp, hw_get_hp, set_ro, nullptr, 0 }, + { "sys", "hv", _sn, 0, hw_print_hv, hw_get_hv, set_ro, nullptr, 0 }, + { "sys", "id", _sn, 0, hw_print_id, hw_get_id, set_ro, nullptr, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) - { "", "stat",_i0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state - { "","stat2",_i0, 0, cm_print_stat, cm_get_stat2,set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _ii, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null,0 }, // Model line number - { "", "line",_ii, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity - { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs",_i0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_i0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots",_i0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold",_i0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit",_i0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor",_i0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo",_i0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan",_i0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path",_i0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist",_i0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo",_i0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_i0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_i0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool - { "", "g92e",_i0, 0, cm_print_g92e, cm_get_g92e, set_ro, nullptr, 0 }, // G92 enable state -// { "", "g92e",_i0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm->gmx.origin_offset_enable, 0 }, // G92 enabled + { "", "stat",_i0, 0, cm_print_stat, cm_get_stat, set_ro, nullptr, 0 }, // combined machine state + { "","stat2",_i0, 0, cm_print_stat, cm_get_stat2,set_ro, nullptr, 0 }, // combined machine state + { "", "n", _ii, 0, cm_print_line, cm_get_mline,set_noop,nullptr,0 }, // Model line number + { "", "line",_ii, 0, cm_print_line, cm_get_line, set_ro, nullptr, 0 }, // Active line number - model or runtime line number + { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, nullptr, 0 }, // current velocity + { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, nullptr, 0 }, // feed rate + { "", "macs",_i0, 0, cm_print_macs, cm_get_macs, set_ro, nullptr, 0 }, // raw machine state + { "", "cycs",_i0, 0, cm_print_cycs, cm_get_cycs, set_ro, nullptr, 0 }, // cycle state + { "", "mots",_i0, 0, cm_print_mots, cm_get_mots, set_ro, nullptr, 0 }, // motion state + { "", "hold",_i0, 0, cm_print_hold, cm_get_hold, set_ro, nullptr, 0 }, // feedhold state + { "", "unit",_i0, 0, cm_print_unit, cm_get_unit, set_ro, nullptr, 0 }, // units mode + { "", "coor",_i0, 0, cm_print_coor, cm_get_coor, set_ro, nullptr, 0 }, // coordinate system + { "", "momo",_i0, 0, cm_print_momo, cm_get_momo, set_ro, nullptr, 0 }, // motion mode + { "", "plan",_i0, 0, cm_print_plan, cm_get_plan, set_ro, nullptr, 0 }, // plane select + { "", "path",_i0, 0, cm_print_path, cm_get_path, set_ro, nullptr, 0 }, // path control mode + { "", "dist",_i0, 0, cm_print_dist, cm_get_dist, set_ro, nullptr, 0 }, // distance mode + { "", "admo",_i0, 0, cm_print_admo, cm_get_admo, set_ro, nullptr, 0 }, // arc distance mode + { "", "frmo",_i0, 0, cm_print_frmo, cm_get_frmo, set_ro, nullptr, 0 }, // feed rate mode + { "", "tool",_i0, 0, cm_print_tool, cm_get_toolv,set_ro, nullptr, 0 }, // active tool + { "", "g92e",_i0, 0, cm_print_g92e, cm_get_g92e, set_ro, nullptr, 0 }, // G92 enable state #ifdef TEMPORARY_HAS_LEDS - { "", "_leds",_i0, 0, tx_print_nul, _get_leds,_set_leds, (float *)&cs.null, 0 }, // TEMPORARY - change LEDs + { "", "_leds",_i0, 0, tx_print_nul, _get_leds,_set_leds, nullptr, 0 }, // TEMPORARY - change LEDs #endif - { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position + { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // X machine position + { "mpo","mpoy",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // Y machine position + { "mpo","mpoz",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // Z machine position + { "mpo","mpoa",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // A machine position + { "mpo","mpob",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // B machine position + { "mpo","mpoc",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // C machine position - { "pos","posx",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 5, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position + { "pos","posx",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // X work position + { "pos","posy",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // Y work position + { "pos","posz",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // Z work position + { "pos","posa",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // A work position + { "pos","posb",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // B work position + { "pos","posc",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // C work position - { "ofs","ofsx",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset - { "ofs","ofsy",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset - { "ofs","ofsz",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Z work offset - { "ofs","ofsa",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // A work offset - { "ofs","ofsb",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset - { "ofs","ofsc",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset + { "ofs","ofsx",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // X work offset + { "ofs","ofsy",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // Y work offset + { "ofs","ofsz",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // Z work offset + { "ofs","ofsa",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // A work offset + { "ofs","ofsb",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // B work offset + { "ofs","ofsc",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // C work offset - { "hom","home",_i0, 0, cm_print_home,cm_get_home,cm_set_home,(float *)&cs.null,0 }, // homing state, invoke homing cycle - { "hom","homx",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // X homed - Homing status group - { "hom","homy",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Y homed - { "hom","homz",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // Z homed - { "hom","homa",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // A homed - { "hom","homb",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // B homed - { "hom","homc",_i0, 0, cm_print_hom, cm_get_hom, set_ro, (float *)&cs.null, 0 }, // C homed + { "hom","home",_i0, 0, cm_print_home,cm_get_home,cm_set_home,nullptr,0 }, // homing state, invoke homing cycle + { "hom","homx",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // X homed - Homing status group + { "hom","homy",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // Y homed + { "hom","homz",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // Z homed + { "hom","homa",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // A homed + { "hom","homb",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // B homed + { "hom","homc",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // C homed - { "prb","prbe",_i0, 0, tx_print_nul, cm_get_prob,set_ro, (float *)&cs.null, 0 }, // probing state - { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // X probe results - { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Y probe results - { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // Z probe results - { "prb","prba",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // A probe results - { "prb","prbb",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // B probe results - { "prb","prbc",_f0, 5, tx_print_nul, cm_get_prb, set_ro, (float *)&cs.null, 0 }, // C probe results + { "prb","prbe",_i0, 0, tx_print_nul, cm_get_prob,set_ro, nullptr, 0 }, // probing state + { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // X probe results + { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // Y probe results + { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // Z probe results + { "prb","prba",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // A probe results + { "prb","prbb",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // B probe results + { "prb","prbc",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // C probe results - { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in X axis - { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Y axis - { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in Z axis - { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in A axis - { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in B axis - { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jog, (float *)&cs.null, 0}, // jog in C axis + { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in X axis + { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in Y axis + { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in Z axis + { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in A axis + { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in B axis + { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in C axis - { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts - { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, // motor power readouts + { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, #if (MOTORS > 2) - { "pwr","pwr3",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr3",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, #endif #if (MOTORS > 3) - { "pwr","pwr4",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr4",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, #endif #if (MOTORS > 4) - { "pwr","pwr5",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr5",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, #endif #if (MOTORS > 5) - { "pwr","pwr6",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, + { "pwr","pwr6",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, #endif // Motor parameters - { "1","1ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M1_MOTOR_MAP }, - { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M1_STEP_ANGLE }, - { "1","1tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M1_TRAVEL_PER_REV }, - { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M1_STEPS_PER_UNIT }, - { "1","1mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M1_MICROSTEPS }, - { "1","1po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M1_POLARITY }, - { "1","1pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, - { "1","1pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M1_POWER_LEVEL }, + { "1","1ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M1_MOTOR_MAP }, + { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M1_STEP_ANGLE }, + { "1","1tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M1_TRAVEL_PER_REV }, + { "1","1su",_fipi,5, st_print_su, st_get_su, st_set_su, nullptr, M1_STEPS_PER_UNIT }, + { "1","1mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, nullptr, M1_MICROSTEPS }, + { "1","1po",_iip, 0, st_print_po, st_get_po, st_set_po, nullptr, M1_POLARITY }, + { "1","1pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, nullptr, M1_POWER_MODE }, + { "1","1pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M1_POWER_LEVEL }, // { "1","1pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, // { "1","1mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, #if (MOTORS >= 2) - { "2","2ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M2_MOTOR_MAP }, - { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M2_STEP_ANGLE }, - { "2","2tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M2_TRAVEL_PER_REV }, - { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M2_STEPS_PER_UNIT }, - { "2","2mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M2_MICROSTEPS }, - { "2","2po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M2_POLARITY }, - { "2","2pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, - { "2","2pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M2_POWER_LEVEL}, + { "2","2ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M2_MOTOR_MAP }, + { "2","2sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M2_STEP_ANGLE }, + { "2","2tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M2_TRAVEL_PER_REV }, + { "2","2su",_fipi,5, st_print_su, st_get_su, st_set_su, nullptr, M2_STEPS_PER_UNIT }, + { "2","2mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, nullptr, M2_MICROSTEPS }, + { "2","2po",_iip, 0, st_print_po, st_get_po, st_set_po, nullptr, M2_POLARITY }, + { "2","2pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, nullptr, M2_POWER_MODE }, + { "2","2pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M2_POWER_LEVEL}, // { "2","2pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, // { "2","2mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 3) - { "3","3ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M3_MOTOR_MAP }, - { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M3_STEP_ANGLE }, - { "3","3tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M3_TRAVEL_PER_REV }, - { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M3_STEPS_PER_UNIT }, - { "3","3mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M3_MICROSTEPS }, - { "3","3po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M3_POLARITY }, - { "3","3pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, - { "3","3pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M3_POWER_LEVEL }, + { "3","3ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M3_MOTOR_MAP }, + { "3","3sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M3_STEP_ANGLE }, + { "3","3tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M3_TRAVEL_PER_REV }, + { "3","3su",_fipi,5, st_print_su, st_get_su, st_set_su, nullptr, M3_STEPS_PER_UNIT }, + { "3","3mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, nullptr, M3_MICROSTEPS }, + { "3","3po",_iip, 0, st_print_po, st_get_po, st_set_po, nullptr, M3_POLARITY }, + { "3","3pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, nullptr, M3_POWER_MODE }, + { "3","3pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M3_POWER_LEVEL }, // { "3","3pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, // { "3","3mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 4) - { "4","4ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M4_MOTOR_MAP }, - { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M4_STEP_ANGLE }, - { "4","4tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M4_TRAVEL_PER_REV }, - { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M4_STEPS_PER_UNIT }, - { "4","4mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M4_MICROSTEPS }, - { "4","4po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M4_POLARITY }, - { "4","4pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, - { "4","4pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M4_POWER_LEVEL }, + { "4","4ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M4_MOTOR_MAP }, + { "4","4sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M4_STEP_ANGLE }, + { "4","4tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M4_TRAVEL_PER_REV }, + { "4","4su",_fipi,5, st_print_su, st_get_su, st_set_su, nullptr, M4_STEPS_PER_UNIT }, + { "4","4mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, nullptr, M4_MICROSTEPS }, + { "4","4po",_iip, 0, st_print_po, st_get_po, st_set_po, nullptr, M4_POLARITY }, + { "4","4pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, nullptr, M4_POWER_MODE }, + { "4","4pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M4_POWER_LEVEL }, // { "4","4pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, // { "4","4mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 5) - { "5","5ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M5_MOTOR_MAP }, - { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M5_STEP_ANGLE }, - { "5","5tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M5_TRAVEL_PER_REV }, - { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M5_STEPS_PER_UNIT }, - { "5","5mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M5_MICROSTEPS }, - { "5","5po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M5_POLARITY }, - { "5","5pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, - { "5","5pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M5_POWER_LEVEL }, + { "5","5ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M5_MOTOR_MAP }, + { "5","5sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M5_STEP_ANGLE }, + { "5","5tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M5_TRAVEL_PER_REV }, + { "5","5su",_fipi,5, st_print_su, st_get_su, st_set_su, nullptr, M5_STEPS_PER_UNIT }, + { "5","5mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, nullptr, M5_MICROSTEPS }, + { "5","5po",_iip, 0, st_print_po, st_get_po, st_set_po, nullptr, M5_POLARITY }, + { "5","5pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, nullptr, M5_POWER_MODE }, + { "5","5pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M5_POWER_LEVEL }, // { "5","5pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, // { "5","5mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_5].motor_timeout, M5_MOTOR_TIMEOUT }, #endif #if (MOTORS >= 6) - { "6","6ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, (float *)&cs.null, M6_MOTOR_MAP }, - { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, (float *)&cs.null, M6_STEP_ANGLE }, - { "6","6tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, (float *)&cs.null, M6_TRAVEL_PER_REV }, - { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, (float *)&cs.null, M6_STEPS_PER_UNIT }, - { "6","6mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, (float *)&cs.null, M6_MICROSTEPS }, - { "6","6po",_iip, 0, st_print_po, st_get_po, st_set_po, (float *)&cs.null, M6_POLARITY }, - { "6","6pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, - { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, (float *)&cs.null, M6_POWER_LEVEL }, + { "6","6ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M6_MOTOR_MAP }, + { "6","6sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M6_STEP_ANGLE }, + { "6","6tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M6_TRAVEL_PER_REV }, + { "6","6su",_fipi,5, st_print_su, st_get_su, st_set_su, nullptr, M6_STEPS_PER_UNIT }, + { "6","6mi",_iip, 0, st_print_mi, st_get_mi, st_set_mi, nullptr, M6_MICROSTEPS }, + { "6","6po",_iip, 0, st_print_po, st_get_po, st_set_po, nullptr, M6_POLARITY }, + { "6","6pm",_iip, 0, st_print_pm, st_get_pm, st_set_pm, nullptr, M6_POWER_MODE }, + { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M6_POWER_LEVEL }, // { "6","6pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, // { "6","6mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, #endif // Axis parameters - { "x","xam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, X_AXIS_MODE }, - { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, X_VELOCITY_MAX }, - { "x","xfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, X_FEEDRATE_MAX }, - { "x","xtn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, X_TRAVEL_MIN }, - { "x","xtm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, X_TRAVEL_MAX }, - { "x","xjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, X_JERK_MAX }, - { "x","xjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, X_JERK_HIGH_SPEED }, - { "x","xhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, X_HOMING_INPUT }, - { "x","xhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, X_HOMING_DIRECTION }, - { "x","xsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, X_SEARCH_VELOCITY }, - { "x","xlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, X_LATCH_VELOCITY }, - { "x","xlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, X_LATCH_BACKOFF }, - { "x","xzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, X_ZERO_BACKOFF }, + { "x","xam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, X_AXIS_MODE }, + { "x","xvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, X_VELOCITY_MAX }, + { "x","xfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, X_FEEDRATE_MAX }, + { "x","xtn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, X_TRAVEL_MIN }, + { "x","xtm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, X_TRAVEL_MAX }, + { "x","xjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, X_JERK_MAX }, + { "x","xjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, X_JERK_HIGH_SPEED }, + { "x","xhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, X_HOMING_INPUT }, + { "x","xhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, X_HOMING_DIRECTION }, + { "x","xsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, X_SEARCH_VELOCITY }, + { "x","xlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, X_LATCH_VELOCITY }, + { "x","xlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, X_LATCH_BACKOFF }, + { "x","xzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, X_ZERO_BACKOFF }, - { "y","yam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Y_AXIS_MODE }, - { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Y_VELOCITY_MAX }, - { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Y_FEEDRATE_MAX }, - { "y","ytn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Y_TRAVEL_MIN }, - { "y","ytm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Y_TRAVEL_MAX }, - { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Y_JERK_MAX }, - { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, Y_JERK_HIGH_SPEED }, - { "y","yhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Y_HOMING_INPUT }, - { "y","yhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Y_HOMING_DIRECTION }, - { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Y_SEARCH_VELOCITY }, - { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Y_LATCH_VELOCITY }, - { "y","ylb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Y_LATCH_BACKOFF }, - { "y","yzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, Y_ZERO_BACKOFF }, + { "y","yam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, Y_AXIS_MODE }, + { "y","yvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, Y_VELOCITY_MAX }, + { "y","yfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, Y_FEEDRATE_MAX }, + { "y","ytn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, Y_TRAVEL_MIN }, + { "y","ytm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, Y_TRAVEL_MAX }, + { "y","yjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, Y_JERK_MAX }, + { "y","yjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, Y_JERK_HIGH_SPEED }, + { "y","yhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, Y_HOMING_INPUT }, + { "y","yhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, Y_HOMING_DIRECTION }, + { "y","ysv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, Y_SEARCH_VELOCITY }, + { "y","ylv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, Y_LATCH_VELOCITY }, + { "y","ylb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, Y_LATCH_BACKOFF }, + { "y","yzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, Y_ZERO_BACKOFF }, - { "z","zam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, Z_AXIS_MODE }, - { "z","zvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, Z_VELOCITY_MAX }, - { "z","zfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, Z_FEEDRATE_MAX }, - { "z","ztn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, Z_TRAVEL_MIN }, - { "z","ztm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, Z_TRAVEL_MAX }, - { "z","zjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, Z_JERK_MAX }, - { "z","zjh",_fipc, 0, cm_print_jh, cm_get_jm, cm_set_jh, (float *)&cs.null, Z_JERK_HIGH_SPEED }, - { "z","zhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, Z_HOMING_INPUT }, - { "z","zhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, Z_HOMING_DIRECTION }, - { "z","zsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, Z_SEARCH_VELOCITY }, - { "z","zlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, Z_LATCH_VELOCITY }, - { "z","zlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, Z_LATCH_BACKOFF }, - { "z","zzb",_fipc, 5, cm_print_zb, cm_get_lb, cm_set_zb, (float *)&cs.null, Z_ZERO_BACKOFF }, + { "z","zam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, Z_AXIS_MODE }, + { "z","zvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, Z_VELOCITY_MAX }, + { "z","zfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, Z_FEEDRATE_MAX }, + { "z","ztn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, Z_TRAVEL_MIN }, + { "z","ztm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, Z_TRAVEL_MAX }, + { "z","zjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, Z_JERK_MAX }, + { "z","zjh",_fipc, 0, cm_print_jh, cm_get_jm, cm_set_jh, nullptr, Z_JERK_HIGH_SPEED }, + { "z","zhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, Z_HOMING_INPUT }, + { "z","zhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, Z_HOMING_DIRECTION }, + { "z","zsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, Z_SEARCH_VELOCITY }, + { "z","zlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, Z_LATCH_VELOCITY }, + { "z","zlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, Z_LATCH_BACKOFF }, + { "z","zzb",_fipc, 5, cm_print_zb, cm_get_lb, cm_set_zb, nullptr, Z_ZERO_BACKOFF }, - { "a","aam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, A_AXIS_MODE }, - { "a","avm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, A_VELOCITY_MAX }, - { "a","afr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, A_FEEDRATE_MAX }, - { "a","atn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, A_TRAVEL_MIN }, - { "a","atm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, A_TRAVEL_MAX }, - { "a","ajm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, A_JERK_MAX }, - { "a","ajh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, A_JERK_HIGH_SPEED }, - { "a","ara",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, A_RADIUS}, - { "a","ahi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, A_HOMING_INPUT }, - { "a","ahd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, A_HOMING_DIRECTION }, - { "a","asv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, A_SEARCH_VELOCITY }, - { "a","alv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, A_LATCH_VELOCITY }, - { "a","alb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, A_LATCH_BACKOFF }, - { "a","azb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, A_ZERO_BACKOFF }, + { "a","aam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, A_AXIS_MODE }, + { "a","avm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, A_VELOCITY_MAX }, + { "a","afr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, A_FEEDRATE_MAX }, + { "a","atn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, A_TRAVEL_MIN }, + { "a","atm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, A_TRAVEL_MAX }, + { "a","ajm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, A_JERK_MAX }, + { "a","ajh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, A_JERK_HIGH_SPEED }, + { "a","ara",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, nullptr, A_RADIUS}, + { "a","ahi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, A_HOMING_INPUT }, + { "a","ahd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, A_HOMING_DIRECTION }, + { "a","asv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, A_SEARCH_VELOCITY }, + { "a","alv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, A_LATCH_VELOCITY }, + { "a","alb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, A_LATCH_BACKOFF }, + { "a","azb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, A_ZERO_BACKOFF }, - { "b","bam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, B_AXIS_MODE }, - { "b","bvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, B_VELOCITY_MAX }, - { "b","bfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, B_FEEDRATE_MAX }, - { "b","btn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, B_TRAVEL_MIN }, - { "b","btm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, B_TRAVEL_MAX }, - { "b","bjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, B_JERK_MAX }, - { "b","bjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, B_JERK_HIGH_SPEED }, - { "b","bra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, B_RADIUS }, - { "b","bhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, B_HOMING_INPUT }, - { "b","bhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, B_HOMING_DIRECTION }, - { "b","bsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, B_SEARCH_VELOCITY }, - { "b","blv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, B_LATCH_VELOCITY }, - { "b","blb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, B_LATCH_BACKOFF }, - { "b","bzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, B_ZERO_BACKOFF }, + { "b","bam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, B_AXIS_MODE }, + { "b","bvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, B_VELOCITY_MAX }, + { "b","bfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, B_FEEDRATE_MAX }, + { "b","btn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, B_TRAVEL_MIN }, + { "b","btm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, B_TRAVEL_MAX }, + { "b","bjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, B_JERK_MAX }, + { "b","bjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, B_JERK_HIGH_SPEED }, + { "b","bra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, nullptr, B_RADIUS }, + { "b","bhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, B_HOMING_INPUT }, + { "b","bhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, B_HOMING_DIRECTION }, + { "b","bsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, B_SEARCH_VELOCITY }, + { "b","blv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, B_LATCH_VELOCITY }, + { "b","blb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, B_LATCH_BACKOFF }, + { "b","bzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, B_ZERO_BACKOFF }, - { "c","cam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, (float *)&cs.null, C_AXIS_MODE }, - { "c","cvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, (float *)&cs.null, C_VELOCITY_MAX }, - { "c","cfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, (float *)&cs.null, C_FEEDRATE_MAX }, - { "c","ctn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, (float *)&cs.null, C_TRAVEL_MIN }, - { "c","ctm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, (float *)&cs.null, C_TRAVEL_MAX }, - { "c","cjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, (float *)&cs.null, C_JERK_MAX }, - { "c","cjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, (float *)&cs.null, C_JERK_HIGH_SPEED }, - { "c","cra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, (float *)&cs.null, C_RADIUS }, - { "c","chi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, (float *)&cs.null, C_HOMING_INPUT }, - { "c","chd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, (float *)&cs.null, C_HOMING_DIRECTION }, - { "c","csv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, (float *)&cs.null, C_SEARCH_VELOCITY }, - { "c","clv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, (float *)&cs.null, C_LATCH_VELOCITY }, - { "c","clb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, (float *)&cs.null, C_LATCH_BACKOFF }, - { "c","czb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, (float *)&cs.null, C_ZERO_BACKOFF }, + { "c","cam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, C_AXIS_MODE }, + { "c","cvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, C_VELOCITY_MAX }, + { "c","cfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, C_FEEDRATE_MAX }, + { "c","ctn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, C_TRAVEL_MIN }, + { "c","ctm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, C_TRAVEL_MAX }, + { "c","cjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, C_JERK_MAX }, + { "c","cjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, C_JERK_HIGH_SPEED }, + { "c","cra",_fipc, 5, cm_print_ra, cm_get_ra, cm_set_ra, nullptr, C_RADIUS }, + { "c","chi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, C_HOMING_INPUT }, + { "c","chd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, C_HOMING_DIRECTION }, + { "c","csv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, C_SEARCH_VELOCITY }, + { "c","clv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, C_LATCH_VELOCITY }, + { "c","clb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, C_LATCH_BACKOFF }, + { "c","czb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, C_ZERO_BACKOFF }, // Digital input configs { "di1","di1mo",_iip, 0, io_print_mo, io_get_mo, io_set_mo, nullptr, DI1_MODE }, @@ -411,25 +410,25 @@ const cfgItem_t cfgArray[] = { #endif // Digital input state readers - { "in","in1", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in2", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in3", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in4", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in5", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in6", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in7", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, - { "in","in8", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in1", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in2", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in3", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in4", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in5", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in6", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in7", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, + { "in","in8", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #if (D_IN_CHANNELS >= 9) - { "in","in9", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in9", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #endif #if (D_IN_CHANNELS >= 10) - { "in","in10", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in10", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #endif #if (D_IN_CHANNELS >= 11) - { "in","in11", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in11", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #endif #if (D_IN_CHANNELS >= 12) - { "in","in12", _i0, 0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, + { "in","in12", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #endif // digital output configs @@ -448,18 +447,18 @@ const cfgItem_t cfgArray[] = { { "do13","do13mo",_iip, 0, io_print_domode, io_get_domode, io_set_domode, nullptr, DO13_MODE }, // Digital output state readers (default to non-active) - { "out","out1", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out2", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out3", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out4", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out5", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out6", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out7", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out8", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out9", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out10", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out11", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, - { "out","out12", _i0, 2, io_print_out, io_get_output, io_set_output, (float *)&cs.null, 0 }, + { "out","out1", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out2", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out3", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out4", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out5", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out6", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out7", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out8", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out9", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out10", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out11", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, + { "out","out12", _i0, 2, io_print_out, io_get_output, io_set_output, nullptr, 0 }, // PWM settings { "p1","p1frq",_fip, 0, pwm_print_p1frq, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].frequency, P1_PWM_FREQUENCY }, @@ -475,214 +474,214 @@ const cfgItem_t cfgArray[] = { // temperature configs - pid active values (read-only) // NOTICE: If you change these PID group keys, you MUST change the get/set functions too! - { "pid1","pid1p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid1","pid1i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid1","pid1d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid1","pid1p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, nullptr, 0 }, + { "pid1","pid1i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, nullptr, 0 }, + { "pid1","pid1d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, nullptr, 0 }, - { "pid2","pid2p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid2","pid2d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid2","pid2p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, nullptr, 0 }, + { "pid2","pid2i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, nullptr, 0 }, + { "pid2","pid2d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, nullptr, 0 }, - { "pid3","pid3p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, (float *)&cs.null, 0 }, - { "pid3","pid3d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, (float *)&cs.null, 0 }, + { "pid3","pid3p",_fip, 3, tx_print_nul, cm_get_pid_p, set_ro, nullptr, 0 }, + { "pid3","pid3i",_fip, 5, tx_print_nul, cm_get_pid_i, set_ro, nullptr, 0 }, + { "pid3","pid3d",_fip, 5, tx_print_nul, cm_get_pid_d, set_ro, nullptr, 0 }, // temperature configs - heater set values (read-write) // NOTICE: If you change these heater group keys, you MUST change the get/set functions too! - { "he1","he1e", _bip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H1_DEFAULT_ENABLE }, - { "he1","he1at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he1","he1p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H1_DEFAULT_P }, - { "he1","he1i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H1_DEFAULT_I }, - { "he1","he1d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H1_DEFAULT_D }, - { "he1","he1st",_fi, 1, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he1","he1t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he1","he1op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he1","he1tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he1","he1an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he1","he1fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he1","he1fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he1","he1fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he1","he1fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he1","he1e", _bip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, nullptr, H1_DEFAULT_ENABLE }, + { "he1","he1at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, nullptr, 0 }, + { "he1","he1p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, nullptr, H1_DEFAULT_P }, + { "he1","he1i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, nullptr, H1_DEFAULT_I }, + { "he1","he1d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, nullptr, H1_DEFAULT_D }, + { "he1","he1st",_fi, 1, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, nullptr, 0 }, + { "he1","he1t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, nullptr, 0 }, + { "he1","he1op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, nullptr, 0 }, + { "he1","he1tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, nullptr, 0 }, + { "he1","he1an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, nullptr, 0 }, + { "he1","he1fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, nullptr, 0 }, + { "he1","he1fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, nullptr, 0 }, + { "he1","he1fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, nullptr, 0 }, + { "he1","he1fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, nullptr, 0 }, - { "he2","he2e", _iip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H2_DEFAULT_ENABLE }, - { "he2","he2at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he2","he2p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H2_DEFAULT_P }, - { "he2","he2i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H2_DEFAULT_I }, - { "he2","he2d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H2_DEFAULT_D }, - { "he2","he2st",_fi, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he2","he2t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he2","he2op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he2","he2tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he2","he2an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he2","he2fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he2","he2fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he2","he2fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he2","he2fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he2","he2e", _iip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, nullptr, H2_DEFAULT_ENABLE }, + { "he2","he2at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, nullptr, 0 }, + { "he2","he2p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, nullptr, H2_DEFAULT_P }, + { "he2","he2i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, nullptr, H2_DEFAULT_I }, + { "he2","he2d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, nullptr, H2_DEFAULT_D }, + { "he2","he2st",_fi, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, nullptr, 0 }, + { "he2","he2t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, nullptr, 0 }, + { "he2","he2op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, nullptr, 0 }, + { "he2","he2tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, nullptr, 0 }, + { "he2","he2an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, nullptr, 0 }, + { "he2","he2fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, nullptr, 0 }, + { "he2","he2fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, nullptr, 0 }, + { "he2","he2fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, nullptr, 0 }, + { "he2","he2fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, nullptr, 0 }, - { "he3","he3e", _iip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, (float *)&cs.null, H3_DEFAULT_ENABLE }, - { "he3","he3at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, (float *)&cs.null, 0 }, - { "he3","he3p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, (float *)&cs.null, H3_DEFAULT_P }, - { "he3","he3i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, (float *)&cs.null, H3_DEFAULT_I }, - { "he3","he3d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, (float *)&cs.null, H3_DEFAULT_D }, - { "he3","he3st",_fi, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, (float *)&cs.null, 0 }, - { "he3","he3t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, (float *)&cs.null, 0 }, - { "he3","he3op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, (float *)&cs.null, 0 }, - { "he3","he3tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, (float *)&cs.null, 0 }, - { "he3","he3an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, (float *)&cs.null, 0 }, - { "he3","he3fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, (float *)&cs.null, 0 }, - { "he3","he3fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, (float *)&cs.null, 0 }, - { "he3","he3fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, (float *)&cs.null, 0 }, - { "he3","he3fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, (float *)&cs.null, 0 }, + { "he3","he3e", _iip, 0, tx_print_nul, cm_get_heater_enable, cm_set_heater_enable, nullptr, H3_DEFAULT_ENABLE }, + { "he3","he3at",_b0, 0, tx_print_nul, cm_get_at_temperature, set_ro, nullptr, 0 }, + { "he3","he3p", _fip, 3, tx_print_nul, cm_get_heater_p, cm_set_heater_p, nullptr, H3_DEFAULT_P }, + { "he3","he3i", _fip, 5, tx_print_nul, cm_get_heater_i, cm_set_heater_i, nullptr, H3_DEFAULT_I }, + { "he3","he3d", _fip, 5, tx_print_nul, cm_get_heater_d, cm_set_heater_d, nullptr, H3_DEFAULT_D }, + { "he3","he3st",_fi, 0, tx_print_nul, cm_get_set_temperature, cm_set_set_temperature, nullptr, 0 }, + { "he3","he3t", _fi, 1, tx_print_nul, cm_get_temperature, set_ro, nullptr, 0 }, + { "he3","he3op",_fi, 3, tx_print_nul, cm_get_heater_output, set_ro, nullptr, 0 }, + { "he3","he3tr",_fi, 3, tx_print_nul, cm_get_thermistor_resistance, set_ro, nullptr, 0 }, + { "he3","he3an",_fi, 0, tx_print_nul, cm_get_heater_adc, set_ro, nullptr, 0 }, + { "he3","he3fp",_fi, 1, tx_print_nul, cm_get_fan_power, cm_set_fan_power, nullptr, 0 }, + { "he3","he3fm",_fi, 1, tx_print_nul, cm_get_fan_min_power, cm_set_fan_min_power, nullptr, 0 }, + { "he3","he3fl",_fi, 1, tx_print_nul, cm_get_fan_low_temp, cm_set_fan_low_temp, nullptr, 0 }, + { "he3","he3fh",_fi, 1, tx_print_nul, cm_get_fan_high_temp, cm_set_fan_high_temp, nullptr, 0 }, // Coordinate system offsets (G54-G59 and G92) - { "g54","g54x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_X_OFFSET }, - { "g54","g54y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Y_OFFSET }, - { "g54","g54z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_Z_OFFSET }, - { "g54","g54a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_A_OFFSET }, - { "g54","g54b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_B_OFFSET }, - { "g54","g54c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G54_C_OFFSET }, + { "g54","g54x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_X_OFFSET }, + { "g54","g54y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_Y_OFFSET }, + { "g54","g54z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_Z_OFFSET }, + { "g54","g54a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_A_OFFSET }, + { "g54","g54b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_B_OFFSET }, + { "g54","g54c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_C_OFFSET }, - { "g55","g55x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_X_OFFSET }, - { "g55","g55y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Y_OFFSET }, - { "g55","g55z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_Z_OFFSET }, - { "g55","g55a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_A_OFFSET }, - { "g55","g55b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_B_OFFSET }, - { "g55","g55c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G55_C_OFFSET }, + { "g55","g55x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_X_OFFSET }, + { "g55","g55y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_Y_OFFSET }, + { "g55","g55z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_Z_OFFSET }, + { "g55","g55a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_A_OFFSET }, + { "g55","g55b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_B_OFFSET }, + { "g55","g55c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_C_OFFSET }, - { "g56","g56x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_X_OFFSET }, - { "g56","g56y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Y_OFFSET }, - { "g56","g56z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_Z_OFFSET }, - { "g56","g56a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_A_OFFSET }, - { "g56","g56b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_B_OFFSET }, - { "g56","g56c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G56_C_OFFSET }, + { "g56","g56x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_X_OFFSET }, + { "g56","g56y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_Y_OFFSET }, + { "g56","g56z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_Z_OFFSET }, + { "g56","g56a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_A_OFFSET }, + { "g56","g56b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_B_OFFSET }, + { "g56","g56c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_C_OFFSET }, - { "g57","g57x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_X_OFFSET }, - { "g57","g57y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Y_OFFSET }, - { "g57","g57z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_Z_OFFSET }, - { "g57","g57a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_A_OFFSET }, - { "g57","g57b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_B_OFFSET }, - { "g57","g57c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G57_C_OFFSET }, + { "g57","g57x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_X_OFFSET }, + { "g57","g57y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_Y_OFFSET }, + { "g57","g57z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_Z_OFFSET }, + { "g57","g57a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_A_OFFSET }, + { "g57","g57b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_B_OFFSET }, + { "g57","g57c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_C_OFFSET }, - { "g58","g58x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_X_OFFSET }, - { "g58","g58y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Y_OFFSET }, - { "g58","g58z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_Z_OFFSET }, - { "g58","g58a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_A_OFFSET }, - { "g58","g58b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_B_OFFSET }, - { "g58","g58c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G58_C_OFFSET }, + { "g58","g58x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_X_OFFSET }, + { "g58","g58y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_Y_OFFSET }, + { "g58","g58z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_Z_OFFSET }, + { "g58","g58a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_A_OFFSET }, + { "g58","g58b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_B_OFFSET }, + { "g58","g58c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_C_OFFSET }, - { "g59","g59x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_X_OFFSET }, - { "g59","g59y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Y_OFFSET }, - { "g59","g59z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_Z_OFFSET }, - { "g59","g59a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_A_OFFSET }, - { "g59","g59b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_B_OFFSET }, - { "g59","g59c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, (float *)&cs.null, G59_C_OFFSET }, + { "g59","g59x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_X_OFFSET }, + { "g59","g59y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_Y_OFFSET }, + { "g59","g59z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_Z_OFFSET }, + { "g59","g59a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_A_OFFSET }, + { "g59","g59b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_B_OFFSET }, + { "g59","g59c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_C_OFFSET }, - { "g92","g92x",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 },// G92 handled differently - { "g92","g92y",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92z",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92a",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92b",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, - { "g92","g92c",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, (float *)&cs.null, 0 }, + { "g92","g92x",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 },// G92 handled differently + { "g92","g92y",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92z",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92a",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92b",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92c",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, // Coordinate positions (G28, G30) - { "g28","g28x",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 },// g28 handled differently - { "g28","g28y",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28z",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28a",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28b",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, - { "g28","g28c",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, (float *)&cs.null, 0 }, + { "g28","g28x",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 },// g28 handled differently + { "g28","g28y",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28z",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28a",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28b",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28c",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, - { "g30","g30x",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 },// g30 handled differently - { "g30","g30y",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30z",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30a",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30b",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, - { "g30","g30c",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, (float *)&cs.null, 0 }, + { "g30","g30x",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 },// g30 handled differently + { "g30","g30y",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30z",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30a",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30b",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30c",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, // this is a 128bit UUID for identifying a previously committed job state - { "jid","jida",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, - { "jid","jidb",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0}, - { "jid","jidc",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, - { "jid","jidd",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, + { "jid","jida",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0 }, + { "jid","jidb",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0 }, + { "jid","jidc",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0 }, + { "jid","jidd",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0 }, // Spindle functions - { "sp","spmo", _iip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, (float *)&cs.null, SPINDLE_MODE }, - { "sp","spph", _bip, 0, sp_print_spph, sp_get_spph, sp_set_spph, (float *)&cs.null, SPINDLE_PAUSE_ON_HOLD }, - { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, (float *)&cs.null, SPINDLE_SPINUP_DELAY }, - { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, (float *)&cs.null, SPINDLE_SPEED_MIN}, - { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, (float *)&cs.null, SPINDLE_SPEED_MAX}, - { "sp","spep", _iip, 0, sp_print_spep, sp_get_spep, sp_set_spep, (float *)&cs.null, SPINDLE_ENABLE_POLARITY }, - { "sp","spdp", _iip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, (float *)&cs.null, SPINDLE_DIR_POLARITY }, - { "sp","spoe", _bip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, (float *)&cs.null, SPINDLE_OVERRIDE_ENABLE}, - { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, (float *)&cs.null, SPINDLE_OVERRIDE_FACTOR}, - { "sp","spc", _i0, 0, sp_print_spc, sp_get_spc, sp_set_spc, (float *)&cs.null, 0 }, // spindle state - { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, (float *)&cs.null, 0 }, // spindle speed + { "sp","spmo", _iip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, nullptr, SPINDLE_MODE }, + { "sp","spph", _bip, 0, sp_print_spph, sp_get_spph, sp_set_spph, nullptr, SPINDLE_PAUSE_ON_HOLD }, + { "sp","spde", _fip, 2, sp_print_spde, sp_get_spde, sp_set_spde, nullptr, SPINDLE_SPINUP_DELAY }, + { "sp","spsn", _fip, 2, sp_print_spsn, sp_get_spsn, sp_set_spsn, nullptr, SPINDLE_SPEED_MIN}, + { "sp","spsm", _fip, 2, sp_print_spsm, sp_get_spsm, sp_set_spsm, nullptr, SPINDLE_SPEED_MAX}, + { "sp","spep", _iip, 0, sp_print_spep, sp_get_spep, sp_set_spep, nullptr, SPINDLE_ENABLE_POLARITY }, + { "sp","spdp", _iip, 0, sp_print_spdp, sp_get_spdp, sp_set_spdp, nullptr, SPINDLE_DIR_POLARITY }, + { "sp","spoe", _bip, 0, sp_print_spoe, sp_get_spoe, sp_set_spoe, nullptr, SPINDLE_OVERRIDE_ENABLE}, + { "sp","spo", _fip, 3, sp_print_spo, sp_get_spo, sp_set_spo, nullptr, SPINDLE_OVERRIDE_FACTOR}, + { "sp","spc", _i0, 0, sp_print_spc, sp_get_spc, sp_set_spc, nullptr, 0 }, // spindle state + { "sp","sps", _f0, 0, sp_print_sps, sp_get_sps, sp_set_sps, nullptr, 0 }, // spindle speed // Coolant functions - { "co","coph", _bip, 0, co_print_coph, co_get_coph, co_set_coph, (float *)&cs.null, COOLANT_PAUSE_ON_HOLD }, - { "co","comp", _iip, 0, co_print_comp, co_get_comp, co_set_comp, (float *)&cs.null, COOLANT_MIST_POLARITY }, - { "co","cofp", _iip, 0, co_print_cofp, co_get_cofp, co_set_cofp, (float *)&cs.null, COOLANT_FLOOD_POLARITY }, - { "co","com", _i0, 0, co_print_com, co_get_com, co_set_com, (float *)&cs.null, 0 }, // mist coolant enable - { "co","cof", _i0, 0, co_print_cof, co_get_cof, co_set_cof, (float *)&cs.null, 0 }, // flood coolant enable + { "co","coph", _bip, 0, co_print_coph, co_get_coph, co_set_coph, nullptr, COOLANT_PAUSE_ON_HOLD }, + { "co","comp", _iip, 0, co_print_comp, co_get_comp, co_set_comp, nullptr, COOLANT_MIST_POLARITY }, + { "co","cofp", _iip, 0, co_print_cofp, co_get_cofp, co_set_cofp, nullptr, COOLANT_FLOOD_POLARITY }, + { "co","com", _i0, 0, co_print_com, co_get_com, co_set_com, nullptr, 0 }, // mist coolant enable + { "co","cof", _i0, 0, co_print_cof, co_get_cof, co_set_cof, nullptr, 0 }, // flood coolant enable // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, (float *)&cs.null, JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, (float *)&cs.null, CHORDAL_TOLERANCE }, - { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, (float *)&cs.null, FEEDHOLD_Z_LIFT }, - { "sys","sl", _bipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, (float *)&cs.null, SOFT_LIMIT_ENABLE }, - { "sys","lim", _bipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, (float *)&cs.null, HARD_LIMIT_ENABLE }, - { "sys","saf", _bipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, (float *)&cs.null, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48", _bin, 0, cm_print_m48, cm_get_m48, cm_get_m48, (float *)&cs.null, 1 }, // M48/M49 feedrate & spindle override enable - { "sys","froe",_bin, 0, cm_print_froe, cm_get_froe,cm_get_froe,(float *)&cs.null, FEED_OVERRIDE_ENABLE}, - { "sys","fro", _fin, 3, cm_print_fro, cm_get_fro, cm_set_fro, (float *)&cs.null, FEED_OVERRIDE_FACTOR}, - { "sys","troe",_bin, 0, cm_print_troe, cm_get_troe,cm_get_troe,(float *)&cs.null, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","tro", _fin, 3, cm_print_tro, cm_get_tro, cm_set_tro, (float *)&cs.null, TRAVERSE_OVERRIDE_FACTOR}, - { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&cs.null, MOTOR_POWER_TIMEOUT}, // N is seconds of timeout - { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, (float *)&cs.null, 0 }, // SET to enable motors - { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, (float *)&cs.null, 0 }, // SET to disable motors + { "sys","jt", _fipn, 2, cm_print_jt, cm_get_jt, cm_set_jt, nullptr, JUNCTION_INTEGRATION_TIME }, + { "sys","ct", _fipnc,4, cm_print_ct, cm_get_ct, cm_set_ct, nullptr, CHORDAL_TOLERANCE }, + { "sys","zl", _fipnc,3, cm_print_zl, cm_get_zl, cm_set_zl, nullptr, FEEDHOLD_Z_LIFT }, + { "sys","sl", _bipn, 0, cm_print_sl, cm_get_sl, cm_set_sl, nullptr, SOFT_LIMIT_ENABLE }, + { "sys","lim", _bipn, 0, cm_print_lim, cm_get_lim, cm_set_lim, nullptr, HARD_LIMIT_ENABLE }, + { "sys","saf", _bipn, 0, cm_print_saf, cm_get_saf, cm_set_saf, nullptr, SAFETY_INTERLOCK_ENABLE }, + { "sys","m48", _bin, 0, cm_print_m48, cm_get_m48, cm_get_m48, nullptr, 1 }, // M48/M49 feedrate & spindle override enable + { "sys","froe",_bin, 0, cm_print_froe, cm_get_froe,cm_get_froe,nullptr, FEED_OVERRIDE_ENABLE}, + { "sys","fro", _fin, 3, cm_print_fro, cm_get_fro, cm_set_fro, nullptr, FEED_OVERRIDE_FACTOR}, + { "sys","troe",_bin, 0, cm_print_troe, cm_get_troe,cm_get_troe,nullptr, TRAVERSE_OVERRIDE_ENABLE}, + { "sys","tro", _fin, 3, cm_print_tro, cm_get_tro, cm_set_tro, nullptr, TRAVERSE_OVERRIDE_FACTOR}, + { "sys","mt", _fipn, 2, st_print_mt, st_get_mt, st_set_mt, nullptr, MOTOR_POWER_TIMEOUT}, // N is seconds of timeout + { "", "me", _f0, 0, st_print_me, get_nul, st_set_me, nullptr, 0 }, // SET to enable motors + { "", "md", _f0, 0, st_print_md, get_nul, st_set_md, nullptr, 0 }, // SET to disable motors // Communications and reporting parameters #ifdef __TEXT_MODE - { "sys","tv", _iipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, (float *)&cs.null, TEXT_VERBOSITY }, + { "sys","tv", _iipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, nullptr, TEXT_VERBOSITY }, #endif - { "sys","ej", _iipn, 0, js_print_ej, js_get_ej, js_set_ej, (float *)&cs.null, COMM_MODE }, - { "sys","jv", _iipn, 0, js_print_jv, js_get_jv, js_set_jv, (float *)&cs.null, JSON_VERBOSITY }, - { "sys","qv", _iipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, (float *)&cs.null, QUEUE_REPORT_VERBOSITY }, - { "sys","sv", _iipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, (float *)&cs.null, STATUS_REPORT_VERBOSITY }, - { "sys","si", _iipn, 0, sr_print_si, sr_get_si, sr_set_si, (float *)&cs.null, STATUS_REPORT_INTERVAL_MS }, + { "sys","ej", _iipn, 0, js_print_ej, js_get_ej, js_set_ej, nullptr, COMM_MODE }, + { "sys","jv", _iipn, 0, js_print_jv, js_get_jv, js_set_jv, nullptr, JSON_VERBOSITY }, + { "sys","qv", _iipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, nullptr, QUEUE_REPORT_VERBOSITY }, + { "sys","sv", _iipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, nullptr, STATUS_REPORT_VERBOSITY }, + { "sys","si", _iipn, 0, sr_print_si, sr_get_si, sr_set_si, nullptr, STATUS_REPORT_INTERVAL_MS }, // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco - { "sys","gpl", _iipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, (float *)&cs.null, GCODE_DEFAULT_PLANE }, - { "sys","gun", _iipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, (float *)&cs.null, GCODE_DEFAULT_UNITS }, - { "sys","gco", _iipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, (float *)&cs.null, GCODE_DEFAULT_COORD_SYSTEM }, - { "sys","gpa", _iipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, (float *)&cs.null, GCODE_DEFAULT_PATH_CONTROL }, - { "sys","gdi", _iipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, (float *)&cs.null, GCODE_DEFAULT_DISTANCE_MODE }, - { "", "gc2", _s0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // send gcode to secondary planner - { "", "gc", _s0, 0, tx_print_nul, gc_get_gc, gc_run_gc, (float *)&cs.null, 0 }, // gcode block - must be last in this group + { "sys","gpl", _iipn, 0, cm_print_gpl, cm_get_gpl, cm_set_gpl, nullptr, GCODE_DEFAULT_PLANE }, + { "sys","gun", _iipn, 0, cm_print_gun, cm_get_gun, cm_set_gun, nullptr, GCODE_DEFAULT_UNITS }, + { "sys","gco", _iipn, 0, cm_print_gco, cm_get_gco, cm_set_gco, nullptr, GCODE_DEFAULT_COORD_SYSTEM }, + { "sys","gpa", _iipn, 0, cm_print_gpa, cm_get_gpa, cm_set_gpa, nullptr, GCODE_DEFAULT_PATH_CONTROL }, + { "sys","gdi", _iipn, 0, cm_print_gdi, cm_get_gdi, cm_set_gdi, nullptr, GCODE_DEFAULT_DISTANCE_MODE }, + { "", "gc2", _s0, 0, tx_print_nul, gc_get_gc, gc_run_gc, nullptr, 0 }, // send gcode to secondary planner + { "", "gc", _s0, 0, tx_print_nul, gc_get_gc, gc_run_gc, nullptr, 0 }, // gcode block - must be last in this group // Actions and Reports - { "", "sr", _n0, 0, sr_print_sr, sr_get, sr_set, (float *)&cs.null, 0 }, // request and set status reports - { "", "qr", _n0, 0, qr_print_qr, qr_get, set_nul, (float *)&cs.null, 0 }, // get queue value - planner buffers available - { "", "qi", _n0, 0, qr_print_qi, qi_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers added to queue - { "", "qo", _n0, 0, qr_print_qo, qo_get, set_nul, (float *)&cs.null, 0 }, // get queue value - buffers removed from queue - { "", "er", _n0, 0, tx_print_nul, rpt_er, set_nul, (float *)&cs.null, 0 }, // get bogus exception report for testing - { "", "rx", _n0, 0, tx_print_int, get_rx, set_nul, (float *)&cs.null, 0 }, // get RX buffer bytes or packets - { "", "dw", _i0, 0, tx_print_int, st_get_dw, set_noop, (float *)&cs.null, 0 }, // get dwell time remaining - { "", "msg", _s0, 0, tx_print_str, get_nul, set_noop, (float *)&cs.null, 0 }, // no operation on messages - { "", "alarm",_n0, 0, tx_print_nul, cm_alrm, cm_alrm, (float *)&cs.null, 0 }, // trigger alarm - { "", "panic",_n0, 0, tx_print_nul, cm_pnic, cm_pnic, (float *)&cs.null, 0 }, // trigger panic - { "", "shutd",_n0, 0, tx_print_nul, cm_shutd, cm_shutd, (float *)&cs.null, 0 }, // trigger shutdown - { "", "clear",_n0, 0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // GET "clear" to clear alarm state - { "", "clr", _n0, 0, tx_print_nul, cm_clr, cm_clr, (float *)&cs.null, 0 }, // synonym for "clear" - { "", "tick", _n0, 0, tx_print_int, get_tick, set_nul, (float *)&cs.null, 0 }, // get system time tic - { "", "tram", _b0, 0, cm_print_tram,cm_get_tram,cm_set_tram,(float *)&cs.null, 0 }, // SET to attempt setting rotation matrix from probes - { "", "defa", _b0, 0, tx_print_nul, help_defa,set_defaults,(float *)&cs.null,0 }, // set/print defaults / help screen - { "", "flash",_b0, 0, tx_print_nul, help_flash,hw_flash, (float *)&cs.null,0 }, + { "", "sr", _n0, 0, sr_print_sr, sr_get, sr_set, nullptr, 0 }, // request and set status reports + { "", "qr", _n0, 0, qr_print_qr, qr_get, set_nul, nullptr, 0 }, // get queue value - planner buffers available + { "", "qi", _n0, 0, qr_print_qi, qi_get, set_nul, nullptr, 0 }, // get queue value - buffers added to queue + { "", "qo", _n0, 0, qr_print_qo, qo_get, set_nul, nullptr, 0 }, // get queue value - buffers removed from queue + { "", "er", _n0, 0, tx_print_nul, rpt_er, set_nul, nullptr, 0 }, // get bogus exception report for testing + { "", "rx", _n0, 0, tx_print_int, get_rx, set_nul, nullptr, 0 }, // get RX buffer bytes or packets + { "", "dw", _i0, 0, tx_print_int, st_get_dw, set_noop, nullptr, 0 }, // get dwell time remaining + { "", "msg", _s0, 0, tx_print_str, get_nul, set_noop, nullptr, 0 }, // no operation on messages + { "", "alarm",_n0, 0, tx_print_nul, cm_alrm, cm_alrm, nullptr, 0 }, // trigger alarm + { "", "panic",_n0, 0, tx_print_nul, cm_pnic, cm_pnic, nullptr, 0 }, // trigger panic + { "", "shutd",_n0, 0, tx_print_nul, cm_shutd, cm_shutd, nullptr, 0 }, // trigger shutdown + { "", "clear",_n0, 0, tx_print_nul, cm_clr, cm_clr, nullptr, 0 }, // GET "clear" to clear alarm state + { "", "clr", _n0, 0, tx_print_nul, cm_clr, cm_clr, nullptr, 0 }, // synonym for "clear" + { "", "tick", _n0, 0, tx_print_int, get_tick, set_nul, nullptr, 0 }, // get system time tic + { "", "tram", _b0, 0, cm_print_tram,cm_get_tram,cm_set_tram,nullptr,0 }, // SET to attempt setting rotation matrix from probes + { "", "defa", _b0, 0, tx_print_nul, help_defa,set_defaults,nullptr,0 }, // set/print defaults / help screen + { "", "flash",_b0, 0, tx_print_nul, help_flash,hw_flash, nullptr, 0 }, #ifdef __HELP_SCREENS - { "", "help",_b0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // prints config help screen - { "", "h", _b0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0 }, // alias for "help" + { "", "help",_b0, 0, tx_print_nul, help_config, set_nul, nullptr, 0 }, // prints config help screen + { "", "h", _b0, 0, tx_print_nul, help_config, set_nul, nullptr, 0 }, // alias for "help" #endif #ifdef __USER_DATA @@ -709,242 +708,242 @@ const cfgItem_t cfgArray[] = { #endif // Tool table offsets - { "tof","tofx",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofy",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofz",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofa",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofb",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, - { "tof","tofc",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, (float *)&cs.null, 0 }, + { "tof","tofx",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofy",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofz",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofa",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofb",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofc",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, // Tool table - { "tt1","tt1x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_X_OFFSET }, - { "tt1","tt1y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Y_OFFSET }, - { "tt1","tt1z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_Z_OFFSET }, - { "tt1","tt1a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_A_OFFSET }, - { "tt1","tt1b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_B_OFFSET }, - { "tt1","tt1c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, + { "tt1","tt1x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_X_OFFSET }, + { "tt1","tt1y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_Y_OFFSET }, + { "tt1","tt1z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_Z_OFFSET }, + { "tt1","tt1a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_A_OFFSET }, + { "tt1","tt1b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_B_OFFSET }, + { "tt1","tt1c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_C_OFFSET }, - { "tt2","tt2x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_X_OFFSET }, - { "tt2","tt2y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Y_OFFSET }, - { "tt2","tt2z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_Z_OFFSET }, - { "tt2","tt2a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_A_OFFSET }, - { "tt2","tt2b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_B_OFFSET }, - { "tt2","tt2c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT2_C_OFFSET }, + { "tt2","tt2x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_X_OFFSET }, + { "tt2","tt2y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_Y_OFFSET }, + { "tt2","tt2z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_Z_OFFSET }, + { "tt2","tt2a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_A_OFFSET }, + { "tt2","tt2b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_B_OFFSET }, + { "tt2","tt2c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_C_OFFSET }, - { "tt3","tt3x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_X_OFFSET }, - { "tt3","tt3y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Y_OFFSET }, - { "tt3","tt3z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_Z_OFFSET }, - { "tt3","tt3a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_A_OFFSET }, - { "tt3","tt3b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT3_B_OFFSET }, - { "tt3","tt3c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT1_C_OFFSET }, + { "tt3","tt3x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_X_OFFSET }, + { "tt3","tt3y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_Y_OFFSET }, + { "tt3","tt3z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_Z_OFFSET }, + { "tt3","tt3a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_A_OFFSET }, + { "tt3","tt3b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_B_OFFSET }, + { "tt3","tt3c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_C_OFFSET }, - { "tt4","tt4x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_X_OFFSET }, - { "tt4","tt4y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Y_OFFSET }, - { "tt4","tt4z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_Z_OFFSET }, - { "tt4","tt4a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_A_OFFSET }, - { "tt4","tt4b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_B_OFFSET }, - { "tt4","tt4c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT4_C_OFFSET }, + { "tt4","tt4x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_X_OFFSET }, + { "tt4","tt4y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_Y_OFFSET }, + { "tt4","tt4z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_Z_OFFSET }, + { "tt4","tt4a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_A_OFFSET }, + { "tt4","tt4b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_B_OFFSET }, + { "tt4","tt4c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_C_OFFSET }, - { "tt5","tt5x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_X_OFFSET }, - { "tt5","tt5y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Y_OFFSET }, - { "tt5","tt5z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_Z_OFFSET }, - { "tt5","tt5a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_A_OFFSET }, - { "tt5","tt5b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_B_OFFSET }, - { "tt5","tt5c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT5_C_OFFSET }, + { "tt5","tt5x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_X_OFFSET }, + { "tt5","tt5y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_Y_OFFSET }, + { "tt5","tt5z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_Z_OFFSET }, + { "tt5","tt5a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_A_OFFSET }, + { "tt5","tt5b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_B_OFFSET }, + { "tt5","tt5c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_C_OFFSET }, - { "tt6","tt6x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_X_OFFSET }, - { "tt6","tt6y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Y_OFFSET }, - { "tt6","tt6z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_Z_OFFSET }, - { "tt6","tt6a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_A_OFFSET }, - { "tt6","tt6b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_B_OFFSET }, - { "tt6","tt6c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT6_C_OFFSET }, + { "tt6","tt6x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_X_OFFSET }, + { "tt6","tt6y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_Y_OFFSET }, + { "tt6","tt6z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_Z_OFFSET }, + { "tt6","tt6a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_A_OFFSET }, + { "tt6","tt6b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_B_OFFSET }, + { "tt6","tt6c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_C_OFFSET }, - { "tt7","tt7x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_X_OFFSET }, - { "tt7","tt7y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Y_OFFSET }, - { "tt7","tt7z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_Z_OFFSET }, - { "tt7","tt7a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_A_OFFSET }, - { "tt7","tt7b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_B_OFFSET }, - { "tt7","tt7c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT7_C_OFFSET }, + { "tt7","tt7x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_X_OFFSET }, + { "tt7","tt7y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_Y_OFFSET }, + { "tt7","tt7z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_Z_OFFSET }, + { "tt7","tt7a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_A_OFFSET }, + { "tt7","tt7b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_B_OFFSET }, + { "tt7","tt7c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_C_OFFSET }, - { "tt8","tt8x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_X_OFFSET }, - { "tt8","tt8y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Y_OFFSET }, - { "tt8","tt8z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_Z_OFFSET }, - { "tt8","tt8a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_A_OFFSET }, - { "tt8","tt8b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_B_OFFSET }, - { "tt8","tt8c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT8_C_OFFSET }, + { "tt8","tt8x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_X_OFFSET }, + { "tt8","tt8y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_Y_OFFSET }, + { "tt8","tt8z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_Z_OFFSET }, + { "tt8","tt8a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_A_OFFSET }, + { "tt8","tt8b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_B_OFFSET }, + { "tt8","tt8c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_C_OFFSET }, - { "tt9","tt9x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_X_OFFSET }, - { "tt9","tt9y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Y_OFFSET }, - { "tt9","tt9z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_Z_OFFSET }, - { "tt9","tt9a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_A_OFFSET }, - { "tt9","tt9b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_B_OFFSET }, - { "tt9","tt9c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT9_C_OFFSET }, + { "tt9","tt9x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_X_OFFSET }, + { "tt9","tt9y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_Y_OFFSET }, + { "tt9","tt9z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_Z_OFFSET }, + { "tt9","tt9a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_A_OFFSET }, + { "tt9","tt9b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_B_OFFSET }, + { "tt9","tt9c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_C_OFFSET }, - { "tt10","tt10x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_X_OFFSET }, - { "tt10","tt10y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Y_OFFSET }, - { "tt10","tt10z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_Z_OFFSET }, - { "tt10","tt10a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_A_OFFSET }, - { "tt10","tt10b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_B_OFFSET }, - { "tt10","tt10c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT10_C_OFFSET }, + { "tt10","tt10x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_X_OFFSET }, + { "tt10","tt10y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_Y_OFFSET }, + { "tt10","tt10z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_Z_OFFSET }, + { "tt10","tt10a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_A_OFFSET }, + { "tt10","tt10b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_B_OFFSET }, + { "tt10","tt10c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_C_OFFSET }, - { "tt11","tt11x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_X_OFFSET }, - { "tt11","tt11y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Y_OFFSET }, - { "tt11","tt11z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_Z_OFFSET }, - { "tt11","tt11a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_A_OFFSET }, - { "tt11","tt11b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_B_OFFSET }, - { "tt11","tt11c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT11_C_OFFSET }, + { "tt11","tt11x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_X_OFFSET }, + { "tt11","tt11y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_Y_OFFSET }, + { "tt11","tt11z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_Z_OFFSET }, + { "tt11","tt11a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_A_OFFSET }, + { "tt11","tt11b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_B_OFFSET }, + { "tt11","tt11c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_C_OFFSET }, - { "tt12","tt12x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_X_OFFSET }, - { "tt12","tt12y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Y_OFFSET }, - { "tt12","tt12z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_Z_OFFSET }, - { "tt12","tt12a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_A_OFFSET }, - { "tt12","tt12b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_B_OFFSET }, - { "tt12","tt12c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT12_C_OFFSET }, + { "tt12","tt12x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_X_OFFSET }, + { "tt12","tt12y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_Y_OFFSET }, + { "tt12","tt12z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_Z_OFFSET }, + { "tt12","tt12a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_A_OFFSET }, + { "tt12","tt12b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_B_OFFSET }, + { "tt12","tt12c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_C_OFFSET }, - { "tt13","tt13x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_X_OFFSET }, - { "tt13","tt13y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Y_OFFSET }, - { "tt13","tt13z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_Z_OFFSET }, - { "tt13","tt13a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_A_OFFSET }, - { "tt13","tt13b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_B_OFFSET }, - { "tt13","tt13c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT13_C_OFFSET }, + { "tt13","tt13x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_X_OFFSET }, + { "tt13","tt13y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_Y_OFFSET }, + { "tt13","tt13z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_Z_OFFSET }, + { "tt13","tt13a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_A_OFFSET }, + { "tt13","tt13b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_B_OFFSET }, + { "tt13","tt13c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_C_OFFSET }, - { "tt14","tt14x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_X_OFFSET }, - { "tt14","tt14y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Y_OFFSET }, - { "tt14","tt14z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_Z_OFFSET }, - { "tt14","tt14a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_A_OFFSET }, - { "tt14","tt14b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_B_OFFSET }, - { "tt14","tt14c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT14_C_OFFSET }, + { "tt14","tt14x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_X_OFFSET }, + { "tt14","tt14y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_Y_OFFSET }, + { "tt14","tt14z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_Z_OFFSET }, + { "tt14","tt14a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_A_OFFSET }, + { "tt14","tt14b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_B_OFFSET }, + { "tt14","tt14c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_C_OFFSET }, - { "tt15","tt15x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_X_OFFSET }, - { "tt15","tt15y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Y_OFFSET }, - { "tt15","tt15z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_Z_OFFSET }, - { "tt15","tt15a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_A_OFFSET }, - { "tt15","tt15b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_B_OFFSET }, - { "tt15","tt15c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT15_C_OFFSET }, + { "tt15","tt15x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_X_OFFSET }, + { "tt15","tt15y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_Y_OFFSET }, + { "tt15","tt15z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_Z_OFFSET }, + { "tt15","tt15a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_A_OFFSET }, + { "tt15","tt15b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_B_OFFSET }, + { "tt15","tt15c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_C_OFFSET }, - { "tt16","tt16x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_X_OFFSET }, - { "tt16","tt16y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Y_OFFSET }, - { "tt16","tt16z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_Z_OFFSET }, - { "tt16","tt16a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_A_OFFSET }, - { "tt16","tt16b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_B_OFFSET }, - { "tt16","tt16c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT16_C_OFFSET }, + { "tt16","tt16x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_X_OFFSET }, + { "tt16","tt16y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_Y_OFFSET }, + { "tt16","tt16z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_Z_OFFSET }, + { "tt16","tt16a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_A_OFFSET }, + { "tt16","tt16b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_B_OFFSET }, + { "tt16","tt16c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_C_OFFSET }, - { "tt17","tt17x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_X_OFFSET }, - { "tt17","tt17y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Y_OFFSET }, - { "tt17","tt17z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_Z_OFFSET }, - { "tt17","tt17a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_A_OFFSET }, - { "tt17","tt17b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_B_OFFSET }, - { "tt17","tt17c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT17_C_OFFSET }, + { "tt17","tt17x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_X_OFFSET }, + { "tt17","tt17y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_Y_OFFSET }, + { "tt17","tt17z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_Z_OFFSET }, + { "tt17","tt17a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_A_OFFSET }, + { "tt17","tt17b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_B_OFFSET }, + { "tt17","tt17c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_C_OFFSET }, - { "tt18","tt18x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_X_OFFSET }, - { "tt18","tt18y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Y_OFFSET }, - { "tt18","tt18z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_Z_OFFSET }, - { "tt18","tt18a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_A_OFFSET }, - { "tt18","tt18b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_B_OFFSET }, - { "tt18","tt18c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT18_C_OFFSET }, + { "tt18","tt18x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_X_OFFSET }, + { "tt18","tt18y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_Y_OFFSET }, + { "tt18","tt18z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_Z_OFFSET }, + { "tt18","tt18a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_A_OFFSET }, + { "tt18","tt18b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_B_OFFSET }, + { "tt18","tt18c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_C_OFFSET }, - { "tt19","tt19x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_X_OFFSET }, - { "tt19","tt19y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Y_OFFSET }, - { "tt19","tt19z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_Z_OFFSET }, - { "tt19","tt19a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_A_OFFSET }, - { "tt19","tt19b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_B_OFFSET }, - { "tt19","tt19c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT19_C_OFFSET }, + { "tt19","tt19x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_X_OFFSET }, + { "tt19","tt19y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_Y_OFFSET }, + { "tt19","tt19z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_Z_OFFSET }, + { "tt19","tt19a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_A_OFFSET }, + { "tt19","tt19b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_B_OFFSET }, + { "tt19","tt19c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_C_OFFSET }, - { "tt20","tt20x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_X_OFFSET }, - { "tt20","tt20y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Y_OFFSET }, - { "tt20","tt20z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_Z_OFFSET }, - { "tt20","tt20a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_A_OFFSET }, - { "tt20","tt20b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_B_OFFSET }, - { "tt20","tt20c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT20_C_OFFSET }, + { "tt20","tt20x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_X_OFFSET }, + { "tt20","tt20y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_Y_OFFSET }, + { "tt20","tt20z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_Z_OFFSET }, + { "tt20","tt20a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_A_OFFSET }, + { "tt20","tt20b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_B_OFFSET }, + { "tt20","tt20c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_C_OFFSET }, - { "tt21","tt21x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_X_OFFSET }, - { "tt21","tt21y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Y_OFFSET }, - { "tt21","tt21z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_Z_OFFSET }, - { "tt21","tt21a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_A_OFFSET }, - { "tt21","tt21b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_B_OFFSET }, - { "tt21","tt21c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT21_C_OFFSET }, + { "tt21","tt21x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_X_OFFSET }, + { "tt21","tt21y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_Y_OFFSET }, + { "tt21","tt21z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_Z_OFFSET }, + { "tt21","tt21a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_A_OFFSET }, + { "tt21","tt21b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_B_OFFSET }, + { "tt21","tt21c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_C_OFFSET }, - { "tt22","tt22x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_X_OFFSET }, - { "tt22","tt22y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Y_OFFSET }, - { "tt22","tt22z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_Z_OFFSET }, - { "tt22","tt22a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_A_OFFSET }, - { "tt22","tt22b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_B_OFFSET }, - { "tt22","tt22c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT22_C_OFFSET }, + { "tt22","tt22x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_X_OFFSET }, + { "tt22","tt22y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_Y_OFFSET }, + { "tt22","tt22z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_Z_OFFSET }, + { "tt22","tt22a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_A_OFFSET }, + { "tt22","tt22b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_B_OFFSET }, + { "tt22","tt22c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_C_OFFSET }, - { "tt23","tt23x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_X_OFFSET }, - { "tt23","tt23y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Y_OFFSET }, - { "tt23","tt23z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_Z_OFFSET }, - { "tt23","tt23a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_A_OFFSET }, - { "tt23","tt23b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_B_OFFSET }, - { "tt23","tt23c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT23_C_OFFSET }, + { "tt23","tt23x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_X_OFFSET }, + { "tt23","tt23y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_Y_OFFSET }, + { "tt23","tt23z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_Z_OFFSET }, + { "tt23","tt23a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_A_OFFSET }, + { "tt23","tt23b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_B_OFFSET }, + { "tt23","tt23c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_C_OFFSET }, - { "tt24","tt24x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_X_OFFSET }, - { "tt24","tt24y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Y_OFFSET }, - { "tt24","tt24z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_Z_OFFSET }, - { "tt24","tt24a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_A_OFFSET }, - { "tt24","tt24b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_B_OFFSET }, - { "tt24","tt24c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT24_C_OFFSET }, + { "tt24","tt24x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_X_OFFSET }, + { "tt24","tt24y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_Y_OFFSET }, + { "tt24","tt24z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_Z_OFFSET }, + { "tt24","tt24a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_A_OFFSET }, + { "tt24","tt24b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_B_OFFSET }, + { "tt24","tt24c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_C_OFFSET }, - { "tt25","tt25x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_X_OFFSET }, - { "tt25","tt25y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Y_OFFSET }, - { "tt25","tt25z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_Z_OFFSET }, - { "tt25","tt25a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_A_OFFSET }, - { "tt25","tt25b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_B_OFFSET }, - { "tt25","tt25c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT25_C_OFFSET }, + { "tt25","tt25x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_X_OFFSET }, + { "tt25","tt25y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_Y_OFFSET }, + { "tt25","tt25z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_Z_OFFSET }, + { "tt25","tt25a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_A_OFFSET }, + { "tt25","tt25b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_B_OFFSET }, + { "tt25","tt25c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_C_OFFSET }, - { "tt26","tt26x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_X_OFFSET }, - { "tt26","tt26y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Y_OFFSET }, - { "tt26","tt26z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_Z_OFFSET }, - { "tt26","tt26a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_A_OFFSET }, - { "tt26","tt26b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_B_OFFSET }, - { "tt26","tt26c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT26_C_OFFSET }, + { "tt26","tt26x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_X_OFFSET }, + { "tt26","tt26y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_Y_OFFSET }, + { "tt26","tt26z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_Z_OFFSET }, + { "tt26","tt26a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_A_OFFSET }, + { "tt26","tt26b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_B_OFFSET }, + { "tt26","tt26c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_C_OFFSET }, - { "tt27","tt27x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_X_OFFSET }, - { "tt27","tt27y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Y_OFFSET }, - { "tt27","tt27z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_Z_OFFSET }, - { "tt27","tt27a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_A_OFFSET }, - { "tt27","tt27b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_B_OFFSET }, - { "tt27","tt27c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT27_C_OFFSET }, + { "tt27","tt27x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_X_OFFSET }, + { "tt27","tt27y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_Y_OFFSET }, + { "tt27","tt27z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_Z_OFFSET }, + { "tt27","tt27a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_A_OFFSET }, + { "tt27","tt27b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_B_OFFSET }, + { "tt27","tt27c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_C_OFFSET }, - { "tt28","tt28x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_X_OFFSET }, - { "tt28","tt28y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Y_OFFSET }, - { "tt28","tt28z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_Z_OFFSET }, - { "tt28","tt28a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_A_OFFSET }, - { "tt28","tt28b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_B_OFFSET }, - { "tt28","tt28c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT28_C_OFFSET }, + { "tt28","tt28x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_X_OFFSET }, + { "tt28","tt28y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_Y_OFFSET }, + { "tt28","tt28z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_Z_OFFSET }, + { "tt28","tt28a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_A_OFFSET }, + { "tt28","tt28b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_B_OFFSET }, + { "tt28","tt28c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_C_OFFSET }, - { "tt29","tt29x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_X_OFFSET }, - { "tt29","tt29y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Y_OFFSET }, - { "tt29","tt29z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_Z_OFFSET }, - { "tt29","tt29a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_A_OFFSET }, - { "tt29","tt29b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_B_OFFSET }, - { "tt29","tt29c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT29_C_OFFSET }, + { "tt29","tt29x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_X_OFFSET }, + { "tt29","tt29y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_Y_OFFSET }, + { "tt29","tt29z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_Z_OFFSET }, + { "tt29","tt29a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_A_OFFSET }, + { "tt29","tt29b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_B_OFFSET }, + { "tt29","tt29c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_C_OFFSET }, - { "tt30","tt30x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_X_OFFSET }, - { "tt30","tt30y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Y_OFFSET }, - { "tt30","tt30z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_Z_OFFSET }, - { "tt30","tt30a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_A_OFFSET }, - { "tt30","tt30b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_B_OFFSET }, - { "tt30","tt30c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT30_C_OFFSET }, + { "tt30","tt30x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_X_OFFSET }, + { "tt30","tt30y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_Y_OFFSET }, + { "tt30","tt30z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_Z_OFFSET }, + { "tt30","tt30a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_A_OFFSET }, + { "tt30","tt30b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_B_OFFSET }, + { "tt30","tt30c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_C_OFFSET }, - { "tt31","tt31x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_X_OFFSET }, - { "tt31","tt31y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Y_OFFSET }, - { "tt31","tt31z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_Z_OFFSET }, - { "tt31","tt31a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_A_OFFSET }, - { "tt31","tt31b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_B_OFFSET }, - { "tt31","tt31c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT31_C_OFFSET }, + { "tt31","tt31x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_X_OFFSET }, + { "tt31","tt31y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_Y_OFFSET }, + { "tt31","tt31z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_Z_OFFSET }, + { "tt31","tt31a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_A_OFFSET }, + { "tt31","tt31b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_B_OFFSET }, + { "tt31","tt31c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_C_OFFSET }, - { "tt32","tt32x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_X_OFFSET }, - { "tt32","tt32y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Y_OFFSET }, - { "tt32","tt32z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_Z_OFFSET }, - { "tt32","tt32a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_A_OFFSET }, - { "tt32","tt32b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_B_OFFSET }, - { "tt32","tt32c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, (float *)&cs.null, TT32_C_OFFSET }, + { "tt32","tt32x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_X_OFFSET }, + { "tt32","tt32y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_Y_OFFSET }, + { "tt32","tt32z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_Z_OFFSET }, + { "tt32","tt32a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_A_OFFSET }, + { "tt32","tt32b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_B_OFFSET }, + { "tt32","tt32c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_C_OFFSET }, // Diagnostic parameters #ifdef __DIAGNOSTIC_PARAMETERS - { "", "clc",_f0, 0, tx_print_nul, st_clc, st_clc, (float *)&cs.null, 0 }, // clear diagnostic step counters - // { "", "_dam",_f0, 0, tx_print_nul, cm_dam, cm_dam, (float *)&cs.null, 0 }, // dump active model + { "", "clc",_f0, 0, tx_print_nul, st_clc, st_clc, nullptr, 0 }, // clear diagnostic step counters + // { "", "_dam",_f0, 0, tx_print_nul, cm_dam, cm_dam, nullptr, 0 }, // dump active model { "_te","_tex",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_X], 0 }, // X target endpoint { "_te","_tey",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_Y], 0 }, @@ -1012,46 +1011,46 @@ const cfgItem_t cfgArray[] = { // Persistence for status report - must be in sequence // *** Count must agree with NV_STATUS_REPORT_LEN in report.h *** - { "","se00",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[0],0 }, - { "","se01",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[1],0 }, - { "","se02",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[2],0 }, - { "","se03",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[3],0 }, - { "","se04",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[4],0 }, - { "","se05",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[5],0 }, - { "","se06",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[6],0 }, - { "","se07",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[7],0 }, - { "","se08",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[8],0 }, - { "","se09",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[9],0 }, - { "","se10",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[10],0 }, - { "","se11",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[11],0 }, - { "","se12",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[12],0 }, - { "","se13",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[13],0 }, - { "","se14",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[14],0 }, - { "","se15",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[15],0 }, - { "","se16",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[16],0 }, - { "","se17",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[17],0 }, - { "","se18",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[18],0 }, - { "","se19",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[19],0 }, - { "","se20",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[20],0 }, - { "","se21",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[21],0 }, - { "","se22",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[22],0 }, - { "","se23",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[23],0 }, - { "","se24",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[24],0 }, - { "","se25",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[25],0 }, - { "","se26",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[26],0 }, - { "","se27",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[27],0 }, - { "","se28",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[28],0 }, - { "","se29",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[29],0 }, - { "","se30",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[30],0 }, - { "","se31",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[31],0 }, - { "","se32",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[32],0 }, - { "","se33",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[33],0 }, - { "","se34",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[34],0 }, - { "","se35",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[35],0 }, - { "","se36",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[36],0 }, - { "","se37",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[37],0 }, - { "","se38",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[38],0 }, - { "","se39",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[39],0 }, + { "","se00",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[0], 0 }, + { "","se01",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[1], 0 }, + { "","se02",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[2], 0 }, + { "","se03",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[3], 0 }, + { "","se04",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[4], 0 }, + { "","se05",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[5], 0 }, + { "","se06",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[6], 0 }, + { "","se07",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[7], 0 }, + { "","se08",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[8], 0 }, + { "","se09",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[9], 0 }, + { "","se10",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[10], 0 }, + { "","se11",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[11], 0 }, + { "","se12",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[12], 0 }, + { "","se13",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[13], 0 }, + { "","se14",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[14], 0 }, + { "","se15",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[15], 0 }, + { "","se16",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[16], 0 }, + { "","se17",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[17], 0 }, + { "","se18",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[18], 0 }, + { "","se19",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[19], 0 }, + { "","se20",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[20], 0 }, + { "","se21",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[21], 0 }, + { "","se22",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[22], 0 }, + { "","se23",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[23], 0 }, + { "","se24",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[24], 0 }, + { "","se25",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[25], 0 }, + { "","se26",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[26], 0 }, + { "","se27",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[27], 0 }, + { "","se28",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[28], 0 }, + { "","se29",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[29], 0 }, + { "","se30",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[30], 0 }, + { "","se31",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[31], 0 }, + { "","se32",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[32], 0 }, + { "","se33",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[33], 0 }, + { "","se34",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[34], 0 }, + { "","se35",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[35], 0 }, + { "","se36",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[36], 0 }, + { "","se37",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[37], 0 }, + { "","se38",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[38], 0 }, + { "","se39",_ip, 0, tx_print_nul, get_int32, set_int32,(float *)&sr.status_report_list[39], 0 }, // Count is 40, since se00 counts as one. // Group lookups - must follow the single-valued entries for proper sub-string matching @@ -1064,158 +1063,158 @@ const cfgItem_t cfgArray[] = { // - Uber groups (count these separately) #define FIXED_GROUPS 4 - { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // system group - { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PWM 1 group - { "","sp", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // Spindle group - { "","co", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // Coolant group + { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // system group + { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PWM 1 group + { "","sp", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // Spindle group + { "","co", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // Coolant group #define AXIS_GROUPS AXES - { "","x", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis groups - { "","y", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","z", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","a", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","b", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","c", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","x", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // axis groups + { "","y", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","z", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","a", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","b", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","c", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #define MOTOR_GROUPS MOTORS - { "","1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor groups + { "","1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // motor groups #if (MOTORS >= 2) - { "","2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","2", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif #if (MOTORS >= 3) - { "","3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","3", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif #if (MOTORS >= 4) - { "","4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","4", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif #if (MOTORS >= 5) - { "","5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","5", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif #if (MOTORS >= 6) - { "","6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","6", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif #define DIGITAL_IN_GROUPS 10 - { "","in", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input state - { "","di1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input configs - { "","di2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","in", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // input state + { "","di1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // input configs + { "","di2", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di3", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di4", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di5", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di6", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di7", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di8", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","di9", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #define DIGITAL_OUT_GROUPS 14 - { "","out", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output state - { "","do1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output configs - { "","do2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do10", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do11", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do12", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do13", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","out", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // output state + { "","do1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // output configs + { "","do2", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do3", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do4", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do5", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do6", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do7", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do8", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do9", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do10", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do11", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do12", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","do13", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #define COORDINATE_OFFSET_GROUPS 9 - { "","g54",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // coord offset groups - { "","g55",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g56",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g57",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g58",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g59",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g92",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // origin offsets - { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position - { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position + { "","g54",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // coord offset groups + { "","g55",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","g56",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","g57",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","g58",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","g59",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","g92",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // origin offsets + { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // g28 home position + { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // g30 home position #define TOOL_OFFSET_GROUPS 33 - { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // current tool offsets - { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt4",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt5",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt6",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt7",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt8",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt9",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt17",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt18",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt19",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt20",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt21",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt22",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt23",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt24",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt25",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt26",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt27",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt29",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt31",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt32",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets + { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // current tool offsets + { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt4",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt5",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt6",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt7",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt8",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt9",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt17",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt18",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt19",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt20",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt21",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt22",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt23",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt24",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt25",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt26",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt27",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt28",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt29",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt30",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt31",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets + { "","tt32",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // tt offsets #define MACHINE_STATE_GROUPS 8 - { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group - { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group - { "","ofs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work offset group - { "","hom",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis homing state group - { "","prb",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // probing state group - { "","pwr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor power enagled group - { "","jog",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis jogging state group - { "","jid",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // job ID group + { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // machine position group + { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // work position group + { "","ofs",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // work offset group + { "","hom",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // axis homing state group + { "","prb",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // probing state group + { "","pwr",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // motor power enagled group + { "","jog",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // axis jogging state group + { "","jid",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // job ID group #define TEMPERATURE_GROUPS 6 - { "","he1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 1 group - { "","he2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 2 group - { "","he3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 3 group - { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 1 group - { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 2 group - { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 3 group + { "","he1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // heater 1 group + { "","he2", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // heater 2 group + { "","he3", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // heater 3 group + { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 1 group + { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 2 group + { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 3 group #ifdef __USER_DATA #define USER_DATA_GROUPS 4 - { "","uda", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group - { "","udb", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group - { "","udc", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group - { "","udd", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group + { "","uda", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // user data group + { "","udb", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // user data group + { "","udc", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // user data group + { "","udd", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // user data group #endif #ifdef __DIAGNOSTIC_PARAMETERS #define DIAGNOSTIC_GROUPS 8 - { "","_te",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // target axis endpoint group - { "","_tr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // target axis runtime group - { "","_ts",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // target motor steps group - { "","_ps",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // position motor steps group - { "","_cs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // commanded motor steps group - { "","_es",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // encoder steps group - { "","_xs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // correction steps group - { "","_fe",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // following error group + { "","_te",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // target axis endpoint group + { "","_tr",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // target axis runtime group + { "","_ts",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // target motor steps group + { "","_ps",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // position motor steps group + { "","_cs",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // commanded motor steps group + { "","_es",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // encoder steps group + { "","_xs",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // correction steps group + { "","_fe",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // following error group #endif #define NV_COUNT_UBER_GROUPS 6 // Uber-group (groups of groups, for text-mode displays only) // *** Must agree with NV_COUNT_UBER_GROUPS below **** - { "", "m", _f0, 0, tx_print_nul, _do_motors, set_nul,(float *)&cs.null,0 }, - { "", "q", _f0, 0, tx_print_nul, _do_axes, set_nul,(float *)&cs.null,0 }, - { "", "o", _f0, 0, tx_print_nul, _do_offsets,set_nul,(float *)&cs.null,0 }, - { "", "di", _f0, 0, tx_print_nul,_do_inputs, set_nul,(float *)&cs.null,0 }, - { "", "do", _f0, 0, tx_print_nul,_do_outputs,set_nul,(float *)&cs.null,0 }, - { "", "$", _f0, 0, tx_print_nul, _do_all, set_nul,(float *)&cs.null,0 } + { "", "m", _f0, 0, tx_print_nul, _do_motors, set_nul, nullptr, 0 }, + { "", "q", _f0, 0, tx_print_nul, _do_axes, set_nul, nullptr, 0 }, + { "", "o", _f0, 0, tx_print_nul, _do_offsets,set_nul, nullptr, 0 }, + { "", "di", _f0, 0, tx_print_nul,_do_inputs, set_nul, nullptr, 0 }, + { "", "do", _f0, 0, tx_print_nul,_do_outputs,set_nul, nullptr, 0 }, + { "", "$", _f0, 0, tx_print_nul, _do_all, set_nul, nullptr, 0 } }; /***** Make sure these defines line up with any changes in the above table *****/ diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 13ce7d2b..22ef04f8 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -469,10 +469,8 @@ static stat_t _run_job_kill_final() cm_set_motion_state(MOTION_STOP); // set to stop and set the active model cm->hold_state = FEEDHOLD_OFF; -// cm->cycle_type = CYCLE_NONE; -// cm->machine_state = MACHINE_ALARM; - cm_program_end(); + rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); sr_request_status_report(SR_REQUEST_IMMEDIATE); return (STAT_OK); From ae0145c28f8ca80787cfbe23860c040ef10cfb24 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 21 Mar 2017 06:32:45 -0400 Subject: [PATCH 219/283] Some comments and naming changes to offsets for clarity --- g2core/canonical_machine.cpp | 100 +++++++++++++++++++---------------- g2core/canonical_machine.h | 8 +-- g2core/cycle_probing.cpp | 2 +- g2core/gcode.h | 16 +++--- g2core/gcode_parser.cpp | 23 ++++---- 5 files changed, 78 insertions(+), 71 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f045b6f0..11212add 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -190,7 +190,7 @@ void canonical_machine_reset(cmMachine_t *_cm) // NOTE: Should unhome axes here _cm->homing_state = HOMING_NOT_HOMED; - // reset request flags + // reset request state and flags _cm->queue_flush_state = QUEUE_FLUSH_OFF; _cm->cycle_start_state = CYCLE_START_OFF; _cm->job_kill_state = JOB_KILL_OFF; @@ -219,7 +219,7 @@ void canonical_machine_reset(cmMachine_t *_cm) void canonical_machine_reset_rotation(cmMachine_t *_cm) { - // We must make it an identity matrix for no rotation + // Make it an identity matrix for no rotation memset(&_cm->rotation_matrix, 0, sizeof(float)*3*3); _cm->rotation_matrix[0][0] = 1.0; _cm->rotation_matrix[1][1] = 1.0; @@ -314,10 +314,11 @@ cmCombinedState cm_get_combined_state(cmMachine_t *_cm) **** Model State Getters and Setters *************************************************** ****************************************************************************************/ /* These getters and setters will work on any gm model with inputs: - * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model - * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct - * ACTIVE_MODEL cm->am // active model pointer is maintained by state management + * MODEL (GCodeState_t *)&cm->gm // absolute pointer from canonical machine gm model + * RUNTIME (GCodeState_t *)&mr->gm // absolute pointer from runtime mm struct + * ACTIVE_MODEL cm->am // active model pointer is maintained by state management */ + uint32_t cm_get_linenum(const GCodeState_t *gcode_state) { return gcode_state->linenum;} cmMotionMode cm_get_motion_mode(const GCodeState_t *gcode_state) { return gcode_state->motion_mode;} uint8_t cm_get_coord_system(const GCodeState_t *gcode_state) { return gcode_state->coord_system;} @@ -376,10 +377,11 @@ void cm_set_model_linenum(int32_t linenum) * canonical units (mm, mm/min). The offsets are only used to translate in and out of * canonical form during incoming processing, and for displays in responses. * - * Managing the coordinate systems & offsets is somewhat complicated. The following affect offsets: + * Managing coordinate systems & offsets is somewhat complicated. The following affect offsets: * - coordinate system selected. 1-6 correspond to G54-G59 - * - G92 offsets are added "on top of" the coord system offsets -- if origin_offset_enable == true + * - G92 offsets are added "on top of" coord system offsets -- if g92_offset_enable == true * - tool offsets are also accounted for + * - absolute override (G53) * * Position displays {pos:n} are always in work coordinates aka using 'display' offsets * - position displays are assembled by applying all active offsets to the current machine position @@ -389,37 +391,41 @@ void cm_set_model_linenum(int32_t linenum) * - Probing also has a very short move that behaves this way * * The offsets themselves are "the truth". These are: - * - cm.coord_offset[coord][axis] coordinate offsets for G53-G59, by axis - persistent - * - cm.tool_offset[axis] offsets for currently selected and active tool - persistent - * - cm.gmx.origin_offset[axis] G92 origin offset. Not persistent + * - cm.coord_offset[coord][axis] coordinate offsets for G53-G59, by axis - persistent + * - cm.tool_offset[axis] offsets for currently selected and active tool - persistent + * - cm.gmx.g92_offset[axis] G92 origin offset. Not persistent * * - cm_get_combined_offset() puts the above together to provide a combined, active offset. - * G92 offsets are only included if it is active + * G92 offsets are only included if g92 is active (gmx.g92_offset_enable == true) * * Display offsets + * *** Display offsets are for display only and CANNOT be used to set positions *** * - cm_set_display_offsets() writes combined offsets to cm.gm.display_offset[] - * *** This is for display purposes only and should not be used to set positions *** * - cm_set_display_offsets() should be called every time underlying data would cause a change * - cm_set_display_offsets() takes absolute override display rules into account * - Use cm_get_display_offset() to return the display offset value */ /* Absolute Override is the Gcode G53 convention to allow one and only one Gcode block * to be run in absolute coordinates, regardless of coordinate offsets, G92 offsets, and - * tool offsets. If absolute_override is set to ABSOLUTE_OVERRIDE_ON_AND_DISPLAY the display - * values will be set to 0.0 for the offset value. This bit is here to support G28 and G30 - * return moves and other moves that run in absolute override mode but may want position - * to be reported using all current offsets (work offsets), versus an explicit G53 move that - * should be displayed in absolute coordinates. + * tool offsets. See cmAbsoluteOverride for enumerations. + * + * - If absolute_override is set to ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_OFFSETS + * move will run in absolute coordinates but POS will display using current offsets. + * This is to support G28 and G30 return moves and other moves that run in absolute + * override mode but may want position to be reported using all current offsets + * + * - If absolute_override is set to ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_NO_OFFSETS + * move will run in absolute coordinates and POS will display using no offsets. */ float cm_get_combined_offset(const uint8_t axis) { - if (cm->gm.absolute_override >= ABSOLUTE_OVERRIDE_ON) { + if (cm->gm.absolute_override >= ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_OFFSETS) { return (0); } float offset = cm->coord_offset[cm->gm.coord_system][axis] + cm->tool_offset[axis]; - if (cm->gmx.origin_offset_enable == true) { - offset += cm->gmx.origin_offset[axis]; + if (cm->gmx.g92_offset_enable == true) { + offset += cm->gmx.g92_offset[axis]; } return (offset); } @@ -434,7 +440,7 @@ void cm_set_display_offsets(GCodeState_t *gcode_state) for (uint8_t axis = AXIS_X; axis < AXES; axis++) { // if absolute override is on for G53 so position should be displayed with no offsets - if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_AND_DISPLAY) { + if (cm->gm.absolute_override == ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_NO_OFFSETS) { gcode_state->display_offset[axis] = 0; } @@ -442,8 +448,8 @@ void cm_set_display_offsets(GCodeState_t *gcode_state) else { gcode_state->display_offset[axis] = cm->coord_offset[cm->gm.coord_system][axis] + cm->tool_offset[axis]; - if (cm->gmx.origin_offset_enable == true) { - gcode_state->display_offset[axis] += cm->gmx.origin_offset[axis]; + if (cm->gmx.g92_offset_enable == true) { + gcode_state->display_offset[axis] += cm->gmx.g92_offset[axis]; } } } @@ -853,7 +859,7 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, tt.tt_offset[P_word][axis] = cm->gmx.position[axis] - _to_millimeters(offset[axis]) - cm->coord_offset[cm->gm.coord_system][axis] - - (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); + (cm->gmx.g92_offset[axis] * cm->gmx.g92_offset_enable); } cm->deferred_write_flag = true; // persist offsets once machining cycle is over } @@ -934,7 +940,7 @@ static void _exec_offset(float *value, bool *flag) float offsets[AXES]; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { offsets[axis] = cm->coord_offset[coord_system][axis] + cm->tool_offset[axis] + - (cm->gmx.origin_offset[axis] * cm->gmx.origin_offset_enable); + (cm->gmx.g92_offset[axis] * cm->gmx.g92_offset_enable); } mp_set_runtime_display_offset(offsets); } @@ -1021,25 +1027,25 @@ static void _exec_absolute_origin(float *value, bool *flag) } /****************************************************************************************** - * cm_set_origin_offsets() - G92 - * cm_reset_origin_offsets() - G92.1 - * cm_suspend_origin_offsets() - G92.2 - * cm_resume_origin_offsets() - G92.3 + * cm_set_g92_offsets() - G92 + * cm_reset_g92_offsets() - G92.1 + * cm_suspend_g92_offsets() - G92.2 + * cm_resume_g92_offsets() - G92.3 * * G92's behave according to NIST 3.5.18 & LinuxCNC G92 * http://linuxcnc.org/docs/html/gcode/gcode.html#sec:G92-G92.1-G92.2-G92.3 */ -stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) +stat_t cm_set_g92_offsets(const float offset[], const bool flag[]) { // set offsets in the Gcode model extended context - cm->gmx.origin_offset_enable = true; + cm->gmx.g92_offset_enable = true; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { - cm->gmx.origin_offset[axis] = cm->gmx.position[axis] - - cm->coord_offset[cm->gm.coord_system][axis] - - cm->tool_offset[axis] - - _to_millimeters(offset[axis]); + cm->gmx.g92_offset[axis] = cm->gmx.position[axis] - + cm->coord_offset[cm->gm.coord_system][axis] - + cm->tool_offset[axis] - + _to_millimeters(offset[axis]); } } // now pass the offset to the callback - setting the coordinate system also applies the offsets @@ -1049,11 +1055,11 @@ stat_t cm_set_origin_offsets(const float offset[], const bool flag[]) return (STAT_OK); } -stat_t cm_reset_origin_offsets() +stat_t cm_reset_g92_offsets() { - cm->gmx.origin_offset_enable = false; + cm->gmx.g92_offset_enable = false; for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - cm->gmx.origin_offset[axis] = 0; + cm->gmx.g92_offset[axis] = 0; } float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); @@ -1061,18 +1067,18 @@ stat_t cm_reset_origin_offsets() return (STAT_OK); } -stat_t cm_suspend_origin_offsets() +stat_t cm_suspend_g92_offsets() { - cm->gmx.origin_offset_enable = false; + cm->gmx.g92_offset_enable = false; float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); cm_set_display_offsets(MODEL); return (STAT_OK); } -stat_t cm_resume_origin_offsets() +stat_t cm_resume_g92_offsets() { - cm->gmx.origin_offset_enable = true; + cm->gmx.g92_offset_enable = true; float value[] = { (float)cm->gm.coord_system }; mp_queue_command(_exec_offset, value, nullptr); cm_set_display_offsets(MODEL); @@ -1140,7 +1146,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm while (mp_planner_is_full(mp)); // Make sure you have available buffers uint8_t saved_distance_mode = cm_get_distance_mode(MODEL); - cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); // Position was stored in absolute coords + cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_OFFSETS); // Position stored in abs coords cm_set_distance_mode(ABSOLUTE_DISTANCE_MODE); // Must run in absolute distance mode bool flags2[] = { 1,1,1,1,1,1 }; @@ -1552,8 +1558,8 @@ static void _exec_program_finalize(float *value, bool *flag) // perform the following resets if it's a program END if (machine_state == MACHINE_PROGRAM_END) { - cm_suspend_origin_offsets(); // G92.2 - as per NIST -// cm_reset_origin_offsets(); // G92.1 - alternative to above + cm_suspend_g92_offsets(); // G92.2 - as per NIST +// cm_reset_g92_offsets(); // G92.1 - alternative to above cm_set_coord_system(cm->default_coord_system); // reset to default coordinate system cm_select_plane(cm->default_select_plane); // reset to default arc plane cm_set_distance_mode(cm->default_distance_mode); @@ -1992,8 +1998,8 @@ stat_t cm_get_prb(nvObj_t *nv) { return (get_float(nv, cm->probe_results[0][_ax stat_t cm_get_coord(nvObj_t *nv) { return (get_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } stat_t cm_set_coord(nvObj_t *nv) { return (set_float(nv, cm->coord_offset[_coord(nv)][_axis(nv)])); } -stat_t cm_get_g92e(nvObj_t *nv) { return (get_integer(nv, cm->gmx.origin_offset_enable)); } -stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.origin_offset[_axis(nv)])); } +stat_t cm_get_g92e(nvObj_t *nv) { return (get_integer(nv, cm->gmx.g92_offset_enable)); } +stat_t cm_get_g92(nvObj_t *nv) { return (get_float(nv, cm->gmx.g92_offset[_axis(nv)])); } stat_t cm_get_g28(nvObj_t *nv) { return (get_float(nv, cm->gmx.g28_position[_axis(nv)])); } stat_t cm_get_g30(nvObj_t *nv) { return (get_float(nv, cm->gmx.g30_position[_axis(nv)])); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index de1909eb..88a91c75 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -422,10 +422,10 @@ stat_t cm_set_absolute_origin(const float origin[], bool flag[]); // G void cm_set_axis_origin(uint8_t axis, const float position); // G28.3 planner callback stat_t cm_set_coord_system(const uint8_t coord_system); // G54 - G59 -stat_t cm_set_origin_offsets(const float offset[], const bool flag[]); // G92 -stat_t cm_reset_origin_offsets(void); // G92.1 -stat_t cm_suspend_origin_offsets(void); // G92.2 -stat_t cm_resume_origin_offsets(void); // G92.3 +stat_t cm_set_g92_offsets(const float offset[], const bool flag[]); // G92 +stat_t cm_reset_g92_offsets(void); // G92.1 +stat_t cm_suspend_g92_offsets(void); // G92.2 +stat_t cm_resume_g92_offsets(void); // G92.3 // Free Space Motion (4.3.4) //stat_t cm_straight_traverse(const float target[], const bool flags[]); // G0 diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index 1fd4fda4..fad4fc6b 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -209,7 +209,7 @@ static void _motion_end_callback(float* vect, bool* flag) static stat_t _probe_move(const float target[], const bool flags[]) { - cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON); + cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_OFFSETS); pb.waiting_for_motion_complete = true; // set this BEFORE the motion starts cm_straight_feed(target, flags, PROFILE_FAST); // NB: feed rate was set earlier, so it's OK mp_queue_command(_motion_end_callback, nullptr, nullptr); // the last two arguments are ignored anyway diff --git a/g2core/gcode.h b/g2core/gcode.h index 0a0e9e9f..e7bfd315 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -47,10 +47,10 @@ typedef enum { // these are in order to optimized CASE NEXT_ACTION_SET_TL_OFFSET, // G43 NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET,// G43.2 NEXT_ACTION_CANCEL_TL_OFFSET, // G49 - NEXT_ACTION_SET_ORIGIN_OFFSETS, // G92 - NEXT_ACTION_RESET_ORIGIN_OFFSETS, // G92.1 - NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2 - NEXT_ACTION_RESUME_ORIGIN_OFFSETS, // G92.3 + NEXT_ACTION_SET_G92_OFFSETS, // G92 + NEXT_ACTION_RESET_G92_OFFSETS, // G92.1 + NEXT_ACTION_SUSPEND_G92_OFFSETS, // G92.2 + NEXT_ACTION_RESUME_G92_OFFSETS, // G92.3 NEXT_ACTION_JSON_COMMAND_SYNC, // M100 NEXT_ACTION_JSON_WAIT // M101 } cmNextAction; @@ -120,8 +120,8 @@ typedef enum { typedef enum { ABSOLUTE_OVERRIDE_OFF = 0, // G53 disabled - ABSOLUTE_OVERRIDE_ON, // G53 enabled for movement - ABSOLUTE_OVERRIDE_ON_AND_DISPLAY // G53 enabled for movement and display + ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_OFFSETS, // G53 enabled for movement, displays use current offsets + ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_NO_OFFSETS // G53 enabled for movement, displays use no offset } cmAbsoluteOverride; typedef enum { // G Modal Group 13 @@ -265,7 +265,7 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used uint8_t program_flow; // used only by the gcode_parser float position[AXES]; // XYZABC model position (Note: not used in gn or gf) - float origin_offset[AXES]; // XYZABC G92 offsets (Note: not used in gn or gf) + float g92_offset[AXES]; // XYZABC G92 offsets (aka origin offsets) (Note: not used in gn or gf) float g28_position[AXES]; // XYZABC stored machine position for G28 float g30_position[AXES]; // XYZABC stored machine position for G30 float p1_position[AXES]; // XYZABC stored machine position for return to p1 planner @@ -276,7 +276,7 @@ typedef struct GCodeStateExtended { // Gcode dynamic state extensions - used bool mto_enable; // traverse override enable float mto_factor; // valid from 0.05 to 1.00 - bool origin_offset_enable; // G92 offsets enabled/disabled. 0=disabled, 1=enabled + bool g92_offset_enable; // G92 offsets enabled/disabled. 0=disabled, 1=enabled bool block_delete_switch; // set true to enable block deletes (true is default) uint16_t magic_end; diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 8564dc50..159bf697 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -30,7 +30,7 @@ // Structures used by Gcode parser typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context - + uint8_t next_action; // handles G modal group 1 moves & non-modals cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89 uint8_t program_flow; // used only by the gcode_parser @@ -582,7 +582,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) break; } case 49: SET_NON_MODAL (next_action, NEXT_ACTION_CANCEL_TL_OFFSET); - case 53: SET_NON_MODAL (absolute_override, ABSOLUTE_OVERRIDE_ON_AND_DISPLAY); + case 53: SET_NON_MODAL (absolute_override, ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_NO_OFFSETS); case 54: SET_MODAL (MODAL_GROUP_G12, coord_system, G54); case 55: SET_MODAL (MODAL_GROUP_G12, coord_system, G55); case 56: SET_MODAL (MODAL_GROUP_G12, coord_system, G56); @@ -617,10 +617,10 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) } case 92: { switch (_point(value)) { - case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_ORIGIN_OFFSETS); - case 1: SET_NON_MODAL (next_action, NEXT_ACTION_RESET_ORIGIN_OFFSETS); - case 2: SET_NON_MODAL (next_action, NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS); - case 3: SET_NON_MODAL (next_action, NEXT_ACTION_RESUME_ORIGIN_OFFSETS); + case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_G92_OFFSETS); + case 1: SET_NON_MODAL (next_action, NEXT_ACTION_RESET_G92_OFFSETS); + case 2: SET_NON_MODAL (next_action, NEXT_ACTION_SUSPEND_G92_OFFSETS); + case 3: SET_NON_MODAL (next_action, NEXT_ACTION_RESUME_G92_OFFSETS); default: status = STAT_GCODE_COMMAND_UNSUPPORTED; } break; @@ -734,6 +734,8 @@ static stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; + cm_cycle_start(); // any G, M or other word will autostart cycle if not already started + if (gf.linenum) { cm_set_model_linenum(gv.linenum); } @@ -753,7 +755,6 @@ static stat_t _execute_gcode_block(char *active_comment) EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, F_word); // F EXEC_FUNC(spindle_speed_sync, S_word); // S - EXEC_FUNC(cm_select_tool, tool_select); // T - tool_select is where it's written EXEC_FUNC(cm_change_tool, tool_change); // M6 - is where it's effected @@ -820,10 +821,10 @@ static stat_t _execute_gcode_block(char *active_comment) gv.L_word, gf.L_word, gv.target, gf.target); break;} - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gv.target, gf.target); break;}// G92 - case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 - case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 - case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 + case NEXT_ACTION_SET_G92_OFFSETS: { status = cm_set_g92_offsets(gv.target, gf.target); break;} // G92 + case NEXT_ACTION_RESET_G92_OFFSETS: { status = cm_reset_g92_offsets(); break;} // G92.1 + case NEXT_ACTION_SUSPEND_G92_OFFSETS: { status = cm_suspend_g92_offsets(); break;} // G92.2 + case NEXT_ACTION_RESUME_G92_OFFSETS: { status = cm_resume_g92_offsets(); break;} // G92.3 case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 From 5031f4c8c69a5ffa0f5359da5c29a4f2632e0498 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 21 Mar 2017 08:04:31 -0400 Subject: [PATCH 220/283] Comments and cleanup --- g2core/canonical_machine.cpp | 409 ++++++++++++++++------------------- g2core/coolant.cpp | 17 +- g2core/spindle.cpp | 61 +++--- 3 files changed, 233 insertions(+), 254 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 11212add..3d856b40 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -124,14 +124,7 @@ cmToolTable_t tt; // global tool table **** GENERIC STATIC FUNCTIONS AND VARIABLES ******************************************** ****************************************************************************************/ -// command execution callbacks from planner queue -static void _exec_offset(float *value, bool *flag); -static void _exec_change_tool(float *value, bool *flag); -static void _exec_select_tool(float *value, bool *flag); -static void _exec_absolute_origin(float *value, bool *flag); -static void _exec_program_finalize(float *value, bool *flag); - -static int8_t _axis(const nvObj_t *nv); +static int8_t _axis(const nvObj_t *nv); // return axis number from token/group in nv /**************************************************************************************** **** CODE ****************************************************************************** @@ -499,13 +492,14 @@ float cm_get_absolute_position(const GCodeState_t *gcode_state, const uint8_t ax * These functions are not part of the NIST defined functions ****************************************************************************************/ -/* +/**************************************************************************************** * cm_update_model_position() - set gmx endpoint position for a traverse, feed or arc * - * Note: As far as the canonical machine is concerned the final position of a Gcode block (move) - * is achieved as soon as the move is planned and the move target becomes the new model position. - * In reality the planner will (in all likelihood) have only just queued the move for later - * execution, and the real tool position is still close to the starting point. + * Note: As far as the canonical machine is concerned the final position of a Gcode block + * (move) is achieved as soon as the move is planned and the move target becomes the new + * model position. In reality the planner will (in all likelihood) have only just queued + * the move for later execution, and the real tool position is still close to the starting + * point. */ void cm_update_model_position() @@ -538,12 +532,33 @@ stat_t cm_deferred_write_callback() } /**************************************************************************************** - * cm_set_tram() - JSON command to trigger computing the rotation matrix * cm_get_tram() - JSON query to determine if the rotation matrix is set (non-identity) + * cm_set_tram() - JSON command to trigger computing the rotation matrix * - * There MUST be three valid probes stored. + * For set_tram there MUST be three valid probes stored. */ +stat_t cm_get_tram(nvObj_t *nv) +{ + nv->value_int = true; // believe it or not, the compiler likes this form best - most efficient code + + if (fp_NOT_ZERO(cm->rotation_z_offset) || + fp_NOT_ZERO(cm->rotation_matrix[0][1]) || + fp_NOT_ZERO(cm->rotation_matrix[0][2]) || + fp_NOT_ZERO(cm->rotation_matrix[1][0]) || + fp_NOT_ZERO(cm->rotation_matrix[1][2]) || + fp_NOT_ZERO(cm->rotation_matrix[2][0]) || + fp_NOT_ZERO(cm->rotation_matrix[2][1]) || + fp_NE(1.0, cm->rotation_matrix[0][0]) || + fp_NE(1.0, cm->rotation_matrix[1][1]) || + fp_NE(1.0, cm->rotation_matrix[2][2])) + { + nv->value_int = false; + } + nv->valuetype = TYPE_BOOLEAN; + return (STAT_OK); +} + stat_t cm_set_tram(nvObj_t *nv) { if (!nv->value_int) { // if false, reset the matrix and return @@ -577,9 +592,9 @@ stat_t cm_set_tram(nvObj_t *nv) (d2_x*d2_x + d2_y*d2_y + d2_z*d2_z)); // Step 1c: compute the cross product and normalize - float n_x = (d0_z*d2_y - d0_y*d2_z)*combined_magnitude_inv; - float n_y = (d0_x*d2_z - d0_z*d2_x)*combined_magnitude_inv; - float n_z = (d0_y*d2_x - d0_x*d2_y)*combined_magnitude_inv; + float n_x = (d0_z*d2_y - d0_y*d2_z) * combined_magnitude_inv; + float n_y = (d0_x*d2_z - d0_z*d2_x) * combined_magnitude_inv; + float n_z = (d0_y*d2_x - d0_x*d2_y) * combined_magnitude_inv; // Step 1d: flip the normal if it's negative if (n_z < 0.0) { @@ -605,10 +620,10 @@ stat_t cm_set_tram(nvObj_t *nv) /* matrix = { - {1 - q_yy_2, q_xy_2, q_wy_2, 0}, - {q_xy_2, 1 - q_xx_2, -q_wx_2, 0}, - {-q_wy_2, q_wx_2, 1 - q_xx_2 - q_yy_2, i}, - {0, 0, 0, 1} + {1 - q_yy_2, q_xy_2, q_wy_2, 0}, + {q_xy_2, 1 - q_xx_2, -q_wx_2, 0}, + {-q_wy_2, q_wx_2, 1 - q_xx_2 - q_yy_2, i}, + {0, 0, 0, 1} } */ cm->rotation_matrix[0][0] = 1 - q_yy_2; @@ -630,27 +645,6 @@ stat_t cm_set_tram(nvObj_t *nv) return (STAT_OK); } -stat_t cm_get_tram(nvObj_t *nv) -{ - nv->value_int = true; // believe it or not, the compiler likes this form best - most efficient code - - if (fp_NOT_ZERO(cm->rotation_z_offset) || - fp_NOT_ZERO(cm->rotation_matrix[0][1]) || - fp_NOT_ZERO(cm->rotation_matrix[0][2]) || - fp_NOT_ZERO(cm->rotation_matrix[1][0]) || - fp_NOT_ZERO(cm->rotation_matrix[1][2]) || - fp_NOT_ZERO(cm->rotation_matrix[2][0]) || - fp_NOT_ZERO(cm->rotation_matrix[2][1]) || - fp_NE(1.0, cm->rotation_matrix[0][0]) || - fp_NE(1.0, cm->rotation_matrix[1][1]) || - fp_NE(1.0, cm->rotation_matrix[2][2])) - { - nv->value_int = false; - } - nv->valuetype = TYPE_BOOLEAN; - return (STAT_OK); -} - /**************************************************************************************** * cm_set_model_target() - set target vector in GM model * @@ -782,7 +776,7 @@ stat_t cm_test_soft_limits(const float target[]) * cm_set_arc_distance_mode() - G90.1, G91.1 * cm_set_g10_data() - G10 (delayed persistence) * - * These functions assume input validation occurred upstream. + * These functions assume input validation occurred upstream, most likely in gcode parser. */ stat_t cm_select_plane(const uint8_t plane) @@ -815,9 +809,7 @@ stat_t cm_set_arc_distance_mode(const uint8_t mode) * This function applies the offset to the GM model but does not persist the offsets * during the Gcode cycle. The persist flag is used to persist offsets once the cycle * has ended. You can also use $g54x - $g59c config functions to change offsets. - * - * It also does not reset the work offsets which may be accomplished by calling - * cm_set_display_offsets() immediately afterwards. + * It also does resets the display offsets to reflect the new values. */ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, @@ -878,9 +870,20 @@ stat_t cm_set_g10_data(const uint8_t P_word, const bool P_flag, * cm_set_tl_offset() - G43 * cm_cancel_tl_offset() - G49 * cm_set_coord_system() - G54-G59 - * _exec_offset() - callback from planner + * _exec_offset() - callback from planner command */ +static void _exec_offset(float *value, bool *flag) +{ + uint8_t coord_system = ((uint8_t)value[0]); // coordinate system is passed in value[0] element + float offsets[AXES]; + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { + offsets[axis] = cm->coord_offset[coord_system][axis] + cm->tool_offset[axis] + + (cm->gmx.g92_offset[axis] * cm->gmx.g92_offset_enable); + } + mp_set_runtime_display_offset(offsets); +} + stat_t cm_set_tl_offset(const uint8_t H_word, const bool H_flag, const bool apply_additional) { uint8_t tool; @@ -934,17 +937,6 @@ stat_t cm_set_coord_system(const uint8_t coord_system) // set coordinate system return (STAT_OK); } -static void _exec_offset(float *value, bool *flag) -{ - uint8_t coord_system = ((uint8_t)value[0]); // coordinate system is passed in value[0] element - float offsets[AXES]; - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - offsets[axis] = cm->coord_offset[coord_system][axis] + cm->tool_offset[axis] + - (cm->gmx.g92_offset[axis] * cm->gmx.g92_offset_enable); - } - mp_set_runtime_display_offset(offsets); -} - /****************************************************************************************** * cm_set_position_by_axis() - set the position of a single axis in the model, planner and runtime * cm_reset_position_to_absolute_position() - set all positions to current absolute position in mr @@ -963,11 +955,12 @@ static void _exec_offset(float *value, bool *flag) * initialization sequences and during cycles (such as homing cycles) when you know there * are no more moves in the planner and that all motion has stopped. * You can use cm_get_runtime_busy() to be sure the system is quiescent. + * + * TODO: Turn this into a queued command so it executes from the planner */ void cm_set_position_by_axis(const uint8_t axis, const float position) { - // TODO: Interlock involving runtime_busy test cm->gmx.position[axis] = position; cm->gm.target[axis] = position; mp_set_planner_position(axis, position); @@ -983,9 +976,7 @@ void cm_reset_position_to_absolute_position(cmMachine_t *_cm) } } -/**************************************************************************************** - *** G28.3 functions and support *** - * +/* * cm_set_absolute_origin() - G28.3 - model, planner and queue to runtime * _exec_absolute_origin() - callback from planner * @@ -998,23 +989,6 @@ void cm_reset_position_to_absolute_position(cmMachine_t *_cm) * as homed. */ -stat_t cm_set_absolute_origin(const float origin[], bool flag[]) -{ - float value[AXES]; - - for (uint8_t axis = AXIS_X; axis < AXES; axis++) { - if (flag[axis]) { -// REMOVED value[axis] = cm->offset[cm->gm.coord_system][axis] + _to_millimeters(origin[axis]); // G2 Issue #26 - value[axis] = _to_millimeters(origin[axis]); - cm->gmx.position[axis] = value[axis]; // set model position - cm->gm.target[axis] = value[axis]; // reset model target - mp_set_planner_position(axis, value[axis]); // set mm position - } - } - mp_queue_command(_exec_absolute_origin, value, flag); - return (STAT_OK); -} - static void _exec_absolute_origin(float *value, bool *flag) { for (uint8_t axis = AXIS_X; axis < AXES; axis++) { @@ -1026,6 +1000,23 @@ static void _exec_absolute_origin(float *value, bool *flag) mp_set_steps_to_runtime_position(); } +stat_t cm_set_absolute_origin(const float origin[], bool flag[]) +{ + float value[AXES]; + + for (uint8_t axis = AXIS_X; axis < AXES; axis++) { + if (flag[axis]) { +// REMOVED value[axis] = cm->offset[cm->gm.coord_system][axis] + _to_millimeters(origin[axis]); // G2 Issue #26 + value[axis] = _to_millimeters(origin[axis]); // replaced the above + cm->gmx.position[axis] = value[axis]; // set model position + cm->gm.target[axis] = value[axis]; // reset model target + mp_set_planner_position(axis, value[axis]); // set mm position + } + } + mp_queue_command(_exec_absolute_origin, value, flag); + return (STAT_OK); +} + /****************************************************************************************** * cm_set_g92_offsets() - G92 * cm_reset_g92_offsets() - G92.1 @@ -1103,7 +1094,7 @@ stat_t cm_straight_traverse(const float *target, const bool *flags, const uint8_ cm_set_model_target(target, flags); ritorno (cm_test_soft_limits(cm->gm.target)); // test soft limits; exit if thrown cm_set_display_offsets(&cm->gm); // capture the fully resolved offsets to the state - cm_cycle_start(); // required for homing & other cycles + cm_cycle_start(); // required here for homing & other cycles stat_t status = mp_aline(&cm->gm); // send the move to the planner cm_update_model_position(); // update gmx.position to ready for next incoming move @@ -1117,10 +1108,10 @@ stat_t cm_straight_traverse(const float *target, const bool *flags, const uint8_ } /**************************************************************************************** - * cm_set_g28_position() - G28.1 * cm_goto_g28_position() - G28 - * cm_set_g30_position() - G30.1 + * cm_set_g28_position() - G28.1 * cm_goto_g30_position() - G30 + * cm_set_g30_position() - G30.1 * _goto_stored_position() - helper */ @@ -1274,14 +1265,14 @@ stat_t cm_straight_feed(const float *target, const bool *flags, const uint8_t mo return (status); } -/*********************************************************************************** - **** Spindle Functions (4.3.7) **************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Spindle Functions (4.3.7) ********************************************************* + ****************************************************************************************/ // see spindle.cpp/.h -/*********************************************************************************** - **** Tool Functions (4.3.8) ******************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Tool Functions (4.3.8) ************************************************************ + ****************************************************************************************/ /* * cm_select_tool() - T parameter * _exec_select_tool() - execution callback @@ -1292,6 +1283,11 @@ stat_t cm_straight_feed(const float *target, const bool *flags, const uint8_t mo * Note: These functions don't actually do anything for now, and there's a bug * where T and M in different blocks don't work correctly */ +static void _exec_select_tool(float *value, bool *flag) +{ + cm->gm.tool_select = (uint8_t)value[0]; +} + stat_t cm_select_tool(const uint8_t tool_select) { if (tool_select > TOOLS) { @@ -1302,9 +1298,10 @@ stat_t cm_select_tool(const uint8_t tool_select) return (STAT_OK); } -static void _exec_select_tool(float *value, bool *flag) +static void _exec_change_tool(float *value, bool *flag) { - cm->gm.tool_select = (uint8_t)value[0]; + cm->gm.tool = (uint8_t)value[0]; + // TODO - change tool offsets and update display offsets } stat_t cm_change_tool(const uint8_t tool_change) @@ -1314,18 +1311,12 @@ stat_t cm_change_tool(const uint8_t tool_change) return (STAT_OK); } -static void _exec_change_tool(float *value, bool *flag) -{ - cm->gm.tool = (uint8_t)value[0]; - // TODO - change tool offsets and update display offsets -} - -/*********************************************************************************** - **** Miscellaneous Functions (4.3.9) ********************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Miscellaneous Functions (4.3.9) *************************************************** + ****************************************************************************************/ // see coolant.cpp/.h -/*********************************************************************************** +/**************************************************************************************** * cm_message() - queue a RAM string as a message in the response (unconditionally) */ @@ -1334,11 +1325,11 @@ void cm_message(const char *message) nv_add_string((const char *)"msg", message); // add message to the response object } -/*********************************************************************************** - **** Overrides ******************************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Overrides ************************************************************************* + ****************************************************************************************/ -/*********************************************************************************** +/**************************************************************************************** * cm_reset_overrides() - reset manual feedrate and spindle overrides to initial conditions */ @@ -1351,13 +1342,7 @@ void cm_reset_overrides() cm->gmx.mto_factor = 1.0; } -/* -static void _exec_feed_override(const bool m48_enable, const bool m50_enable, const float override_factor) -{ -} -*/ - -/*********************************************************************************** +/**************************************************************************************** * cm_m48_enable() - M48, M49 * * M48 is the master enable for manual feedrate override and spindle override @@ -1387,7 +1372,7 @@ stat_t cm_m48_enable(uint8_t enable) // M48, M49 return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * cm_fro_control() - M50 feed rate override comtrol * cm_tro_control() - M50.1 traverse override comtrol * @@ -1487,35 +1472,35 @@ stat_t cm_tro_control(const float P_word, const bool P_flag) // M50.1 return (STAT_OK); } -/*********************************************************************************** - **** Program Functions (4.3.10) *************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** Program Functions (4.3.10) ******************************************************** + ****************************************************************************************/ /* This group implements stop, start, and end functions. * It is extended beyond the NIST spec to handle various situations. * * _exec_program_finalize() - helper - * cm_cycle_start() - * cm_cycle_end() - * cm_program_stop() - M0 - * cm_optional_program_stop() - M1 - * cm_program_end() - M2, M30 + * cm_cycle_start() - sets MACHINE_CYCLE condition wwhich enables planner execution + * cm_cycle_end() - resets MACHINE_CYCLE + * cm_program_stop() - M0 - performs NIST STOP functions + * cm_optional_program_stop() - M1 - conditionally performs NIST STOP functions + * cm_program_end() - M2, M30 - performs NIST END functions (with some differences) */ /* * Program and cycle state functions * - * cm_program_stop and cm_optional_program_stop are synchronous Gcode commands - * that are received through the interpreter. They cause all motion to stop - * at the end of the current command, including spindle motion. + * cm_program_stop and cm_optional_program_stop are synchronous Gcode commands that are + * received through the interpreter. They cause all motion to stop at the end of the + * current command, including spindle motion. * - * Note that the stop occurs at the end of the immediately preceding command - * (i.e. the stop is queued behind the last command). + * Note that the stop occurs at the end of the immediately preceding command + * (i.e. the stop is queued behind the last command). * - * cm_program_end is a stop that also resets the machine to initial state + * cm_program_end is a stop that also resets the machine to initial state * - * cm_program_end() implements M2 and M30 - * The END behaviors are defined by NIST 3.6.1 are: - * 1a. Origin offsets are set to the default (like G54) - * 1b. Axis offsets are set to zero (like G92.2) + * cm_program_end() implements M2 and M30 + * The END behaviors are defined by NIST 3.6.1 are: + * 1a. Coordinate offsets are set to the default (like G54) + * 1b. G92 origin offsets are set to zero (like G92.2) * 2. Selected plane is set to CANON_PLANE_XY (like G17) * 3. Distance mode is set to MODE_ABSOLUTE (like G90) * 4. Feed rate mode is set to UNITS_PER_MINUTE (like G94) @@ -1527,15 +1512,16 @@ stat_t cm_tro_control(const float P_word, const bool P_flag) // M50.1 * * cm_program_end() implments things slightly differently (1a, 8): * 1a. Set default coordinate system (uses $gco, not G54) - * 1b. Axis offsets are SUSPENDED (G92.2) + * 1b. G92 origin offsets are SUSPENDED (G92.2) * 2. Selected plane is set to default plane ($gpl) * 3. Distance mode is set to MODE_ABSOLUTE (like G90) * 4. Feed rate mode is set to UNITS_PER_MINUTE (like G94) - * 5. Not implemented - * 6. Not implemented + * 5. Feed and speed overrides are set to ON (like M48) + * 6. (Cutter compensation not implemented) * 7. The spindle is stopped (like M5) * 8. Motion mode is CANCELED like G80 (not set to G1 as per NIST) * 9. Coolant is turned off (like M9) + * 10. Turn off all heaters and fans */ static void _exec_program_finalize(float *value, bool *flag) @@ -1559,17 +1545,16 @@ static void _exec_program_finalize(float *value, bool *flag) // perform the following resets if it's a program END if (machine_state == MACHINE_PROGRAM_END) { cm_suspend_g92_offsets(); // G92.2 - as per NIST -// cm_reset_g92_offsets(); // G92.1 - alternative to above cm_set_coord_system(cm->default_coord_system); // reset to default coordinate system cm_select_plane(cm->default_select_plane); // reset to default arc plane - cm_set_distance_mode(cm->default_distance_mode); + cm_set_distance_mode(cm->default_distance_mode); // reset to default distance mode cm_set_arc_distance_mode(INCREMENTAL_DISTANCE_MODE);// always the default // toolhead.control_immediate(TOOLHEAD_OFF); // M5 spindle_control_immediate(SPINDLE_OFF); // M5 - coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH);// M9 + coolant_control_immediate(COOLANT_OFF,COOLANT_BOTH);// M9 cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // G94 cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);// NIST specifies G1 (MOTION_MODE_STRAIGHT_FEED), but we cancel motion mode. Safer. - cm_reset_overrides(); // reset feedrate the spindle overrides + cm_reset_overrides(); // enable G48, reset feed rate, traverse and spindle overrides temperature_reset(); // turn off all heaters and fans } sr_request_status_report(SR_REQUEST_IMMEDIATE); // request a final and full status report (not filtered) @@ -1618,38 +1603,68 @@ void cm_program_end() mp_queue_command(_exec_program_finalize, value, nullptr); } -/*********************************************************************************** - **** Additional Functions ********************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Additional Functions ************************************************************** + ****************************************************************************************/ /* * cm_json_command() - M100 + * cm_json_wait() - M102 */ stat_t cm_json_command(char *json_string) { return mp_json_command(json_string); } -/* - * cm_json_wait() - M102 - */ stat_t cm_json_wait(char *json_string) { return mp_json_wait(json_string); } +/**************************************************************************************** + * cm_run_home() - run homing sequence + */ + +stat_t cm_run_home(nvObj_t *nv) +{ + if (nv->value_int) { // if true + float axes[] = { 1,1,1,1,1,1 }; + bool flags[] = { 1,1,1,1,1,1 }; + cm_homing_cycle_start(axes, flags); + } + return (STAT_OK); +} + +/**************************************************************************************** + * Jogging Commands + * + * cm_get_jogging_dest() + * cm_run_jog() + */ + +float cm_get_jogging_dest(void) +{ + return cm->jogging_dest; +} + +stat_t cm_run_jog(nvObj_t *nv) +{ + set_float(nv, cm->jogging_dest); + cm_jogging_cycle_start(_axis(nv)); + return (STAT_OK); +} /************************************** * END OF CANONICAL MACHINE FUNCTIONS * **************************************/ -/*********************************************************************************** - **** CONFIGURATION AND INTERFACE FUNCTIONS **************************************** - *********************************************************************************** +/**************************************************************************************** + **** CONFIGURATION AND INTERFACE FUNCTIONS ********************************************* + **************************************************************************************** * Functions to get and set variables from the cfgArray table * These functions are not part of the NIST defined functions - ***********************************************************************************/ + ****************************************************************************************/ -/***** AXIS HELPERS ***************************************************************** +/***** AXIS HELPERS ********************************************************************** * _coord() - return coordinate system number (53=0...59=6) or -1 if error * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) * cm_get_axis_type() - return linear axis (0), rotary axis (1) or error (-1) @@ -1724,80 +1739,43 @@ char cm_get_axis_char(const int8_t axis) return (axis_char[axis]); } -/*********************************************************************************** - * Run Commands - * - * cm_run_home() - run homing sequence - */ - -stat_t cm_run_home(nvObj_t *nv) -{ - if (nv->value_int) { // if true - float axes[] = { 1,1,1,1,1,1 }; - bool flags[] = { 1,1,1,1,1,1 }; - cm_homing_cycle_start(axes, flags); - } - return (STAT_OK); -} - -/* - * Jogging Commands - * - * cm_get_jogging_dest() - * cm_run_jog() - */ - -float cm_get_jogging_dest(void) -{ - return cm->jogging_dest; -} - -stat_t cm_run_jog(nvObj_t *nv) -{ - set_float(nv, cm->jogging_dest); - cm_jogging_cycle_start(_axis(nv)); - return (STAT_OK); -} - /**** Functions called directly from cfgArray table - mostly wrappers **** * _get_msg_helper() - helper to get string values * - * cm_get_stat() - get combined machine state as value and string - * cm_get_macs() - get raw machine state as value and string - * cm_get_cycs() - get raw cycle state as value and string - * cm_get_mots() - get raw motion state as value and string - * cm_get_hold() - get raw hold state as value and string - * cm_get_home() - get raw homing state as value and string + * cm_get_stat() - get combined machine state as value and string + * cm_get_macs() - get raw machine state as value and string + * cm_get_cycs() - get raw cycle state as value and string + * cm_get_mots() - get raw motion state as value and string + * cm_get_hold() - get raw hold state as value and string + * cm_get_home() - get raw homing state as value and string * - * cm_get_unit() - get units mode as integer and display string - * cm_get_coor() - get goodinate system - * cm_get_momo() - get runtime motion mode - * cm_get_plan() - get model plane select - * cm_get_path() - get model path control mode - * cm_get_dist() - get model distance mode - * cm_get_admo() - get model arc distance mode - * cm_get_frmo() - get model feed rate mode - * cm_get_tool() - get tool - * cm_get_feed() - get feed rate - * cm_get_mline()- get model line number for status reports - * cm_get_line() - get active (model or runtime) line number for status reports - * cm_get_vel() - get runtime velocity - * cm_get_ofs() - get current work offset (runtime) - * cm_get_pos() - get current work position (runtime) - * cm_get_mpos() - get current machine position (runtime) + * cm_get_unit() - get units mode as integer and display string + * cm_get_coor() - get goodinate system + * cm_get_momo() - get runtime motion mode + * cm_get_plan() - get model plane select + * cm_get_path() - get model path control mode + * cm_get_dist() - get model distance mode + * cm_get_admo() - get model arc distance mode + * cm_get_frmo() - get model feed rate mode + * cm_get_tool() - get tool + * cm_get_feed() - get feed rate + * cm_get_mline() - get model line number for status reports + * cm_get_line() - get active (model or runtime) line number for status reports + * cm_get_vel() - get runtime velocity + * cm_get_ofs() - get current work offset (runtime) + * cm_get_pos() - get current work position (runtime) + * cm_get_mpos() - get current machine position (runtime) * - * cm_print_pos()- print work position (with proper units) + * cm_print_pos() - print work position (with proper units) * cm_print_mpos()- print machine position (always mm units) * cm_print_coor()- print coordinate offsets with linear units * cm_print_corr()- print coordinate offsets with rotary units */ - -// Strings for writing settings as nvObj string values -// Ref: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=120881&start=0 - #ifdef __TEXT_MODE +// Strings for text mode displays: + static const char msg_units0[] = " in"; // used by generic print functions static const char msg_units1[] = " mm"; static const char msg_units2[] = " deg"; @@ -1940,7 +1918,7 @@ static const char *const msg_frmo[] = { msg_g93, msg_g94, msg_g95 }; #endif // __TEXT_MODE -// Add the string for the enum to the nv, but leave it as a TYPE_INT +//_get_msg_helper() - add the string for the enum to the nv, but leave it as a TYPE_INTEGER stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], int32_t value) { nv->value_int = value; @@ -1949,7 +1927,7 @@ stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], int32_t value } stat_t cm_get_stat(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm1)));} -stat_t cm_get_stat2(nvObj_t *nv) { return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm2)));} +stat_t cm_get_stat2(nvObj_t *nv){ return(_get_msg_helper(nv, msg_stat, cm_get_combined_state(&cm2)));} stat_t cm_get_macs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_macs, cm_get_machine_state()));} stat_t cm_get_cycs(nvObj_t *nv) { return(_get_msg_helper(nv, msg_cycs, cm_get_cycle_type()));} stat_t cm_get_mots(nvObj_t *nv) { return(_get_msg_helper(nv, msg_mots, cm_get_motion_state()));} @@ -2039,10 +2017,7 @@ stat_t cm_set_tt(nvObj_t *nv) /************************************ **** AXIS GET AND SET FUNCTIONS **** ************************************/ - /* - * AXIS GET AND SET FUNCTIONS - * * cm_get_am() - get axis mode w/enumeration string * cm_set_am() - set axis mode w/exception handling for axis type * cm_get_tn() - get axis travel min @@ -2271,7 +2246,6 @@ stat_t cm_set_gdi(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)cm->default_d /*********************************************************************************** * Debugging Commands ***********************************************************************************/ - /* * cm_dam() - dump active model */ @@ -2299,6 +2273,7 @@ stat_t cm_dam(nvObj_t *nv) return (STAT_OK); } + /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index fc813202..6d3f6f1a 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -43,7 +43,7 @@ coCoolant_t coolant; static void _exec_coolant_control(float* value, bool* flag); -/* +/**************************************************************************************** * coolant_init() * coolant_reset() */ @@ -57,7 +57,7 @@ void coolant_reset() { coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); } -/* +/**************************************************************************************** * coolant_control_immediate() - execute coolant control immediately * coolant_control_sync() - queue a coolant control to the planner buffer * _exec_coolant_control() - actually execute the coolant command @@ -149,9 +149,9 @@ static void _exec_coolant_control(float* value, bool* flag) { } } -/*********************************************************************************** - **** Coolant Settings ************************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Coolant Settings ****************************************************************** + ****************************************************************************************/ stat_t co_get_com(nvObj_t *nv) { return(get_integer(nv, coolant.mist.state)); } stat_t co_set_com(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value_int, COOLANT_MIST)); } @@ -159,7 +159,8 @@ stat_t co_get_cof(nvObj_t *nv) { return(get_integer(nv, coolant.flood.state)); } stat_t co_set_cof(nvObj_t *nv) { return(coolant_control_immediate((coControl)nv->value_int, COOLANT_FLOOD)); } stat_t co_get_coph(nvObj_t *nv) { return(get_integer(nv, coolant.mist.pause_enable)); } -stat_t co_set_coph(nvObj_t *nv) { +stat_t co_set_coph(nvObj_t *nv) +{ ritorno(set_integer(nv, (uint8_t &)coolant.mist.pause_enable, 0, 1)); return (set_integer(nv, (uint8_t &)coolant.flood.pause_enable, 0, 1)); } @@ -169,9 +170,9 @@ stat_t co_set_comp(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)coolant.mist stat_t co_get_cofp(nvObj_t *nv) { return(get_integer(nv, coolant.flood.polarity)); } stat_t co_set_cofp(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)coolant.flood.polarity, 0, 1)); } -/*********************************************************************************** +/**************************************************************************************** * TEXT MODE SUPPORT - * Functions to print variables from the cfgArray table + * Functions to print variables from the cfgArray table***** ***********************************************************************************/ #ifdef __TEXT_MODE diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index c5f42a26..dd505aa1 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -50,7 +50,7 @@ static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm); spindle.direction = SPINDLE_CW; \ } -/*********************************************************************************** +/**************************************************************************************** * spindle_init() * spindle_reset() - stop spindle, set speed to zero, and reset values */ @@ -71,10 +71,10 @@ void spindle_reset() spindle_control_immediate(SPINDLE_OFF); } -/*********************************************************************************** +/**************************************************************************************** + * _exec_spindle_control() - actually execute the spindle command * spindle_control_immediate() - execute spindle control immediately * spindle_control_sync() - queue a spindle control to the planner buffer - * _exec_spindle_control() - actually execute the spindle command * * Basic operation: Spindle function is executed by _exec_spindle_control(). * Spindle_control_immediate() performs the control as soon as it's received. @@ -87,29 +87,32 @@ void spindle_reset() * The spindle.direction value is not affected (although this doesn't really matter). * * - SPINDLE_CW or SPINDLE_CCW turns sets direction accordingly and spindle on. - * In spindle_control_sync() a non-zero spinup delay runs a dwell immediately following - * the spindle change, but only if the planner had planned the spindle operation to zero. - * (I.e. if the spindle controls / S words do not plan to zero the delay is not run). - * Spindle_control_immediate() has no spinup delay or dwell behavior. + * In spindle_control_sync() a non-zero spinup delay runs a dwell immediately + * following the spindle change, but only if the planner had planned the spindle + * operation to zero. (I.e. if the spindle controls / S words do not plan to zero + * the delay is not run). Spindle_control_immediate() has no spinup delay or + * dwell behavior. * * - SPINDLE_PAUSE is only applicable to CW and CCW states. It forces the spindle OFF and * sets spindle.state to PAUSE. A PAUSE received when not in CW or CCW state is ignored. * * - SPINDLE_RESUME, if in a PAUSE state, reverts to previous SPINDLE_CW or SPINDLE_CCW. - * The SPEED is not changed, and if it were changed in the interim the "new" speed is used. - * If RESUME is received from spindle_control_sync() the usual spinup delay behavior occurs. - * If RESUME is received when not in a PAUSED state it is ignored. This recognizes that the main - * reason an immediate command would be issued - either manually by the user or by an alarm or - * some other program function - is to stop a spindle. So the Resume should be ignored for safety. + * The SPEED is not changed, and if it were changed in the interim the "new" speed + * is used. If RESUME is received from spindle_control_sync() the usual spinup delay + * behavior occurs. If RESUME is received when not in a PAUSED state it is ignored. + * This recognizes that the main reason an immediate command would be issued - either + * manually by the user or by an alarm or some other program function - is to stop + * a spindle. So the Resume should be ignored for safety. */ /* Notes: - * - Since it's possible to queue a sync'd control, and then set any spindle state with an - * immediate() before the queued command is reached, _exec_spindle_control() must gracefully - * handle any arbitrary state transition (not just the "legal" ones). + * - Since it's possible to queue a sync'd control, and then set any spindle state + * with an immediate() before the queued command is reached, _exec_spindle_control() + * must gracefully handle any arbitrary state transition (not just the "legal" ones). * - * - The spinup and spindown rows are present, but are not implemented unless we findwe need them. - * It's easy enough to set these flags using the bit vector passed from sync(), but unsetting - * them once the delay is complete would take some more work. + * - The spinup and spindown rows are present, but are not implemented unless we + * find we need them. It's easy enough to set these flags using the bit vector + * passed from sync(),but unsetting them once the delay is complete would take + * some more work. * * Q: Do we need a spin-down for direction reversal? * Q: Should the JSON be able to pause and resume? For test purposes only? @@ -242,10 +245,10 @@ stat_t spindle_control_sync(spControl control) // uses spControl arg: OFF, CW, return(STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** + * _exec_spindle_speed() - actually execute the spindle speed command * spindle_speed_immediate() - execute spindle speed change immediately * spindle_speed_sync() - queue a spindle speed change to the planner buffer - * _exec_spindle_speed() - actually execute the spindle speed command * * Setting S0 is considered as turning spindle off. Setting S to non-zero from S0 * will enable a spinup delay if spinups are npn-zero. @@ -286,7 +289,7 @@ stat_t spindle_speed_sync(float speed) return (STAT_OK); } -/*********************************************************************************** +/**************************************************************************************** * _get_spindle_pwm() - return PWM phase (duty cycle) for dir and speed */ @@ -321,7 +324,7 @@ static float _get_spindle_pwm (spSpindle_t &_spindle, pwmControl_t &_pwm) } } -/*********************************************************************************** +/**************************************************************************************** * spindle_override_control() * spindle_start_override() * spindle_end_override() @@ -371,14 +374,14 @@ void spindle_end_override(const float ramp_time) * END OF SPINDLE FUNCTIONS * ****************************/ -/*********************************************************************************** +/**************************************************************************************** * CONFIGURATION AND INTERFACE FUNCTIONS * Functions to get and set variables from the cfgArray table - ***********************************************************************************/ + ****************************************************************************************/ -/*********************************************************************************** - **** Spindle Settings ************************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** Spindle Settings ****************************************************************** + ****************************************************************************************/ stat_t sp_get_spmo(nvObj_t *nv) { return(get_integer(nv, spindle.mode)); } stat_t sp_set_spmo(nvObj_t *nv) { return(set_integer(nv, (uint8_t &)spindle.mode, SPINDLE_DISABLED, SPINDLE_MODE_MAX)); } @@ -418,10 +421,10 @@ stat_t sp_set_spc(nvObj_t *nv) { return(spindle_control_immediate((spControl)nv- stat_t sp_get_sps(nvObj_t *nv) { return(get_float(nv, spindle.speed)); } stat_t sp_set_sps(nvObj_t *nv) { return(spindle_speed_immediate(nv->value_flt)); } -/*********************************************************************************** +/**************************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table - ***********************************************************************************/ + ****************************************************************************************/ #ifdef __TEXT_MODE From 693cb04d1a9a6f15b5db4eb6d66ad5fa775f4535 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 23 Mar 2017 11:50:18 -0400 Subject: [PATCH 221/283] Cleanup after very messy merge --- g2core/canonical_machine.h | 87 +------- g2core/config.h | 1 - g2core/config_app.cpp | 369 +------------------------------- g2core/controller.cpp | 4 +- g2core/gcode_parser.cpp | 243 +-------------------- g2core/marlin_compatibility.cpp | 10 +- g2core/report.cpp | 1 + g2core/settings.h | 6 +- 8 files changed, 25 insertions(+), 696 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 40204e9d..953c76a8 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -427,14 +427,12 @@ stat_t cm_set_absolute_origin(const float origin[], bool flag[]); // G void cm_set_axis_origin(uint8_t axis, const float position); // G28.3 planner callback stat_t cm_set_coord_system(const uint8_t coord_system); // G54 - G59 -stat_t cm_set_g92_offsets(const float offset[], const bool flag[]); // G92 -stat_t cm_reset_g92_offsets(void); // G92.1 -stat_t cm_suspend_g92_offsets(void); // G92.2 -stat_t cm_resume_g92_offsets(void); // G92.3 +stat_t cm_set_g92_offsets(const float offset[], const bool flag[]); // G92 +stat_t cm_reset_g92_offsets(void); // G92.1 +stat_t cm_suspend_g92_offsets(void); // G92.2 +stat_t cm_resume_g92_offsets(void); // G92.3 // Free Space Motion (4.3.4) -//stat_t cm_straight_traverse(const float target[], const bool flags[]); // G0 -//stat_t cm_straight_traverse(const float *target, const bool *flags); // G0 stat_t cm_straight_traverse(const float *target, const bool *flags, const uint8_t motion_profile); // G0 stat_t cm_set_g28_position(void); // G28.1 stat_t cm_goto_g28_position(const float target[], const bool flags[]); // G28 @@ -447,8 +445,6 @@ stat_t cm_set_feed_rate_mode(const uint8_t mode); // G stat_t cm_set_path_control(GCodeState_t *gcode_state, const uint8_t mode); // G61, G61.1, G64 // Machining Functions (4.3.6) -//stat_t cm_straight_feed(const float target[], const bool flags[]); // G1 -//stat_t cm_straight_feed(const float *target, const bool *flags); // G1 stat_t cm_straight_feed(const float *target, const bool *flags, const uint8_t motion_profile); //G1 stat_t cm_dwell(const float seconds); // G4, P parameter @@ -673,73 +669,6 @@ stat_t cm_set_gdi(nvObj_t *nv); // set gcode default distance mode #ifdef __TEXT_MODE -/* <<<<<< HEAD - void cm_print_vel(nvObj_t *nv); // model state reporting - void cm_print_feed(nvObj_t *nv); - void cm_print_line(nvObj_t *nv); - void cm_print_stat(nvObj_t *nv); - void cm_print_macs(nvObj_t *nv); - void cm_print_cycs(nvObj_t *nv); - void cm_print_mots(nvObj_t *nv); - void cm_print_hold(nvObj_t *nv); - void cm_print_home(nvObj_t *nv); - void cm_print_hom(nvObj_t *nv); - void cm_print_unit(nvObj_t *nv); - void cm_print_coor(nvObj_t *nv); - void cm_print_momo(nvObj_t *nv); - void cm_print_plan(nvObj_t *nv); - void cm_print_path(nvObj_t *nv); - void cm_print_dist(nvObj_t *nv); - void cm_print_admo(nvObj_t *nv); - void cm_print_frmo(nvObj_t *nv); - void cm_print_tool(nvObj_t *nv); - void cm_print_g92e(nvObj_t *nv); - - void cm_print_gpl(nvObj_t *nv); // Gcode defaults - void cm_print_gun(nvObj_t *nv); - void cm_print_gco(nvObj_t *nv); - void cm_print_gpa(nvObj_t *nv); - void cm_print_gdi(nvObj_t *nv); - - void cm_print_lin(nvObj_t *nv); // generic print for linear values - void cm_print_pos(nvObj_t *nv); // print runtime work position in prevailing units - void cm_print_mpo(nvObj_t *nv); // print runtime work position always in MM uints - void cm_print_ofs(nvObj_t *nv); // print runtime work offset always in MM uints - - void cm_print_jt(nvObj_t *nv); // global CM settings - void cm_print_ct(nvObj_t *nv); - void cm_print_zl(nvObj_t *nv); - void cm_print_sl(nvObj_t *nv); - void cm_print_lim(nvObj_t *nv); - void cm_print_saf(nvObj_t *nv); - - void cm_print_m48(nvObj_t *nv); - void cm_print_froe(nvObj_t *nv); - void cm_print_fro(nvObj_t *nv); - void cm_print_troe(nvObj_t *nv); - void cm_print_tro(nvObj_t *nv); - - void cm_print_tram(nvObj_t *nv); // print if the axis has been rotated - - void cm_print_am(nvObj_t *nv); // axis print functions - void cm_print_fr(nvObj_t *nv); - void cm_print_vm(nvObj_t *nv); - void cm_print_tm(nvObj_t *nv); - void cm_print_tn(nvObj_t *nv); - void cm_print_jm(nvObj_t *nv); - void cm_print_jh(nvObj_t *nv); - void cm_print_ra(nvObj_t *nv); - - void cm_print_hi(nvObj_t *nv); - void cm_print_hd(nvObj_t *nv); - void cm_print_sv(nvObj_t *nv); - void cm_print_lv(nvObj_t *nv); - void cm_print_lb(nvObj_t *nv); - void cm_print_zb(nvObj_t *nv); - void cm_print_cofs(nvObj_t *nv); - void cm_print_cpos(nvObj_t *nv); - -=======*/ void cm_print_vel(nvObj_t *nv); // model state reporting void cm_print_feed(nvObj_t *nv); void cm_print_line(nvObj_t *nv); @@ -786,12 +715,6 @@ stat_t cm_set_gdi(nvObj_t *nv); // set gcode default distance mode void cm_print_troe(nvObj_t *nv); void cm_print_tro(nvObj_t *nv); -// void cm_print_m48e(nvObj_t *nv); -// void cm_print_mfoe(nvObj_t *nv); -// void cm_print_mfo(nvObj_t *nv); -// void cm_print_mtoe(nvObj_t *nv); -// void cm_print_mto(nvObj_t *nv); - void cm_print_tram(nvObj_t *nv); // print if the axis has been rotated void cm_print_nxln(nvObj_t *nv); // print the value of the next line number expected @@ -813,8 +736,6 @@ stat_t cm_set_gdi(nvObj_t *nv); // set gcode default distance mode void cm_print_cofs(nvObj_t *nv); void cm_print_cpos(nvObj_t *nv); -//>>>>>>> refs/heads/edge - #else // __TEXT_MODE #define cm_print_vel tx_print_stub // model state reporting diff --git a/g2core/config.h b/g2core/config.h index 196f392d..1ade7dcc 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -223,7 +223,6 @@ typedef enum { // value typing for config and JSON // transient types and types used during JSON processing TYPE_PARENT // object is a parent to a sub-object -// TYPE_NEW_LEVEL, // 'value' is actually child key at new nesting level // TYPE_NULL_STRING, // empty string - treated as null // TYPE_TYPE_ERROR // none of the above } valueType; diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 3a6914aa..f2a3a046 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -113,7 +113,6 @@ const cfgItem_t cfgArray[] = { { "sys", "id", _sn, 0, hw_print_id, hw_get_id, set_ro, nullptr, 0 }, // device ID (ASCII signature) // dynamic model attributes for reporting purposes (up front for speed) -//<<<<<< HEAD { "", "stat",_i0, 0, cm_print_stat, cm_get_stat, set_ro, nullptr, 0 }, // combined machine state { "","stat2",_i0, 0, cm_print_stat, cm_get_stat2,set_ro, nullptr, 0 }, // combined machine state { "", "n", _ii, 0, cm_print_line, cm_get_mline,set_noop,nullptr,0 }, // Model line number @@ -134,28 +133,6 @@ const cfgItem_t cfgArray[] = { { "", "frmo",_i0, 0, cm_print_frmo, cm_get_frmo, set_ro, nullptr, 0 }, // feed rate mode { "", "tool",_i0, 0, cm_print_tool, cm_get_toolv,set_ro, nullptr, 0 }, // active tool { "", "g92e",_i0, 0, cm_print_g92e, cm_get_g92e, set_ro, nullptr, 0 }, // G92 enable state -/*======= - { "", "stat",_f0, 0, cm_print_stat, cm_get_stat, set_ro, (float *)&cs.null, 0 }, // combined machine state - { "", "n", _fi, 0, cm_print_line, cm_get_mline,set_noop,(float *)&cs.null, 0 }, // Model line number - { "", "line",_fi, 0, cm_print_line, cm_get_line, set_ro, (float *)&cs.null, 0 }, // Active line number - model or runtime line number - { "", "vel", _f0, 2, cm_print_vel, cm_get_vel, set_ro, (float *)&cs.null, 0 }, // current velocity - { "", "feed",_f0, 2, cm_print_feed, cm_get_feed, set_ro, (float *)&cs.null, 0 }, // feed rate - { "", "macs",_f0, 0, cm_print_macs, cm_get_macs, set_ro, (float *)&cs.null, 0 }, // raw machine state - { "", "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_ro, (float *)&cs.null, 0 }, // cycle state - { "", "mots",_f0, 0, cm_print_mots, cm_get_mots, set_ro, (float *)&cs.null, 0 }, // motion state - { "", "hold",_f0, 0, cm_print_hold, cm_get_hold, set_ro, (float *)&cs.null, 0 }, // feedhold state - { "", "unit",_f0, 0, cm_print_unit, cm_get_unit, set_ro, (float *)&cs.null, 0 }, // units mode - { "", "coor",_f0, 0, cm_print_coor, cm_get_coor, set_ro, (float *)&cs.null, 0 }, // coordinate system - { "", "momo",_f0, 0, cm_print_momo, cm_get_momo, set_ro, (float *)&cs.null, 0 }, // motion mode - { "", "plan",_f0, 0, cm_print_plan, cm_get_plan, set_ro, (float *)&cs.null, 0 }, // plane select - { "", "path",_f0, 0, cm_print_path, cm_get_path, set_ro, (float *)&cs.null, 0 }, // path control mode - { "", "dist",_f0, 0, cm_print_dist, cm_get_dist, set_ro, (float *)&cs.null, 0 }, // distance mode - { "", "admo",_f0, 0, cm_print_admo, cm_get_admo, set_ro, (float *)&cs.null, 0 }, // arc distance mode - { "", "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_ro, (float *)&cs.null, 0 }, // feed rate mode - { "", "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_ro, (float *)&cs.null, 0 }, // active tool - { "", "g92e",_f0, 0, cm_print_g92e, get_ui8, set_ro, (float *)&cm.gmx.origin_offset_enable, 0 }, // G92 enabled - ->>>>>>> refs/heads/edge*/ #ifdef TEMPORARY_HAS_LEDS { "", "_leds",_i0, 0, tx_print_nul, _get_leds,_set_leds, nullptr, 0 }, // TEMPORARY - change LEDs #endif @@ -607,7 +584,6 @@ const cfgItem_t cfgArray[] = { { "g92","g92c",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, // Coordinate positions (G28, G30) -//<<<<<< HEAD { "g28","g28x",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 },// g28 handled differently { "g28","g28y",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, { "g28","g28z",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, @@ -621,254 +597,6 @@ const cfgItem_t cfgArray[] = { { "g30","g30a",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, { "g30","g30b",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, { "g30","g30c",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, -/*======= - { "g28","g28x",_fic, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g28_position[AXIS_X], 0 },// g28 handled differently - { "g28","g28y",_fic, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g28_position[AXIS_Y], 0 }, - { "g28","g28z",_fic, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g28_position[AXIS_Z], 0 }, - { "g28","g28a",_fi, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g28_position[AXIS_A], 0 }, - { "g28","g28b",_fi, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g28_position[AXIS_B], 0 }, - { "g28","g28c",_fi, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g28_position[AXIS_C], 0 }, - - { "g30","g30x",_fic, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g30_position[AXIS_X], 0 },// g30 handled differently - { "g30","g30y",_fic, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g30_position[AXIS_Y], 0 }, - { "g30","g30z",_fic, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g30_position[AXIS_Z], 0 }, - { "g30","g30a",_fi, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g30_position[AXIS_A], 0 }, - { "g30","g30b",_fi, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g30_position[AXIS_B], 0 }, - { "g30","g30c",_fi, 3, cm_print_cpos, get_flt, set_ro, (float *)&cm.gmx.g30_position[AXIS_C], 0 }, - - // Default values for current tool length offsets (not configurable, set to zero) - { "tof","tofx",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tl_offset[AXIS_X], 0 }, - { "tof","tofy",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tl_offset[AXIS_Y], 0 }, - { "tof","tofz",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tl_offset[AXIS_Z], 0 }, - { "tof","tofa",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_A], 0 }, - { "tof","tofb",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_B], 0 }, - { "tof","tofc",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tl_offset[AXIS_C], 0 }, - - // Tool table offsets - { "tt1","tt1x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[1][AXIS_X], TT1_X_OFFSET }, - { "tt1","tt1y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[1][AXIS_Y], TT1_Y_OFFSET }, - { "tt1","tt1z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[1][AXIS_Z], TT1_Z_OFFSET }, - { "tt1","tt1a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[1][AXIS_A], TT1_A_OFFSET }, - { "tt1","tt1b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[1][AXIS_B], TT1_B_OFFSET }, - { "tt1","tt1c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[1][AXIS_C], TT1_C_OFFSET }, - - { "tt2","tt2x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[2][AXIS_X], TT2_X_OFFSET }, - { "tt2","tt2y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[2][AXIS_Y], TT2_Y_OFFSET }, - { "tt2","tt2z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[2][AXIS_Z], TT2_Z_OFFSET }, - { "tt2","tt2a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[2][AXIS_A], TT2_A_OFFSET }, - { "tt2","tt2b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[2][AXIS_B], TT2_B_OFFSET }, - { "tt2","tt2c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[2][AXIS_C], TT2_C_OFFSET }, - - { "tt3","tt3x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[3][AXIS_X], TT3_X_OFFSET }, - { "tt3","tt3y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[3][AXIS_Y], TT3_Y_OFFSET }, - { "tt3","tt3z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[3][AXIS_Z], TT3_Z_OFFSET }, - { "tt3","tt3a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[3][AXIS_A], TT3_A_OFFSET }, - { "tt3","tt3b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[3][AXIS_B], TT3_B_OFFSET }, - { "tt3","tt3c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[3][AXIS_C], TT1_C_OFFSET }, - - { "tt4","tt4x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[4][AXIS_X], TT4_X_OFFSET }, - { "tt4","tt4y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[4][AXIS_Y], TT4_Y_OFFSET }, - { "tt4","tt4z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[4][AXIS_Z], TT4_Z_OFFSET }, - { "tt4","tt4a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[4][AXIS_A], TT4_A_OFFSET }, - { "tt4","tt4b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[4][AXIS_B], TT4_B_OFFSET }, - { "tt4","tt4c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[4][AXIS_C], TT4_C_OFFSET }, - - { "tt5","tt5x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[5][AXIS_X], TT5_X_OFFSET }, - { "tt5","tt5y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[5][AXIS_Y], TT5_Y_OFFSET }, - { "tt5","tt5z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[5][AXIS_Z], TT5_Z_OFFSET }, - { "tt5","tt5a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[5][AXIS_A], TT5_A_OFFSET }, - { "tt5","tt5b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[5][AXIS_B], TT5_B_OFFSET }, - { "tt5","tt5c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[5][AXIS_C], TT5_C_OFFSET }, - - { "tt6","tt6x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[6][AXIS_X], TT6_X_OFFSET }, - { "tt6","tt6y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[6][AXIS_Y], TT6_Y_OFFSET }, - { "tt6","tt6z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[6][AXIS_Z], TT6_Z_OFFSET }, - { "tt6","tt6a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[6][AXIS_A], TT6_A_OFFSET }, - { "tt6","tt6b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[6][AXIS_B], TT6_B_OFFSET }, - { "tt6","tt6c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[6][AXIS_C], TT6_C_OFFSET }, - - { "tt7","tt7x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[7][AXIS_X], TT7_X_OFFSET }, - { "tt7","tt7y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[7][AXIS_Y], TT7_Y_OFFSET }, - { "tt7","tt7z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[7][AXIS_Z], TT7_Z_OFFSET }, - { "tt7","tt7a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[7][AXIS_A], TT7_A_OFFSET }, - { "tt7","tt7b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[7][AXIS_B], TT7_B_OFFSET }, - { "tt7","tt7c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[7][AXIS_C], TT7_C_OFFSET }, - - { "tt8","tt8x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[8][AXIS_X], TT8_X_OFFSET }, - { "tt8","tt8y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[8][AXIS_Y], TT8_Y_OFFSET }, - { "tt8","tt8z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[8][AXIS_Z], TT8_Z_OFFSET }, - { "tt8","tt8a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[8][AXIS_A], TT8_A_OFFSET }, - { "tt8","tt8b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[8][AXIS_B], TT8_B_OFFSET }, - { "tt8","tt8c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[8][AXIS_C], TT8_C_OFFSET }, - - { "tt9","tt9x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[9][AXIS_X], TT9_X_OFFSET }, - { "tt9","tt9y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[9][AXIS_Y], TT9_Y_OFFSET }, - { "tt9","tt9z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[9][AXIS_Z], TT9_Z_OFFSET }, - { "tt9","tt9a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[9][AXIS_A], TT9_A_OFFSET }, - { "tt9","tt9b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[9][AXIS_B], TT9_B_OFFSET }, - { "tt9","tt9c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[9][AXIS_C], TT9_C_OFFSET }, - - { "tt10","tt10x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[10][AXIS_X], TT10_X_OFFSET }, - { "tt10","tt10y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[10][AXIS_Y], TT10_Y_OFFSET }, - { "tt10","tt10z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[10][AXIS_Z], TT10_Z_OFFSET }, - { "tt10","tt10a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[10][AXIS_A], TT10_A_OFFSET }, - { "tt10","tt10b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[10][AXIS_B], TT10_B_OFFSET }, - { "tt10","tt10c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[10][AXIS_C], TT10_C_OFFSET }, - - { "tt11","tt11x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[11][AXIS_X], TT11_X_OFFSET }, - { "tt11","tt11y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[11][AXIS_Y], TT11_Y_OFFSET }, - { "tt11","tt11z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[11][AXIS_Z], TT11_Z_OFFSET }, - { "tt11","tt11a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[11][AXIS_A], TT11_A_OFFSET }, - { "tt11","tt11b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[11][AXIS_B], TT11_B_OFFSET }, - { "tt11","tt11c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[11][AXIS_C], TT11_C_OFFSET }, - - { "tt12","tt12x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[12][AXIS_X], TT12_X_OFFSET }, - { "tt12","tt12y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[12][AXIS_Y], TT12_Y_OFFSET }, - { "tt12","tt12z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[12][AXIS_Z], TT12_Z_OFFSET }, - { "tt12","tt12a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[12][AXIS_A], TT12_A_OFFSET }, - { "tt12","tt12b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[12][AXIS_B], TT12_B_OFFSET }, - { "tt12","tt12c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[12][AXIS_C], TT12_C_OFFSET }, - - { "tt13","tt13x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[13][AXIS_X], TT13_X_OFFSET }, - { "tt13","tt13y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[13][AXIS_Y], TT13_Y_OFFSET }, - { "tt13","tt13z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[13][AXIS_Z], TT13_Z_OFFSET }, - { "tt13","tt13a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[13][AXIS_A], TT13_A_OFFSET }, - { "tt13","tt13b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[13][AXIS_B], TT13_B_OFFSET }, - { "tt13","tt13c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[13][AXIS_C], TT13_C_OFFSET }, - - { "tt14","tt14x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[14][AXIS_X], TT14_X_OFFSET }, - { "tt14","tt14y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[14][AXIS_Y], TT14_Y_OFFSET }, - { "tt14","tt14z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[14][AXIS_Z], TT14_Z_OFFSET }, - { "tt14","tt14a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[14][AXIS_A], TT14_A_OFFSET }, - { "tt14","tt14b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[14][AXIS_B], TT14_B_OFFSET }, - { "tt14","tt14c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[14][AXIS_C], TT14_C_OFFSET }, - - { "tt15","tt15x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[15][AXIS_X], TT15_X_OFFSET }, - { "tt15","tt15y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[15][AXIS_Y], TT15_Y_OFFSET }, - { "tt15","tt15z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[15][AXIS_Z], TT15_Z_OFFSET }, - { "tt15","tt15a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[15][AXIS_A], TT15_A_OFFSET }, - { "tt15","tt15b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[15][AXIS_B], TT15_B_OFFSET }, - { "tt15","tt15c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[15][AXIS_C], TT15_C_OFFSET }, - - { "tt16","tt16x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[16][AXIS_X], TT16_X_OFFSET }, - { "tt16","tt16y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[16][AXIS_Y], TT16_Y_OFFSET }, - { "tt16","tt16z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[16][AXIS_Z], TT16_Z_OFFSET }, - { "tt16","tt16a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[16][AXIS_A], TT16_A_OFFSET }, - { "tt16","tt16b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[16][AXIS_B], TT16_B_OFFSET }, - { "tt16","tt16c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[16][AXIS_C], TT16_C_OFFSET }, - - { "tt17","tt17x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[17][AXIS_X], TT17_X_OFFSET }, - { "tt17","tt17y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[17][AXIS_Y], TT17_Y_OFFSET }, - { "tt17","tt17z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[17][AXIS_Z], TT17_Z_OFFSET }, - { "tt17","tt17a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[17][AXIS_A], TT17_A_OFFSET }, - { "tt17","tt17b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[17][AXIS_B], TT17_B_OFFSET }, - { "tt17","tt17c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[17][AXIS_C], TT17_C_OFFSET }, - - { "tt18","tt18x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[18][AXIS_X], TT18_X_OFFSET }, - { "tt18","tt18y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[18][AXIS_Y], TT18_Y_OFFSET }, - { "tt18","tt18z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[18][AXIS_Z], TT18_Z_OFFSET }, - { "tt18","tt18a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[18][AXIS_A], TT18_A_OFFSET }, - { "tt18","tt18b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[18][AXIS_B], TT18_B_OFFSET }, - { "tt18","tt18c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[18][AXIS_C], TT18_C_OFFSET }, - - { "tt19","tt19x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[19][AXIS_X], TT19_X_OFFSET }, - { "tt19","tt19y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[19][AXIS_Y], TT19_Y_OFFSET }, - { "tt19","tt19z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[19][AXIS_Z], TT19_Z_OFFSET }, - { "tt19","tt19a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[19][AXIS_A], TT19_A_OFFSET }, - { "tt19","tt19b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[19][AXIS_B], TT19_B_OFFSET }, - { "tt19","tt19c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[19][AXIS_C], TT19_C_OFFSET }, - - { "tt20","tt20x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[20][AXIS_X], TT20_X_OFFSET }, - { "tt20","tt20y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[20][AXIS_Y], TT20_Y_OFFSET }, - { "tt20","tt20z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[20][AXIS_Z], TT20_Z_OFFSET }, - { "tt20","tt20a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[20][AXIS_A], TT20_A_OFFSET }, - { "tt20","tt20b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[20][AXIS_B], TT20_B_OFFSET }, - { "tt20","tt20c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[20][AXIS_C], TT20_C_OFFSET }, - - { "tt21","tt21x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[21][AXIS_X], TT21_X_OFFSET }, - { "tt21","tt21y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[21][AXIS_Y], TT21_Y_OFFSET }, - { "tt21","tt21z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[21][AXIS_Z], TT21_Z_OFFSET }, - { "tt21","tt21a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[21][AXIS_A], TT21_A_OFFSET }, - { "tt21","tt21b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[21][AXIS_B], TT21_B_OFFSET }, - { "tt21","tt21c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[21][AXIS_C], TT21_C_OFFSET }, - - { "tt22","tt22x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[22][AXIS_X], TT22_X_OFFSET }, - { "tt22","tt22y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[22][AXIS_Y], TT22_Y_OFFSET }, - { "tt22","tt22z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[22][AXIS_Z], TT22_Z_OFFSET }, - { "tt22","tt22a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[22][AXIS_A], TT22_A_OFFSET }, - { "tt22","tt22b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[22][AXIS_B], TT22_B_OFFSET }, - { "tt22","tt22c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[22][AXIS_C], TT22_C_OFFSET }, - - { "tt23","tt23x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[23][AXIS_X], TT23_X_OFFSET }, - { "tt23","tt23y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[23][AXIS_Y], TT23_Y_OFFSET }, - { "tt23","tt23z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[23][AXIS_Z], TT23_Z_OFFSET }, - { "tt23","tt23a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[23][AXIS_A], TT23_A_OFFSET }, - { "tt23","tt23b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[23][AXIS_B], TT23_B_OFFSET }, - { "tt23","tt23c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[23][AXIS_C], TT23_C_OFFSET }, - - { "tt24","tt24x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[24][AXIS_X], TT24_X_OFFSET }, - { "tt24","tt24y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[24][AXIS_Y], TT24_Y_OFFSET }, - { "tt24","tt24z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[24][AXIS_Z], TT24_Z_OFFSET }, - { "tt24","tt24a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[24][AXIS_A], TT24_A_OFFSET }, - { "tt24","tt24b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[24][AXIS_B], TT24_B_OFFSET }, - { "tt24","tt24c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[24][AXIS_C], TT24_C_OFFSET }, - - { "tt25","tt25x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[25][AXIS_X], TT25_X_OFFSET }, - { "tt25","tt25y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[25][AXIS_Y], TT25_Y_OFFSET }, - { "tt25","tt25z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[25][AXIS_Z], TT25_Z_OFFSET }, - { "tt25","tt25a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[25][AXIS_A], TT25_A_OFFSET }, - { "tt25","tt25b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[25][AXIS_B], TT25_B_OFFSET }, - { "tt25","tt25c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[25][AXIS_C], TT25_C_OFFSET }, - - { "tt26","tt26x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[26][AXIS_X], TT26_X_OFFSET }, - { "tt26","tt26y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[26][AXIS_Y], TT26_Y_OFFSET }, - { "tt26","tt26z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[26][AXIS_Z], TT26_Z_OFFSET }, - { "tt26","tt26a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[26][AXIS_A], TT26_A_OFFSET }, - { "tt26","tt26b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[26][AXIS_B], TT26_B_OFFSET }, - { "tt26","tt26c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[26][AXIS_C], TT26_C_OFFSET }, - - { "tt27","tt27x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[27][AXIS_X], TT27_X_OFFSET }, - { "tt27","tt27y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[27][AXIS_Y], TT27_Y_OFFSET }, - { "tt27","tt27z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[27][AXIS_Z], TT27_Z_OFFSET }, - { "tt27","tt27a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[27][AXIS_A], TT27_A_OFFSET }, - { "tt27","tt27b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[27][AXIS_B], TT27_B_OFFSET }, - { "tt27","tt27c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[27][AXIS_C], TT27_C_OFFSET }, - - { "tt28","tt28x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[28][AXIS_X], TT28_X_OFFSET }, - { "tt28","tt28y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[28][AXIS_Y], TT28_Y_OFFSET }, - { "tt28","tt28z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[28][AXIS_Z], TT28_Z_OFFSET }, - { "tt28","tt28a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[28][AXIS_A], TT28_A_OFFSET }, - { "tt28","tt28b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[28][AXIS_B], TT28_B_OFFSET }, - { "tt28","tt28c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[28][AXIS_C], TT28_C_OFFSET }, - - { "tt29","tt29x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[29][AXIS_X], TT29_X_OFFSET }, - { "tt29","tt29y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[29][AXIS_Y], TT29_Y_OFFSET }, - { "tt29","tt29z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[29][AXIS_Z], TT29_Z_OFFSET }, - { "tt29","tt29a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[29][AXIS_A], TT29_A_OFFSET }, - { "tt29","tt29b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[29][AXIS_B], TT29_B_OFFSET }, - { "tt29","tt29c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[29][AXIS_C], TT29_C_OFFSET }, - - { "tt30","tt30x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[30][AXIS_X], TT30_X_OFFSET }, - { "tt30","tt30y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[30][AXIS_Y], TT30_Y_OFFSET }, - { "tt30","tt30z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[30][AXIS_Z], TT30_Z_OFFSET }, - { "tt30","tt30a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[30][AXIS_A], TT30_A_OFFSET }, - { "tt30","tt30b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[30][AXIS_B], TT30_B_OFFSET }, - { "tt30","tt30c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[30][AXIS_C], TT30_C_OFFSET }, - - { "tt31","tt31x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[31][AXIS_X], TT31_X_OFFSET }, - { "tt31","tt31y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[31][AXIS_Y], TT31_Y_OFFSET }, - { "tt31","tt31z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[31][AXIS_Z], TT31_Z_OFFSET }, - { "tt31","tt31a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[31][AXIS_A], TT31_A_OFFSET }, - { "tt31","tt31b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[31][AXIS_B], TT31_B_OFFSET }, - { "tt31","tt31c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[31][AXIS_C], TT31_C_OFFSET }, - - { "tt32","tt32x",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[32][AXIS_X], TT32_X_OFFSET }, - { "tt32","tt32y",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[32][AXIS_Y], TT32_Y_OFFSET }, - { "tt32","tt32z",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.tt_offset[32][AXIS_Z], TT32_Z_OFFSET }, - { "tt32","tt32a",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[32][AXIS_A], TT32_A_OFFSET }, - { "tt32","tt32b",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[32][AXIS_B], TT32_B_OFFSET }, - { "tt32","tt32c",_fip, 3, cm_print_cofs, get_flt, set_flt,(float *)&cm.tt_offset[32][AXIS_C], TT32_C_OFFSET }, ->>>>>>> refs/heads/edge */ // this is a 128bit UUID for identifying a previously committed job state { "jid","jida",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0 }, @@ -916,20 +644,11 @@ const cfgItem_t cfgArray[] = { #ifdef __TEXT_MODE { "sys","tv", _iipn, 0, tx_print_tv, txt_get_tv, txt_set_tv, nullptr, TEXT_VERBOSITY }, #endif -//<<<<<< HEAD { "sys","ej", _iipn, 0, js_print_ej, js_get_ej, js_set_ej, nullptr, COMM_MODE }, { "sys","jv", _iipn, 0, js_print_jv, js_get_jv, js_set_jv, nullptr, JSON_VERBOSITY }, { "sys","qv", _iipn, 0, qr_print_qv, qr_get_qv, qr_set_qv, nullptr, QUEUE_REPORT_VERBOSITY }, { "sys","sv", _iipn, 0, sr_print_sv, sr_get_sv, sr_set_sv, nullptr, STATUS_REPORT_VERBOSITY }, { "sys","si", _iipn, 0, sr_print_si, sr_get_si, sr_set_si, nullptr, STATUS_REPORT_INTERVAL_MS }, -/*======= - { "sys","ej", _fipn, 0, js_print_ej, get_ui8, json_set_ej,(float *)&cs.comm_mode, COMM_MODE }, - { "sys","jv", _fipn, 0, js_print_jv, get_ui8, json_set_jv,(float *)&js.json_verbosity, JSON_VERBOSITY }, - { "sys","qv", _fipn, 0, qr_print_qv, get_ui8, set_012, (float *)&qr.queue_report_verbosity, QR_OFF}, // default to OFF, set to QUEUE_REPORT_VERBOSITY after connected - { "sys","sv", _fipn, 0, sr_print_sv, get_ui8, set_012, (float *)&sr.status_report_verbosity, SR_OFF}, // default to OFF, set to STATUS_REPORT_VERBOSITY after connectied - { "sys","si", _fipn, 0, sr_print_si, get_int, sr_set_si, (float *)&sr.status_report_interval, STATUS_REPORT_INTERVAL_MS }, - { "", "nxln", _f0, 0, cm_print_nxln,cm_get_nxln,cm_set_nxln,(float *)&cs.null, 0 }, ->>>>>>> refs/heads/edge */ // Gcode defaults // NOTE: The ordering within the gcode defaults is important for token resolution. gc must follow gco @@ -1374,7 +1093,6 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 6) { "","6", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif -//<<<<<< HEAD #define DIGITAL_IN_GROUPS 10 { "","in", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // input state @@ -1467,86 +1185,7 @@ const cfgItem_t cfgArray[] = { { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 1 group { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 2 group { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 3 group -/*======= - // +4 = 6 - { "","x", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis groups - { "","y", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","z", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","a", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","b", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","c", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +6 = 12 - { "","in", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input state - { "","di1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input configs - { "","di2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +10 = 22 - { "","out", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output state - { "","do1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output configs - { "","do2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do10", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do11", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do12", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do13", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +14 = 36 - { "","g54",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // coord offset groups - { "","g55",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g56",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g57",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g58",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g59",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g92",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // origin offsets - { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position - { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position - // +9 = 45 - { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tool offsets - { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt4",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt5",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt6",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt7",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt8",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt9",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - // +17 = 62 - { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group - { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group - { "","ofs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work offset group - { "","hom",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis homing state group - { "","prb",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // probing state group - { "","pwr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor power enagled group - { "","jog",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis jogging state group - { "","jid",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // job ID group - // +8 = 70 - { "","he1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 1 group - { "","he2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 2 group - { "","he3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 3 group - { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 1 group - { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 2 group - { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 3 group - // +6 = 76 ->>>>>>> refs/heads/edge */ + #ifdef __USER_DATA #define USER_DATA_GROUPS 4 @@ -1910,14 +1549,8 @@ static stat_t get_tick(nvObj_t *nv) static const char fmt_rx[] = "rx:%d\n"; static const char fmt_ex[] = "[ex] enable flow control%10d [0=off,1=XON/XOFF, 2=RTS/CTS]\n"; -//static const char fmt_ec[] = "[ec] expand LF to CRLF on TX%6d [0=off,1=on]\n"; -//static const char fmt_ee[] = "[ee] enable echo%18d [0=off,1=on]\n"; -//static const char fmt_baud[] = "[baud] USB baud rate%15d [1=9600,2=19200,3=38400,4=57600,5=115200,6=230400]\n"; void cfg_print_rx(nvObj_t *nv) { text_print(nv, fmt_rx);} // TYPE_INT void cfg_print_ex(nvObj_t *nv) { text_print(nv, fmt_ex);} // TYPE_INT -//void cfg_print_ec(nvObj_t *nv) { text_print(nv, fmt_ec);} // TYPE_INT -//void cfg_print_ee(nvObj_t *nv) { text_print(nv, fmt_ee);} // TYPE_INT -//void cfg_print_baud(nvObj_t *nv) { text_print(nv, fmt_baud);} // TYPE_INT #endif // __TEXT_MODE diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 2db71399..e0bd991c 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -288,8 +288,8 @@ static void _dispatch_kernel(const devflags_t flags) #endif #if MARLIN_COMPAT_ENABLED == true - else if (js.json_mode == MARLIN_COMM_MODE) { // handle marlin-specific protocol gcode - cs.comm_request_mode = MARLIN_COMM_MODE; // mode of this command + else if (js.json_mode == MARLIN_COMM_MODE) { // handle marlin-specific protocol gcode + cs.comm_request_mode = MARLIN_COMM_MODE; // mode of this command marlin_response(gcode_parser(cs.bufp), cs.saved_buf); } #endif diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index debfcb43..edc44626 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -139,13 +139,6 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) -// uint8_t tool; // Tool after T and M6 (tool_select and tool_change) -// uint8_t tool_select; // T value - T sets this value -// uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" -// uint8_t mist_coolant; // TRUE = mist on (M7), FALSE = off (M9) -// uint8_t flood_coolant; // TRUE = flood on (M8), FALSE = off (M9) -// uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - uint8_t tool; // Tool after T and M6 (tool_select and tool_change) uint8_t tool_select; // T value - T sets this value uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" @@ -159,11 +152,6 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context bool mto_control; // M50.1 traverse override control bool sso_control; // M51 spindle speed override control -// bool m48_enable; // M48/M49 input (enables for feed and spindle) -// bool fro_control; // M50 feedrate override control -// bool tro_control; // M50.1 traverse override control -// bool spo_control; // M51 spindle speed override control - #if MARLIN_COMPAT_ENABLED == true float E_word; // E - "extruder" - may be interpreted any number of ways bool marlin_relative_extruder_mode; // M82, M83 (Marlin-only) @@ -198,13 +186,6 @@ typedef struct GCodeFlags { // Gcode input flags bool origin_offset_mode; bool absolute_override; -// bool tool; -// bool tool_select; -// bool tool_change; -// bool mist_coolant; -// bool flood_coolant; -// bool spindle_control; - bool tool; bool tool_select; bool tool_change; @@ -218,11 +199,6 @@ typedef struct GCodeFlags { // Gcode input flags bool mto_control; bool sso_control; -// bool m48_enable; -// bool fro_control; -// bool tro_control; -// bool spo_control; - bool checksum; #if MARLIN_COMPAT_ENABLED == true @@ -240,100 +216,8 @@ typedef struct GCodeParser { GCodeParser_t gp; // main parser struct GCodeValue_t gv; // gcode input values GCodeFlag_t gf; // gcode input flags -/* -// Structures used by Gcode parser - -typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context - - uint8_t next_action; // handles G modal group 1 moves & non-modals - cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89 - uint8_t program_flow; // used only by the gcode_parser - int32_t linenum; // N word - - float target[AXES]; // XYZABC where the move should go - float arc_offset[3]; // IJK - used by arc commands - float arc_radius; // R - radius value in arc radius mode - - float F_word; // F - normalized to millimeters/minute - uint8_t H_word; // H word - used by G43s - uint8_t L_word; // L word - used by G10s - float P_word; // P - parameter used for dwell time in seconds, G10 coord select... - float S_word; // S word - in RPM - - uint8_t feed_rate_mode; // See cmFeedRateMode for settings - uint8_t select_plane; // G17,G18,G19 - values to set plane to - uint8_t units_mode; // G20,G21 - 0=inches (G20), 1 = mm (G21) - uint8_t coord_system; // G54-G59 - select coordinate system 1-9 - uint8_t path_control; // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS - uint8_t distance_mode; // G91 0=use absolute coords(G90), 1=incremental movement - uint8_t arc_distance_mode; // G90.1=use absolute IJK offsets, G91.1=incremental IJK offsets - uint8_t origin_offset_mode; // G92...TRUE=in origin offset mode - uint8_t absolute_override; // G53 TRUE = move using machine coordinates - this block only (G53) - uint8_t tool; // Tool after T and M6 (tool_select and tool_change) - uint8_t tool_select; // T value - T sets this value - uint8_t tool_change; // M6 tool change flag - moves "tool_select" to "tool" - uint8_t coolant_mist; // TRUE = mist on (M7) - uint8_t coolant_flood; // TRUE = flood on (M8) - uint8_t coolant_off; // TRUE = turn off all coolants (M9) - uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) - - bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool fro_control; // M50 feedrate override control - bool tro_control; // M50.1 traverse override control - bool spo_control; // M51 spindle speed override control -} GCodeValue_t; - -typedef struct GCodeFlags { // Gcode input flags - - bool next_action; - bool motion_mode; - bool program_flow; - bool linenum; - - bool target[AXES]; - bool arc_offset[3]; - bool arc_radius; - - bool F_word; - bool H_word; - bool L_word; - bool P_word; - bool S_word; - - bool feed_rate_mode; - bool select_plane; - bool units_mode; - bool coord_system; - bool path_control; - bool distance_mode; - bool arc_distance_mode; - bool origin_offset_mode; - bool absolute_override; - bool tool; - bool tool_select; - bool tool_change; - bool coolant_mist; - bool coolant_flood; - bool coolant_off; - bool spindle_control; - - bool m48_enable; - bool fro_control; - bool tro_control; - bool spo_control; -} GCodeFlag_t; - -typedef struct GCodeParser { - bool modals[MODAL_GROUP_COUNT]; -} GCodeParser_t; - -GCodeParser_t gp; // main parser struct -GCodeValue_t gv; // gcode input values -GCodeFlag_t gf; // gcode input flags -*/ // local helper functions and macros -// <<<<<< HEAD static void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value, int32_t *value_int); static stat_t _point(float value); @@ -346,20 +230,6 @@ static stat_t _execute_gcode_block(char *active_comment); // Execute t #define SET_NON_MODAL(parm,val) ({gv.parm=val; gf.parm=true; break;}) #define EXEC_FUNC(f,v) if(gf.v) { status=f(gv.v);} -/*======= -void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_delete_flag); -stat_t _get_next_gcode_word(char **pstr, char *letter, float *value); -stat_t _point(float value); -stat_t _verify_checksum(char *str); -stat_t _validate_gcode_block(char *active_comment); -stat_t _parse_gcode_block(char *line, char *active_comment); // Parse the block into the GN/GF structs -stat_t _execute_gcode_block(char *active_comment); // Execute the gcode block - -#define SET_MODAL(m,parm,val) ({gv.parm=val; gf.parm=true; gp.modals[m]=true; break;}) -#define SET_NON_MODAL(parm,val) ({gv.parm=val; gf.parm=true; break;}) -#define EXEC_FUNC(f,v) if(gf.v) { status=f(gv.v);} ->>>>>>> refs/heads/edge */ - /* * gcode_parser_init() */ @@ -719,30 +589,18 @@ static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value, int3 *letter = **pstr; (*pstr)++; -//<<<<<< HEAD - // X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255 +// Removed support for hex numbers +// // X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255 // if ((**pstr == '0') && (*(*pstr+1) == 'X')) { // *value = 0; // (*pstr)++; // return (STAT_OK); // pointer points to X // } // -// // // get-value general case -// // char *end; -// // *value_int = atol(*pstr); // needed to get an accurate line number for N > 8,388,608 -// // *value = strtof(*pstr, &end); -/* ======= -// // X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255 -// if ((**pstr == '0') && (*(*pstr+1) == 'X')) { -// *value = 0; -// (*pstr)++; -// return (STAT_OK); // pointer points to X -// } -// // // get-value general case -// char *end = *pstr; +// char *end; +// *value_int = atol(*pstr); // needed to get an accurate line number for N > 8,388,608 // *value = strtof(*pstr, &end); ->>>>>>> refs/heads/edge*/ // get-value general case char *end = *pstr; @@ -952,17 +810,6 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 9: SET_MODAL (MODAL_GROUP_M8, coolant_off, COOLANT_OFF); case 48: SET_MODAL (MODAL_GROUP_M9, m48_enable, true); case 49: SET_MODAL (MODAL_GROUP_M9, m48_enable, false); -/*<<<<<< HEAD - case 50: - switch (_point(value)) { - case 0: SET_MODAL (MODAL_GROUP_M9, fro_control, true); - case 1: SET_MODAL (MODAL_GROUP_M9, tro_control, true); - default: status = STAT_GCODE_COMMAND_UNSUPPORTED; - } - break; - case 51: SET_MODAL (MODAL_GROUP_M9, spo_control, true); - case 100: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC); -======= */ case 50: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); switch (_point(value)) { case 0: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); @@ -978,7 +825,6 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) default: status = STAT_GCODE_COMMAND_UNSUPPORTED; } break; -// >>>>>>> refs/heads/edge case 101: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_WAIT); #if MARLIN_COMPAT_ENABLED == true @@ -1097,7 +943,6 @@ stat_t _execute_gcode_block(char *active_comment) { stat_t status = STAT_OK; -// <<<<<< HEAD cm_cycle_start(); // any G, M or other word will autostart cycle if not already started if (gf.linenum) { @@ -1105,7 +950,7 @@ stat_t _execute_gcode_block(char *active_comment) } EXEC_FUNC(cm_m48_enable, m48_enable); -/* +++++ +/* if (gf.fro_control) { // feedrate override ritorno(cm_fro_control(gv.P_word, gf.P_word)); } @@ -1140,39 +985,6 @@ stat_t _execute_gcode_block(char *active_comment) if (gf.coolant_off) { ritorno(coolant_control_sync((coControl)gv.coolant_off, COOLANT_BOTH)); // M9 } -/* ======= - if (gf.linenum) { - cm_set_model_linenum(gv.linenum); - } - EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 - EXEC_FUNC(cm_set_feed_rate, F_word); // F - - ritorno(_execute_gcode_block_marlin()); // execute Marlin commands if Marlin compatibility enabled - if (gf.linenum && gf.checksum) { - ritorno(cm_check_linenum()); - } - - EXEC_FUNC(cm_set_spindle_speed, S_word); // S - if (gf.sso_control) { // spindle speed override - ritorno(cm_sso_control(gv.P_word, gf.P_word)); - } - - EXEC_FUNC(cm_select_tool, tool_select); // tool_select is where it's written - EXEC_FUNC(cm_change_tool, tool_change); // M6 - EXEC_FUNC(cm_spindle_control, spindle_control); // spindle CW, CCW, OFF - - EXEC_FUNC(cm_mist_coolant_control, mist_coolant); // M7, M9 - EXEC_FUNC(cm_flood_coolant_control, flood_coolant); // M8, M9 also disables mist coolant if OFF - EXEC_FUNC(cm_m48_enable, m48_enable); - - if (gf.mfo_control) { // manual feedrate override - ritorno(cm_mfo_control(gv.P_word, gf.P_word)); - } - if (gf.mto_control) { // manual traverse override - ritorno(cm_mto_control(gv.P_word, gf.P_word)); - } - ->>>>>>> refs/heads/edge */ if (gv.next_action == NEXT_ACTION_DWELL) { // G4 - dwell ritorno(cm_dwell(gv.P_word)); // return if error, otherwise complete the block } @@ -1182,21 +994,12 @@ stat_t _execute_gcode_block(char *active_comment) switch (gv.next_action) { // Tool length offsets case NEXT_ACTION_SET_TL_OFFSET: { // G43 -/*<<<<<< HEAD - ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, false)); - break; - } - case NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET: { // G43.2 - ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, true)); - break; -======= */ ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, false)); break; } case NEXT_ACTION_SET_ADDITIONAL_TL_OFFSET: { // G43.2 ritorno(cm_set_tl_offset(gv.H_word, gf.H_word, true)); break; -// >>>>>>> refs/heads/edge } case NEXT_ACTION_CANCEL_TL_OFFSET: { // G49 ritorno(cm_cancel_tl_offset()); @@ -1216,7 +1019,6 @@ stat_t _execute_gcode_block(char *active_comment) //--> set retract mode goes here switch (gv.next_action) { -// <<<<<< HEAD case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 @@ -1252,39 +1054,6 @@ stat_t _execute_gcode_block(char *active_comment) case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target, PROFILE_NORMAL); break;} // G1 case MOTION_MODE_CW_ARC: // G2 case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gv.target, gf.target, // G3 -/* ======= - case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 - case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gv.target, gf.target); break;} // G30 - - case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gv.target, gf.target); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gv.target, gf.target); break;} // G28.3 - case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(gv.target, gf.target); break;} // G28.4 - - case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gv.target, gf.target, true, true); break;} // G38.2 - case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(gv.target, gf.target, true, false); break;} // G38.3 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gv.target, gf.target, false, true); break;} // G38.4 - case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gv.target, gf.target, false, false); break;}// G38.5 - - case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(gv.target, gf.target); break;}// G92 - case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;} // G92.1 - case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;} // G92.2 - case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;} // G92.3 - - case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100.0 - case NEXT_ACTION_JSON_COMMAND_ASYNC: { status = cm_json_command_immediate(active_comment); break;} // M100.1 - case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 - - case NEXT_ACTION_DEFAULT: { - cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override - switch (gv.motion_mode) { - case MOTION_MODE_CANCEL_MOTION_MODE: { cm.gm.motion_mode = gv.motion_mode; break;} // G80 - case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(gv.target, gf.target); break;} // G0 - case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(gv.target, gf.target); break;} // G1 - case MOTION_MODE_CW_ARC: // G2 - case MOTION_MODE_CCW_ARC: { status = cm_arc_feed(gv.target, gf.target, // G3 ->>>>>>> refs/heads/edge*/ gv.arc_offset, gf.arc_offset, gv.arc_radius, gf.arc_radius, gv.P_word, gf.P_word, @@ -1313,7 +1082,7 @@ stat_t _execute_gcode_block(char *active_comment) } /*********************************************************************************** - * _execute_gcode_block_marlin() - collect Marlin exection functions here + * _execute_gcode_block_marlin() - collect Marlin Gcode execution functions here */ static stat_t _execute_gcode_block_marlin() diff --git a/g2core/marlin_compatibility.cpp b/g2core/marlin_compatibility.cpp index 85d11a92..bc9c8a31 100644 --- a/g2core/marlin_compatibility.cpp +++ b/g2core/marlin_compatibility.cpp @@ -17,6 +17,15 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/* + * This file contains most of the code needed to support marlin compatibility mode. + * Other files that are affected include: + * - gcode_parser.cpp/.h heavily affected + * - canonical_machine.cpp/.h setting targets + * - controller.cpp main-loop callback, fake_stk500, specialized dispatching + * - report.cpp system ready message tuned for marlin + * - xio.cpp/.h protocol support + */ #include "g2core.h" // #1 #include "config.h" // #2 #include "settings.h" @@ -25,7 +34,6 @@ #include "controller.h" #include "gcode_parser.h" -//#include "gcode.h" #include "canonical_machine.h" #include "util.h" #include "xio.h" // for char definitions diff --git a/g2core/report.cpp b/g2core/report.cpp index ed8d46e1..a419e180 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -112,6 +112,7 @@ void rpt_print_loading_configs_message(void) void rpt_print_system_ready_message(void) { + // If in Marlin mode and connected as Marlin do not send a startup message #if MARLIN_COMPAT_ENABLED == true if (MARLIN_COMM_MODE != js.json_mode) { _startup_helper(STAT_OK, "SYSTEM READY"); diff --git a/g2core/settings.h b/g2core/settings.h index 0a966f73..82586f43 100644 --- a/g2core/settings.h +++ b/g2core/settings.h @@ -35,11 +35,9 @@ #ifndef SETTINGS_H_ONCE #define SETTINGS_H_ONCE -//#include "canonical_machine.h" +// Defines that need to be here instead of a more logical place like canonical_machine.h -// Defines that need to be here instead of a more logical place - -#define RADIUS_MIN (0.0001) // minimum value for ABC radius settings +#define RADIUS_MIN (0.0001) // minimum value for ABC radius settings /**** MACHINE PROFILES ****************************************************** * From a609467986b2f874eaced467b912f54ea2c9620f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 23 Mar 2017 13:58:37 -0400 Subject: [PATCH 222/283] Fix status reporting bug --- g2core/config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/g2core/config.cpp b/g2core/config.cpp index 8ce74a0a..48ca1533 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -423,6 +423,7 @@ uint8_t nv_get_type(nvObj_t *nv) /* * nv_coerce_types() - change types based on type field in configApp table */ + void nv_coerce_types(nvObj_t *nv) { if (nv->valuetype == TYPE_NULL) { // don't change type if it's a GET query From 3439c38072449a0a6e2a6bdcaf1e5f1159a15274 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 23 Mar 2017 15:27:10 -0400 Subject: [PATCH 223/283] Testing fix for in-hold job kill --- g2core/cycle_feedhold.cpp | 88 +++++++++++++--------------- g2core/report.cpp | 21 +++++-- g2core/settings/settings_makeblock.h | 4 +- 3 files changed, 57 insertions(+), 56 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 22ef04f8..14f2b514 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -363,35 +363,13 @@ static void _start_cycle_restart() default: {} } switch (cm1.hold_exit) { - case FEEDHOLD_EXIT_CYCLE: { - op.add_action(_run_restart_cycle); - break; - } - case FEEDHOLD_EXIT_FLUSH: { - op.add_action(_run_queue_flush); - op.add_action(_run_program_stop); - break; - } - case FEEDHOLD_EXIT_STOP: { - op.add_action(_run_program_stop); - break; - } - case FEEDHOLD_EXIT_END: { - op.add_action(_run_program_end); - break; - } - case FEEDHOLD_EXIT_ALARM: { - op.add_action(_run_alarm); - break; - } - case FEEDHOLD_EXIT_SHUTDOWN: { - op.add_action(_run_shutdown); - break; - } - case FEEDHOLD_EXIT_INTERLOCK: { - op.add_action(_run_interlock); - break; - } + case FEEDHOLD_EXIT_CYCLE: { op.add_action(_run_restart_cycle); break; } + case FEEDHOLD_EXIT_FLUSH: { op.add_action(_run_queue_flush); } // no break + case FEEDHOLD_EXIT_STOP: { op.add_action(_run_program_stop); break; } + case FEEDHOLD_EXIT_END: { op.add_action(_run_program_end); break; } + case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } + case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } + case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } default: {} } } @@ -442,14 +420,15 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner * _run_job_kill_final() - perform the job kill. queue flush, enter alarm with no movement * _start_job_kill() - invoke the job kill function, which may start from various states * - * Job kill cases: - * Job kill from machining cycle (1) hold, flush and enter ALARM state - * Job kill from PROBE (2) flush and enter ALARM state - * Job kill from HOMING (3) flush and enter ALARM state - * Job kill from JOGGING (4) flush and enter ALARM state - * Job kill from feedhold (5) flush and enter ALARM state - * Job kill from interlock (6) flush and enter ALARM state - * job kill has no action if from: (7) READY, STOP, END, ALARM, SHUTDOWN, PANIC states + * Job kill cases: Actions: + * (0) job kill has no action if from READY, STOP, END, ALARM, SHUTDOWN, PANIC states + * (1) Job kill from machining cycle hold, flush and enter ALARM state + * (2) Job kill from PROBE flush and enter ALARM state + * (3) Job kill from HOMING flush and enter ALARM state + * (4) Job kill from JOGGING flush and enter ALARM state + * (5a) Job kill from finished hold flush and enter ALARM state + * (5b) Job kill from pending jold flush and enter ALARM state + * (6) Job kill from interlock flush and enter ALARM state */ void cm_request_job_kill() @@ -457,37 +436,50 @@ void cm_request_job_kill() cm1.job_kill_state = JOB_KILL_REQUESTED; } -static stat_t _run_job_kill_final() +// _run_job_kill() is completely synchronous so it can be called directly +// and does not need to be part of an opertion(). + +static stat_t _run_job_kill() { // switch to p1 (may already be in it) - cm = &cm1; // return to primary planner (p1) - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; + _run_queue_flush(); + coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); // stop coolant spindle_control_immediate(SPINDLE_OFF); // stop spindle - cm_set_motion_state(MOTION_STOP); // set to stop and set the active model + cm_set_motion_state(MOTION_STOP); // set to stop and set the active model cm->hold_state = FEEDHOLD_OFF; cm_program_end(); rpt_exception(STAT_KILL_JOB, "Job killed by ^d"); sr_request_status_report(SR_REQUEST_IMMEDIATE); + cm->job_kill_state = JOB_KILL_OFF; return (STAT_OK); } +// _start_job_kill() will be entered multiple times until the REQUEST is reset to OFF + static void _start_job_kill() { - // Cases (1 - 4) if (cm1.machine_state == MACHINE_CYCLE) { - if (cm1.hold_state == FEEDHOLD_OFF) { + if (cm1.hold_state == FEEDHOLD_OFF) { // Cases 1-4 - in cycle and not in a hold op.add_action(_feedhold_no_actions); - } - op.add_action(_run_queue_flush); - op.add_action(_run_job_kill_final); // Case (5) - op.run_operation(); +// op.add_action(_run_job_kill); +// cm1.job_kill_state = JOB_KILL_OFF; +// return; + } + if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 5a - in a finished hold + _run_job_kill(); +// cm1.job_kill_state = JOB_KILL_OFF; +// return; + } + return; // Case 5b - hold is in progress. Wait for hold to reach HOLD } - cm1.job_kill_state = JOB_KILL_OFF; // nothing to do. turn off the request + cm1.job_kill_state = JOB_KILL_OFF; // Case 0 - nothing to do. turn off the request } /**************************************************************************************** diff --git a/g2core/report.cpp b/g2core/report.cpp index a419e180..1875b719 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -377,6 +377,7 @@ static uint8_t _populate_filtered_status_report() const char sr_str[] = "sr"; bool has_data = false; char tmp[TOKEN_LEN+1]; + float current_value; nvObj_t *nv = nv_reset_nv_list(); // sets nv to the start of the body // Set thresholds to detect value changes based on precision for the value. @@ -394,20 +395,28 @@ static uint8_t _populate_filtered_status_report() } nv_get_nvObj(nv); - // report values that have changed by more than 0.0001, but always stops and ends - if ((fabs(nv->value_int - sr.status_report_value[i]) > precision[cfgArray[nv->index].precision]) || + // extract the value and cast into a float, regardless of value type + if ((valueType)(cfgArray[nv->index].flags & F_TYPE_MASK) == TYPE_FLOAT) { + current_value = nv->value_flt; + } else { + current_value = (float)nv->value_int; + } + + // report values that have changed by more than the indicated precision, but always stops and ends + if ((fabs(current_value - sr.status_report_value[i]) > precision[cfgArray[nv->index].precision]) || ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_STOP)) || ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_END))) { strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here... strcat(tmp, nv->token); strcpy(nv->token, tmp); //...or here. - sr.status_report_value[i] = nv->value_int; - if ((nv = nv->nx) == NULL) return (false); // should never be NULL unless SR length exceeds available buffer array + sr.status_report_value[i] = current_value; + if ((nv = nv->nx) == NULL) { // should never be NULL unless SR length exceeds available buffer array + return (false); + } has_data = true; - } else { - nv->valuetype = TYPE_EMPTY; // filter this value out of the report + nv->valuetype = TYPE_EMPTY; // filter this value out of the report } } return (has_data); diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index d8e14d60..28b21d6e 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -57,8 +57,8 @@ // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! -#define MARLIN_COMPAT_ENABLED false // enable marlin compatibility mode //+++++ +#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! +#define MARLIN_COMPAT_ENABLED false // enable marlin compatibility mode #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE #define TEXT_VERBOSITY TV_VERBOSE // one of: TV_SILENT, TV_VERBOSE From 3c441ff55d913ebb2fb8b72c756cc2a37866cc57 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 24 Mar 2017 08:34:54 -0400 Subject: [PATCH 224/283] Restored overrides to their stubbed settings; some cleanup --- g2core/cycle_feedhold.cpp | 9 ++---- g2core/gcode_parser.cpp | 45 ++++++++++++++-------------- g2core/marlin_compatibility.cpp | 8 ++--- g2core/marlin_compatibility.h | 2 +- g2core/settings/settings_makeblock.h | 2 +- g2core/xio.cpp | 8 ++--- 6 files changed, 34 insertions(+), 40 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 14f2b514..0c87d855 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -436,8 +436,8 @@ void cm_request_job_kill() cm1.job_kill_state = JOB_KILL_REQUESTED; } -// _run_job_kill() is completely synchronous so it can be called directly -// and does not need to be part of an opertion(). +// _run_job_kill() is completely synchronous so it can be called +// directly and does not need to be part of an opertion(). static stat_t _run_job_kill() { @@ -468,14 +468,9 @@ static void _start_job_kill() if (cm1.machine_state == MACHINE_CYCLE) { if (cm1.hold_state == FEEDHOLD_OFF) { // Cases 1-4 - in cycle and not in a hold op.add_action(_feedhold_no_actions); -// op.add_action(_run_job_kill); -// cm1.job_kill_state = JOB_KILL_OFF; -// return; } if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 5a - in a finished hold _run_job_kill(); -// cm1.job_kill_state = JOB_KILL_OFF; -// return; } return; // Case 5b - hold is in progress. Wait for hold to reach HOLD } diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index edc44626..9feba84d 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -60,8 +60,8 @@ typedef enum { // Used for detecting gcode errors. See #define MODAL_GROUP_COUNT (MODAL_GROUP_M9+1) // Note 1: Our G0 omits G4,G30,G53,G92.1,G92.2,G92.3 as these have no axis components to error check -/* The difference between NextAction and MotionMode is that NextAction is - * used by the current block, and may carry non-modal commands, whereas +/* The difference between NextAction and MotionMode (in canonical machine) is that +* NextAction is used by the current block, and may carry non-modal commands, whereas * MotionMode persists across blocks (as G modal group 1) */ @@ -91,7 +91,7 @@ typedef enum { // these are in order to optimiz NEXT_ACTION_JSON_COMMAND_ASYNC, // M100.1 NEXT_ACTION_JSON_WAIT, // M101 -#if MARLIN_COMPAT_ENABLED == true +#if MARLIN_COMPAT_ENABLED == true // supported Marlin Gcode and M codes. Also E NEXT_ACTION_MARLIN_TRAM_BED, // G29 NEXT_ACTION_MARLIN_DISABLE_MOTORS, // M84 NEXT_ACTION_MARLIN_SET_MT, // M84 (with S), M85 @@ -117,17 +117,16 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context gpNextAction next_action; // handles G modal group 1 moves & non-modals cmMotionMode motion_mode; // Group1: G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89 uint8_t program_flow; // used only by the gcode_parser - uint32_t linenum; // N word + uint32_t linenum; // gcode N word float target[AXES]; // XYZABC where the move should go float arc_offset[3]; // IJK - used by arc commands - float arc_radius; // R - radius value in arc radius mode - - float F_word; // F - normalized to millimeters/minute + float arc_radius; // R word - radius value in arc radius mode + float F_word; // F word - feedrate as present in the F word (will be normalized later) + float P_word; // P word - parameter used for dwell time in seconds, G10 commands + float S_word; // S word - usually in RPM uint8_t H_word; // H word - used by G43s uint8_t L_word; // L word - used by G10s - float P_word; // P - parameter used for dwell time in seconds, G10 coord select... - float S_word; // S word - in RPM uint8_t feed_rate_mode; // See cmFeedRateMode for settings uint8_t select_plane; // G17,G18,G19 - values to set plane to @@ -148,9 +147,9 @@ typedef struct GCodeInputValue { // Gcode inputs - meaning depends on context uint8_t spindle_control; // 0=OFF (M5), 1=CW (M3), 2=CCW (M4) bool m48_enable; // M48/M49 input (enables for feed and spindle) - bool mfo_control; // M50 feedrate override control - bool mto_control; // M50.1 traverse override control - bool sso_control; // M51 spindle speed override control + bool fro_control; // M50 feedrate override control + bool tro_control; // M50.1 traverse override control + bool spo_control; // M51 spindle speed override control #if MARLIN_COMPAT_ENABLED == true float E_word; // E - "extruder" - may be interpreted any number of ways @@ -171,10 +170,10 @@ typedef struct GCodeFlags { // Gcode input flags bool arc_radius; bool F_word; - bool H_word; - bool L_word; bool P_word; bool S_word; + bool H_word; + bool L_word; bool feed_rate_mode; bool select_plane; @@ -195,9 +194,9 @@ typedef struct GCodeFlags { // Gcode input flags bool spindle_control; bool m48_enable; - bool mfo_control; - bool mto_control; - bool sso_control; + bool fro_control; + bool tro_control; + bool spo_control; bool checksum; @@ -810,14 +809,14 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 9: SET_MODAL (MODAL_GROUP_M8, coolant_off, COOLANT_OFF); case 48: SET_MODAL (MODAL_GROUP_M9, m48_enable, true); case 49: SET_MODAL (MODAL_GROUP_M9, m48_enable, false); - case 50: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); + case 50: switch (_point(value)) { - case 0: SET_MODAL (MODAL_GROUP_M9, mfo_control, true); - case 1: SET_MODAL (MODAL_GROUP_M9, mto_control, true); + case 0: SET_MODAL (MODAL_GROUP_M9, fro_control, true); + case 1: SET_MODAL (MODAL_GROUP_M9, tro_control, true); default: status = STAT_GCODE_COMMAND_UNSUPPORTED; } break; - case 51: SET_MODAL (MODAL_GROUP_M9, sso_control, true); + case 51: SET_MODAL (MODAL_GROUP_M9, spo_control, true); case 100: switch (_point(value)) { case 0: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_COMMAND_SYNC); @@ -950,7 +949,7 @@ stat_t _execute_gcode_block(char *active_comment) } EXEC_FUNC(cm_m48_enable, m48_enable); -/* + if (gf.fro_control) { // feedrate override ritorno(cm_fro_control(gv.P_word, gf.P_word)); } @@ -960,7 +959,7 @@ stat_t _execute_gcode_block(char *active_comment) if (gf.spo_control) { // spindle speed override ritorno(spindle_override_control(gv.P_word, gf.P_word)); } -*/ + EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode); // G93, G94 EXEC_FUNC(cm_set_feed_rate, F_word); // F diff --git a/g2core/marlin_compatibility.cpp b/g2core/marlin_compatibility.cpp index bc9c8a31..688682b0 100644 --- a/g2core/marlin_compatibility.cpp +++ b/g2core/marlin_compatibility.cpp @@ -20,11 +20,11 @@ /* * This file contains most of the code needed to support marlin compatibility mode. * Other files that are affected include: - * - gcode_parser.cpp/.h heavily affected - * - canonical_machine.cpp/.h setting targets + * - gcode_parser.cpp/.h big additions for handling Marlin gcode and other functions + * - canonical_machine.cpp/.h setting targets for relative extruder coordinates * - controller.cpp main-loop callback, fake_stk500, specialized dispatching - * - report.cpp system ready message tuned for marlin - * - xio.cpp/.h protocol support + * - report.cpp system ready message suppressed for Marlin + * - xio.cpp/.h Marlin protocol support */ #include "g2core.h" // #1 #include "config.h" // #2 diff --git a/g2core/marlin_compatibility.h b/g2core/marlin_compatibility.h index 91051392..168eb2ae 100644 --- a/g2core/marlin_compatibility.h +++ b/g2core/marlin_compatibility.h @@ -47,7 +47,7 @@ stat_t marlin_start_tramming_bed(); // G29 stat_t marlin_list_sd_response(); // M20 stat_t marlin_select_sd_response(const char *file); // M23 -stat_t marlin_set_extruder_mode(const uint8_t mode); // M82, M82 +stat_t marlin_set_extruder_mode(const uint8_t mode); // M82, M82 stat_t marlin_disable_motors(); // M84 stat_t marlin_set_motor_timeout(float s); // M84 Sxxx, M85 Sxxx, M18 Sxxx diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 28b21d6e..cb5ee38b 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -57,7 +57,7 @@ // Communications and reporting settings -#define USB_SERIAL_PORTS_EXPOSED 2 // Valid options are 1 or 2, only! +#define USB_SERIAL_PORTS_EXPOSED 1 // Valid options are 1 or 2, only! #define MARLIN_COMPAT_ENABLED false // enable marlin compatibility mode #define COMM_MODE JSON_MODE // one of: TEXT_MODE, JSON_MODE diff --git a/g2core/xio.cpp b/g2core/xio.cpp index 86dd0bce..5daf884c 100644 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -487,15 +487,15 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> { struct SkipSections { struct SkipSection { - uint16_t start_offset; // the offset of the first character to skip - uint16_t end_offset; // the offset of the next character to read after skipping + uint16_t start_offset; // the offset of the first character to skip + uint16_t end_offset; // the offset of the next character to read after skipping }; static constexpr uint16_t _section_count = 16; SkipSection _sections[_section_count]; - uint8_t read_section_idx; // index of the first skip section to skip - uint8_t write_section_idx; // index of the next skip section to populate + uint8_t read_section_idx; // index of the first skip section to skip + uint8_t write_section_idx; // index of the next skip section to populate bool isFull() { return ((write_section_idx+1)&(_section_count-1)) == read_section_idx; From 4c4ee144660c7931e748fb542dfe3d259024ad7b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 24 Mar 2017 11:11:53 -0400 Subject: [PATCH 225/283] Notes --- g2core/gcode_parser.cpp | 98 ++++++++++++++------------------- g2core/marlin_compatibility.cpp | 2 +- 2 files changed, 42 insertions(+), 58 deletions(-) diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 9feba84d..5c1d1632 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -315,39 +315,48 @@ static stat_t _verify_checksum(char *str) return STAT_OK; } -/* +/**************************************************************************************** * _normalize_gcode_block() - normalize a block (line) of gcode in place * - * Normalization functions: - * - Isolate "active comments" - * - Many of the following are performed in active comments as well - * - Strings are handled special (TODO) - * - Active comments are moved to the end of the string, and multiple active comments are merged into one - * - convert all letters to upper case - * - remove white space, control and other invalid characters - * - remove (erroneous) leading zeros that might be taken to mean Octal - * - identify and return start of comments and messages - * - signal if a block-delete character (/) was encountered in the first space + * Baseline normalization functions: + * - Isolate comments. See below. + * The rest of this applies just to the GCODE string itself (not the comments): + * - Remove white space, control and other invalid characters + * - Convert all letters to upper case + * - Remove (erroneous) leading zeros that might be taken to mean Octal + * - Signal if a block-delete character (/) was encountered in the first space * - NOTE: Assumes no leading whitespace as this was removed at the controller dispatch level * * So this: "g1 x100 Y100 f400" becomes this: "G1X100Y100F400" * - * Comment and message handling: + * Comment, active comment and message handling: + * - Comment fields start with a '(' char or alternately a semicolon ';' or percent '%' + * - Semicolon ';' or percent '%' end the line. All characters past are discarded + * - Multiple embedded comments are acceptable if '(' form * - Active comments start with exactly "({" and end with "})" (no relaxing, invalid is invalid) - * - Comments field start with a '(' char or alternately a semicolon ';' - * - Active comments are moved to the end of the string and merged. - * - Messages are converted to ({msg:"blah"}) active comments. + * - Active comments are moved to the end of the string + * - Multiple active comments are merged and moved to the end of the string + * - Gcode message comments (MSG) are converted to ({msg:"blah"}) active comments * - The 'MSG' specifier in comment can have mixed case but cannot cannot have embedded white spaces - * - Other "plain" comments will be discarded. - * - Multiple embedded comments are acceptable. - * - Multiple active comments will be merged. - * - Only ONE MSG comment will be accepted. + * - Only ONE MSG comment will be accepted + * - Other "plain" comments are discarded * * Returns: * - com points to comment string or to NUL if no comment * - msg points to message string or to NUL if no comment * - block_delete_flag is set true if block delete encountered, false otherwise */ +/* Active comment notes: + * + * We will convert as follows: + * FROM: G0 ({blah: t}) x10 (comment) + * TO : g0x10\0{blah:t} + * NOTES: Active comments moved to the end, stripped of (), everything lowercased, and plain comment removed. + * + * FROM: M100 ({a:t}) (comment) ({b:f}) (comment) + * TO : m100\0{a:t,b:f} + * NOTES: multiple active comments merged, stripped of (), and actual comments ignored. + */ char _normalize_scratch[RX_BUFFER_SIZE]; @@ -357,28 +366,13 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del char *gc_rd = str; // read pointer char *gc_wr = _normalize_scratch; // write pointer - char *ac_rd = str; // Active Comment read pointer char *ac_wr = _normalize_scratch; // Active Comment write pointer - bool last_char_was_digit = false; // used for octal stripping - /* Active comment notes: - - We will convert as follows: - FROM: G0 ({blah: t}) x10 (comment) - TO : g0x10\0{blah:t} - NOTES: Active comments moved to the end, stripped of (), everything lowercased, and plain comment removed. - - FROM: M100 ({a:t}) (comment) ({b:f}) (comment) - TO : m100\0{a:t,b:f} - NOTES: multiple active comments merged, stripped of (), and actual comments ignored. - */ - // Move the ac_wr point forward one for every non-AC character we KEEP (plus one for a NULL in between) ac_wr++; // account for the in-between NULL - // mark block deletes if (*gc_rd == '/') { *block_delete_flag = true; @@ -388,10 +382,8 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del } while (*gc_rd != 0) { - // check for ';' or '%' comments that end the line. - if ((*gc_rd == ';') || (*gc_rd == '%')) { - // go ahead and snap the string off cleanly here - *gc_rd = 0; + if ((*gc_rd == ';') || (*gc_rd == '%')) { // check for ';' or '%' comments that end the line + *gc_rd = 0; // go ahead and snap the string off cleanly here break; } @@ -404,7 +396,7 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del ((*(gc_rd+2) == 'g') || (*(gc_rd+2) == 'G')) )) { if (ac_rd == nullptr) { - ac_rd = gc_rd; // note the start of the first AC + ac_rd = gc_rd; // note the start of the first AC } // skip the comment, handling strings carefully @@ -416,7 +408,6 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del if ((*gc_rd == '\\') && (*(gc_rd+1) != 0)) { gc_rd++; // Skip it, it's escaped. } - } else if ((*gc_rd == ')')) { break; } @@ -426,9 +417,7 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del } } else { *(gc_rd-1) = ' '; // Change the '(' to a space to simplify the comment copy later - - // skip ahead until we find a ')' (or NULL) - while ((*gc_rd != 0) && (*gc_rd != ')')) { + while ((*gc_rd != 0) && (*gc_rd != ')')) { // skip ahead until we find a ')' (or NULL) gc_rd++; } } @@ -436,6 +425,7 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del bool do_copy = false; // Perform Octal stripping - remove invalid leading zeros in number strings + // Otherwise number conversions can fail, as Gcode does not support octal but C libs do // Change 0123.004 to 123.004, or -0234.003 to -234.003 if (isdigit(*gc_rd) || (*gc_rd == '.')) { // treat '.' as a digit so we don't strip after one if (last_char_was_digit || (*gc_rd != '0') || !isdigit(*(gc_rd+1))) { @@ -447,7 +437,6 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del last_char_was_digit = false; do_copy = true; } - if (do_copy) { *(gc_wr++) = toupper(*gc_rd); ac_wr++; // move the ac start position @@ -458,10 +447,7 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del // Enforce null termination *gc_wr = 0; - - // note the beginning of the comments - char *comment_start = ac_wr; - + char *comment_start = ac_wr; // note the beginning of the comments if (ac_rd != nullptr) { // Now we'll copy the comments to the scratch @@ -568,8 +554,7 @@ void _normalize_gcode_block(char *str, char **active_comment, uint8_t *block_del *active_comment = str + (comment_start - _normalize_scratch); } - -/* +/**************************************************************************************** * _get_next_gcode_word() - get gcode word consisting of a letter and a value * * This function requires the Gcode string to be normalized. @@ -630,7 +615,7 @@ static uint8_t _point(const float value) return((uint8_t)(value*10 - trunc(value)*10)); // isolate the decimal point as an int } -/* +/**************************************************************************************** * _validate_gcode_block() - check for some gross Gcode block semantic violations */ @@ -655,7 +640,7 @@ static stat_t _validate_gcode_block(char *active_comment) return (STAT_OK); } -/* +/**************************************************************************************** * _parse_gcode_block() - parses one line of NULL terminated G-Code. * * All the parser does is load the state values in gn (next model state) and set flags @@ -679,7 +664,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) // Causes a later exception if // (1) INVERSE_TIME_MODE is active and a feed rate is not provided or // (2) INVERSE_TIME_MODE is changed to UNITS_PER_MINUTE and a new feed rate is missing - if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate req'd when in INV_TIME_MODE + if (cm->gm.feed_rate_mode == INVERSE_TIME_MODE) {// new feed rate required when in INV_TIME_MODE gv.F_word = 0; gf.F_word = true; } @@ -714,7 +699,6 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) #if MARLIN_COMPAT_ENABLED == true case 29: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_TRAM_BED); #endif - case 30: { switch (_point(value)) { case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G30_POSITION); @@ -826,7 +810,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) break; case 101: SET_NON_MODAL (next_action, NEXT_ACTION_JSON_WAIT); -#if MARLIN_COMPAT_ENABLED == true +#if MARLIN_COMPAT_ENABLED == true // Note: case ordering and presence/absence of break;s is very important case 20:marlin_list_sd_response(); status = STAT_COMPLETE; break; // List SD card case 21: // Initialize SD card case 22: status = STAT_COMPLETE; break; // Release SD card @@ -842,7 +826,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 105: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_PRINT_TEMPERATURES);// request temperature report case 106: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_SET_FAN_SPEED); // set fan speed range 0 - 255 case 107: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_STOP_FAN); // stop fan (speed = 0) - case 108: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_CANCEL_WAIT_TEMP); // cancel wait for temparature + case 108: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_CANCEL_WAIT_TEMP); // cancel wait for temperature case 114: SET_NON_MODAL (next_action, NEXT_ACTION_MARLIN_PRINT_POSITION); // request position report case 109: gf.marlin_wait_for_temp = true; // NO break! // set wait for temp and execute M104 @@ -895,7 +879,7 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) return (_execute_gcode_block(active_comment)); // if successful execute the block } -/* +/**************************************************************************************** * _execute_gcode_block() - execute parsed block * * Conditionally (based on whether a flag is set in gf) call the canonical machining diff --git a/g2core/marlin_compatibility.cpp b/g2core/marlin_compatibility.cpp index 688682b0..278c3a33 100644 --- a/g2core/marlin_compatibility.cpp +++ b/g2core/marlin_compatibility.cpp @@ -21,7 +21,7 @@ * This file contains most of the code needed to support marlin compatibility mode. * Other files that are affected include: * - gcode_parser.cpp/.h big additions for handling Marlin gcode and other functions - * - canonical_machine.cpp/.h setting targets for relative extruder coordinates + * - canonical_machine.cpp/.h setting targets for relative_extruder_mode coordinates * - controller.cpp main-loop callback, fake_stk500, specialized dispatching * - report.cpp system ready message suppressed for Marlin * - xio.cpp/.h Marlin protocol support From 7c661593750d9b9dd71856b7000b20144db01482 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 30 Mar 2017 11:33:10 -0400 Subject: [PATCH 226/283] Comments --- g2core/plan_line.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 350c6295..824816f3 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -106,7 +106,7 @@ float mp_get_runtime_display_position(uint8_t axis) { /**************************************************************************************** * mp_get_runtime_busy() - returns TRUE if motion control busy (i.e. robot is moving) - * mp_runtime_is_idle() - returns TRUE is steppers are not actively moving + * mp_runtime_is_idle() - returns TRUE if steppers are not actively moving * * Use mp_get_runtime_busy() to sync to the queue. If you wait until it returns * FALSE you know the queue is empty and the motors have stopped. @@ -600,6 +600,24 @@ static void _calculate_jerk(mpBuf_t* bf) * so that the elapsed time from the start to the end of the motion is T plus * any time required for acceleration or deceleration. */ +/* + * Axis Decoupling Notes + * + * Use cases: + * - 3D mode (Machining) - All XYZABC axes must obey full jerk constraints + * - 2.5d mode (Contouring) - Treat as 3D mode (at least for now) + * - 2D mode (Routing) - Routing moves: XY obey jerk, Z movement does not affect move time + * + * - Case 1 - Z tab move w/XY movement - Z movement below 'delta' threshold + * Z is allowed to move at indicated velocity without slowing down XY (decoupled) + * + * - Case 2 - Z climb or plunge w/XY movement - Z movement above 'delta' threshold + * - Case 3 - Z climb or plunge w/o X or Y movement - Z must obey velocity/jerk constraints + * + * Z side loading factor - what's the maximum lateral force that be applied to the cutter? + * F = ma + * S(z) / V(xy) + */ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const float axis_square[]) { float feed_time = 0; // one of: XYZ time, ABC time or inverse time. Mutually exclusive @@ -611,13 +629,13 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa // compute feed time for feeds and probe motion if (bf->gm.motion_mode != MOTION_MODE_STRAIGHT_TRAVERSE) { if (bf->gm.feed_rate_mode == INVERSE_TIME_MODE) { - feed_time = bf->gm.feed_rate; // NB: feed rate was un-inverted to minutes by cm_set_feed_rate() + feed_time = bf->gm.feed_rate; // NB: feed rate was un-inverted to minutes by cm_set_feed_rate() bf->gm.feed_rate_mode = UNITS_PER_MINUTE_MODE; } else { // compute length of linear move in millimeters. Feed rate is provided as mm/min feed_time = sqrt(axis_square[AXIS_X] + axis_square[AXIS_Y] + axis_square[AXIS_Z]) / bf->gm.feed_rate; - // if no linear axes, compute length of multi-axis rotary move in degrees. Feed rate is provided as - // degrees/min + // if no linear axes, compute length of multi-axis rotary move in degrees. + // Feed rate is provided as degrees/min if (fp_ZERO(feed_time)) { feed_time = sqrt(axis_square[AXIS_A] + axis_square[AXIS_B] + axis_square[AXIS_C]) / bf->gm.feed_rate; } @@ -628,7 +646,7 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa if (bf->axis_flags[axis]) { if (bf->gm.motion_mode == MOTION_MODE_STRAIGHT_TRAVERSE) { tmp_time = fabs(axis_length[axis]) / cm->a[axis].velocity_max; - } else { // gm.motion_mode == MOTION_MODE_STRAIGHT_FEED + } else { // gm.motion_mode == MOTION_MODE_STRAIGHT_FEED tmp_time = fabs(axis_length[axis]) / cm->a[axis].feedrate_max; } max_time = max(max_time, tmp_time); From 04f2ee38e81057c3c351a2b7e87f54d377a43e24 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 31 Mar 2017 14:10:39 -0400 Subject: [PATCH 227/283] Working on job kill bug --- g2core/controller.cpp | 4 ++-- g2core/g2core.cppproj | 4 ++-- g2core/settings/settings_shopbot_test.h | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index e0bd991c..5fa01e97 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -259,9 +259,9 @@ static void _dispatch_kernel(const devflags_t flags) // trap single character commands if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } - else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } else if (*cs.bufp == '~') { cm_request_cycle_start(); } - else if (*cs.bufp == EOT) { cm_request_job_kill(); } + else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } + else if (*cs.bufp == EOT) { cm_request_job_kill(); xio_flush_to_command(); } else if (*cs.bufp == ENQ) { controller_request_enquiry(); } else if (*cs.bufp == CAN) { hw_hard_reset(); } // reset immediately diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0d5b8f5b..b8ee2360 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/settings/settings_shopbot_test.h b/g2core/settings/settings_shopbot_test.h index 92cd827f..53c980a9 100644 --- a/g2core/settings/settings_shopbot_test.h +++ b/g2core/settings/settings_shopbot_test.h @@ -125,7 +125,6 @@ #define M4_POWER_MODE MOTOR_POWER_MODE #define M4_POWER_LEVEL MOTOR_POWER_LEVEL -#if (MOTORS >= 5) #define M5_MOTOR_MAP AXIS_B #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 48 // (0.5 * 25.4) @@ -141,7 +140,6 @@ #define M6_POLARITY 0 #define M6_POWER_MODE MOTOR_POWER_MODE #define M6_POWER_LEVEL MOTOR_POWER_LEVEL -#endif // *** axis settings ********************************************************************************* From f278cb156f9f6d200be74704ebdacf59b1f0faa1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 4 Apr 2017 09:53:15 +0200 Subject: [PATCH 228/283] No functional changes --- g2core/cycle_feedhold.cpp | 6 ++++++ g2core/plan_zoid.cpp | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 0c87d855..12c8f1a9 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -379,6 +379,9 @@ static void _start_cycle_restart() * cm_request_queue_flush() - set request enum only * _start_queue_flush() - run a queue flush from a % * _restart_flush() - run a queue flush from an action + * + * cm_request_queue_flush() should be called concurrently with xio_flush_to_command() + * cm_request_queue_flush(); xio_flush_to_command(); */ void cm_request_queue_flush() @@ -420,6 +423,9 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner * _run_job_kill_final() - perform the job kill. queue flush, enter alarm with no movement * _start_job_kill() - invoke the job kill function, which may start from various states * + * cm_request_job_kill() should be called concurrently with xio_flush_to_command() + * cm_request_job_kill(); xio_flush_to_command(); + * * Job kill cases: Actions: * (0) job kill has no action if from READY, STOP, END, ALARM, SHUTDOWN, PANIC states * (1) Job kill from machining cycle hold, flush and enter ALARM state diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index fc90178d..c6f2d4be 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -358,10 +358,10 @@ float mp_get_target_length(const float v_0, const float v_1, const mpBuf_t* bf) } /* - * mp_get_target_velocity() - find the velocity we would achieve if we *accelerated* from v_0 + * mp_get_target_velocity() - find the velocity we would achieve if we accelerated from v_0 * - * Get "the velocity" that we would end up at if we *accelerated* from v_0 - * over the provided L (length) and J (jerk, provided in the bf structure). + * Get the velocity that we would end up at if we accelerated from v_0 + * over the provided L (length) and J (jerk, provided in the bf structure) */ // 14 *, 1 /, 1 sqrt, 1 cbrt @@ -374,16 +374,16 @@ float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t* bf) const float j = bf->jerk; - const float a80 = 7.698003589195; // 80 * a - const float a_2 = 0.00925925925926; // a^2 + const float a80 = 7.698003589195; // 80 * a + const float a_2 = 0.00925925925926; // a^2 - const float v_0_2 = v_0 * v_0; // v_0^2 - const float v_0_3 = v_0_2 * v_0; // v_0^3 + const float v_0_2 = v_0 * v_0; // v_0^2 + const float v_0_3 = v_0_2 * v_0; // v_0^3 - const float L_2 = L * L; // L^2 + const float L_2 = L * L; // L^2 - const float b_part1 = 9 * j * L_2; // 9 j L^2 - const float b_part2 = a80 * v_0_3; // 80 a v_0^3 + const float b_part1 = 9 * j * L_2; // 9 j L^2 + const float b_part2 = a80 * v_0_3; // 80 a v_0^3 // b^3 = a^2 (3 L sqrt(j (2 b_part2 + b_part1)) + b_part2 + b_part1) const float b_cubed = a_2 * (3 * L * sqrt(j * (2 * b_part2 + b_part1)) + b_part2 + b_part1); @@ -405,7 +405,7 @@ float mp_get_target_velocity(const float v_0, const float L, const mpBuf_t* bf) * Get the velocity that we would end up at if we decelerated from v_0, * over the provided L (length) and J (jerk, provided in the bf structure). * - * We have to use a root finding solution, since there is actually three possible + * We have to use a root finding solution, since there are actually three possible * solutions. We can eliminate one quickly, since it's the acceleration case. * * The other two cases are occasionally the same value, but this is rare. @@ -513,7 +513,7 @@ static float _get_meet_velocity(const float v_0, if (block->head_length > L) { block->head_length = L; block->body_length = 0; - v_1 = mp_get_target_velocity(v_0, L, bf); + v_1 = mp_get_target_velocity(v_0, L, bf); } else { block->body_length = L - block->head_length; } @@ -525,7 +525,7 @@ static float _get_meet_velocity(const float v_0, if (block->tail_length > L) { block->tail_length = L; block->body_length = 0; - v_1 = mp_get_target_velocity(v_2, L, bf); + v_1 = mp_get_target_velocity(v_2, L, bf); } else { block->body_length = L - block->tail_length; } From 008406f6e8c6a32cb8f567df1d44bb88319021da Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 10 Apr 2017 07:39:34 -0400 Subject: [PATCH 229/283] Minor commit - testing --- g2core/cycle_feedhold.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 12c8f1a9..e9269940 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -474,6 +474,7 @@ static void _start_job_kill() if (cm1.machine_state == MACHINE_CYCLE) { if (cm1.hold_state == FEEDHOLD_OFF) { // Cases 1-4 - in cycle and not in a hold op.add_action(_feedhold_no_actions); +// op.add_action(_run_job_kill); } if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 5a - in a finished hold _run_job_kill(); From 1278b0b824665a603bb1a72a529f7f566a7b25c3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 10 Apr 2017 12:59:57 -0400 Subject: [PATCH 230/283] =?UTF-8?q?Interim=20commit=20-=20fixes=20JSON=20c?= =?UTF-8?q?ommand=20queuing,=20sequencing=20job=20kill.=20Still=20has=20pr?= =?UTF-8?q?oblems=20with=20embedded=20M30=E2=80=99s=20in=20the=20file.=20W?= =?UTF-8?q?hich=20perhaps=20is=20as=20it=20should.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/cycle_feedhold.cpp | 49 +++++++++++++++++++++++---------------- g2core/g2core.cppproj | 4 ++-- g2core/gcode_parser.cpp | 22 +++++++++--------- g2core/planner.cpp | 13 +++++++---- 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index e9269940..51254d5c 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -426,15 +426,16 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner * cm_request_job_kill() should be called concurrently with xio_flush_to_command() * cm_request_job_kill(); xio_flush_to_command(); * - * Job kill cases: Actions: - * (0) job kill has no action if from READY, STOP, END, ALARM, SHUTDOWN, PANIC states - * (1) Job kill from machining cycle hold, flush and enter ALARM state - * (2) Job kill from PROBE flush and enter ALARM state - * (3) Job kill from HOMING flush and enter ALARM state - * (4) Job kill from JOGGING flush and enter ALARM state - * (5a) Job kill from finished hold flush and enter ALARM state - * (5b) Job kill from pending jold flush and enter ALARM state - * (6) Job kill from interlock flush and enter ALARM state + * Job kill cases: Actions: + * (0) job kill from ALARM, SHUTDOWN, PANIC no action, end request + * (1) job kill from READY, STOP, END perform PROGRAM_END + * (2a) Job kill from machining cycle hold, flush, perform PROGRAM_END + * (2b) Job kill from pending hold wait for hold to complete + * (2c) Job kill from finished hold flush, perform PROGRAM_END + * (3) Job kill from PROBE flush, perform PROGRAM_END + * (4) Job kill from HOMING flush, perform PROGRAM_END + * (5) Job kill from JOGGING flush, perform PROGRAM_END + * (6) job kill from INTERLOCK perform PROGRAM_END */ void cm_request_job_kill() @@ -448,8 +449,8 @@ void cm_request_job_kill() static stat_t _run_job_kill() { // switch to p1 (may already be in it) - cm = &cm1; // return to primary planner (p1) - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer mr = mp->mr; _run_queue_flush(); @@ -457,7 +458,7 @@ static stat_t _run_job_kill() coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); // stop coolant spindle_control_immediate(SPINDLE_OFF); // stop spindle - cm_set_motion_state(MOTION_STOP); // set to stop and set the active model + cm_set_motion_state(MOTION_STOP); // set to stop and set the active model cm->hold_state = FEEDHOLD_OFF; cm_program_end(); @@ -471,17 +472,25 @@ static stat_t _run_job_kill() static void _start_job_kill() { - if (cm1.machine_state == MACHINE_CYCLE) { - if (cm1.hold_state == FEEDHOLD_OFF) { // Cases 1-4 - in cycle and not in a hold - op.add_action(_feedhold_no_actions); -// op.add_action(_run_job_kill); + switch (cm1.machine_state) { + case MACHINE_ALARM: // Case 0's - nothing to do. turn off the request + case MACHINE_SHUTDOWN: + case MACHINE_PANIC: { + cm1.job_kill_state = JOB_KILL_OFF; + return; } - if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 5a - in a finished hold - _run_job_kill(); + case MACHINE_CYCLE: { // Case 2's + if (cm1.hold_state == FEEDHOLD_OFF) { // Case 2a - in cycle and not in a hold + op.add_action(_feedhold_no_actions); +// op.add_action(_run_job_kill); + } + if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 2c - in a finished hold + _run_job_kill(); + } + return; // Case 2b - hold is in progress. Wait for hold to reach HOLD } - return; // Case 5b - hold is in progress. Wait for hold to reach HOLD + default: { _run_job_kill(); } // Cases 1,3,4,5,6 } - cm1.job_kill_state = JOB_KILL_OFF; // Case 0 - nothing to do. turn off the request } /**************************************************************************************** diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b8ee2360..0d5b8f5b 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 5c1d1632..34aa168f 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -1002,13 +1002,13 @@ stat_t _execute_gcode_block(char *active_comment) //--> set retract mode goes here switch (gv.next_action) { - case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 - case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 - case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 - case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gv.target, gf.target); break;} // G30 + case NEXT_ACTION_SET_G28_POSITION: { status = cm_set_g28_position(); break;} // G28.1 + case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(gv.target, gf.target); break;} // G28 + case NEXT_ACTION_SET_G30_POSITION: { status = cm_set_g30_position(); break;} // G30.1 + case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(gv.target, gf.target); break;} // G30 - case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gv.target, gf.target); break;} // G28.2 - case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gv.target, gf.target); break;}// G28.3 + case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(gv.target, gf.target); break;} // G28.2 + case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(gv.target, gf.target); break;} // G28.3 case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(gv.target, gf.target); break;} // G28.4 case NEXT_ACTION_STRAIGHT_PROBE_ERR: { status = cm_straight_probe(gv.target, gf.target, true, true); break;} // G38.2 @@ -1016,14 +1016,14 @@ stat_t _execute_gcode_block(char *active_comment) case NEXT_ACTION_STRAIGHT_PROBE_AWAY_ERR:{ status = cm_straight_probe(gv.target, gf.target, false, true); break;} // G38.4 case NEXT_ACTION_STRAIGHT_PROBE_AWAY: { status = cm_straight_probe(gv.target, gf.target, false, false); break;}// G38.5 - case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gv.P_word, gf.P_word, + case NEXT_ACTION_SET_G10_DATA: { status = cm_set_g10_data(gv.P_word, gf.P_word, // G10 gv.L_word, gf.L_word, gv.target, gf.target); break;} - case NEXT_ACTION_SET_G92_OFFSETS: { status = cm_set_g92_offsets(gv.target, gf.target); break;} // G92 - case NEXT_ACTION_RESET_G92_OFFSETS: { status = cm_reset_g92_offsets(); break;} // G92.1 - case NEXT_ACTION_SUSPEND_G92_OFFSETS: { status = cm_suspend_g92_offsets(); break;} // G92.2 - case NEXT_ACTION_RESUME_G92_OFFSETS: { status = cm_resume_g92_offsets(); break;} // G92.3 + case NEXT_ACTION_SET_G92_OFFSETS: { status = cm_set_g92_offsets(gv.target, gf.target); break;} // G92 + case NEXT_ACTION_RESET_G92_OFFSETS: { status = cm_reset_g92_offsets(); break;} // G92.1 + case NEXT_ACTION_SUSPEND_G92_OFFSETS: { status = cm_suspend_g92_offsets(); break;} // G92.2 + case NEXT_ACTION_RESUME_G92_OFFSETS: { status = cm_resume_g92_offsets(); break;} // G92.3 case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 diff --git a/g2core/planner.cpp b/g2core/planner.cpp index 43bf8f73..e1849591 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -105,7 +105,6 @@ struct _json_commands_t { int8_t available; // Constructor (initializer) - // Note, reset routines handle zeroing out all of the above _json_commands_t() { json_command_buffer_t *js_pv = &_json_bf[JSON_COMMAND_BUFFER_SIZE - 1]; for (uint8_t i=0; i < JSON_COMMAND_BUFFER_SIZE; i++) { @@ -113,9 +112,7 @@ struct _json_commands_t { _json_bf[i].pv = js_pv; js_pv = &_json_bf[i]; } - _json_r = &_json_bf[0]; - _json_w = _json_r; - available = JSON_COMMAND_BUFFER_SIZE; + reset(); }; // Write a json command to the buffer, using up one slot @@ -135,6 +132,13 @@ struct _json_commands_t { _json_r = _json_r->nx; available++; } + + // Reset the JSON command queue + void reset() { + _json_r = &_json_bf[0]; + _json_w = _json_r; + available = JSON_COMMAND_BUFFER_SIZE; + } }; _json_commands_t jc; @@ -203,6 +207,7 @@ void planner_reset(mpPlanner_t *_mp) // reset planner queue, cease MR act // selectively reset mpPlanner and mpPlannerRuntime w/o actually wiping them _mp->reset(); _mp->mr->reset(); + jc.reset(); _init_planner_queue(_mp, _mp->q.bf, _mp->q.queue_size); // reset planner buffers } From f3e950c81b23eabed11e5f8ede4ea1542a9b633d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 10 Apr 2017 15:19:43 -0400 Subject: [PATCH 231/283] stuff --- g2core/controller.cpp | 28 ++++++++++++++-------------- g2core/plan_exec.cpp | 3 +-- g2core/planner.cpp | 6 ++---- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 5fa01e97..bd60a7a8 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -52,15 +52,15 @@ #include "marlin_compatibility.h" #endif -/*********************************************************************************** - **** STRUCTURE ALLOCATIONS ********************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** STRUCTURE ALLOCATIONS ************************************************************* + ****************************************************************************************/ controller_t cs; // controller state structure -/*********************************************************************************** - **** STATICS AND LOCALS *********************************************************** - ***********************************************************************************/ +/**************************************************************************************** + **** STATICS AND LOCALS **************************************************************** + ****************************************************************************************/ static void _controller_HSM(void); static stat_t _led_indicator(void); // twiddle the LED indicator @@ -81,9 +81,9 @@ static stat_t _controller_state(void); // manage controller state trans static Motate::OutputPin safe_pin; -/*********************************************************************************** - **** CODE ************************************************************************* - ***********************************************************************************/ +/**************************************************************************************** + **** CODE ****************************************************************************** + ****************************************************************************************/ /* * controller_init() - controller init */ @@ -187,7 +187,7 @@ static void _controller_HSM() DISPATCH(_dispatch_command()); // MUST BE LAST - read and execute next command } -/***************************************************************************** +/**************************************************************************************** * command dispatchers * _dispatch_control - entry point for control-only dispatches * _dispatch_command - entry point for control and data dispatches @@ -319,8 +319,7 @@ static void _dispatch_kernel(const devflags_t flags) } } -/**** Local Functions ********************************************************/ - +/**** Local Functions ******************************************************************/ /* * _reset_comms_mode() - reset the communications mode (and other effected settings) after connection or disconnection @@ -461,7 +460,8 @@ static stat_t _sync_to_planner() return (STAT_OK); } -/* ALARM STATE HANDLERS +/**************************************************************************************** + * ALARM STATE HANDLERS * * _shutdown_handler() - put system into shutdown state * _limit_switch_handler() - shut down system if limit switch fired @@ -526,7 +526,7 @@ static stat_t _interlock_handler(void) return(STAT_OK); } -/* +/**************************************************************************************** * _init_assertions() - initialize controller memory integrity assertions * _test_assertions() - check controller memory integrity assertions * _test_system_assertions() - check assertions for entire system diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 84ea6211..3fbed2cf 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -265,8 +265,7 @@ stat_t mp_exec_move() return (STAT_NOOP); } - if (bf->block_type == BLOCK_TYPE_ALINE) { // cycle auto-start for lines only -// if ((bf->block_type == BLOCK_TYPE_ALINE) || (bf->block_type == BLOCK_TYPE_COMMAND)) { + if (bf->block_type == BLOCK_TYPE_ALINE) { // cycle auto-start for lines only // first-time operations if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_BACK_PLANNED) && (cm->motion_state == MOTION_RUN)) { diff --git a/g2core/planner.cpp b/g2core/planner.cpp index e1849591..fd72aa18 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -344,7 +344,7 @@ stat_t mp_runtime_command(mpBuf_t *bf) static void _exec_json_command(float *value, bool *flag) { char *json_string = jc.read_buffer(); - json_parse_for_exec(json_string, true); // process it + json_parse_for_exec(json_string, true); // process it jc.free_buffer(); } @@ -377,11 +377,9 @@ static stat_t _exec_json_wait(mpBuf_t *bf) while ((nv != NULL) && (nv->valuetype != TYPE_EMPTY)) { // For now we ignore non-BOOL if (nv->valuetype == TYPE_BOOLEAN) { -// bool old_value = !fp_ZERO(nv->value); // force it to bool bool old_value = (bool)nv->value_int; // force it to bool nv_get_nvObj(nv); -// bool new_value = !fp_ZERO(nv->value); bool new_value = (bool)nv->value_int; if (old_value != new_value) { st_prep_dwell((uint32_t)(0.1 * 1000000.0));// 1ms converted to uSec @@ -444,7 +442,7 @@ static stat_t _exec_dwell(mpBuf_t *bf) { st_prep_dwell((uint32_t)(bf->block_time * 1000000.0));// convert seconds to uSec if (mp_free_run_buffer()) { - cm_cycle_end(); // free buffer & perform cycle_end if planner is empty + cm_cycle_end(); // free buffer & perform cycle_end if planner is empty } return (STAT_OK); } From 8eb99f25135e073fceb4fab2930ba4110df22741 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 10 Apr 2017 17:03:45 -0400 Subject: [PATCH 232/283] Found segment fault in hold message preparation --- g2core/canonical_machine.cpp | 18 ++++++++++++------ g2core/controller.cpp | 3 ++- g2core/report.cpp | 6 ++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index fa43f8f5..0345163a 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1907,12 +1907,18 @@ static const char msg_hold0[] = "Off"; static const char msg_hold1[] = "Requested"; static const char msg_hold2[] = "Sync"; static const char msg_hold3[] = "Decel Continue"; -static const char msg_hold4[] = "Decel to Zero"; -static const char msg_hold5[] = "Decel Done"; -static const char msg_hold6[] = "Pending"; -static const char msg_hold7[] = "Hold"; -static const char *const msg_hold[] = { msg_hold0, msg_hold1, msg_hold2, msg_hold3, - msg_hold4, msg_hold5, msg_hold6, msg_hold7 }; +static const char msg_hold4[] = "Decel To Zero"; +static const char msg_hold5[] = "Decel Complete"; +static const char msg_hold6[] = "Motion Stopping"; +static const char msg_hold7[] = "Motion Stopped"; +static const char msg_hold8[] = "Hold Actions Pending"; +static const char msg_hold9[] = "Hold Actions Complete"; +static const char msg_hold10[] = "Holding"; +static const char msg_hold11[] = "Hold Exit Actions Pending"; +static const char msg_hold12[] = "Hold Exit Actions Complete"; +static const char *const msg_hold[] = { msg_hold0, msg_hold1, msg_hold2, msg_hold3, msg_hold4, + msg_hold5, msg_hold6, msg_hold7, msg_hold8, msg_hold9, + msg_hold10, msg_hold11, msg_hold12 }; static const char msg_home0[] = "Not Homed"; static const char msg_home1[] = "Homed"; diff --git a/g2core/controller.cpp b/g2core/controller.cpp index bd60a7a8..036f6316 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -258,7 +258,8 @@ static void _dispatch_kernel(const devflags_t flags) } // trap single character commands - if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } +// if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } + if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_HOLD, FEEDHOLD_EXIT_CYCLE); } else if (*cs.bufp == '~') { cm_request_cycle_start(); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } else if (*cs.bufp == EOT) { cm_request_job_kill(); xio_flush_to_command(); } diff --git a/g2core/report.cpp b/g2core/report.cpp index 1875b719..34ae4ecc 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -404,8 +404,10 @@ static uint8_t _populate_filtered_status_report() // report values that have changed by more than the indicated precision, but always stops and ends if ((fabs(current_value - sr.status_report_value[i]) > precision[cfgArray[nv->index].precision]) || - ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_STOP)) || - ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_END))) { +// ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_STOP)) || +// ((nv->index == sr.stat_index) && fp_EQ(nv->value_int, COMBINED_PROGRAM_END))) { + ((nv->index == sr.stat_index) && (nv->value_int == COMBINED_PROGRAM_STOP)) || + ((nv->index == sr.stat_index) && (nv->value_int == COMBINED_PROGRAM_END))) { strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here... strcat(tmp, nv->token); From 1c6f81f85762d2e586200a77f7a8d147ad5da174 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 11 Apr 2017 09:46:59 -0400 Subject: [PATCH 233/283] Fix case where hold buffer with remainder of move was not being forward planned (plan_exec.cpp line 1045); Added additional checks to prevent feedhold from being initiated during non-motion cycles. Still needs special handling for corner cases - to be described in header comments in cycle_feedhold.cpp --- g2core/canonical_machine.h | 2 +- g2core/controller.cpp | 3 +- g2core/cycle_feedhold.cpp | 97 +++++++++++++++++++++++++++++++------- g2core/plan_exec.cpp | 34 ++++++------- g2core/stepper.cpp | 5 ++ 5 files changed, 104 insertions(+), 37 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 953c76a8..beaf85a8 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -121,7 +121,7 @@ typedef enum { // feedhold type parameter } cmFeedholdType; typedef enum { // feedhold final operation - FEEDHOLD_EXIT_CYCLE = 0, // exit feedhold with cycle restart - HOLD or STOP, depending on type + FEEDHOLD_EXIT_CYCLE = 0, // exit feedhold with cycle restart FEEDHOLD_EXIT_FLUSH, // exit feedhold with flush FEEDHOLD_EXIT_STOP, // perform program stop FEEDHOLD_EXIT_END, // perform program end diff --git a/g2core/controller.cpp b/g2core/controller.cpp index 036f6316..bd60a7a8 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -258,8 +258,7 @@ static void _dispatch_kernel(const devflags_t flags) } // trap single character commands -// if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } - if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_HOLD, FEEDHOLD_EXIT_CYCLE); } + if (*cs.bufp == '!') { cm_request_feedhold(FEEDHOLD_TYPE_ACTIONS, FEEDHOLD_EXIT_CYCLE); } else if (*cs.bufp == '~') { cm_request_cycle_start(); } else if (*cs.bufp == '%') { cm_request_queue_flush(); xio_flush_to_command(); } else if (*cs.bufp == EOT) { cm_request_job_kill(); xio_flush_to_command(); } diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 51254d5c..da715a81 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -203,7 +203,7 @@ void cm_operation_init() * * Feedhold processing performs the following (in rough sequence order): * - * (0) - Feedhold is request bu calling cm_feedhold_reqeust() + * (0) - Feedhold is request by calling cm_feedhold_request() * * Control transfers to plan_exec.cpp feedhold functions: * @@ -232,6 +232,13 @@ void cm_operation_init() * (6) - Remove the hold state / there is queued motion - see cycle_feedhold.cpp * (7) - Remove the hold state / there is no queued motion - see cycle_feedhold.cpp */ +/* + * List of all possible cases where a feedhold can be received, and what to do about them + * + * (0) - Feedhold received when the system is idle. There is no CYCLE (CYCLE_NONE) + * (1) + */ + /**************************************************************************************** * cm_operation_runner_callback() - run feedhold operations and sequence queued requests @@ -507,8 +514,13 @@ static void _start_job_kill() void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) { - // Can only initiate a feedhold if you are in a machining cycle not already in a feedhold - if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { + // Can only initiate a feedhold if you are in a machining cycle, running, and not already in a feedhold + + if ((cm1.hold_state == FEEDHOLD_OFF) && + (cm1.machine_state == MACHINE_CYCLE) && (cm1.motion_state == MOTION_RUN)) { + +// if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { + cm1.hold_type = type; cm1.hold_exit = exit; cm1.hold_profile = ((type == FEEDHOLD_TYPE_ACTIONS) || (type == FEEDHOLD_TYPE_HOLD)) ? @@ -528,7 +540,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } default: {} } - cm1.hold_state = FEEDHOLD_SYNC; // start feedhold state machine in aline exec +// cm1.hold_state = FEEDHOLD_SYNC; // may be redundant, unless default {} was triggered return; } @@ -541,7 +553,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) // Reset the request if it's invalid if ((cm1.machine_state != MACHINE_CYCLE) || (cm1.motion_state == MOTION_STOP)) { - cm->hold_state = FEEDHOLD_OFF; // cannot honor the feedhold request. reset it + cm->hold_state = FEEDHOLD_OFF; // cannot honor the feedhold request. reset it } } @@ -555,42 +567,93 @@ static void _start_feedhold() } } */ + +static void _check_motion_stopped() +{ + if (mp_runtime_is_idle()) { // wait for steppers to actually finish + + mpBuf_t *bf = mp_get_r(); + + // Motion has stopped, so we can rely on positions and other values to be stable + // If SKIP type, discard the remainder of the block and position to the next block + if (cm->hold_type == FEEDHOLD_TYPE_SKIP) { + copy_vector(mp->position, mr->position); // update planner position to the final runtime position + mp_free_run_buffer(); // advance to next block, discarding the rest of the move + } else { // Otherwise setup the block to complete motion (regardless of how hold will ultimately be exited) + bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + bf->buffer_state = MP_BUFFER_BACK_PLANNED; // so it can be forward planned again + bf->plannable = true; // needed so block can be re-planned + } + mr->reset(); // reset MR for next use and for forward planning + cm_set_motion_state(MOTION_STOP); + cm->hold_state = FEEDHOLD_MOTION_STOPPED; + sr_request_status_report(SR_REQUEST_IMMEDIATE); + } +} + static stat_t _feedhold_skip() { - if (cm1.hold_state == FEEDHOLD_OFF) { // if entered while OFF start a feedhold - cm1.hold_state = FEEDHOLD_SYNC; + if (cm1.hold_state == FEEDHOLD_OFF) { // if entered while OFF start a feedhold + cm1.hold_type = FEEDHOLD_TYPE_SKIP; +// cm1.hold_exit = FEEDHOLD_EXIT_FLUSH; // default exit for SKIP is FLUSH... + cm1.hold_state = FEEDHOLD_SYNC; // ...FLUSH can be overridden by setting hold_exit after this function } if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { return (STAT_EAGAIN); } - cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't plan (see mp_plan_block_list()) - mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks - st_request_forward_plan(); // replan from the new bf buffer + cm1.hold_state = FEEDHOLD_OFF; // cannot be in HOLD or command won't plan (see mp_plan_block_list()) + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks + st_request_forward_plan(); // replan from the new bf buffer return (STAT_OK); } static stat_t _feedhold_no_actions() { - if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold - cm1.hold_state = FEEDHOLD_SYNC; + // initiate the feedhold + if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold + cm1.hold_type = FEEDHOLD_TYPE_HOLD; +// cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for NO_ACTIONS is STOP... + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function } - if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { // wait until it reaches the hold point + + // if motion has already stopped declare that you are in a feedhold +// if (cm1.motion_state == MOTION_STOP) { +// _check_motion_stopped(); +// } + + // wait until feedhold reaches the hold point + if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { return (STAT_EAGAIN); } - mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks - st_request_forward_plan(); // replan from the new bf buffer + // complete the feedhold + mp_replan_queue(mp_get_r()); // unplan current forward plan (bf head block), and reset all blocks + st_request_forward_plan(); // replan from the new bf buffer cm1.hold_state = FEEDHOLD_HOLD; return (STAT_OK); } static void _feedhold_actions_done_callback(float* vect, bool* flag) { - cm1.hold_state = FEEDHOLD_HOLD_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_HOLD + cm1.hold_state = FEEDHOLD_HOLD_ACTIONS_COMPLETE; // penultimate state before transitioning to FEEDHOLD_HOLD sr_request_status_report(SR_REQUEST_IMMEDIATE); } -static stat_t _feedhold_with_actions() // Execute Case (5) +static stat_t _feedhold_with_actions() // Execute Case (5) { + // if entered while OFF start a feedhold + if (cm1.hold_state == FEEDHOLD_OFF) { + cm1.hold_type = FEEDHOLD_TYPE_ACTIONS; +// cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for ACTIONS is STOP... + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function + return (STAT_EAGAIN); + } + + // if motion has already stopped declare that you are in a feedhold +// if (cm1.motion_state == MOTION_STOP) { +// _check_motion_stopped(); +// } + // Check to run first-time code if (cm1.hold_state == FEEDHOLD_MOTION_STOPPED) { cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 3fbed2cf..a6a261d6 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -154,20 +154,20 @@ static void _init_forward_diffs(float v_0, float v_1); * * (Note: all COMMAND(s) in 2j. should be in PLANNED state) */ - -// _plan_aline() - mp_forward_plan() helper -// -// Calculate ramps for the current planning block and the next PREPPED buffer -// The PREPPED buffer will be set to PLANNED later... -// -// Pass in the bf buffer that will "link" with the planned block -// The block and the buffer are implicitly linked for exec_aline() -// -// Note that that can only be one PLANNED move at a time. -// This is to help sync mr->p to point to the next planned mr->bf -// mr->p is only advanced in mp_exec_aline(), after mp.r = mr->p. -// This code aligns the buffers and the blocks for exec_aline(). - +/* + * _plan_aline() - mp_forward_plan() helper + * + * Calculate ramps for the current planning block and the next PREPPED buffer + * The PREPPED buffer will be set to PLANNED later... + * + * Pass in the bf buffer that will "link" with the planned block + * The block and the buffer are implicitly linked for exec_aline() + * + * Note that that can only be one PLANNED move at a time. + * This is to help sync mr->p to point to the next planned mr->bf + * mr->p is only advanced in mp_exec_aline(), after mp.r = mr->p. + * This code aligns the buffers and the blocks for exec_aline(). + */ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) { mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you @@ -1030,7 +1030,7 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) static stat_t _exec_aline_feedhold(mpBuf_t *bf) { - // Case (4) - Completing the feedhold - Wait for the steppers to stop + // Case (4) - Wait for the steppers to stop and complete the feedhold if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish @@ -1042,13 +1042,13 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) } else { // Otherwise setup the block to complete motion (regardless of how hold will ultimately be exited) bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - bf->plannable = true; // needed so block can be replanned + bf->buffer_state = MP_BUFFER_BACK_PLANNED; // so it can be forward planned again + bf->plannable = true; // needed so block can be re-planned } mr->reset(); // reset MR for next use and for forward planning cm_set_motion_state(MOTION_STOP); cm->hold_state = FEEDHOLD_MOTION_STOPPED; sr_request_status_report(SR_REQUEST_IMMEDIATE); -// cs.controller_state = CONTROLLER_READY; // Can this be removed? +++++ // remove controller readline() PAUSE } return (STAT_NOOP); // hold here. leave with a NOOP so it does not attempt another load and exec. } diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 16909313..95cb0b1c 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -364,6 +364,11 @@ namespace Motate { // Define timer inside Motate namespace } } // namespace Motate +/**************************************************************************************** + * st_request_forward_plan - performs forward planning on penultimate block + * fwd_plan interrupt - interrupt handler for calling forward planning function + */ + void st_request_forward_plan() { fwd_plan_timer.setInterruptPending(); From 78308fca46f9521b447c2a38976e09b0d661a2fb Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 11 Apr 2017 14:13:37 -0400 Subject: [PATCH 234/283] Added feedhold state diagram to documentation folder --- Resources/Documentation/SystemStates.graffle | Bin 5805 -> 12715 bytes g2core/cycle_feedhold.cpp | 7 ------- 2 files changed, 7 deletions(-) diff --git a/Resources/Documentation/SystemStates.graffle b/Resources/Documentation/SystemStates.graffle index 4bdcd9b1007cfd0362160efc89cc6fd9aabb6cce..7ef6770e9404a837c6874b812e83bbeee01143f6 100644 GIT binary patch literal 12715 zcmY-0V{|3q)-LSW>Dabyb!?j}X2-VCv2CvOiq*00bZmEQJNbIQ-#G6%yRI>+YSgd# zRdYV~e2OFn4(vY%B-llsuj{(hT+KR4GQ+i5nsYVBM zN@7?T1SWdJx#GdcxfKj4)rMpcDZFg;rVh@xAaK^Z94jB6_MXoIZt!k*uZx&(c$GF{Ivh&o^9UTzuVS-RKOJKEb_g!IRWB#)YR?5>>f0nhW# zcMPr#0M{Ua_z|P*iBhW>&5?I^!q`1W;*W!~?f04Ol?iAH7Vd(tOzbzGna@qXbH(!f zk6jj{nLQBbi|5eA!HpQEeE#^h-`_Ui)!{TRSHW+$`%&spLE4$~p=T=xXNE8;+{61Y zwDt*`Mw$M`?v#eh>vHJx;ovA7zTXt51Q0?r*(3JOppf?!GpYUPwoDTR9NI5{Nr}1} zM=3GZ6Wm)j-s}1DQ*AHx#FHLsI8kMWpQ#rpkhA#a@D#A-o`w1H2=R6G$5`XP^B{CZfjm*E9ZOEcq`K|)t6Trf ze?0f><7_Jje8N+FeF^2g-`+|#&3r!G8?hvOn|_?x`V8XzyqdCq7= zVF}1R&zUJ8x_-JEd+PbRohNAex-Ad=DA`ubauimq$@gD2_|X28?Hu3lt9W_;nU6MK zveOeVe_}Ougk|+5Zrrdhqxji*K;KN%c~{N*25iIAZF6PW1339KFY(-bZ`T<)>Dik2 z7JTLB_|Bc{*WGodWuxzMD2bAv04m{qKJK~w{x+YnyYl4*cpRH|8A*6v+V;#rrsu}G3#l+R|@(v9C4E7+rKZ?JD&FF8^ko%hC zT70>gq28)Gy)Lmv-!SNMTbVdoHN)nSy?qi0%)L1xaGu&0)$7d_d}Y!n*QR8;^E(At zRK8@KK4tjTWq3>Q2wMdz6x>XHQAJN@_}R~NUYGF5!^TdM#r(_@Jo7tKh>xbuINJTB zOAIUVaN^ZLU`}1sXCUkXZ@Xe3&wqfSE-HKQA_8L+yWv^SrQCRskP)pf)fMzhX<7to z9+#poF)=lVN8cAFHMRVOWlJUC01?|kk6qPyKD>zEGs0B2GPBGIROY}hUeqnfC;mA- z8I?1w;$_}cN~efJc_@ifE1g}dZHM^?6@EA{c$)xN9oYhcGzE!$L-s=L>}(Fomx^s# zx{ccuNe!H5T6d8cgdaE4w%;8lfXy8~`&$=l1ME#Yu$Wlwe&`C+-hgTBHewscb2!bi zIa88b$wPz$gYa7;#`2e#5@m*j;WUeKqS{mfqv#&0Aos(#yM3d@J6Z}YAu~!By59oMwS^QlUEAG(t(5pxRH^<3h~N+ZpO~(GpFK}rL6L^;D<-O zca^`tV(WZ~_oGX% zp&%ZU>6>FHzAI+&Bep=b%l$`Zrk%4t1lrfApo5}~8GEM`@_Dw&Ob4iyU$CO1qqGO~ zSy#AR6y~9Svv^kR5&7Mvk2R{$`Hi4=naFd5O&(*LyoTEp8MC4J_NBEBc#9(fsT#z| zX~Zx&+4BaZK@XI+(^EzSX_sa9gz327BPcUBYv&}vD&HIzJ9J7kBKk_@Xt$p;J|BnX z@_8~N4E^{XsFCNq*$3#crUL=l(E{5_%vM%`+$;2l;(4lt^s}_xXHvUWntbb^98L$i zkNPtD?e~YA3PSQ9=7=f!ZfD^IjwwuGk@f2bg<9A)WsKcCg2TYq( zfuT6I+SAMdS~v#jB;iTYL-c%bq0rG(cx{fnmkPoq1Z~<0yVokuJ0fr9ap3of73^Oc z!0!usUO(6hsNJ!V@65@=88~=K-KJzag1-P_fY=J1W$veslO`vO<%hSWNxOH+U_VL6 zc$Q4a#(}CTsB`U45YMXt@7`d}WDS8!1cF?NV;A_dPu+Eh?0{m?seZjQ*9L+k?AM_= zkpGYU1-Qt;g0n@LVW#&o)mVPi)vc7y9N0;LoC5@356YtV+qs5=Ee`D-*RfdqPEpgyn-y(wZ9UvJbCo^*u1( zCuQuB8h|1e6SftPjm8JYMDBveM81;^q1R-=^dmc-t!4^oa!rlu2nysT0Nd=!LEcAI z8i!la4G^=Y5w>QAFGHY^$`n(uc7g}bNc7!BH^m$&7!GxZv(eDCzc5hi(2=7CHKSLy z$q-(}e(nj_fLCIPt#&x(9+QSapi%Rw=BkHrHkcxa@uHGRFhkH8h$4)9I(Tw1e)p>z zu4aYA&dCRNWxNsuzO#|2*4bjMmbD!;V=x_Wq+}#BQ zF8RjTTI;zdOh5YYAxfquj1@)qMD`+%{?=s1D8NeTIY+?ZcwB}6L_wCRs%|A10Lb5N%r|!td?+wzbLeL35vO;c|D?5LA9%uqmwaM=+f0IKnbQB}AJsC$m zY(bIUeB9iW;LMr}?r<$p-*7q3P-WUoqw%y>mgeT1|7KU#pcRWcXU*j0&<}%SCf;RBB5N4 zsq^|9AZvEzFs|SsI&y!bKGIj1J8T4Ig;hMdftbdvLXY*YvL_NVo*_4QLPL37S6%e2P(-$W(Bp9 zOQ1uhYi!Qzwj2X6Wixbn&^!nzj$+|Jn0D`As$sfMU<)c3JUABGt8KrzIh;)_*Jbbk zn5mR!*O^^TCZD*8omMaSuz218624X^~jn5U!0oCf$JlaZG*MuU4#S;Ee8#A6cp z98jq0I?>*}DHuukVV9O@X_nG`;CI)3pg>8yu3+zsNRqxH34O*n)XrAe-V|?YNlgZa z6XMEPhpo2Z5hSsb9+0p(htkFSSZ*?<`W!%=wr{U);k2?dPup+4Pk?7*O1Sibbm8Ue zqwsP8k-LC*kJ4w;PgZ&=C`lA)8yhlhAu=%wA8L*Hw2UD7|d7(I)vIA%td}**qZBF7<5FG>r;}wjcH7A7;BtT|DtwOBomD|3h<=$lVyU<|_kW0kj8!cD>{Z3pma{k5B|HkgYL4DkZ~&xvfn-{EpQ zw>Nd}V#hQRb;U%I!~&CuGxEqXysaBSS;l5(v%0lH$F=?&3oxa=ipob#-=402U3nlK z(JEK<(qs}UIRv5{^dj69Z^z1z3`f{6>R5_l&Cu|X+z>R^IteI(y?TL43l{|P%wb&k zh_KR)&b2l5!csvdKdw}xk7$N%kNT=S>-2o!PQwY(%PV?vE?J;$=?U}rjNORngb}KZ zdZ&|+=<)3nV+salKBdKkut!ctm6KYqUZ)oa(%Qdg6t;FY_V{a;<2a05@HRZV>G;a? zcyh`B4MBGh!A#v?3{L3{QnlXNrHg$B$n%_ev5%7aqj!oO)L5W9Gu7{v#gK;mmdN5F z1U$qhp2A`HBj$5&b1>W5aNe|^hOqM6vs|?ny*&V7_(oULW^P(^S1V(miywWaCSQ8?2FBmI?>B+TrH&3A6-qBVehC5zWy0;;Mh33;rpfi35p8vX)dFjW1QNJ4I`o?4<88)+rvrtS&SQHZ;0P8J=-j^=HA zLvUCJ&EgO_#+vhaSF+?paG6GEg7E}%PM%gND$9ZOU&9GwIvX^)<(z~C8qMCi9H|p` zIQ~9SwT#TxLVG#vpN?0=JTWv=$L-ua6iz*SR*|TCl>Wnzx@87ME06fHLfuDQxoZqc zt7p0WRk2d&OV3`sSFa61c9JnWC(t643YS7Hh3@py^D0f?hnq=`R(s{9Ax|k)UZvrkRqc@kkG%4&mG_hP4aAYhW$iw1RDszAwkQ7| z#4{27JHkjB>t2Pl)MJl4u1xf^f9C{QAepCj<^%-=vvZ_a%O!220p}W?TqA!xbfUl* zkdx9b{Wlb5kgC8qascxsn;FM4B!^eU#ypJfWr!}c+J@Gw;h}VXia@8u)v8TG)?8f; z6NnBd4wo|_>Pq--+TmKly60|6AU0hiAxc^vWNS~m7W0xzp zZ?PZC)npSZo0Cu01{oE?)v0(KvT5w2v|LTX#naEc7kd|H7sACd>m21M$LPzK^Qxgw}gYaKrI8 zLinKuq5Q7|ll~ETj_-;zv&TH*Bwi`^s))$jiX{^ztl&qJuU5r^$E7&4^rR{CMH#NE*`9dG8aA; zapmM?Mn0`;^&8E{ew7Ql3Y7TM(9%~E5V3UyZ2k{L4S!Zm5{zWiDm7 z`(i4?@D6l769p#i{dnmqeeUDvk(0x7dImFX=XSPQ(3p!epH6#m@Bfk%TYgJPiNQ`1 z+cC&?2ZG?Ln0!_t2gz1{)WQS++ehT!pGNZS6URW5KQ3)0?l)akXy6$&c*)IHRn_4f{ z+6sPljkC>iQu=8z9#I-i4+)!?HKP!WdfhKtECEB4BUPs%iuN7tKYyPZPY8NA%cJj7 zZTYE3U!-x6X!BeG8P_{BZJIqZMjMgW6O7-`?1b?nQbx?r1+hbA{bPf9wErq@2{@7) zKpT4f>6ERk{gn<|@Yn)?2JfiesYHPA(7)Z5>x^>C;&<3xXE$pRJD2Ga`v4_~B;z`t}rkXR*Bxbia@($V8c5snFo z&4YCK+u#cLDcC74t$V5W9x)0{D+$Zdp-c)3c!--Q>RQW~ycTo)DYh1Pab>!IJ~@)3 z$z!3Pq;Ez8qQAbO(NJeUb?=h(m7cf1=2*jlB-`v>efeR@L7Z^eNa%?rvSBroT}PVy zi~YX}GoIk@dBD@t&{ygIKPzl7A@F~G2Ic=Jj#>4Ng$>V7h4gt0$w#m=GJb+23~iZzX5^0(bG%*1 zxilJ{ZNpiYHtNzZ-OHqucLoePYU=?d<}`C}p*7W1$CAPurxn&?`!}LeGU{?N);zM3 zk5(_Z+NtOO~nPnLCp}03f~%kxuuwyQtCH*`~w7v(C98+HxBK z;g}lB$I)}LyQAB?K2IIyXImgbs@psrUDk1~-(cLB~QF&$8@1(Gwi)uqT zdZ{2~H$0ve&<87PNwCq)bo5g`CJFSs>ODVP0c>OI0!%$US6}ISlB38FgUmYU8 zO6eNxF6iV0>j7WdS#n5hJBFeXx%T~<^JiWRViI2@Mm1_tSlwKBifdDqogWqeN}fdB z?#Zz{m}EGd;;iW$NY;hyzixuB_tkOyBM?0|Lf(T;y|WYz>&mSLxtpX1WzXO$rzgS6 z@Od@|t6jup0mbC{t*qc6eHh`RHJ5ZlaHjSS#Ul_CmgJ*Uyc=ocvpkxkD0)JVca7xB zC(C{Vk6UiacI&uh9`w5&z+neCqSxJXKyn^c>h#PNM$hRkZL;>Pq&&8*)aQh+h;y*u zuOh-@2nLqMTKu7s1=RErRF_|U6_%Kznb-r}-}z3O6k;MVMnWXt_lK{VoE!pWq>K)`Jm>amqg z<}g5QI6E~sVVey1Xg;myP0U)jD)m(9#`cQ&dcjmgvSde%5GtFNbQ~9W!s1Aa|3*{) zB#O@2g0~uo9axc25G?!S*!%ABqfdLfhk1%BFJq=&7{# zARI$_dNGTHKhV8qGSdIu`ZU3h!#o~f70AxQ?IAV$(q^SG;QcWns%UV1+BUqoTXv)o&mP~1l=Yu62MNd zz##R)x4||)V>#5i<`B!UHI#?F3*?nTBzm00ERIPc3Qh8drVvnXtU!P`SZGl@IzoJ9_jQx9|{ zSwNaK_S-JL`H*xoIVjedvNP+VTQ&9@`8ECCZE^QquTt|rF~}I~S@T{v!J=*1GeK_U zAjxE8Xu1Ymc#>G|4;x4a2#OXwn(-?v59;1&sFf@*0Ssd+2ws>FGg4j{hb=bL$_1qx zo$t=w3Ez3Ynk+XQL;t+Oy^b{Ja#;xG|LY)>++6ksRXO=MQV@>5ypC`JJ*5t{Sz)xFw}_JqU5q0YD%vGq%qspyAYruq!5-$I?ee1~@f z6Y>BwG6oHCjD{ECNoEMyOFWP%H^Yj<76jw=S~y#q<_1f(7K+1s47vn4Z2L=7x|N!Y zgUN?XgEFTfU*0jj42Tj+{~XOHI9#UaV;8AOT+pN*!xV9oS{u( znRM;Rlapj&3%u@rV5JxFO`V>l7DS2IvNeh6NMvQS7LhK-djDfBULi)?Sg+X`SVnlo z3pLiqYM)Ggh7By6JEWU5Pyw5VnE$p)244MBrQWn=kiJjZBp`M4o)8k0>6*<;#G1-` z2$9#EZn`Frm&^>KZLv&GcL1f%#AX6k4pu%8Jijj;RK7l_Uh$XuCe?0DKEpT(F; zbFOU7jo6M-6}4T@9LW_tPbkY^$Si|29p=hM$b>lnrhNndm@fgZDW*PR5X9_7k}OQ?(ns2YDQE0;sa^3O7Ex;ba`rk zYPs!Ue|b(!!?nKeT*gc=v8$RXpH9U$S723F^Hu2=INVd4pAT!R&}P_DC#FWz(OIL* z#Ag>p0jDES1weU|ky}=-oiQv$mJS$^ek?tWSk0QB=lT}dhwW98es?Vfx&HRNc=LQe-cdhS zo-)45os^%+9WfGg?gU+Vr7&FGF$z@;YdaCl#%0MV_8~s>%jQ!knOttl4U*~$4w{E% z+M%W(n>L6la7T{8u&u&ird&MFn!OM5%fCC{Fk%3poeG2>bx`7sy^|^&D*m4c` z->}JNOQ$SZ(>GUi<4k$&thVreJrznm^zjH=zs%ICc2)NIb}KncJ@;aBSz2rZjG-)r z6(U+ZT5rTuMm4$5?KY;q-dpmMKi>DV1*;0;A~X8sR$Xm&_*fy$pIwkkv@>Y>(798s zbSg$K>2z9Sucu6ud6WyIQjPf*g2l=T*H?ri)hNO1?`4qqbC2v@?vqjkz@#6*NZ%3Ur!N+a%Lt6rv;~J zyAzbyx=a+-EW*?vTV?gFTzava)m1j+@Yj{uT9}VTCW$)PY#O6kiY!-4Z=QWge%H`t-#0)ocd|j2@yAk|OsT|aKC9)*+8^YUB@Qk>` zqp-x!baPaDod#c^S1;0pe7WD zjd;5ZQ?jI&6oArUiL;Iiqu;W|uA+@|RF} z{NfmbU>8j5NZ)$n(9?`*4^pN+dNBc=BKG5Aq@P(g7UZF`*y2-wE^E;78xniAufnrs zL(~zlcX%dyBo;0Y8kA5GuT+aRSElwzd%@7ml&hwcZBb-fh7mMRR$<0fm*_?Jv;|!G z!={}!gd)I~K@aGe4Aps$i9vQkbUL`ky=|M3E+}HqkNAZ8{z_fpo!f)Ly^&)shB`{Y zsDWwIZFV zJN*a{x2)6DK}DPiX%}-*;KZKm#aSBc<$xY=tVAn)+SIO?xMV1W&NzgYr^jsgCV_g6 zz2lu|(g_B-5}9OfhEQvaqxfC)CwMh7ZPXrp;8}}+tz>eM-%$(3mraCArxX^gM;>q$ z+&ShH!B^-~nFKB#!7=ItgEvh&fM?Ddie#0zi^QIbOf#@*_AvOLu7P%JtPX6$0FMW4 zhx)%9203Bu(@f94wfuwxS8`1N%dLbcUjWPfZ{iS2w}ak~-kdi?;)?Zr#{ zIqCqOiyS7%*1&eIn_L%#5s9}M!3{ka8<9CXkbviZ{L_qph(DXZD3B}Y&mYhsT=ulP zsQVh|8|)(ZKPSKVlY>s(REc0JApe;+bWe5qT`DF+MX9c1N+ITVdBVs|czqskt8&%m zWRYReI;rrA)z1s>9RVF`(29C$ht;Q_p*#M+LqPcp;M5OIv+zlGR4f|r(RMo z?D`F9+plKbw+mTzZlg?(y%=jLRko-~j82=h>K9M~Zmb2R?d8@BG94jN& zj66#vj1>ufwyztS*wT1)O<~+UOpk_nY16gFwcAFWplGFRweY)TEN2Ojp~c!mowiy$ zWr_*;PMQlcXWd_>^7~}zX->*k#GB|+T z_OKX}W$Y#m zs%Hzml=k^}GY0yg0U4WQHo9cf0`kdAa`Vyyw>b55VEVMYpzNeUSLREBN zf-O-0ou;fIvlM5iehOF#0>H`E6|_QA@(fDpw2{;4b-zdxYhbj5VJ;pUG7V0>T{JQc zo99Jj#*pUa|J`X4fJANAY>_EVVXDEab+=N>Zr59?=;T#bx)u$+d}iLo$nFp`8+ucr zJ6d2&$H>om}x!lyIVnIn%TTX@wrxq-+O6@0lQ{P&4xgM9y^F4$IP zLHd5_S3+?$FiN(qwgKJZwz7tyj-+loQH#yHoqC20$pVK8ibhvQH)zy}={};!&0f@` z6t#Tq5)o}&E+MGRlHlNEQ$D?Fhf1E73qvs$F1U?)lIv>7;NM%>elx9UlQhyDYZhLv zs*)I@4>f094r@ECJIa;~Ladt40ydvW!(DGR@XMG0;W?%{Sm!%4y^35hrE!4e{0Xb^ z1My$Lv6Ox3j_C=EqvHY=lpdGiK09-zGldV`a|xR1f6Y(}^tV{80E^G;-2K~rzAUMu z>A(*g&LB`_)^6)sP@nrNC517PO@?VavL|^3oP3w7WcHk2NxTapan}U;Pv3&MVrE@9 zJ|2v3Lu_dwvOp6#MD?}bCnxMm4*6MI_X6u>JOT;0>3~m2jv0Q&UqcYm=^1 ztrjq>V%k}|2pP8uQlh5S$(#FTYJU%JF{mLKD+}J$!W7`?jSoBiPI~Tuz|rt5T|}Ce zUhb#HeB=$*CftNf^wWI+GKcI;$a`wBT+5X3zXt0~jKDS@3uAnhPeVH>ANmyZt&|7p zG(&#ant=U*{iGuG{g4L6ZKDHWP@E~=!Hsf}g7 zCfGEfH|y!!bX825t_)Syj*bgC2v|o!)a$*zgS60T@xzd80>?7vDgBS^qY}M#bU_?) z^XWN`{*aLvjmNI#dVM1Egn_b6jv2h#c<2ExZ9lK6!7?I{50c_gCkhUjD=#^Rf!fD8 zEW=7kc~JTZMN6l2XM`-!8ogZNAynrkT9rMW*ki?^SJM*sy4L}J#Qr9~|B0Vd&<6_A0 zn2D7bK`b+C+5F)=JEwz_JOnvYsyjlh0GH6zWUsh2H>hqAq!4V$sHEjEm{?ad`hW=Q z3&goZzdz`S0e#oeJQp?clv%Lz8-}eC zAI&T$Jg?=n5H3M=s!eQom45pYbGe+VB9&BZ>5?8nDks;nobd`bQj8Bub5J{!KB=V& z`I;MwY;}D)JL_^tn@7&!+SjJ@=MT)gA2VN=gFCPtTyNE>)fZHo7cDaOTh7=~1{y2^ zgIRq2a)wQ#e|(Mf$Ikbx>jM<-fQ9RrIe2gr0*fx=CLDOU0VFQC?43YX^Eriyd0ulJ za&0qH>ZkGdtSn~h*-W*8iJkF3;c>nRl|k);nyih4Ly;nKDwbxKVuJwV{pyAroaq{j zFkqigJ&H`HcLq#*-)M*R9XJ-QEVqM6SF(Jl*vn4G(w|u&1UwVjv{pL^BdM&M?QWRQ zZ>ZwCWWEBlY>BuC+@WXWdMr3K>|79sL<|zawbMK?A zsF@VS&_{QQ4lr3kKIl?^dD^luA@3y2*X#P}y3E1C`c%sdj! zzbE3H4iPN*VTS)L_CYJ3K%NRfF6J>&Pn@}P9x^m>lroMdcm3bK7wTQ;@fBC^p$;e*R-QGpz(c@9kx!OFu z&6;Kc!Q~)fYa^DY7$fwK(*I+cY)EZKIX84L!?ve`WtqQsKH|C|1|GG)a-Tn7s2|Um z=D!?a*QfkT7au-ubUE=dFz5}uMRNzw`4bpZ_#1iKokIT9ll6S=|4R--;rAq;`{5S_ z1t{z?WyxCyB~HxGu&8#z*5C~_x9dB8onm%ObSg3>B}>rTB|_w?^uc58VF(&nX)N-a zJ{nOdP-T$X(k_$o0?DoD&AZahSnBWQ^qtQywKA5^S01Cf}Bnd2dK_@p(Z*V zE5TYco%H>GIaCt{<)?w>aPmw}H->@XV9gBfLqf7NW`zvJ!=3DfWQRfn?*(>KVMdUgjLAtN89i1dPyvd5+vn#h$MP=h}AK?EEOB6 z=AJuKBj5SondrfY@6}efBinha3U`72b&w59iy!}){-hb~b=a^@Pskp|8D{XdUrPZ! zvVN4h8^7>RGCB50&1Z+!;C#hMbu{G_NNRKVnm;D;Ps%62b;Yc{S&x}D%#hiz|J<@! zvM6OPl2m&x=nlO3PTv`4r!Tu6^|V@Gsho8(Sw^;_$@yxZU<+c)}a4e$qlFh23xDUZ=^8jblr|0bAe>Nj$oT~x7WGU#k zP7DbAgab$h+qQTDN&aX1va3vY>d7yE zzPxNbnwghZ_yr-bx0}9lL>9ug{jbsl;kymB+4TxbD&Ln<~Ip4 z-pPm2MD!MRhtTW7(0z<2~y=f3My3myszp*~+q2 z<9Sz$JZKW?Pk}Ga^%Do;p&C|YF`AAvDm8(4k%ej>)Ef;<$_#|yxdgfydJ~DzggYfR{=cREY!g5e?LilLH;S{$+-Uu H3HJX1JkQxm literal 5805 zcmV;e7EqUNjmAt;*OosLq4!_NNx!EhLO z`}@yMpE<{`U!9yfDv$mB=Wic64=87y3&H9{o^Y*Pd-oT5W zf+zdauhS%|Y`^CwD$9>q&a*^r9J~6f0}|dvOtX ztoz38shm!dDE6N0PsDR6A(LI2d+=m`nt4` zdN!Azwkpaua3*$=+yvfSa$4i;p~^D)Jb#*doIQUQyVvt-%`5iyUA{W1J!cIu{WkxS zwcyD6BZ{sXjEEyQ{Nj$@#s0vbkA-PdrY)K8$TUS1jIY9jz#oK_{9!f!RQhD-_EZ)# z`Pg%Vr%*iEPrpn>)h~KvK64YVTonW$>p;*!(1G+ZppPMT{t47irFJ@#C@!Zz^n<{8 z?S+vams33RN5jCqIqA7UrC8|rq4Tq&Kg!8o_6mnAh+S6WbVS)aaC zQ<|nPzLUzfK7Fa7a0%)b6^2yDmdiqm$|?^5oxC(y2y5EZLN|5uVP$9(oxI$93r1D7 ztr`#EmW5SE0Dy*fg|+EdZ0gR6J>6+FtU9X>;?C`~XimqBoTY-T7s__#v3343_EDE^QfUQbgF3@M>OF1|$xIh#=Yo^rKIx1YCB)%Py5wK}?H$h*V? zO>G*7Ui{we`{QB}Y4vIGHT2_8em}XaN}{}E-UgP;Vaa}%>RWs|AAo0ZaskiWaO9`| z^o9e7C_3v!y~x#%2q4)nqw%@=opA8r+u4OO=E-?*b^*>VM%Vsmbav6ZbmNhi0OzF_ zeDO48_}6zO+0z3{iT>*>_WFp@vq9{6q5g6nj6L4_{oqRE&z{aY@duZQ7hbqMMJmCA2fEhhs@{k= zXT1yHydQ_oBl?fBhU%u8lAmL@UtuQ5$V_tIno>Iq)F4-ORsp5bcLaa}JWNG8{ZZJ1 z&=y$U@6S(mMDS#5f+vW9;Jx<41@M>8D4!E9=9CE^Meg;Z5JabGGO~{tSauj2*#t!?=_1L6T_qMqN?b{UabYT8YI#RS&u_Yu|i82 z`gqnS2Cz253q%X><)xP&Zw*0%ki{xo16tSsTJPfIG8#mo8yvc^UQ)YK*wM=+pRTEy z4La}^r`Z!;;dD_AfS>Cj9 z10j9w4cy*MLHfcCMw20#v%Dp1SGT%418~<5YF`4Fs;*PiR-HB_$SRZ8>JGVyBNV|a zw*ZLiz~L6e5JIgqM0O>Rj4B-#46DCsVuA;IhIf}3zVJhTbm{fmPI=)1m9!kP1-@{3D-H?&)*Mplh+-+ZO35XZ5<#f9$q209 z6@ckR8o{E=kY$pVNp6x!64HuElGaSpqG%%&1=~VV2(>aOkP@N`s`#>Lyo5^u(!!sG zzjp9+9{shX0~fUIfS6wLWpc71_`|NMIc60xnRLsF~j=k2eH^- zvB6?P{V9YEda5C!Xv6M2)fV`n<)rkX7klK(!o;Q>b?f~~|3=uewezZ&(v+A$vHh9L zv}{s)9nM4oN^D`r!p>$KWCiI0rEowBN&uovvvk;H7)yc)hLA!=(j6*2RH@yeDgqT; z*OD)hEth-=!%PB*5u_Y&0PLYpyF+z%7krOydVzQL;3RSH#Xc1#%J3oyWOk%l{g-W9 zDUGA5b&ycXC(>;zq_4)r78Z-J2-XIRqAe_Pp!!S-1&fkHF0qA0yAyVoPs4j&|Lnob zDCpmzt+0AvRDIP&kVr}aRXkB}K3Ub3LbV?g2qS^m%%kaE@8?swE)=7nt@{xplyVL* zVhnK3rA0A|Vs{wDe(6Ph?|uLngk6aN5Li+uqyjO`>_it+tn^G^^#@Mn^p+!ZzX5D* z{*#2arD0hUV+j-mV~R&x0J8vghXL#j+H>Auu#=OhYNpc7-z)?4y}N>TrC^L8fFy>P zWtub98N(2wShZQJ|EJ2nY!QR8M*>CR$9qyOUOMKbG9M>~f+H`$0g}d`Vv{ zjsWXYAvsZy$N&fFA!sb_kBdnSc&#lu3~syP2DzFE3&;qAs=<|svEXI>LE2o))C6(P zzNrbM8$S-uzMnlXu9?|;yw~RjOSk6+OIYe?O2pRB=Rgj-ptSmlpDpc1-$>UU1*ydxv4!BK+)DtB;jgtEHqeXu+XsZ^xh`#abPr1w1S`SaA4Tg9G2% zR0Qv8DuUz^a8OmV;9$XFbN9O-K(a8Pa1!YZ>bne}*n*eM)Cpimu7{#MBAL8*-nfI% zTdL_DHS*LP006`w!LP%#F55|O7FAVwsF zfDynrrmEv=G61PGF8$O>uUguQuUnSX)2B)sGRo`I7i)@8n!fl_sJ{NymfCYb)53IU z+j3b9;im7()8wW0!=!0b>mVYfEE#Cr(aI$0$68YvNnXfi53kK#yY=;bfT|vY5EDeD`rn?vv+mkI*y+0++}kH)dXqTRlU|`-6+$SG zP>g$edjkBiZ%??zoENPL0#WNLVwj*9NoBPp=MYMJV8tTf9YjEuA)r!JFR@2mcI944 z*5WI_5D4KG;~{rR;fT0ikR{s>k4()4=e91nm`D^3=-90a8zHXsCxtv1)TDo=eqgiTU{0>e{#Zv9z@x-oUL+ zCSZHc3~$ddLCP-R08=6{lUSxsgj6WYux&>L1wOP?5d}!KUJI(;WpR7hVzbO(4VVYe zhEVT5hrdDD!FP~(M+ms*5W7rX0z}g_bt~=~uAs?3_`1zO;19wE%U$>W!jYw`&If@T zUpc)f?5DPF^!V&S$2oNS>Q7f!ZrInqzV@&D#ED`@z4t&h%?5Aq{qcy-*6tS}9PR4l z##pL;Fp%U%7|H7u)e(* ze4FhRwA$im89HmXEV9iMP>^QQE|l7Z(k0_sv|jjJbmJ*WL&`I#qe|OD7Yl)5r9&4~ zG9(DsYmibBEJ=0>K_bc|6aJbMw9T0Xm8T#Gb0Lw$m;!*j zPW>r$Qw>^Fz}Nt-TD#R*f|UyEtoW|2efe+Gx7HQky5d_`{PnovAG@L7a~?swJ8%4{ z*@wa&wOnTPv9RYRCt-iJT*6QEh>YrSW6E#diW%$wV3_l^0D}L-93rh_@vWDLp zerx!x;kSn08vffG{#VL|#6i^itSmp=wB@fc+P}oncxW*3Q4qMpk=HMp%$)zef<_7q zkMIetd@6IuL&!u<0VU&iIJNuWGA)!#DsPwj$&ddMNlwo z2<5m6r^ZdH3R@|5(;65{Th6jNYgwJQtb@6%%w1MyFD?1Y>I`Oe4%3#!tj=SKOvcP* zOzK(UGbNE4PE(dL@tVfW#>j1I*o~3jG%u+DGv(imJjd7`6|PgycFd)e8Ba~Cn^}*U z_tY^TBljr-ZUucS2Bh*1WeLlJ<~-=vXfRMsp;!?3M^(}5d62oUYKi$Rs0T$0ogXas zSj;_`?wiNZc*%fhE?rw^;gdOZp)!{jl`I(ho~NEd8+bS`z!BJSn?`0J6?11IqP`fhjspDmCIYE zAV#ZylZ*dUsiZ$T8J`a{)R?Z8y3I{~h*%H&CLZ{ZuQAGDN?)sC*BVENBj&h+bTd&7 zk+C#{nugvJgqflo^2U+>Oaa>Dq9X*=cyyf>0qItXa;U@6wTMP%3P!gy7F~T)D^Ww} zKh~=nwkNBeughhtP7nM%<3xp$OL7<#u;6g7pHzvugC;^+&K?#3NUVt6XUn zCJfxJRY$jqi@r;0r$VjRNuZ7Is>$B6W;g z!OcfiXT_%Otk}~lF6^`&#GTt|k)?T-=2@Dz9-8;wbNe^WBe-LlhpDA`Eoh#wYdm(1 z$FA{M<8O_>HU6vIj_N1A8~A^v_j7<9-H-aChCmdiK-{IXvUOo=8?gYyw-uNf0v)bb z*%H9Jf?_&lYM5;~O!Fj0t^^AMJ674GjoAD{MQqMq;?NC(O@?lskCVx@%YHwvzO$a1 zJv|w^Jyn-kv00fUU*?3W|2K+_31)FGi}(6vqx3Sm9_dtbadXV(OgeOjqtmE?{QP~> z_Za(qZ}d9qefDMvjiWgy{m~!!=kw;SDJC6W$L?SrXVe_#GXuOUC3vJJjfodG5dV+o z4Ns#&r_YCBHU!-pFP@h?Lx7Tv(l5R&#&0J1*1a-Z+npBUz^eFhY=l;0xb2U=cfC}! zZkVbXMB}7>pdN(2G6`N~P?X{r>!&?G?nQ6>@R>hKN`o4T(wI(VPdvps+ydTD^$wKe zgS48@!-0Z^N?rOBDPu+5rveJxl`Zsxe5cIv!d8zniImO#3@tVKOyV&=_q|mx%qcD|LW2JHC8fXqx z2Yntjkkz_buQ6{=4x>a7sq7f!d?4gl#3a9qAaawUK2N?ASk&D){$wS*jAH*U&6!la z{jfCRss;6;zJ_N*L5By)U;UTA2ETuT!293B;Ez`?qXY8W;cu@_o?jkZzWV?uJpc4- z&>I}7-}~=Az&|d}Uw#Y@)bpd~^z;<{`sW{?-hzWypPnC_{HbJKd=0LTepy`o*WN|4 zO7mzqS(N{=J5-}SPumUISJ&jGtdQy5JuZtp&`^pV2k*Tv%20TQ!FeA#;=P{oZL%j$ zqv0m9FJfrg5${4zD{+lI*9+J0!r*4PcE69V4+4J>HlPtov_#1&)^0+@6#kz2Nfn5W z-0+J#DiDAy#g&4~v>N*Gc1D{HdWrv~32RCdYa{H2J+Ecj5263(*qhHE7rgz4k@q}I z{CH8be{4$NKKY@VG}VLZ(KwD(OQbDX<-edxf1iIHx}j3G|I3;<7p;D7|0XK}ah{sx zd`L0VAyp>VjmvD~ft9Ymm{IM*Og(qzeER(TIGCHpih$~)b9dR};7R`3!TL9|R>CT8-zHz?rOtSLHB=+#!7Hie{Q&k=xhS^ftb+U1WZx+)XF%Iro9 reRP9yrH5*#^#-N+$(X-+;b{(06*!rH4g;k>Paph0#f_tLen|lU)mn5F diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index da715a81..4b7b421a 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -232,13 +232,6 @@ void cm_operation_init() * (6) - Remove the hold state / there is queued motion - see cycle_feedhold.cpp * (7) - Remove the hold state / there is no queued motion - see cycle_feedhold.cpp */ -/* - * List of all possible cases where a feedhold can be received, and what to do about them - * - * (0) - Feedhold received when the system is idle. There is no CYCLE (CYCLE_NONE) - * (1) - */ - /**************************************************************************************** * cm_operation_runner_callback() - run feedhold operations and sequence queued requests From 720cd6d4157891df6c16db0c268e5254e6897cf6 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 11 Apr 2017 15:01:34 -0400 Subject: [PATCH 235/283] bandaid --- g2core/cycle_feedhold.cpp | 22 +++++++++++++++++----- g2core/g2core.cppproj | 4 ++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 4b7b421a..1517ffea 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -480,10 +480,14 @@ static void _start_job_kill() return; } case MACHINE_CYCLE: { // Case 2's - if (cm1.hold_state == FEEDHOLD_OFF) { // Case 2a - in cycle and not in a hold - op.add_action(_feedhold_no_actions); -// op.add_action(_run_job_kill); - } +// if (cm1.motion_state == MOTION_RUN) { // +++++ bandaid + if (cm1.hold_state == FEEDHOLD_OFF) { // Case 2a - in cycle and not in a hold + op.add_action(_feedhold_no_actions); + // op.add_action(_run_job_kill); + } +// } else { +// cm1.hold_state = FEEDHOLD_HOLD; // +++++ bandaid +// } if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 2c - in a finished hold _run_job_kill(); } @@ -607,7 +611,15 @@ static stat_t _feedhold_no_actions() if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold cm1.hold_type = FEEDHOLD_TYPE_HOLD; // cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for NO_ACTIONS is STOP... - cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function +//+++ add these lines + if (cm1.motion_state == MOTION_RUN) { + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function + } else { + _check_motion_stopped(); + cm->hold_state = FEEDHOLD_HOLD; + } +// cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function +//++++ to here } // if motion has already stopped declare that you are in a feedhold diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0d5b8f5b..b8ee2360 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 From 8e5d0384dc09f25ee290d73dae4fb043bb544ed9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 12 Apr 2017 07:48:51 -0400 Subject: [PATCH 236/283] Fixed case where Z movement was not transferred back to p1 planner in event of a job kill. See cycle_feedhold.cpp, line 450; Comments and some cleanup --- g2core/cycle_feedhold.cpp | 121 +++++++++++++++++--------------------- g2core/g2core.cppproj | 4 +- g2core/plan_exec.cpp | 2 +- 3 files changed, 58 insertions(+), 69 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 1517ffea..311c2aef 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -273,7 +273,7 @@ stat_t cm_operation_runner_callback() _start_cycle_restart(); } - // run the operation or operation continuation + // run the operation or operation continuation (callback) return (op.run_operation()); } @@ -305,7 +305,6 @@ stat_t cm_feedhold_command_blocker() static stat_t _run_program_stop() { cm_cycle_end(); // end cycle and run program stop -// cm_program_stop(); return (STAT_OK); } @@ -315,20 +314,9 @@ static stat_t _run_program_end() return (STAT_OK); } -static stat_t _run_alarm() -{ - return (STAT_OK); -} - -static stat_t _run_shutdown() -{ - return (STAT_OK); -} - -static stat_t _run_interlock() -{ - return (STAT_OK); -} +static stat_t _run_alarm() { return (STAT_OK); } +static stat_t _run_shutdown() { return (STAT_OK); } +static stat_t _run_interlock() { return (STAT_OK); } /**************************************************************************************** * cm_request_cycle_start() - set request enum only @@ -377,11 +365,11 @@ static void _start_cycle_restart() /**************************************************************************************** * cm_request_queue_flush() - set request enum only - * _start_queue_flush() - run a queue flush from a % - * _restart_flush() - run a queue flush from an action + * _start_queue_flush() - run a queue flush from a % + * _run_queue_flush() - run a queue flush from an action * - * cm_request_queue_flush() should be called concurrently with xio_flush_to_command() - * cm_request_queue_flush(); xio_flush_to_command(); + * cm_request_queue_flush() should be called concurrently with xio_flush_to_command(), like this: + * { cm_request_queue_flush(); xio_flush_to_command(); } */ void cm_request_queue_flush() @@ -408,6 +396,10 @@ static void _start_queue_flush() } } +// _run_queue_flush() should not be called until motion has stopped. +// It is completely synchronous so it can be called directly; +// it does not need to be part of an operation(). + static stat_t _run_queue_flush() // typically runs from cm1 planner { cm_abort_arc(cm); // kill arcs so they don't just create more alines @@ -420,11 +412,11 @@ static stat_t _run_queue_flush() // typically runs from cm1 planner /**************************************************************************************** * cm_request_job_kill() - Control-D handler - set request flag only by ^d - * _run_job_kill_final() - perform the job kill. queue flush, enter alarm with no movement + * _run_job_kill() - perform the job kill. queue flush, program_end * _start_job_kill() - invoke the job kill function, which may start from various states * - * cm_request_job_kill() should be called concurrently with xio_flush_to_command() - * cm_request_job_kill(); xio_flush_to_command(); + * cm_request_job_kill() should be called concurrently with xio_flush_to_command(), like this: + * { cm_request_job_kill(); xio_flush_to_command(); } * * Job kill cases: Actions: * (0) job kill from ALARM, SHUTDOWN, PANIC no action, end request @@ -443,22 +435,30 @@ void cm_request_job_kill() cm1.job_kill_state = JOB_KILL_REQUESTED; } -// _run_job_kill() is completely synchronous so it can be called -// directly and does not need to be part of an opertion(). +// _run_job_kill() should not be called until motion has stopped. +// It is completely synchronous so it can be called directly; +// it does not need to be part of an operation(). static stat_t _run_job_kill() { - // switch to p1 (may already be in it) - cm = &cm1; // return to primary planner (p1) - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; + // if in p2 switch to p1 and copy actual position back to p1 + if (cm == &cm2) { + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; + + copy_vector(cm1.gmx.position, mr2.position); // transfer actual position back to p1 + copy_vector(cm1.gm.target, mr2.position); + copy_vector(mp1.position, mr2.position); + copy_vector(mr1.position, mr2.position); + } _run_queue_flush(); coolant_control_immediate(COOLANT_OFF, COOLANT_BOTH); // stop coolant spindle_control_immediate(SPINDLE_OFF); // stop spindle - cm_set_motion_state(MOTION_STOP); // set to stop and set the active model + cm_set_motion_state(MOTION_STOP); // set to stop and set the active model cm->hold_state = FEEDHOLD_OFF; cm_program_end(); @@ -480,14 +480,10 @@ static void _start_job_kill() return; } case MACHINE_CYCLE: { // Case 2's -// if (cm1.motion_state == MOTION_RUN) { // +++++ bandaid - if (cm1.hold_state == FEEDHOLD_OFF) { // Case 2a - in cycle and not in a hold - op.add_action(_feedhold_no_actions); - // op.add_action(_run_job_kill); - } -// } else { -// cm1.hold_state = FEEDHOLD_HOLD; // +++++ bandaid -// } + if (cm1.hold_state == FEEDHOLD_OFF) { // Case 2a - in cycle and not in a hold + op.add_action(_feedhold_no_actions); +// op.add_action(_run_job_kill); + } if (cm1.hold_state == FEEDHOLD_HOLD) { // Case 2c - in a finished hold _run_job_kill(); } @@ -513,11 +509,10 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) { // Can only initiate a feedhold if you are in a machining cycle, running, and not already in a feedhold + // +++++ This needs to be extended to allow HOLDs to be requested when motion has stopped +++++ if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE) && (cm1.motion_state == MOTION_RUN)) { -// if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE)) { - cm1.hold_type = type; cm1.hold_exit = exit; cm1.hold_profile = ((type == FEEDHOLD_TYPE_ACTIONS) || (type == FEEDHOLD_TYPE_HOLD)) ? @@ -537,7 +532,6 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } default: {} } -// cm1.hold_state = FEEDHOLD_SYNC; // may be redundant, unless default {} was triggered return; } @@ -555,7 +549,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) } /* -static void _start_feedhold() +static void _start_p2_feedhold() { // P2 feedholds only allow skip types if ((cm2.hold_state == FEEDHOLD_REQUESTED) && (cm2.motion_state == MOTION_RUN)) { @@ -610,22 +604,16 @@ static stat_t _feedhold_no_actions() // initiate the feedhold if (cm1.hold_state == FEEDHOLD_OFF) { // start a feedhold cm1.hold_type = FEEDHOLD_TYPE_HOLD; -// cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for NO_ACTIONS is STOP... -//+++ add these lines - if (cm1.motion_state == MOTION_RUN) { - cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function - } else { - _check_motion_stopped(); - cm->hold_state = FEEDHOLD_HOLD; - } -// cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function -//++++ to here - } +// cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for NO_ACTIONS is STOP... - // if motion has already stopped declare that you are in a feedhold -// if (cm1.motion_state == MOTION_STOP) { -// _check_motion_stopped(); -// } + if (cm1.motion_state == MOTION_STOP) { // if motion has already stopped declare that you are in a feedhold + _check_motion_stopped(); + cm1.hold_state = FEEDHOLD_HOLD; + } else { + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function + return (STAT_EAGAIN); + } + } // wait until feedhold reaches the hold point if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { @@ -649,17 +637,17 @@ static stat_t _feedhold_with_actions() // Execute Case (5) // if entered while OFF start a feedhold if (cm1.hold_state == FEEDHOLD_OFF) { cm1.hold_type = FEEDHOLD_TYPE_ACTIONS; -// cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for ACTIONS is STOP... - cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function - return (STAT_EAGAIN); +// cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for ACTIONS is STOP... + if (cm1.motion_state == MOTION_STOP) { // if motion has already stopped declare that you are in a feedhold + _check_motion_stopped(); + cm1.hold_state = FEEDHOLD_HOLD; + } else { + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function + return (STAT_EAGAIN); + } } - // if motion has already stopped declare that you are in a feedhold -// if (cm1.motion_state == MOTION_STOP) { -// _check_motion_stopped(); -// } - - // Check to run first-time code + // Code to run once motion has stopped if (cm1.hold_state == FEEDHOLD_MOTION_STOPPED) { cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state @@ -731,6 +719,7 @@ static void _feedhold_restart_actions_done_callback(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } +//+++++ Make this more robust so it handles being called before reaching HOLD state static stat_t _feedhold_restart_no_actions() { if (cm1.hold_state == FEEDHOLD_OFF) { diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b8ee2360..0d5b8f5b 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800030015 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800030015 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index a6a261d6..ace7d9cd 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1042,7 +1042,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) } else { // Otherwise setup the block to complete motion (regardless of how hold will ultimately be exited) bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - bf->buffer_state = MP_BUFFER_BACK_PLANNED; // so it can be forward planned again + bf->buffer_state = MP_BUFFER_BACK_PLANNED; // revert from RUNNING so it can be forward planned again bf->plannable = true; // needed so block can be re-planned } mr->reset(); // reset MR for next use and for forward planning From 310311028ca892e30502b97f27c32f75b6e02dc0 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 12 Apr 2017 08:44:39 -0400 Subject: [PATCH 237/283] =?UTF-8?q?Fixed=20a=20problem=20where=20a=20?= =?UTF-8?q?=E2=80=9Cperfect=E2=80=9D=20deceleration=20causes=20a=20zero=20?= =?UTF-8?q?length=20move,=20which=20cases=20a=20planner=20trap.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/plan_exec.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index ace7d9cd..935bc2e9 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1035,15 +1035,26 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) if (mp_runtime_is_idle()) { // wait for steppers to actually finish // Motion has stopped, so we can rely on positions and other values to be stable - // If SKIP type, discard the remainder of the block and position to the next block + + // If hold was SKIP type, discard the remainder of the block and position to the next block if (cm->hold_type == FEEDHOLD_TYPE_SKIP) { copy_vector(mp->position, mr->position); // update planner position to the final runtime position mp_free_run_buffer(); // advance to next block, discarding the rest of the move - } else { // Otherwise setup the block to complete motion (regardless of how hold will ultimately be exited) - bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move - bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - bf->buffer_state = MP_BUFFER_BACK_PLANNED; // revert from RUNNING so it can be forward planned again - bf->plannable = true; // needed so block can be re-planned + } + + // Otherwise setup the block to complete motion (regardless of how hold will ultimately be exited) + else { + bf->length = get_axis_vector_length(mr->position, mr->target); // update bf w/remaining length in move + + // If length ~= 0 it's because the deceleration was exact. Handle this exception to avoid planning errors + if (bf->length < EPSILON4) { + copy_vector(mp->position, mr->position);// update planner position to the final runtime position + mp_free_run_buffer(); // advance to next block, discarding the zero-length move + } else { + bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer + bf->buffer_state = MP_BUFFER_BACK_PLANNED;// revert from RUNNING so it can be forward planned again + bf->plannable = true; // needed so block can be re-planned + } } mr->reset(); // reset MR for next use and for forward planning cm_set_motion_state(MOTION_STOP); From 6949cbf44f8a902618c501a4db379ba57ebd4bb0 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 12 Apr 2017 14:32:53 -0400 Subject: [PATCH 238/283] Small change to feedhold motion stop --- g2core/plan_exec.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 935bc2e9..c553b6d4 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1052,8 +1052,11 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) mp_free_run_buffer(); // advance to next block, discarding the zero-length move } else { bf->block_state = BLOCK_INITIAL_ACTION; // tell _exec to re-use the bf buffer - bf->buffer_state = MP_BUFFER_BACK_PLANNED;// revert from RUNNING so it can be forward planned again - bf->plannable = true; // needed so block can be re-planned + while (bf->buffer_state > MP_BUFFER_BACK_PLANNED) { + bf->buffer_state = MP_BUFFER_BACK_PLANNED;// revert from RUNNING so it can be forward planned again + bf->plannable = true; // needed so block can be re-planned + bf = mp_get_prev_buffer(bf); + } } } mr->reset(); // reset MR for next use and for forward planning From 847a2fc69c3c6ce44bb931a0ba2e879b2d49e39a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 12 Apr 2017 17:51:16 -0400 Subject: [PATCH 239/283] Fixed a dumb mistake. Still working on the bumps, though. --- g2core/canonical_machine.h | 2 ++ g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index beaf85a8..71a233b1 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -281,6 +281,8 @@ typedef struct cmMachine { // struct to manage canonical machin /**** Runtime variables (PRIVATE) ****/ + uint8_t test; //+++++ + // Global state variables and flags cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0d5b8f5b..b8ee2360 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800030015 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800030015 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index c553b6d4..4e1d466d 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1028,12 +1028,29 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) * or tail. */ +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ + +static void _hold_everything() +{ + cm1.test += 1; + if (cm1.test == 3) { + cm->gm.linenum = 42; + } + +} +#pragma GCC reset_options // DIAGNOSTIC +++++ + + + static stat_t _exec_aline_feedhold(mpBuf_t *bf) { // Case (4) - Wait for the steppers to stop and complete the feedhold if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish + _hold_everything(); + // Motion has stopped, so we can rely on positions and other values to be stable // If hold was SKIP type, discard the remainder of the block and position to the next block @@ -1055,7 +1072,7 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf) while (bf->buffer_state > MP_BUFFER_BACK_PLANNED) { bf->buffer_state = MP_BUFFER_BACK_PLANNED;// revert from RUNNING so it can be forward planned again bf->plannable = true; // needed so block can be re-planned - bf = mp_get_prev_buffer(bf); + bf = mp_get_next_buffer(bf); } } } From f7c65c0f780923e62b768c1ec17af6046bab6ee1 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 12 Apr 2017 19:28:37 -0400 Subject: [PATCH 240/283] Some testing --- g2core/canonical_machine.h | 2 +- g2core/cycle_feedhold.cpp | 12 ++++++++++++ g2core/plan_exec.cpp | 19 +------------------ g2core/plan_line.cpp | 13 +++++++++++++ 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 71a233b1..5aa0992f 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -281,7 +281,7 @@ typedef struct cmMachine { // struct to manage canonical machin /**** Runtime variables (PRIVATE) ****/ - uint8_t test; //+++++ + uint32_t test; //+++++ // Global state variables and flags diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 311c2aef..69c61f95 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -59,6 +59,18 @@ static stat_t _run_alarm(void); static stat_t _run_shutdown(void); static stat_t _run_interlock(void); +/* +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +static void _hold_everything(uint32_t number) +{ + if (++cm1.test == number) { + cm->gm.linenum = 42; + } +} +#pragma GCC reset_options // DIAGNOSTIC +++++ +*/ + /**************************************************************************************** * OPERATIONS AND ACTIONS * diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 4e1d466d..b4518ec0 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -1028,29 +1028,12 @@ static void _exec_aline_normalize_block(mpBlockRuntimeBuf_t *b) * or tail. */ -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ - -static void _hold_everything() -{ - cm1.test += 1; - if (cm1.test == 3) { - cm->gm.linenum = 42; - } - -} -#pragma GCC reset_options // DIAGNOSTIC +++++ - - - static stat_t _exec_aline_feedhold(mpBuf_t *bf) { // Case (4) - Wait for the steppers to stop and complete the feedhold if (cm->hold_state == FEEDHOLD_MOTION_STOPPING) { if (mp_runtime_is_idle()) { // wait for steppers to actually finish - - _hold_everything(); - + // Motion has stopped, so we can rely on positions and other values to be stable // If hold was SKIP type, discard the remainder of the block and position to the next block diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 824816f3..480e6923 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -66,6 +66,17 @@ static void _set_bf_diagnostics(mpBuf_t* bf) { static void _set_bf_diagnostics(mpBuf_t* bf) {} #endif +/* +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +static void _hold_everything(uint32_t number) +{ + if (cm1.gm.linenum = number) { + cm1.test = 1000; + } +} +#pragma GCC reset_options // DIAGNOSTIC +++++ +*/ /* Runtime-specific setters and getters * @@ -227,6 +238,8 @@ stat_t mp_aline(GCodeState_t* _gm) _calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax _set_bf_diagnostics(bf); // DIAGNOSTIC +// _hold_everything(314); + // Note: these next lines must remain in exact order. Position must update before committing the buffer. copy_vector(mp->position, bf->gm.target); // update the planner position for the next move mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) From fef999b8f17a348a5fb02274286075a909b7e60f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 12 Apr 2017 19:31:06 -0400 Subject: [PATCH 241/283] Cleanup --- g2core/cycle_feedhold.cpp | 12 ------------ g2core/plan_line.cpp | 14 -------------- 2 files changed, 26 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 69c61f95..311c2aef 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -59,18 +59,6 @@ static stat_t _run_alarm(void); static stat_t _run_shutdown(void); static stat_t _run_interlock(void); -/* -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ -static void _hold_everything(uint32_t number) -{ - if (++cm1.test == number) { - cm->gm.linenum = 42; - } -} -#pragma GCC reset_options // DIAGNOSTIC +++++ -*/ - /**************************************************************************************** * OPERATIONS AND ACTIONS * diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 480e6923..26f9ed58 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -66,18 +66,6 @@ static void _set_bf_diagnostics(mpBuf_t* bf) { static void _set_bf_diagnostics(mpBuf_t* bf) {} #endif -/* -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ -static void _hold_everything(uint32_t number) -{ - if (cm1.gm.linenum = number) { - cm1.test = 1000; - } -} -#pragma GCC reset_options // DIAGNOSTIC +++++ -*/ - /* Runtime-specific setters and getters * * mp_zero_segment_velocity() - correct velocity in last segment for reporting purposes @@ -238,8 +226,6 @@ stat_t mp_aline(GCodeState_t* _gm) _calculate_vmaxes(bf, axis_length, axis_square); // compute cruise_vmax and absolute_vmax _set_bf_diagnostics(bf); // DIAGNOSTIC -// _hold_everything(314); - // Note: these next lines must remain in exact order. Position must update before committing the buffer. copy_vector(mp->position, bf->gm.target); // update the planner position for the next move mp_commit_write_buffer(BLOCK_TYPE_ALINE); // commit current block (must follow the position update) From 9df36e25bd551945f85645529c43cfd460a80283 Mon Sep 17 00:00:00 2001 From: Ryan Sturmer Date: Fri, 14 Apr 2017 13:49:24 -0400 Subject: [PATCH 242/283] Fix M100.1 --- g2core/gcode_parser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 34aa168f..47e11c6a 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -1025,10 +1025,10 @@ stat_t _execute_gcode_block(char *active_comment) case NEXT_ACTION_SUSPEND_G92_OFFSETS: { status = cm_suspend_g92_offsets(); break;} // G92.2 case NEXT_ACTION_RESUME_G92_OFFSETS: { status = cm_resume_g92_offsets(); break;} // G92.3 - case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100 - case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 -// case NEXT_ACTION_JSON_COMMAND_IMMEDIATE: { status = mp_json_command_immediate(active_comment); break;} // M102 - + case NEXT_ACTION_JSON_COMMAND_SYNC: { status = cm_json_command(active_comment); break;} // M100.0 + case NEXT_ACTION_JSON_COMMAND_ASYNC: { status = cm_json_command_immediate(active_comment); break;} // M100.1 + case NEXT_ACTION_JSON_WAIT: { status = cm_json_wait(active_comment); break;} // M101 + case NEXT_ACTION_DEFAULT: { cm_set_absolute_override(MODEL, gv.absolute_override); // apply absolute override & display as absolute switch (gv.motion_mode) { From d1e08745cc09c19b111da5ef5a691417fffd8dfb Mon Sep 17 00:00:00 2001 From: Ryan Sturmer Date: Fri, 14 Apr 2017 15:55:41 -0400 Subject: [PATCH 243/283] Add low level io --- g2core/gpio.cpp | 68 ++++++++++++++++++++++++++++--------------------- g2core/gpio.h | 3 ++- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index fdd857c5..ff816e68 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -472,6 +472,42 @@ bool gpio_read_input(const uint8_t input_num_ext) return (d_in[input_num_ext-1].state); } +/* + * gpio_set_output() - Set output pins + */ +stat_t gpio_set_output(uint8_t output_num, float value) { + ioMode outMode = d_out[output_num].mode; + if (outMode == IO_MODE_DISABLED) { + value = 0; // Inactive? + } else { + bool invert = (outMode == 0); + if (invert) { + value = 1.0 - value; + } + switch (output_num+1) { + // Generated with: + // perl -e 'for($i=1;$i<14;$i++) { print "case ${i}: { output_${i}_pin = value; } break;\n";}' + // BEGIN generated + case 1: { output_1_pin = value; } break; + case 2: { output_2_pin = value; } break; + case 3: { output_3_pin = value; } break; + case 4: { output_4_pin = value; } break; + case 5: { output_5_pin = value; } break; + case 6: { output_6_pin = value; } break; + case 7: { output_7_pin = value; } break; + case 8: { output_8_pin = value; } break; + case 9: { output_9_pin = value; } break; + case 10: { output_10_pin = value; } break; + case 11: { output_11_pin = value; } break; + case 12: { output_12_pin = value; } break; + case 13: { output_13_pin = value; } break; + // END generated + default: { value = 0; } // inactive + } + } + return STAT_OK; +} + /*********************************************************************************** * CONFIGURATION AND INTERFACE FUNCTIONS @@ -616,43 +652,17 @@ stat_t io_get_output(nvObj_t *nv) } /* - * io_set_output() - read and return output state given an nv object + * io_set_output() - set output state given an nv object */ stat_t io_set_output(nvObj_t *nv) { uint8_t output_num = _io(nv->index); + return gpio_set_output(output_num, nv->value_flt); - ioMode outMode = d_out[output_num-1].mode; - if (outMode == IO_MODE_DISABLED) { - nv->valuetype = TYPE_NULL; // reports back as NULL - - } else { - // send normal or inverted value to output - float value = (outMode == IO_ACTIVE_HIGH) ? nv->value_flt : 1.0 - nv->value_flt; - switch (output_num+1) { // add 1 to get logical pin numbers - // Generated with: - // perl -e 'for($i=1;$i<14;$i++) { print "case ${i}: { output_${i}_pin = value; } break;\n";}' - // BEGIN generated - case 1: { output_1_pin = value; } break; - case 2: { output_2_pin = value; } break; - case 3: { output_3_pin = value; } break; - case 4: { output_4_pin = value; } break; - case 5: { output_5_pin = value; } break; - case 6: { output_6_pin = value; } break; - case 7: { output_7_pin = value; } break; - case 8: { output_8_pin = value; } break; - case 9: { output_9_pin = value; } break; - case 10: { output_10_pin = value; } break; - case 11: { output_11_pin = value; } break; - case 12: { output_12_pin = value; } break; - case 13: { output_13_pin = value; } break; // END generated - default: { nv->value_flt = 0; } // inactive - } - } - return (STAT_OK); } + /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table diff --git a/g2core/gpio.h b/g2core/gpio.h index 1c437d39..80801eb8 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -146,10 +146,11 @@ void gpio_reset(void); void input_reset(void); void output_reset(void); -bool gpio_read_input(const uint8_t input_num); void gpio_set_homing_mode(const uint8_t input_num, const bool is_homing); void gpio_set_probing_mode(const uint8_t input_num, const bool is_probing); int8_t gpio_get_probing_input(void); +bool gpio_read_input(const uint8_t input_num); +stat_t gpio_set_output(uint8_t output_num, float value); stat_t io_get_mo(nvObj_t *nv); stat_t io_set_mo(nvObj_t *nv); From baf3bbfe79337b5c80caa780a65abdebfafb20b3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 17 Apr 2017 08:17:06 -0400 Subject: [PATCH 244/283] Moved some code. No changes. --- g2core/util.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/g2core/util.cpp b/g2core/util.cpp index d00421b3..91996996 100644 --- a/g2core/util.cpp +++ b/g2core/util.cpp @@ -41,26 +41,6 @@ bool FLAGS_NONE[AXES] = { false, false, false, false, false, false }; bool FLAGS_ONE[AXES] = { true, false, false, false, false, false }; bool FLAGS_ALL[AXES] = { true, true, true, true, true, true }; -//*** debug utilities *** - -void LAGER(const char * msg) -{ - char message[64]; - sprintf(message, "%lu: %s\n", SysTickTimer_getValue(), msg); - xio_writeline(message); -} - -void LAGER_cm(const char * msg) -{ - char message[64]; - if (cm == &cm1) { - sprintf(message, "%lu: p1 %s\n", SysTickTimer_getValue(), msg); - } else { - sprintf(message, "%lu: p2 %s\n", SysTickTimer_getValue(), msg); - } - xio_writeline(message); -} - /**** Vector utilities **** * copy_vector() - copy vector of arbitrary length * vector_equal() - test if vectors are equal @@ -717,3 +697,23 @@ char inttoa(char *str, int n) } return (strlen(str)); } + +//*** debug utilities *** + +void LAGER(const char * msg) +{ + char message[64]; + sprintf(message, "%lu: %s\n", SysTickTimer_getValue(), msg); + xio_writeline(message); +} + +void LAGER_cm(const char * msg) +{ + char message[64]; + if (cm == &cm1) { + sprintf(message, "%lu: p1 %s\n", SysTickTimer_getValue(), msg); + } else { + sprintf(message, "%lu: p2 %s\n", SysTickTimer_getValue(), msg); + } + xio_writeline(message); +} From 70a5282c39f29727646f163a0f487ad082276520 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 23 Apr 2017 08:13:10 -0400 Subject: [PATCH 245/283] Fixed issue #24. Works, but needs cleanup --- g2core/cycle_feedhold.cpp | 26 +++++++++++- g2core/plan_exec.cpp | 22 ++++++++-- g2core/planner.h | 1 + g2core/stepper.cpp | 85 ++++++++++++++++++++------------------- g2core/util.h | 6 +++ 5 files changed, 94 insertions(+), 46 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 311c2aef..2f44894a 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -58,6 +58,20 @@ static stat_t _run_program_end(void); static stat_t _run_alarm(void); static stat_t _run_shutdown(void); static stat_t _run_interlock(void); + +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +static void _hold_everything (uint32_t n1, uint32_t n2) // example of function +{ + if (cm->gm.linenum > 200) { + cm1.gm.linenum += 1; + } + +// if (n1 == n2) { +// cm1.gm.linenum = n1; +// } +} +#pragma GCC reset_options // DIAGNOSTIC +++++ /**************************************************************************************** * OPERATIONS AND ACTIONS @@ -638,11 +652,11 @@ static stat_t _feedhold_with_actions() // Execute Case (5) if (cm1.hold_state == FEEDHOLD_OFF) { cm1.hold_type = FEEDHOLD_TYPE_ACTIONS; // cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for ACTIONS is STOP... - if (cm1.motion_state == MOTION_STOP) { // if motion has already stopped declare that you are in a feedhold + if (cm1.motion_state == MOTION_STOP) { // if motion has already stopped declare that you are in a feedhold _check_motion_stopped(); cm1.hold_state = FEEDHOLD_HOLD; } else { - cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function return (STAT_EAGAIN); } } @@ -671,6 +685,12 @@ static stat_t _feedhold_with_actions() // Execute Case (5) copy_vector(cm2.gmx.position, mr1.position); copy_vector(mp2.position, mr1.position); copy_vector(mr2.position, mr1.position); + + copy_vector(mr2.target_steps, mr1.target_steps); + copy_vector(mr2.position_steps, mr1.position_steps); + copy_vector(mr2.commanded_steps, mr1.commanded_steps); + copy_vector(mr2.encoder_steps, mr1.encoder_steps); + copy_vector(mr2.following_error, mr1.following_error); // reassign the globals to the secondary CM cm = &cm2; @@ -683,6 +703,7 @@ static stat_t _feedhold_with_actions() // Execute Case (5) // execute feedhold actions if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); +// cm->gm.linenum = 6060842; // ++++++++ Diagnostic bool flags[] = { 0,0,1,0,0,0 }; float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode cm_straight_traverse(target, flags, PROFILE_NORMAL); @@ -696,6 +717,7 @@ static stat_t _feedhold_with_actions() // Execute Case (5) // wait for hold actions to complete if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_PENDING) { + _hold_everything(0,0); //+++++ return (STAT_EAGAIN); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index b4518ec0..e93fd33a 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -48,6 +48,20 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf); static void _init_forward_diffs(float v_0, float v_1); +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +static void _hold_everything (uint32_t n1, uint32_t n2) // example of function +{ + if (cm->gm.linenum > 237) { + cm1.gm.linenum += 1; + } + +// if (n1 == n2) { +// cm1.gm.linenum = n1; +// } +} +#pragma GCC reset_options // DIAGNOSTIC +++++ + /**************************************************************************************** * mp_forward_plan() - plan commands and moves ahead of exec; call ramping for moves * @@ -267,6 +281,9 @@ stat_t mp_exec_move() if (bf->block_type == BLOCK_TYPE_ALINE) { // cycle auto-start for lines only // first-time operations + +// _hold_everything(0,0); //+++++ + if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_BACK_PLANNED) && (cm->motion_state == MOTION_RUN)) { // debug_trap("mp_exec_move() buffer is not prepped. Starvation"); // IMPORTANT: can't rpt_exception from here! @@ -304,9 +321,6 @@ stat_t mp_exec_move() if (bf->nx->buffer_state >= MP_BUFFER_BACK_PLANNED) { st_request_forward_plan(); } - - // Perform motion state transition. Also sets active model to RUNTIME -// if (cm->motion_state != MOTION_RUN) { cm_set_motion_state(MOTION_RUN); } } if (bf->bf_func == NULL) { return(cm_panic(STAT_INTERNAL_ERROR, "mp_exec_move()")); // never supposed to get here @@ -933,6 +947,7 @@ static stat_t _exec_aline_segment() } kn_inverse_kinematics(mr->gm.target, mr->target_steps); // now determine the target steps... for (uint8_t m=0; mtravel_steps[m] = mr->target_steps[m] - mr->position_steps[m]; travel_steps[m] = mr->target_steps[m] - mr->position_steps[m]; } @@ -943,6 +958,7 @@ static stat_t _exec_aline_segment() } // Call the stepper prep function +// ritorno(st_prep_line(mr->travel_steps, mr->following_error, mr->segment_time)); ritorno(st_prep_line(travel_steps, mr->following_error, mr->segment_time)); copy_vector(mr->position, mr->gm.target); // update position from target if (mr->segment_count == 0) { diff --git a/g2core/planner.h b/g2core/planner.h index d2006685..1d878aab 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -456,6 +456,7 @@ typedef struct mpPlannerRuntime { // persistent runtime variables float position[AXES]; // current move position float waypoint[SECTIONS][AXES]; // head/body/tail endpoints for correction +// float travel_steps[MOTORS]; // +++++ float target_steps[MOTORS]; // current MR target (absolute target as steps) float position_steps[MOTORS]; // current MR position (target from previous segment) float commanded_steps[MOTORS]; // will align with next encoder sample (target from 2nd previous segment) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 95cb0b1c..d4feb9e7 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -58,6 +58,16 @@ static stRunSingleton_t st_run; static void _load_move(void); +#pragma GCC push_options // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +static void _hold_everything (uint32_t n1) +{ + if (n1 > 2000000000) { // 2142329634 + cm2.gm.linenum = 1111; + } +} +#pragma GCC reset_options // DIAGNOSTIC +++++ + /**** Setup motate ****/ using namespace Motate; @@ -213,7 +223,6 @@ stat_t st_motor_power_callback() // called by controller bool have_actually_stopped = false; if ((!st_runtime_isbusy()) && (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) && -// (cm_get_cycle_state() == CYCLE_OFF) (cm_get_machine_state() != MACHINE_CYCLE)) { // if there are no moves to load... have_actually_stopped = true; } @@ -253,10 +262,6 @@ void dda_timer_type::interrupt() dda_timer.getInterruptCause(); // clear interrupt condition // clear all steps from the previous interrupt - // for (uint8_t motor=0; motorstepEnd(); - // } - // loop unrolled version (it's actually faster) motor_1.stepEnd(); motor_2.stepEnd(); #if MOTORS > 2 @@ -288,43 +293,43 @@ void dda_timer_type::interrupt() // } // process DDAs for each motor - if ((st_run.mot[MOTOR_1].substep_accumulator += st_run.mot[MOTOR_1].substep_increment) > 0) { - motor_1.stepStart(); // turn step bit on - st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps; - INCREMENT_ENCODER(MOTOR_1); - } - if ((st_run.mot[MOTOR_2].substep_accumulator += st_run.mot[MOTOR_2].substep_increment) > 0) { - motor_2.stepStart(); // turn step bit on - st_run.mot[MOTOR_2].substep_accumulator -= st_run.dda_ticks_X_substeps; - INCREMENT_ENCODER(MOTOR_2); - } + if ((st_run.mot[MOTOR_1].substep_accumulator += st_run.mot[MOTOR_1].substep_increment) > 0) { + motor_1.stepStart(); // turn step bit on + st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps; + INCREMENT_ENCODER(MOTOR_1); + } + if ((st_run.mot[MOTOR_2].substep_accumulator += st_run.mot[MOTOR_2].substep_increment) > 0) { + motor_2.stepStart(); // turn step bit on + st_run.mot[MOTOR_2].substep_accumulator -= st_run.dda_ticks_X_substeps; + INCREMENT_ENCODER(MOTOR_2); + } #if MOTORS > 2 - if ((st_run.mot[MOTOR_3].substep_accumulator += st_run.mot[MOTOR_3].substep_increment) > 0) { - motor_3.stepStart(); // turn step bit on - st_run.mot[MOTOR_3].substep_accumulator -= st_run.dda_ticks_X_substeps; - INCREMENT_ENCODER(MOTOR_3); - } + if ((st_run.mot[MOTOR_3].substep_accumulator += st_run.mot[MOTOR_3].substep_increment) > 0) { + motor_3.stepStart(); // turn step bit on + st_run.mot[MOTOR_3].substep_accumulator -= st_run.dda_ticks_X_substeps; + INCREMENT_ENCODER(MOTOR_3); + } #endif #if MOTORS > 3 - if ((st_run.mot[MOTOR_4].substep_accumulator += st_run.mot[MOTOR_4].substep_increment) > 0) { - motor_4.stepStart(); // turn step bit on - st_run.mot[MOTOR_4].substep_accumulator -= st_run.dda_ticks_X_substeps; - INCREMENT_ENCODER(MOTOR_4); - } + if ((st_run.mot[MOTOR_4].substep_accumulator += st_run.mot[MOTOR_4].substep_increment) > 0) { + motor_4.stepStart(); // turn step bit on + st_run.mot[MOTOR_4].substep_accumulator -= st_run.dda_ticks_X_substeps; + INCREMENT_ENCODER(MOTOR_4); + } #endif #if MOTORS > 4 - if ((st_run.mot[MOTOR_5].substep_accumulator += st_run.mot[MOTOR_5].substep_increment) > 0) { - motor_5.stepStart(); // turn step bit on - st_run.mot[MOTOR_5].substep_accumulator -= st_run.dda_ticks_X_substeps; - INCREMENT_ENCODER(MOTOR_5); - } + if ((st_run.mot[MOTOR_5].substep_accumulator += st_run.mot[MOTOR_5].substep_increment) > 0) { + motor_5.stepStart(); // turn step bit on + st_run.mot[MOTOR_5].substep_accumulator -= st_run.dda_ticks_X_substeps; + INCREMENT_ENCODER(MOTOR_5); + } #endif #if MOTORS > 5 - if ((st_run.mot[MOTOR_6].substep_accumulator += st_run.mot[MOTOR_6].substep_increment) > 0) { - motor_6.stepStart(); // turn step bit on - st_run.mot[MOTOR_6].substep_accumulator -= st_run.dda_ticks_X_substeps; - INCREMENT_ENCODER(MOTOR_6); - } + if ((st_run.mot[MOTOR_6].substep_accumulator += st_run.mot[MOTOR_6].substep_increment) > 0) { + motor_6.stepStart(); // turn step bit on + st_run.mot[MOTOR_6].substep_accumulator -= st_run.dda_ticks_X_substeps; + INCREMENT_ENCODER(MOTOR_6); + } #endif // Process end of segment. @@ -429,11 +434,6 @@ static void _load_move() // If there are no moves to load start motor power timeouts if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) { - // for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { - // Motors[motor]->motionStopped(); - // } - - // loop unrolled version motor_1.motionStopped(); // ...start motor power timeouts motor_2.motionStopped(); #if (MOTORS > 2) @@ -451,11 +451,12 @@ static void _load_move() return; } // if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) - // handle aline loads first (most common case) NB: there are no more lines, only alines + // handle aline loads first (most common case) if (st_pre.block_type == BLOCK_TYPE_ALINE) { //**** setup the new segment **** + debug_trap_if_true((st_run.dda_ticks_downcount != 0), "_load_move() downcount is not zero"); st_run.dda_ticks_downcount = st_pre.dda_ticks; st_run.dda_ticks_X_substeps = st_pre.dda_ticks_X_substeps; @@ -711,6 +712,8 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment // that results in long-term negative drift. (fabs/round order doesn't matter) st_pre.mot[motor].substep_increment = round(fabs(travel_steps[motor] * DDA_SUBSTEPS)); + + _hold_everything(st_pre.mot[motor].substep_increment); } st_pre.block_type = BLOCK_TYPE_ALINE; st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready diff --git a/g2core/util.h b/g2core/util.h index fe24feee..e692ad56 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -52,6 +52,12 @@ using Motate::SysTickTimer; #pragma GCC push_options // DIAGNOSTIC +++++ #pragma GCC optimize ("O0") // DIAGNOSTIC +++++ // insert function here +static void _hold_everything (uint32_t n1, uint32_t n2) // example of function +{ + if (n1 == n2) { + cm1.gm.linenum +=1; + } +} #pragma GCC reset_options // DIAGNOSTIC +++++ */ From 11d39c93b5ad193e2aebddad5652fc1558d22180 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 23 Apr 2017 08:30:26 -0400 Subject: [PATCH 246/283] Cleanup - interim commit --- g2core/alarm.cpp | 1 - g2core/canonical_machine.h | 2 -- g2core/cycle_feedhold.cpp | 62 +++++++++++++++++++++++++++----------- g2core/plan_exec.cpp | 16 ---------- g2core/planner.h | 1 - g2core/stepper.cpp | 12 -------- g2core/util.h | 4 +-- 7 files changed, 47 insertions(+), 51 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index 975a6e48..a87a2d15 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -196,7 +196,6 @@ stat_t cm_shutdown(const stat_t status, const char *msg) } cm_request_feedhold(FEEDHOLD_TYPE_SCRAM, FEEDHOLD_EXIT_SHUTDOWN); // fast stop and shutdown -//+++++ cm_halt_motion(); // halt motors (may have already been done from GPIO) // spindle_reset(); // stop spindle immediately and set speed to 0 RPM // coolant_reset(); // stop coolant immediately // temperature_reset(); // turn off heaters and fans diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 5aa0992f..beaf85a8 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -281,8 +281,6 @@ typedef struct cmMachine { // struct to manage canonical machin /**** Runtime variables (PRIVATE) ****/ - uint32_t test; //+++++ - // Global state variables and flags cmMachineState machine_state; // macs: machine/cycle/motion is the actual machine state diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 2f44894a..101f15cb 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -59,20 +59,6 @@ static stat_t _run_alarm(void); static stat_t _run_shutdown(void); static stat_t _run_interlock(void); -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ -static void _hold_everything (uint32_t n1, uint32_t n2) // example of function -{ - if (cm->gm.linenum > 200) { - cm1.gm.linenum += 1; - } - -// if (n1 == n2) { -// cm1.gm.linenum = n1; -// } -} -#pragma GCC reset_options // DIAGNOSTIC +++++ - /**************************************************************************************** * OPERATIONS AND ACTIONS * @@ -523,7 +509,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) { // Can only initiate a feedhold if you are in a machining cycle, running, and not already in a feedhold - // +++++ This needs to be extended to allow HOLDs to be requested when motion has stopped +++++ + // +++++ This needs to be extended to allow HOLDs to be requested when motion has stopped if ((cm1.hold_state == FEEDHOLD_OFF) && (cm1.machine_state == MACHINE_CYCLE) && (cm1.motion_state == MOTION_RUN)) { @@ -646,6 +632,47 @@ static void _feedhold_actions_done_callback(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } +static void _enter_p2() +{ + // copy the primary canonical machine to the secondary, + // fix the planner pointer, and reset the secondary planner + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // set parameters in cm, gm and gmx so you can actually use it + cm2.hold_state = FEEDHOLD_OFF; + cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + cm2.queue_flush_state = QUEUE_FLUSH_OFF; + cm2.gm.feed_rate = 0; + + // clear the target and set the positions to the current hold position + memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); + memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); + copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation + copy_vector(cm2.gmx.position, mr1.position); + copy_vector(mp2.position, mr1.position); + copy_vector(mr2.position, mr1.position); + + // copy encoder and error correction terms + copy_vector(mr2.target_steps, mr1.target_steps); + copy_vector(mr2.position_steps, mr1.position_steps); + copy_vector(mr2.commanded_steps, mr1.commanded_steps); + copy_vector(mr2.encoder_steps, mr1.encoder_steps); + copy_vector(mr2.following_error, mr1.following_error); + + // reassign the globals to the secondary CM + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer + mr = mp->mr; +} + +static void _exit_p2() +{ + +} + static stat_t _feedhold_with_actions() // Execute Case (5) { // if entered while OFF start a feedhold @@ -665,6 +692,8 @@ static stat_t _feedhold_with_actions() // Execute Case (5) if (cm1.hold_state == FEEDHOLD_MOTION_STOPPED) { cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state + _enter_p2(); +/* // copy the primary canonical machine to the secondary, // fix the planner pointer, and reset the secondary planner memcpy(&cm2, &cm1, sizeof(cmMachine_t)); @@ -697,13 +726,13 @@ static stat_t _feedhold_with_actions() // Execute Case (5) mp = (mpPlanner_t *)cm->mp; // mp is a void pointer mr = mp->mr; +*/ // set a return position cm_set_g30_position(); // execute feedhold actions if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift cm_set_distance_mode(INCREMENTAL_DISTANCE_MODE); -// cm->gm.linenum = 6060842; // ++++++++ Diagnostic bool flags[] = { 0,0,1,0,0,0 }; float target[] = { 0,0, _to_inches(cm->feedhold_z_lift), 0,0,0 }; // convert to inches if in inches mode cm_straight_traverse(target, flags, PROFILE_NORMAL); @@ -717,7 +746,6 @@ static stat_t _feedhold_with_actions() // Execute Case (5) // wait for hold actions to complete if (cm1.hold_state == FEEDHOLD_HOLD_ACTIONS_PENDING) { - _hold_everything(0,0); //+++++ return (STAT_EAGAIN); } diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index e93fd33a..b4a8effa 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -48,20 +48,6 @@ static stat_t _exec_aline_feedhold(mpBuf_t *bf); static void _init_forward_diffs(float v_0, float v_1); -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ -static void _hold_everything (uint32_t n1, uint32_t n2) // example of function -{ - if (cm->gm.linenum > 237) { - cm1.gm.linenum += 1; - } - -// if (n1 == n2) { -// cm1.gm.linenum = n1; -// } -} -#pragma GCC reset_options // DIAGNOSTIC +++++ - /**************************************************************************************** * mp_forward_plan() - plan commands and moves ahead of exec; call ramping for moves * @@ -282,8 +268,6 @@ stat_t mp_exec_move() if (bf->block_type == BLOCK_TYPE_ALINE) { // cycle auto-start for lines only // first-time operations -// _hold_everything(0,0); //+++++ - if (bf->buffer_state != MP_BUFFER_RUNNING) { if ((bf->buffer_state < MP_BUFFER_BACK_PLANNED) && (cm->motion_state == MOTION_RUN)) { // debug_trap("mp_exec_move() buffer is not prepped. Starvation"); // IMPORTANT: can't rpt_exception from here! diff --git a/g2core/planner.h b/g2core/planner.h index 1d878aab..d2006685 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -456,7 +456,6 @@ typedef struct mpPlannerRuntime { // persistent runtime variables float position[AXES]; // current move position float waypoint[SECTIONS][AXES]; // head/body/tail endpoints for correction -// float travel_steps[MOTORS]; // +++++ float target_steps[MOTORS]; // current MR target (absolute target as steps) float position_steps[MOTORS]; // current MR position (target from previous segment) float commanded_steps[MOTORS]; // will align with next encoder sample (target from 2nd previous segment) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index d4feb9e7..f33387b6 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -58,16 +58,6 @@ static stRunSingleton_t st_run; static void _load_move(void); -#pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ -static void _hold_everything (uint32_t n1) -{ - if (n1 > 2000000000) { // 2142329634 - cm2.gm.linenum = 1111; - } -} -#pragma GCC reset_options // DIAGNOSTIC +++++ - /**** Setup motate ****/ using namespace Motate; @@ -712,8 +702,6 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment // that results in long-term negative drift. (fabs/round order doesn't matter) st_pre.mot[motor].substep_increment = round(fabs(travel_steps[motor] * DDA_SUBSTEPS)); - - _hold_everything(st_pre.mot[motor].substep_increment); } st_pre.block_type = BLOCK_TYPE_ALINE; st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // signal that prep buffer is ready diff --git a/g2core/util.h b/g2core/util.h index e692ad56..b0feef23 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -50,7 +50,7 @@ using Motate::SysTickTimer; /****** Global Scope Variables and Functions ******/ /* #pragma GCC push_options // DIAGNOSTIC +++++ -#pragma GCC optimize ("O0") // DIAGNOSTIC +++++ +#pragma GCC optimize ("O0") // insert function here static void _hold_everything (uint32_t n1, uint32_t n2) // example of function { @@ -58,7 +58,7 @@ static void _hold_everything (uint32_t n1, uint32_t n2) // example of function cm1.gm.linenum +=1; } } -#pragma GCC reset_options // DIAGNOSTIC +++++ +#pragma GCC reset_options */ //*** vector utilities *** From 27e65a4041567fd54da756ed50e407fae82e306e Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 23 Apr 2017 09:04:48 -0400 Subject: [PATCH 247/283] Isolating and testing _enter_p2() --- g2core/cycle_feedhold.cpp | 62 ++++++++++----------------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 101f15cb..ebfc21da 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -632,6 +632,8 @@ static void _feedhold_actions_done_callback(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } +// Encapsulate entering p2, as this is tricky and must be done exactly right + static void _enter_p2() { // copy the primary canonical machine to the secondary, @@ -653,14 +655,14 @@ static void _enter_p2() copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation copy_vector(cm2.gmx.position, mr1.position); copy_vector(mp2.position, mr1.position); + + // copy MR position and encoder terms - needed for following error correction state + // can't just do a memcpy as some things need to be copied and other left alone copy_vector(mr2.position, mr1.position); - - // copy encoder and error correction terms copy_vector(mr2.target_steps, mr1.target_steps); copy_vector(mr2.position_steps, mr1.position_steps); copy_vector(mr2.commanded_steps, mr1.commanded_steps); - copy_vector(mr2.encoder_steps, mr1.encoder_steps); - copy_vector(mr2.following_error, mr1.following_error); + copy_vector(mr2.encoder_steps, mr1.encoder_steps); // NB: following error is re-computed in p2 // reassign the globals to the secondary CM cm = &cm2; @@ -668,9 +670,13 @@ static void _enter_p2() mr = mp->mr; } +// Encapsulate exiting p2 and re-entering p1, as this is tricky and must be done exactly right + static void _exit_p2() { - + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; } static stat_t _feedhold_with_actions() // Execute Case (5) @@ -690,45 +696,9 @@ static stat_t _feedhold_with_actions() // Execute Case (5) // Code to run once motion has stopped if (cm1.hold_state == FEEDHOLD_MOTION_STOPPED) { - cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state - - _enter_p2(); -/* - // copy the primary canonical machine to the secondary, - // fix the planner pointer, and reset the secondary planner - memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // set parameters in cm, gm and gmx so you can actually use it - cm2.hold_state = FEEDHOLD_OFF; - cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - cm2.queue_flush_state = QUEUE_FLUSH_OFF; - cm2.gm.feed_rate = 0; - - // clear the target and set the positions to the current hold position - memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); - memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); - copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation - copy_vector(cm2.gmx.position, mr1.position); - copy_vector(mp2.position, mr1.position); - copy_vector(mr2.position, mr1.position); - - copy_vector(mr2.target_steps, mr1.target_steps); - copy_vector(mr2.position_steps, mr1.position_steps); - copy_vector(mr2.commanded_steps, mr1.commanded_steps); - copy_vector(mr2.encoder_steps, mr1.encoder_steps); - copy_vector(mr2.following_error, mr1.following_error); - - // reassign the globals to the secondary CM - cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // mp is a void pointer - mr = mp->mr; - -*/ - // set a return position - cm_set_g30_position(); + cm->hold_state = FEEDHOLD_HOLD_ACTIONS_PENDING; // next state + _enter_p2(); // enter p2 correctly + cm_set_g30_position(); // set position to return to on exit // execute feedhold actions if (fp_NOT_ZERO(cm->feedhold_z_lift)) { // optional Z lift @@ -808,9 +778,7 @@ static stat_t _feedhold_restart_with_actions() // Execute Cases (6) and (7) // finalize feedhold exit if (cm1.hold_state == FEEDHOLD_EXIT_ACTIONS_COMPLETE) { - cm = &cm1; // return to primary planner (p1) - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; + _exit_p2(); // re-enter p1 correctly return (STAT_OK); } From 57873bbee62f3d0f1bc9b519249865b61f8e1877 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 23 Apr 2017 10:24:37 -0400 Subject: [PATCH 248/283] Testing and cleanup --- g2core/cycle_feedhold.cpp | 30 ++++++++++++++++-------------- g2core/stepper.cpp | 12 +++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index ebfc21da..d45b53e3 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -632,46 +632,48 @@ static void _feedhold_actions_done_callback(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -// Encapsulate entering p2, as this is tricky and must be done exactly right +/**************************************************************************************** + * _enter_p2() - enter p2 planner with proper state transfer from p1 + * _exit_p2() - reenter p1 planner with proper state transfer from p2 + * + * Encapsulate entering and exiting p2, as this is tricky and must be done exactly right + */ static void _enter_p2() { - // copy the primary canonical machine to the secondary, - // fix the planner pointer, and reset the secondary planner + // Copy the primary canonical machine to the secondary. Here it's OK to co a memcpy. + // Set parameters in cm, gm and gmx so you can actually use it memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // set parameters in cm, gm and gmx so you can actually use it cm2.hold_state = FEEDHOLD_OFF; cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; cm2.queue_flush_state = QUEUE_FLUSH_OFF; cm2.gm.feed_rate = 0; - // clear the target and set the positions to the current hold position + // Set mp planner to p2 and reset it + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // Clear the target and set the positions to the current hold position memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation copy_vector(cm2.gmx.position, mr1.position); copy_vector(mp2.position, mr1.position); - - // copy MR position and encoder terms - needed for following error correction state - // can't just do a memcpy as some things need to be copied and other left alone copy_vector(mr2.position, mr1.position); + + // Copy MR position and encoder terms - needed for following error correction state copy_vector(mr2.target_steps, mr1.target_steps); copy_vector(mr2.position_steps, mr1.position_steps); copy_vector(mr2.commanded_steps, mr1.commanded_steps); copy_vector(mr2.encoder_steps, mr1.encoder_steps); // NB: following error is re-computed in p2 - // reassign the globals to the secondary CM + // Reassign the globals to the secondary CM cm = &cm2; mp = (mpPlanner_t *)cm->mp; // mp is a void pointer mr = mp->mr; } -// Encapsulate exiting p2 and re-entering p1, as this is tricky and must be done exactly right - static void _exit_p2() { cm = &cm1; // return to primary planner (p1) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index f33387b6..28430c3f 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -634,15 +634,12 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment return (cm_panic(STAT_PREP_LINE_MOVE_TIME_IS_INFINITE, "st_prep_line()")); } else if (isnan(segment_time)) { // never supposed to happen return (cm_panic(STAT_PREP_LINE_MOVE_TIME_IS_NAN, "st_prep_line()")); -// } else if (segment_time < EPSILON) { -// return (STAT_MINIMUM_TIME_MOVE); } // setup segment parameters // - dda_ticks is the integer number of DDA clock ticks needed to play out the segment // - ticks_X_substeps is the maximum depth of the DDA accumulator (as a negative number) - //st_pre.dda_period = _f_to_period(FREQUENCY_DDA); // FYI: this is a constant - st_pre.dda_ticks = (int32_t)(segment_time * 60 * FREQUENCY_DDA);// NB: converts minutes to seconds + st_pre.dda_ticks = (int32_t)(segment_time * 60 * FREQUENCY_DDA); // NB: converts minutes to seconds st_pre.dda_ticks_X_substeps = st_pre.dda_ticks * DDA_SUBSTEPS; // setup motor parameters @@ -668,11 +665,11 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment } // Detect segment time changes and setup the accumulator correction factor and flag. - // Putting this here computes the correct factor even if the motor was dormant for some - // number of previous moves. Correction is computed based on the last segment time actually used. + // Putting this here computes the correct factor even if the motor was dormant for some number + // of previous moves. Correction is computed based on the last segment time actually used. if (fabs(segment_time - st_pre.mot[motor].prev_segment_time) > 0.0000001) { // highly tuned FP != compare - if (fp_NOT_ZERO(st_pre.mot[motor].prev_segment_time)) { // special case to skip first move + if (fp_NOT_ZERO(st_pre.mot[motor].prev_segment_time)) { // special case to skip first move st_pre.mot[motor].accumulator_correction_flag = true; st_pre.mot[motor].accumulator_correction = segment_time / st_pre.mot[motor].prev_segment_time; } @@ -681,6 +678,7 @@ stat_t st_prep_line(float travel_steps[], float following_error[], float segment // 'Nudge' correction strategy. Inject a single, scaled correction value then hold off // NOTE: This clause can be commented out to test for numerical accuracy and accumulating errors + if ((--st_pre.mot[motor].correction_holdoff < 0) && (fabs(following_error[motor]) > STEP_CORRECTION_THRESHOLD)) { From 86194a410cbd4d9695c3ab291942ef4065e3734a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 26 Apr 2017 06:41:38 -0400 Subject: [PATCH 249/283] Added test for extremely small step increment in _exec_aline_segment(); Left diagnostic trap in for now. --- g2core/cycle_feedhold.cpp | 103 +++++++++++++++++++------------------- g2core/plan_exec.cpp | 20 +++++++- g2core/stepper.cpp | 19 +++++++ g2core/util.h | 3 +- 4 files changed, 91 insertions(+), 54 deletions(-) diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index d45b53e3..7f8f73a6 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -559,6 +559,56 @@ static void _start_p2_feedhold() } */ +/* + * _enter_p2() - enter p2 planner with proper state transfer from p1 + * _exit_p2() - reenter p1 planner with proper state transfer from p2 + * + * Encapsulate entering and exiting p2, as this is tricky and must be done exactly right + */ + +static void _enter_p2() +{ + // Copy the primary canonical machine to the secondary. Here it's OK to co a memcpy. + // Set parameters in cm, gm and gmx so you can actually use it + memcpy(&cm2, &cm1, sizeof(cmMachine_t)); + cm2.hold_state = FEEDHOLD_OFF; + cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; + cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; + cm2.queue_flush_state = QUEUE_FLUSH_OFF; + cm2.gm.feed_rate = 0; + + // Set mp planner to p2 and reset it + cm2.mp = &mp2; + planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer + + // Clear the target and set the positions to the current hold position + memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); + memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); + memset(&(cm2.gm.target_comp), 0, sizeof(cm2.gm.target_comp)); // zero Kahan compensation + + copy_vector(cm2.gmx.position, mr1.position); + copy_vector(mp2.position, mr1.position); + copy_vector(mr2.position, mr1.position); + + // Copy MR position and encoder terms - needed for following error correction state + copy_vector(mr2.target_steps, mr1.target_steps); + copy_vector(mr2.position_steps, mr1.position_steps); + copy_vector(mr2.commanded_steps, mr1.commanded_steps); + copy_vector(mr2.encoder_steps, mr1.encoder_steps); // NB: following error is re-computed in p2 + + // Reassign the globals to the secondary CM + cm = &cm2; + mp = (mpPlanner_t *)cm->mp; // mp is a void pointer + mr = mp->mr; +} + +static void _exit_p2() +{ + cm = &cm1; // return to primary planner (p1) + mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer + mr = mp->mr; +} + static void _check_motion_stopped() { if (mp_runtime_is_idle()) { // wait for steppers to actually finish @@ -606,11 +656,11 @@ static stat_t _feedhold_no_actions() cm1.hold_type = FEEDHOLD_TYPE_HOLD; // cm1.hold_exit = FEEDHOLD_EXIT_STOP; // default exit for NO_ACTIONS is STOP... - if (cm1.motion_state == MOTION_STOP) { // if motion has already stopped declare that you are in a feedhold + if (cm1.motion_state == MOTION_STOP) { // if motion has already stopped declare that you are in a feedhold _check_motion_stopped(); cm1.hold_state = FEEDHOLD_HOLD; } else { - cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function + cm1.hold_state = FEEDHOLD_SYNC; // ... STOP can be overridden by setting hold_exit after this function return (STAT_EAGAIN); } } @@ -632,55 +682,6 @@ static void _feedhold_actions_done_callback(float* vect, bool* flag) sr_request_status_report(SR_REQUEST_IMMEDIATE); } -/**************************************************************************************** - * _enter_p2() - enter p2 planner with proper state transfer from p1 - * _exit_p2() - reenter p1 planner with proper state transfer from p2 - * - * Encapsulate entering and exiting p2, as this is tricky and must be done exactly right - */ - -static void _enter_p2() -{ - // Copy the primary canonical machine to the secondary. Here it's OK to co a memcpy. - // Set parameters in cm, gm and gmx so you can actually use it - memcpy(&cm2, &cm1, sizeof(cmMachine_t)); - cm2.hold_state = FEEDHOLD_OFF; - cm2.gm.motion_mode = MOTION_MODE_CANCEL_MOTION_MODE; - cm2.gm.absolute_override = ABSOLUTE_OVERRIDE_OFF; - cm2.queue_flush_state = QUEUE_FLUSH_OFF; - cm2.gm.feed_rate = 0; - - // Set mp planner to p2 and reset it - cm2.mp = &mp2; - planner_reset((mpPlanner_t *)cm2.mp); // mp is a void pointer - - // Clear the target and set the positions to the current hold position - memset(&(cm2.gm.target), 0, sizeof(cm2.gm.target)); - memset(&(cm2.return_flags), 0, sizeof(cm2.return_flags)); - copy_vector(cm2.gm.target_comp, cm1.gm.target_comp); // preserve original Kahan compensation - copy_vector(cm2.gmx.position, mr1.position); - copy_vector(mp2.position, mr1.position); - copy_vector(mr2.position, mr1.position); - - // Copy MR position and encoder terms - needed for following error correction state - copy_vector(mr2.target_steps, mr1.target_steps); - copy_vector(mr2.position_steps, mr1.position_steps); - copy_vector(mr2.commanded_steps, mr1.commanded_steps); - copy_vector(mr2.encoder_steps, mr1.encoder_steps); // NB: following error is re-computed in p2 - - // Reassign the globals to the secondary CM - cm = &cm2; - mp = (mpPlanner_t *)cm->mp; // mp is a void pointer - mr = mp->mr; -} - -static void _exit_p2() -{ - cm = &cm1; // return to primary planner (p1) - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; -} - static stat_t _feedhold_with_actions() // Execute Case (5) { // if entered while OFF start a feedhold diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index b4a8effa..d2b4b1f6 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -892,6 +892,18 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) * -100 -90 -10 encoder is 10 steps behind commanded steps */ +//+++++ DIAGNOSTIC +++++ +#pragma GCC push_options +#pragma GCC optimize ("O0") +// insert function here +static void _hold_everything (int32_t linenum, uint32_t segments) +{ + if ((mr2.gm.linenum == linenum) && (mr2.segment_count == segments)) { + cm1.gm.linenum +=1; + } +} +#pragma GCC reset_options + static stat_t _exec_aline_segment() { float travel_steps[MOTORS]; @@ -930,9 +942,14 @@ static stat_t _exec_aline_segment() mr->following_error[m] = mr->encoder_steps[m] - mr->commanded_steps[m]; } kn_inverse_kinematics(mr->gm.target, mr->target_steps); // now determine the target steps... + + _hold_everything(159, 2); //+++++ + for (uint8_t m=0; mtravel_steps[m] = mr->target_steps[m] - mr->position_steps[m]; travel_steps[m] = mr->target_steps[m] - mr->position_steps[m]; + if (fabs(travel_steps[m]) < 0.01) { // truncate very small moves to deal with rounding erors + travel_steps[m] = 0; + } } // Update the mb->run_time_remaining -- we know it's missing the current segment's time before it's loaded, that's ok. @@ -942,7 +959,6 @@ static stat_t _exec_aline_segment() } // Call the stepper prep function -// ritorno(st_prep_line(mr->travel_steps, mr->following_error, mr->segment_time)); ritorno(st_prep_line(travel_steps, mr->following_error, mr->segment_time)); copy_vector(mr->position, mr->gm.target); // update position from target if (mr->segment_count == 0) { diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 28430c3f..eb7d572c 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -78,6 +78,25 @@ Motate::SysTickEvent dwell_systick_event {[&] { } }, nullptr}; +/* Note on the above: +It's a lambda function creating a closure function. +The full implementation that uses it is small and may help: +https://github.com/synthetos/Motate/blob/41e5b92a98de4b268d1804bf6eadf3333298fc75/MotateProject/motate/Atmel_sam_common/SamTimers.h#L1147-L1218 +It's just like a function, and is used as a function pointer. + +But the closure part means that whatever variables that were in scope where the +[&](parameters){code} is will be captured by the compiler as references in the generated +function and used wherever the function gets called. In this particular use, there isn't +anything that wouldn't be available anywhere in that file, but they're not being called +from that file. They're being called by the systick interrupt which is over in SamTmers.cpp +So this saves a bunch of work exposing bits that the systick would need to call and encapsulates it. +And there's almost no runtime overhead. Just a check for a valid function pointer and then a call of it. +I'd like to get rid of that check but it's more work than its worth. + +See here for some good info on lambda functions in C++ +http://www.cprogramming.com/c++11/c++11-lambda-closures.html +http://en.cppreference.com/w/cpp/language/lambda +*/ /************************************************************************************ **** CODE ************************************************************************** diff --git a/g2core/util.h b/g2core/util.h index b0feef23..e531b272 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -49,7 +49,8 @@ using Motate::SysTickTimer; /****** Global Scope Variables and Functions ******/ /* -#pragma GCC push_options // DIAGNOSTIC +++++ +// +++++ DIAGNOSTIC +++++ +#pragma GCC push_options #pragma GCC optimize ("O0") // insert function here static void _hold_everything (uint32_t n1, uint32_t n2) // example of function From a24629b2cc82fc4f1543eab2d06c074799d9820f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 26 Apr 2017 06:45:52 -0400 Subject: [PATCH 250/283] Added explanatory comment and removed diagnostic --- g2core/plan_exec.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index d2b4b1f6..73bb0899 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -892,18 +892,6 @@ static stat_t _exec_aline_tail(mpBuf_t *bf) * -100 -90 -10 encoder is 10 steps behind commanded steps */ -//+++++ DIAGNOSTIC +++++ -#pragma GCC push_options -#pragma GCC optimize ("O0") -// insert function here -static void _hold_everything (int32_t linenum, uint32_t segments) -{ - if ((mr2.gm.linenum == linenum) && (mr2.segment_count == segments)) { - cm1.gm.linenum +=1; - } -} -#pragma GCC reset_options - static stat_t _exec_aline_segment() { float travel_steps[MOTORS]; @@ -932,6 +920,11 @@ static stat_t _exec_aline_segment() // Convert target position to steps // Bucket-brigade the old target down the chain before getting the new target from kinematics // + // Very small travels of less than 0.01 step are truncated to zero. This is to correct a condition + // where a rounding error in kinematics could reverse the direction of a move in the extreme head or tail. + // Truncating the move contributes to positional error, but this is corrected by encoder feedback should + // it ever accumulate to more than one step. + // // NB: The direct manipulation of steps to compute travel_steps only works for Cartesian kinematics. // Other kinematics may require transforming travel distance as opposed to simply subtracting steps. @@ -943,11 +936,9 @@ static stat_t _exec_aline_segment() } kn_inverse_kinematics(mr->gm.target, mr->target_steps); // now determine the target steps... - _hold_everything(159, 2); //+++++ - for (uint8_t m=0; mtarget_steps[m] - mr->position_steps[m]; - if (fabs(travel_steps[m]) < 0.01) { // truncate very small moves to deal with rounding erors + if (fabs(travel_steps[m]) < 0.01) { // truncate very small moves to deal with rounding errors travel_steps[m] = 0; } } From 6d5cdf219eb8b493918f2352334fce8aa46879d9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 30 Apr 2017 11:11:58 -0400 Subject: [PATCH 251/283] Fixed arc feedhold error; fixed a bug in G28/G30 return when converting units for rotary axes --- g2core/canonical_machine.cpp | 2 +- g2core/cycle_feedhold.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 0345163a..aad4f8a7 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1183,7 +1183,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm copy_vector(target, stored_position); if (cm->gm.units_mode == INCHES) { - for (uint8_t i=0; imp; // mp is a void pointer - mr = mp->mr; + mp = (mpPlanner_t *)cm2.mp; // mp is a void pointer + mr = mp2.mr; } static void _exit_p2() { cm = &cm1; // return to primary planner (p1) - mp = (mpPlanner_t *)cm->mp; // cm->mp is a void pointer - mr = mp->mr; + mp = (mpPlanner_t *)cm1.mp; // cm->mp is a void pointer + mr = mp1.mr; } static void _check_motion_stopped() From 4608936af1f0ba5525378f1f8c5f189136393bdc Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 4 May 2017 14:31:13 -0400 Subject: [PATCH 252/283] Bumped axes for g2v9 board to 9; corrected error 230 --- g2core/board/G2v9/hardware.h | 2 +- g2core/error.h | 2 +- g2core/g2core.cppproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index ccea0e6c..e2038126 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -44,7 +44,7 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 4 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (index starts at 1) diff --git a/g2core/error.h b/g2core/error.h index a56714e1..2bc5dca8 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -336,7 +336,7 @@ char *get_status_message(stat_t status); #define STAT_SOFT_LIMIT_EXCEEDED_AMAX 228 // soft limit error - A maximum #define STAT_SOFT_LIMIT_EXCEEDED_BMIN 229 // soft limit error - B minimum -#define STAT_SOFT_LIMIT_EXCEEDED_BMAX 220 // soft limit error - B maximum +#define STAT_SOFT_LIMIT_EXCEEDED_BMAX 230 // soft limit error - B maximum #define STAT_SOFT_LIMIT_EXCEEDED_CMIN 231 // soft limit error - C minimum #define STAT_SOFT_LIMIT_EXCEEDED_CMAX 232 // soft limit error - C maximum #define STAT_SOFT_LIMIT_EXCEEDED_ARC 233 // soft limit err on arc diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b8ee2360..876b4307 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800019454 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800036434 + J41800019454 0x284E0A60 10000000 From 6a45a43534779e5a36a475b75d8a3e3b38274e05 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 4 May 2017 15:31:27 -0400 Subject: [PATCH 253/283] Moved UVW to middle of enumeration (3,4,5); Increased size of configurations for axis, coordinate, offsets, tool tables and others for 9 axes; Enabled UVW in Gcode parser --- g2core/config_app.cpp | 186 +++++++++++ g2core/g2core.h | 8 +- g2core/gcode_parser.cpp | 6 +- g2core/settings/settings_default.h | 465 +++++++++++++++++++++++++++ g2core/settings/settings_makeblock.h | 42 +++ 5 files changed, 700 insertions(+), 7 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index f2a3a046..8e5f0f50 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -140,6 +140,9 @@ const cfgItem_t cfgArray[] = { { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // X machine position { "mpo","mpoy",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // Y machine position { "mpo","mpoz",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // Z machine position + { "mpo","mpou",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // U machine position + { "mpo","mpov",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // V machine position + { "mpo","mpow",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // W machine position { "mpo","mpoa",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // A machine position { "mpo","mpob",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // B machine position { "mpo","mpoc",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // C machine position @@ -147,6 +150,9 @@ const cfgItem_t cfgArray[] = { { "pos","posx",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // X work position { "pos","posy",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // Y work position { "pos","posz",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // Z work position + { "pos","posu",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // U work position + { "pos","posv",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // V work position + { "pos","posw",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // W work position { "pos","posa",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // A work position { "pos","posb",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // B work position { "pos","posc",_f0, 5, cm_print_pos, cm_get_pos, set_ro, nullptr, 0 }, // C work position @@ -154,6 +160,9 @@ const cfgItem_t cfgArray[] = { { "ofs","ofsx",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // X work offset { "ofs","ofsy",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // Y work offset { "ofs","ofsz",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // Z work offset + { "ofs","ofsu",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // U work offset + { "ofs","ofsv",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // V work offset + { "ofs","ofsw",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // W work offset { "ofs","ofsa",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // A work offset { "ofs","ofsb",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // B work offset { "ofs","ofsc",_f0, 5, cm_print_ofs, cm_get_ofs, set_ro, nullptr, 0 }, // C work offset @@ -162,6 +171,9 @@ const cfgItem_t cfgArray[] = { { "hom","homx",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // X homed - Homing status group { "hom","homy",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // Y homed { "hom","homz",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // Z homed + { "hom","homu",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // U homed + { "hom","homv",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // V homed + { "hom","homw",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // W homed { "hom","homa",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // A homed { "hom","homb",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // B homed { "hom","homc",_i0, 0, cm_print_hom, cm_get_hom, set_ro, nullptr, 0 }, // C homed @@ -170,6 +182,9 @@ const cfgItem_t cfgArray[] = { { "prb","prbx",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // X probe results { "prb","prby",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // Y probe results { "prb","prbz",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // Z probe results + { "prb","prbu",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // U probe results + { "prb","prbv",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // V probe results + { "prb","prbw",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // W probe results { "prb","prba",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // A probe results { "prb","prbb",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // B probe results { "prb","prbc",_f0, 5, tx_print_nul, cm_get_prb, set_ro, nullptr, 0 }, // C probe results @@ -177,6 +192,9 @@ const cfgItem_t cfgArray[] = { { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in X axis { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in Y axis { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in Z axis + { "jog","jogu",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in U axis + { "jog","jogv",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in V axis + { "jog","jogw",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in W axis { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in A axis { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in B axis { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jog, nullptr, 0}, // jog in C axis @@ -311,6 +329,48 @@ const cfgItem_t cfgArray[] = { { "z","zlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, Z_LATCH_BACKOFF }, { "z","zzb",_fipc, 5, cm_print_zb, cm_get_lb, cm_set_zb, nullptr, Z_ZERO_BACKOFF }, + { "u","uam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, U_AXIS_MODE }, + { "u","uvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, U_VELOCITY_MAX }, + { "u","ufr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, U_FEEDRATE_MAX }, + { "u","utn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, U_TRAVEL_MIN }, + { "u","utm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, U_TRAVEL_MAX }, + { "u","ujm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, U_JERK_MAX }, + { "u","ujh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, U_JERK_HIGH_SPEED }, + { "u","uhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, U_HOMING_INPUT }, + { "u","uhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, U_HOMING_DIRECTION }, + { "u","usv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, U_SEARCH_VELOCITY }, + { "u","ulv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, U_LATCH_VELOCITY }, + { "u","ulb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, U_LATCH_BACKOFF }, + { "u","uzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, U_ZERO_BACKOFF }, + + { "v","vam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, V_AXIS_MODE }, + { "v","vvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, V_VELOCITY_MAX }, + { "v","vfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, V_FEEDRATE_MAX }, + { "v","vtn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, V_TRAVEL_MIN }, + { "v","vtm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, V_TRAVEL_MAX }, + { "v","vjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, V_JERK_MAX }, + { "v","vjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, V_JERK_HIGH_SPEED }, + { "v","vhi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, V_HOMING_INPUT }, + { "v","vhd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, V_HOMING_DIRECTION }, + { "v","vsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, V_SEARCH_VELOCITY }, + { "v","vlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, V_LATCH_VELOCITY }, + { "v","vlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, V_LATCH_BACKOFF }, + { "v","vzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, V_ZERO_BACKOFF }, + + { "w","wam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, W_AXIS_MODE }, + { "w","wvm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, W_VELOCITY_MAX }, + { "w","wfr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, W_FEEDRATE_MAX }, + { "w","wtn",_fipc, 5, cm_print_tn, cm_get_tn, cm_set_tn, nullptr, W_TRAVEL_MIN }, + { "w","wtm",_fipc, 5, cm_print_tm, cm_get_tm, cm_set_tm, nullptr, W_TRAVEL_MAX }, + { "w","wjm",_fipc, 0, cm_print_jm, cm_get_jm, cm_set_jm, nullptr, W_JERK_MAX }, + { "w","wjh",_fipc, 0, cm_print_jh, cm_get_jh, cm_set_jh, nullptr, W_JERK_HIGH_SPEED }, + { "w","whi",_iip, 0, cm_print_hi, cm_get_hi, cm_set_hi, nullptr, W_HOMING_INPUT }, + { "w","whd",_iip, 0, cm_print_hd, cm_get_hd, cm_set_hd, nullptr, W_HOMING_DIRECTION }, + { "w","wsv",_fipc, 0, cm_print_sv, cm_get_sv, cm_set_sv, nullptr, W_SEARCH_VELOCITY }, + { "w","wlv",_fipc, 2, cm_print_lv, cm_get_lv, cm_set_lv, nullptr, W_LATCH_VELOCITY }, + { "w","wlb",_fipc, 5, cm_print_lb, cm_get_lb, cm_set_lb, nullptr, W_LATCH_BACKOFF }, + { "w","wzb",_fipc, 5, cm_print_zb, cm_get_zb, cm_set_zb, nullptr, W_ZERO_BACKOFF }, + { "a","aam",_iip, 0, cm_print_am, cm_get_am, cm_set_am, nullptr, A_AXIS_MODE }, { "a","avm",_fipc, 0, cm_print_vm, cm_get_vm, cm_set_vm, nullptr, A_VELOCITY_MAX }, { "a","afr",_fipc, 0, cm_print_fr, cm_get_fr, cm_set_fr, nullptr, A_FEEDRATE_MAX }, @@ -537,6 +597,9 @@ const cfgItem_t cfgArray[] = { { "g54","g54x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_X_OFFSET }, { "g54","g54y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_Y_OFFSET }, { "g54","g54z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_Z_OFFSET }, + { "g54","g54u",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_U_OFFSET }, + { "g54","g54v",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_V_OFFSET }, + { "g54","g54w",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_W_OFFSET }, { "g54","g54a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_A_OFFSET }, { "g54","g54b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_B_OFFSET }, { "g54","g54c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G54_C_OFFSET }, @@ -544,6 +607,9 @@ const cfgItem_t cfgArray[] = { { "g55","g55x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_X_OFFSET }, { "g55","g55y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_Y_OFFSET }, { "g55","g55z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_Z_OFFSET }, + { "g55","g55u",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_U_OFFSET }, + { "g55","g55v",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_V_OFFSET }, + { "g55","g55w",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_W_OFFSET }, { "g55","g55a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_A_OFFSET }, { "g55","g55b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_B_OFFSET }, { "g55","g55c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G55_C_OFFSET }, @@ -551,6 +617,9 @@ const cfgItem_t cfgArray[] = { { "g56","g56x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_X_OFFSET }, { "g56","g56y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_Y_OFFSET }, { "g56","g56z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_Z_OFFSET }, + { "g56","g56u",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_U_OFFSET }, + { "g56","g56v",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_V_OFFSET }, + { "g56","g56w",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_W_OFFSET }, { "g56","g56a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_A_OFFSET }, { "g56","g56b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_B_OFFSET }, { "g56","g56c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G56_C_OFFSET }, @@ -558,6 +627,9 @@ const cfgItem_t cfgArray[] = { { "g57","g57x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_X_OFFSET }, { "g57","g57y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_Y_OFFSET }, { "g57","g57z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_Z_OFFSET }, + { "g57","g57u",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_U_OFFSET }, + { "g57","g57v",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_V_OFFSET }, + { "g57","g57w",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_W_OFFSET }, { "g57","g57a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_A_OFFSET }, { "g57","g57b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_B_OFFSET }, { "g57","g57c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G57_C_OFFSET }, @@ -565,6 +637,9 @@ const cfgItem_t cfgArray[] = { { "g58","g58x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_X_OFFSET }, { "g58","g58y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_Y_OFFSET }, { "g58","g58z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_Z_OFFSET }, + { "g58","g58u",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_U_OFFSET }, + { "g58","g58v",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_V_OFFSET }, + { "g58","g58w",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_W_OFFSET }, { "g58","g58a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_A_OFFSET }, { "g58","g58b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_B_OFFSET }, { "g58","g58c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G58_C_OFFSET }, @@ -572,6 +647,9 @@ const cfgItem_t cfgArray[] = { { "g59","g59x",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_X_OFFSET }, { "g59","g59y",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_Y_OFFSET }, { "g59","g59z",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_Z_OFFSET }, + { "g59","g59u",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_U_OFFSET }, + { "g59","g59v",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_V_OFFSET }, + { "g59","g59w",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_W_OFFSET }, { "g59","g59a",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_A_OFFSET }, { "g59","g59b",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_B_OFFSET }, { "g59","g59c",_fipc, 5, cm_print_cofs, cm_get_coord, cm_set_coord, nullptr, G59_C_OFFSET }, @@ -579,6 +657,9 @@ const cfgItem_t cfgArray[] = { { "g92","g92x",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 },// G92 handled differently { "g92","g92y",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, { "g92","g92z",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92u",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92v",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, + { "g92","g92w",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, { "g92","g92a",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, { "g92","g92b",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, { "g92","g92c",_fic, 5, cm_print_cofs, cm_get_g92, set_ro, nullptr, 0 }, @@ -587,6 +668,9 @@ const cfgItem_t cfgArray[] = { { "g28","g28x",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 },// g28 handled differently { "g28","g28y",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, { "g28","g28z",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28u",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28v",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, + { "g28","g28w",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, { "g28","g28a",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, { "g28","g28b",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, { "g28","g28c",_fic, 5, cm_print_cpos, cm_get_g28, set_ro, nullptr, 0 }, @@ -594,6 +678,9 @@ const cfgItem_t cfgArray[] = { { "g30","g30x",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 },// g30 handled differently { "g30","g30y",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, { "g30","g30z",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30u",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30v",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, + { "g30","g30w",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, { "g30","g30a",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, { "g30","g30b",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, { "g30","g30c",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, @@ -711,6 +798,9 @@ const cfgItem_t cfgArray[] = { { "tof","tofx",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, { "tof","tofy",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, { "tof","tofz",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofu",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofv",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, + { "tof","tofw",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, { "tof","tofa",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, { "tof","tofb",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, { "tof","tofc",_fipc, 5, cm_print_cofs, cm_get_tof, cm_set_tof, nullptr, 0 }, @@ -719,6 +809,9 @@ const cfgItem_t cfgArray[] = { { "tt1","tt1x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_X_OFFSET }, { "tt1","tt1y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_Y_OFFSET }, { "tt1","tt1z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_Z_OFFSET }, + { "tt1","tt1u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_U_OFFSET }, + { "tt1","tt1v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_V_OFFSET }, + { "tt1","tt1w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_W_OFFSET }, { "tt1","tt1a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_A_OFFSET }, { "tt1","tt1b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_B_OFFSET }, { "tt1","tt1c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_C_OFFSET }, @@ -726,6 +819,9 @@ const cfgItem_t cfgArray[] = { { "tt2","tt2x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_X_OFFSET }, { "tt2","tt2y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_Y_OFFSET }, { "tt2","tt2z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_Z_OFFSET }, + { "tt2","tt2u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_U_OFFSET }, + { "tt2","tt2v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_V_OFFSET }, + { "tt2","tt2w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_W_OFFSET }, { "tt2","tt2a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_A_OFFSET }, { "tt2","tt2b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_B_OFFSET }, { "tt2","tt2c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT2_C_OFFSET }, @@ -733,6 +829,9 @@ const cfgItem_t cfgArray[] = { { "tt3","tt3x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_X_OFFSET }, { "tt3","tt3y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_Y_OFFSET }, { "tt3","tt3z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_Z_OFFSET }, + { "tt3","tt3u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_U_OFFSET }, + { "tt3","tt3v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_V_OFFSET }, + { "tt3","tt3w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_W_OFFSET }, { "tt3","tt3a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_A_OFFSET }, { "tt3","tt3b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT3_B_OFFSET }, { "tt3","tt3c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT1_C_OFFSET }, @@ -740,6 +839,9 @@ const cfgItem_t cfgArray[] = { { "tt4","tt4x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_X_OFFSET }, { "tt4","tt4y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_Y_OFFSET }, { "tt4","tt4z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_Z_OFFSET }, + { "tt4","tt4u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_U_OFFSET }, + { "tt4","tt4v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_V_OFFSET }, + { "tt4","tt4w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_W_OFFSET }, { "tt4","tt4a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_A_OFFSET }, { "tt4","tt4b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_B_OFFSET }, { "tt4","tt4c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT4_C_OFFSET }, @@ -747,6 +849,9 @@ const cfgItem_t cfgArray[] = { { "tt5","tt5x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_X_OFFSET }, { "tt5","tt5y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_Y_OFFSET }, { "tt5","tt5z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_Z_OFFSET }, + { "tt5","tt5u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_U_OFFSET }, + { "tt5","tt5v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_V_OFFSET }, + { "tt5","tt5w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_W_OFFSET }, { "tt5","tt5a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_A_OFFSET }, { "tt5","tt5b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_B_OFFSET }, { "tt5","tt5c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT5_C_OFFSET }, @@ -754,6 +859,9 @@ const cfgItem_t cfgArray[] = { { "tt6","tt6x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_X_OFFSET }, { "tt6","tt6y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_Y_OFFSET }, { "tt6","tt6z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_Z_OFFSET }, + { "tt6","tt6u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_U_OFFSET }, + { "tt6","tt6v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_V_OFFSET }, + { "tt6","tt6w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_W_OFFSET }, { "tt6","tt6a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_A_OFFSET }, { "tt6","tt6b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_B_OFFSET }, { "tt6","tt6c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT6_C_OFFSET }, @@ -761,6 +869,9 @@ const cfgItem_t cfgArray[] = { { "tt7","tt7x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_X_OFFSET }, { "tt7","tt7y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_Y_OFFSET }, { "tt7","tt7z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_Z_OFFSET }, + { "tt7","tt7u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_U_OFFSET }, + { "tt7","tt7v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_V_OFFSET }, + { "tt7","tt7w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_W_OFFSET }, { "tt7","tt7a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_A_OFFSET }, { "tt7","tt7b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_B_OFFSET }, { "tt7","tt7c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT7_C_OFFSET }, @@ -768,6 +879,9 @@ const cfgItem_t cfgArray[] = { { "tt8","tt8x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_X_OFFSET }, { "tt8","tt8y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_Y_OFFSET }, { "tt8","tt8z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_Z_OFFSET }, + { "tt8","tt8u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_U_OFFSET }, + { "tt8","tt8v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_V_OFFSET }, + { "tt8","tt8w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_W_OFFSET }, { "tt8","tt8a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_A_OFFSET }, { "tt8","tt8b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_B_OFFSET }, { "tt8","tt8c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT8_C_OFFSET }, @@ -775,6 +889,9 @@ const cfgItem_t cfgArray[] = { { "tt9","tt9x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_X_OFFSET }, { "tt9","tt9y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_Y_OFFSET }, { "tt9","tt9z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_Z_OFFSET }, + { "tt9","tt9u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_U_OFFSET }, + { "tt9","tt9v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_V_OFFSET }, + { "tt9","tt9w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_W_OFFSET }, { "tt9","tt9a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_A_OFFSET }, { "tt9","tt9b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_B_OFFSET }, { "tt9","tt9c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT9_C_OFFSET }, @@ -782,6 +899,9 @@ const cfgItem_t cfgArray[] = { { "tt10","tt10x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_X_OFFSET }, { "tt10","tt10y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_Y_OFFSET }, { "tt10","tt10z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_Z_OFFSET }, + { "tt10","tt10u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_U_OFFSET }, + { "tt10","tt10v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_V_OFFSET }, + { "tt10","tt10w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_W_OFFSET }, { "tt10","tt10a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_A_OFFSET }, { "tt10","tt10b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_B_OFFSET }, { "tt10","tt10c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT10_C_OFFSET }, @@ -789,6 +909,9 @@ const cfgItem_t cfgArray[] = { { "tt11","tt11x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_X_OFFSET }, { "tt11","tt11y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_Y_OFFSET }, { "tt11","tt11z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_Z_OFFSET }, + { "tt11","tt11u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_U_OFFSET }, + { "tt11","tt11v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_V_OFFSET }, + { "tt11","tt11w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_W_OFFSET }, { "tt11","tt11a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_A_OFFSET }, { "tt11","tt11b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_B_OFFSET }, { "tt11","tt11c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT11_C_OFFSET }, @@ -796,6 +919,9 @@ const cfgItem_t cfgArray[] = { { "tt12","tt12x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_X_OFFSET }, { "tt12","tt12y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_Y_OFFSET }, { "tt12","tt12z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_Z_OFFSET }, + { "tt12","tt12u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_U_OFFSET }, + { "tt12","tt12v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_V_OFFSET }, + { "tt12","tt12w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_W_OFFSET }, { "tt12","tt12a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_A_OFFSET }, { "tt12","tt12b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_B_OFFSET }, { "tt12","tt12c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT12_C_OFFSET }, @@ -803,6 +929,9 @@ const cfgItem_t cfgArray[] = { { "tt13","tt13x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_X_OFFSET }, { "tt13","tt13y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_Y_OFFSET }, { "tt13","tt13z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_Z_OFFSET }, + { "tt13","tt13u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_U_OFFSET }, + { "tt13","tt13v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_V_OFFSET }, + { "tt13","tt13w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_W_OFFSET }, { "tt13","tt13a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_A_OFFSET }, { "tt13","tt13b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_B_OFFSET }, { "tt13","tt13c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT13_C_OFFSET }, @@ -810,6 +939,9 @@ const cfgItem_t cfgArray[] = { { "tt14","tt14x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_X_OFFSET }, { "tt14","tt14y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_Y_OFFSET }, { "tt14","tt14z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_Z_OFFSET }, + { "tt14","tt14u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_U_OFFSET }, + { "tt14","tt14v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_V_OFFSET }, + { "tt14","tt14w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_W_OFFSET }, { "tt14","tt14a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_A_OFFSET }, { "tt14","tt14b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_B_OFFSET }, { "tt14","tt14c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT14_C_OFFSET }, @@ -817,6 +949,9 @@ const cfgItem_t cfgArray[] = { { "tt15","tt15x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_X_OFFSET }, { "tt15","tt15y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_Y_OFFSET }, { "tt15","tt15z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_Z_OFFSET }, + { "tt15","tt15u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_U_OFFSET }, + { "tt15","tt15v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_V_OFFSET }, + { "tt15","tt15w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_W_OFFSET }, { "tt15","tt15a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_A_OFFSET }, { "tt15","tt15b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_B_OFFSET }, { "tt15","tt15c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT15_C_OFFSET }, @@ -824,6 +959,9 @@ const cfgItem_t cfgArray[] = { { "tt16","tt16x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_X_OFFSET }, { "tt16","tt16y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_Y_OFFSET }, { "tt16","tt16z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_Z_OFFSET }, + { "tt16","tt16u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_U_OFFSET }, + { "tt16","tt16v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_V_OFFSET }, + { "tt16","tt16w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_W_OFFSET }, { "tt16","tt16a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_A_OFFSET }, { "tt16","tt16b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_B_OFFSET }, { "tt16","tt16c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT16_C_OFFSET }, @@ -831,6 +969,9 @@ const cfgItem_t cfgArray[] = { { "tt17","tt17x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_X_OFFSET }, { "tt17","tt17y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_Y_OFFSET }, { "tt17","tt17z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_Z_OFFSET }, + { "tt17","tt17u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_U_OFFSET }, + { "tt17","tt17v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_V_OFFSET }, + { "tt17","tt17w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_W_OFFSET }, { "tt17","tt17a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_A_OFFSET }, { "tt17","tt17b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_B_OFFSET }, { "tt17","tt17c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT17_C_OFFSET }, @@ -838,6 +979,9 @@ const cfgItem_t cfgArray[] = { { "tt18","tt18x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_X_OFFSET }, { "tt18","tt18y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_Y_OFFSET }, { "tt18","tt18z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_Z_OFFSET }, + { "tt18","tt18u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_U_OFFSET }, + { "tt18","tt18v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_V_OFFSET }, + { "tt18","tt18w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_W_OFFSET }, { "tt18","tt18a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_A_OFFSET }, { "tt18","tt18b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_B_OFFSET }, { "tt18","tt18c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT18_C_OFFSET }, @@ -845,6 +989,9 @@ const cfgItem_t cfgArray[] = { { "tt19","tt19x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_X_OFFSET }, { "tt19","tt19y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_Y_OFFSET }, { "tt19","tt19z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_Z_OFFSET }, + { "tt19","tt19u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_U_OFFSET }, + { "tt19","tt19v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_V_OFFSET }, + { "tt19","tt19w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_W_OFFSET }, { "tt19","tt19a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_A_OFFSET }, { "tt19","tt19b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_B_OFFSET }, { "tt19","tt19c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT19_C_OFFSET }, @@ -852,6 +999,9 @@ const cfgItem_t cfgArray[] = { { "tt20","tt20x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_X_OFFSET }, { "tt20","tt20y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_Y_OFFSET }, { "tt20","tt20z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_Z_OFFSET }, + { "tt20","tt20u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_U_OFFSET }, + { "tt20","tt20v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_V_OFFSET }, + { "tt20","tt20w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_W_OFFSET }, { "tt20","tt20a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_A_OFFSET }, { "tt20","tt20b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_B_OFFSET }, { "tt20","tt20c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT20_C_OFFSET }, @@ -859,6 +1009,9 @@ const cfgItem_t cfgArray[] = { { "tt21","tt21x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_X_OFFSET }, { "tt21","tt21y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_Y_OFFSET }, { "tt21","tt21z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_Z_OFFSET }, + { "tt21","tt21u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_U_OFFSET }, + { "tt21","tt21v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_V_OFFSET }, + { "tt21","tt21w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_W_OFFSET }, { "tt21","tt21a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_A_OFFSET }, { "tt21","tt21b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_B_OFFSET }, { "tt21","tt21c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT21_C_OFFSET }, @@ -866,6 +1019,9 @@ const cfgItem_t cfgArray[] = { { "tt22","tt22x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_X_OFFSET }, { "tt22","tt22y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_Y_OFFSET }, { "tt22","tt22z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_Z_OFFSET }, + { "tt22","tt22u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_U_OFFSET }, + { "tt22","tt22v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_V_OFFSET }, + { "tt22","tt22w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_W_OFFSET }, { "tt22","tt22a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_A_OFFSET }, { "tt22","tt22b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_B_OFFSET }, { "tt22","tt22c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT22_C_OFFSET }, @@ -873,6 +1029,9 @@ const cfgItem_t cfgArray[] = { { "tt23","tt23x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_X_OFFSET }, { "tt23","tt23y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_Y_OFFSET }, { "tt23","tt23z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_Z_OFFSET }, + { "tt23","tt23u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_U_OFFSET }, + { "tt23","tt23v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_V_OFFSET }, + { "tt23","tt23w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_W_OFFSET }, { "tt23","tt23a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_A_OFFSET }, { "tt23","tt23b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_B_OFFSET }, { "tt23","tt23c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT23_C_OFFSET }, @@ -880,6 +1039,9 @@ const cfgItem_t cfgArray[] = { { "tt24","tt24x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_X_OFFSET }, { "tt24","tt24y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_Y_OFFSET }, { "tt24","tt24z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_Z_OFFSET }, + { "tt24","tt24u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_U_OFFSET }, + { "tt24","tt24v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_V_OFFSET }, + { "tt24","tt24w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_W_OFFSET }, { "tt24","tt24a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_A_OFFSET }, { "tt24","tt24b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_B_OFFSET }, { "tt24","tt24c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT24_C_OFFSET }, @@ -887,6 +1049,9 @@ const cfgItem_t cfgArray[] = { { "tt25","tt25x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_X_OFFSET }, { "tt25","tt25y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_Y_OFFSET }, { "tt25","tt25z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_Z_OFFSET }, + { "tt25","tt25u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_U_OFFSET }, + { "tt25","tt25v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_V_OFFSET }, + { "tt25","tt25w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_W_OFFSET }, { "tt25","tt25a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_A_OFFSET }, { "tt25","tt25b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_B_OFFSET }, { "tt25","tt25c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT25_C_OFFSET }, @@ -894,6 +1059,9 @@ const cfgItem_t cfgArray[] = { { "tt26","tt26x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_X_OFFSET }, { "tt26","tt26y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_Y_OFFSET }, { "tt26","tt26z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_Z_OFFSET }, + { "tt26","tt26u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_U_OFFSET }, + { "tt26","tt26v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_V_OFFSET }, + { "tt26","tt26w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_W_OFFSET }, { "tt26","tt26a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_A_OFFSET }, { "tt26","tt26b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_B_OFFSET }, { "tt26","tt26c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT26_C_OFFSET }, @@ -901,6 +1069,9 @@ const cfgItem_t cfgArray[] = { { "tt27","tt27x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_X_OFFSET }, { "tt27","tt27y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_Y_OFFSET }, { "tt27","tt27z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_Z_OFFSET }, + { "tt27","tt27u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_U_OFFSET }, + { "tt27","tt27v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_V_OFFSET }, + { "tt27","tt27w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_W_OFFSET }, { "tt27","tt27a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_A_OFFSET }, { "tt27","tt27b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_B_OFFSET }, { "tt27","tt27c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT27_C_OFFSET }, @@ -908,6 +1079,9 @@ const cfgItem_t cfgArray[] = { { "tt28","tt28x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_X_OFFSET }, { "tt28","tt28y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_Y_OFFSET }, { "tt28","tt28z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_Z_OFFSET }, + { "tt28","tt28u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_U_OFFSET }, + { "tt28","tt28v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_V_OFFSET }, + { "tt28","tt28w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_W_OFFSET }, { "tt28","tt28a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_A_OFFSET }, { "tt28","tt28b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_B_OFFSET }, { "tt28","tt28c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT28_C_OFFSET }, @@ -915,6 +1089,9 @@ const cfgItem_t cfgArray[] = { { "tt29","tt29x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_X_OFFSET }, { "tt29","tt29y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_Y_OFFSET }, { "tt29","tt29z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_Z_OFFSET }, + { "tt29","tt29u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_U_OFFSET }, + { "tt29","tt29v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_V_OFFSET }, + { "tt29","tt29w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_W_OFFSET }, { "tt29","tt29a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_A_OFFSET }, { "tt29","tt29b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_B_OFFSET }, { "tt29","tt29c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT29_C_OFFSET }, @@ -922,6 +1099,9 @@ const cfgItem_t cfgArray[] = { { "tt30","tt30x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_X_OFFSET }, { "tt30","tt30y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_Y_OFFSET }, { "tt30","tt30z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_Z_OFFSET }, + { "tt30","tt30u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_U_OFFSET }, + { "tt30","tt30v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_V_OFFSET }, + { "tt30","tt30w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_W_OFFSET }, { "tt30","tt30a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_A_OFFSET }, { "tt30","tt30b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_B_OFFSET }, { "tt30","tt30c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT30_C_OFFSET }, @@ -929,6 +1109,9 @@ const cfgItem_t cfgArray[] = { { "tt31","tt31x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_X_OFFSET }, { "tt31","tt31y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_Y_OFFSET }, { "tt31","tt31z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_Z_OFFSET }, + { "tt31","tt31u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_U_OFFSET }, + { "tt31","tt31v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_V_OFFSET }, + { "tt31","tt31w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_W_OFFSET }, { "tt31","tt31a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_A_OFFSET }, { "tt31","tt31b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_B_OFFSET }, { "tt31","tt31c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT31_C_OFFSET }, @@ -936,6 +1119,9 @@ const cfgItem_t cfgArray[] = { { "tt32","tt32x",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_X_OFFSET }, { "tt32","tt32y",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_Y_OFFSET }, { "tt32","tt32z",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_Z_OFFSET }, + { "tt32","tt32u",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_U_OFFSET }, + { "tt32","tt32v",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_V_OFFSET }, + { "tt32","tt32w",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_W_OFFSET }, { "tt32","tt32a",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_A_OFFSET }, { "tt32","tt32b",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_B_OFFSET }, { "tt32","tt32c",_fipc, 5, cm_print_cofs, cm_get_tt, cm_set_tt, nullptr, TT32_C_OFFSET }, diff --git a/g2core/g2core.h b/g2core/g2core.h index a575e29b..80b52c56 100644 --- a/g2core/g2core.h +++ b/g2core/g2core.h @@ -64,12 +64,12 @@ typedef enum { AXIS_X = 0, AXIS_Y, AXIS_Z, + AXIS_U, + AXIS_V, + AXIS_W, AXIS_A, AXIS_B, - AXIS_C, - AXIS_U, // reserved - AXIS_V, // reserved - AXIS_W // reserved + AXIS_C } cmAxes; typedef enum { diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 60f4e7e4..894711d9 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -856,9 +856,9 @@ static stat_t _parse_gcode_block(char *buf, char *active_comment) case 'A': SET_NON_MODAL (target[AXIS_A], value); case 'B': SET_NON_MODAL (target[AXIS_B], value); case 'C': SET_NON_MODAL (target[AXIS_C], value); - // case 'U': SET_NON_MODAL (target[AXIS_U], value); // reserved - // case 'V': SET_NON_MODAL (target[AXIS_V], value); // reserved - // case 'W': SET_NON_MODAL (target[AXIS_W], value); // reserved + case 'U': SET_NON_MODAL (target[AXIS_U], value); + case 'V': SET_NON_MODAL (target[AXIS_V], value); + case 'W': SET_NON_MODAL (target[AXIS_W], value); case 'H': SET_NON_MODAL (H_word, value); case 'I': SET_NON_MODAL (arc_offset[0], value); case 'J': SET_NON_MODAL (arc_offset[1], value); diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index de51c193..b8e75645 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -503,6 +503,129 @@ #define Z_ZERO_BACKOFF 2.0 #endif +// U AXIS +#ifndef U_AXIS_MODE +#define U_AXIS_MODE AXIS_DISABLED // {xam: see canonical_machine.h cmAxisMode for valid values +#endif +#ifndef U_VELOCITY_MAX +#define U_VELOCITY_MAX 1000.0 // {xvm: G0 max velocity in mm/min +#endif +#ifndef U_FEEDRATE_MAX +#define U_FEEDRATE_MAX 1000.0 // {xfr: G1 max feed rate in mm/min +#endif +#ifndef U_TRAVEL_MIN +#define U_TRAVEL_MIN 0.0 // {xtn: minimum travel for soft limits +#endif +#ifndef U_TRAVEL_MAX +#define U_TRAVEL_MAX 0.0 // {xtm: travel between switches or crashes +#endif +#ifndef U_JERK_MAX +#define U_JERK_MAX 1000.0 // {xjm: +#endif +#ifndef U_JERK_HIGH_SPEED +#define U_JERK_HIGH_SPEED 1000.0 // {xjh: +#endif +#ifndef U_HOMING_INPUT +#define U_HOMING_INPUT 0 // {xhi: input used for homing or 0 to disable +#endif +#ifndef U_HOMING_DIRECTION +#define U_HOMING_DIRECTION 0 // {xhd: 0=search moves negative, 1= search moves positive +#endif +#ifndef U_SEARCH_VELOCITY +#define U_SEARCH_VELOCITY 500.0 // {xsv: minus means move to minimum switch +#endif +#ifndef U_LATCH_VELOCITY +#define U_LATCH_VELOCITY 100.0 // {xlv: mm/min +#endif +#ifndef U_LATCH_BACKOFF +#define U_LATCH_BACKOFF 4.0 // {xlb: mm +#endif +#ifndef U_ZERO_BACKOFF +#define U_ZERO_BACKOFF 2.0 // {xzb: mm +#endif + +// V AXIS +#ifndef V_AXIS_MODE +#define V_AXIS_MODE AXIS_DISABLED +#endif +#ifndef V_VELOCITY_MAX +#define V_VELOCITY_MAX 1000.0 +#endif +#ifndef V_FEEDRATE_MAX +#define V_FEEDRATE_MAX 1000.0 +#endif +#ifndef V_TRAVEL_MIN +#define V_TRAVEL_MIN 0.0 +#endif +#ifndef V_TRAVEL_MAX +#define V_TRAVEL_MAX 0.0 +#endif +#ifndef V_JERK_MAX +#define V_JERK_MAX 1000.0 +#endif +#ifndef V_JERK_HIGH_SPEED +#define V_JERK_HIGH_SPEED 1000.0 +#endif +#ifndef V_HOMING_INPUT +#define V_HOMING_INPUT 0 +#endif +#ifndef V_HOMING_DIRECTION +#define V_HOMING_DIRECTION 0 +#endif +#ifndef V_SEARCH_VELOCITY +#define V_SEARCH_VELOCITY 500.0 +#endif +#ifndef V_LATCH_VELOCITY +#define V_LATCH_VELOCITY 100.0 +#endif +#ifndef V_LATCH_BACKOFF +#define V_LATCH_BACKOFF 4.0 +#endif +#ifndef V_ZERO_BACKOFF +#define Y_ZERO_BACKOFF 2.0 +#endif + +// W AXIS +#ifndef W_AXIS_MODE +#define W_AXIS_MODE AXIS_DISABLED +#endif +#ifndef W_VELOCITY_MAX +#define W_VELOCITY_MAX 1000.0 +#endif +#ifndef W_FEEDRATE_MAX +#define W_FEEDRATE_MAX 1000.0 +#endif +#ifndef W_TRAVEL_MAX +#define W_TRAVEL_MAX 0.0 +#endif +#ifndef W_TRAVEL_MIN +#define W_TRAVEL_MIN 0.0 +#endif +#ifndef W_JERK_MAX +#define W_JERK_MAX 500.0 +#endif +#ifndef W_JERK_HIGH_SPEED +#define W_JERK_HIGH_SPEED 500.0 +#endif +#ifndef W_HOMING_INPUT +#define W_HOMING_INPUT 0 +#endif +#ifndef W_HOMING_DIRECTION +#define W_HOMING_DIRECTION 0 +#endif +#ifndef W_SEARCH_VELOCITY +#define W_SEARCH_VELOCITY 250.0 +#endif +#ifndef W_LATCH_VELOCITY +#define W_LATCH_VELOCITY 25.0 +#endif +#ifndef W_LATCH_BACKOFF +#define W_LATCH_BACKOFF 4.0 +#endif +#ifndef W_ZERO_BACKOFF +#define W_ZERO_BACKOFF 2.0 +#endif + /*************************************************************************************** * Rotary values can be chosen to make the motor react the same as X for testing * To calculate the speeds here, in Wolfram Alpha-speak: @@ -979,6 +1102,15 @@ #ifndef G54_Z_OFFSET #define G54_Z_OFFSET 0 #endif +#ifndef G54_U_OFFSET +#define G54_U_OFFSET 0 +#endif +#ifndef G54_V_OFFSET +#define G54_V_OFFSET 0 +#endif +#ifndef G54_W_OFFSET +#define G54_W_OFFSET 0 +#endif #ifndef G54_A_OFFSET #define G54_A_OFFSET 0 #endif @@ -998,6 +1130,15 @@ #ifndef G55_Z_OFFSET #define G55_Z_OFFSET 0 #endif +#ifndef G55_U_OFFSET +#define G55_U_OFFSET 0 +#endif +#ifndef G55_V_OFFSET +#define G55_V_OFFSET 0 +#endif +#ifndef G55_W_OFFSET +#define G55_W_OFFSET 0 +#endif #ifndef G55_A_OFFSET #define G55_A_OFFSET 0 #endif @@ -1017,6 +1158,15 @@ #ifndef G56_Z_OFFSET #define G56_Z_OFFSET 0 #endif +#ifndef G56_U_OFFSET +#define G56_U_OFFSET 0 +#endif +#ifndef G56_V_OFFSET +#define G56_V_OFFSET 0 +#endif +#ifndef G56_W_OFFSET +#define G56_W_OFFSET 0 +#endif #ifndef G56_A_OFFSET #define G56_A_OFFSET 0 #endif @@ -1036,6 +1186,15 @@ #ifndef G57_Z_OFFSET #define G57_Z_OFFSET 0 #endif +#ifndef G57_U_OFFSET +#define G57_U_OFFSET 0 +#endif +#ifndef G57_V_OFFSET +#define G57_V_OFFSET 0 +#endif +#ifndef G57_W_OFFSET +#define G57_W_OFFSET 0 +#endif #ifndef G57_A_OFFSET #define G57_A_OFFSET 0 #endif @@ -1055,6 +1214,15 @@ #ifndef G58_Z_OFFSET #define G58_Z_OFFSET 0 #endif +#ifndef G58_U_OFFSET +#define G58_U_OFFSET 0 +#endif +#ifndef G58_V_OFFSET +#define G58_V_OFFSET 0 +#endif +#ifndef G58_W_OFFSET +#define G58_W_OFFSET 0 +#endif #ifndef G58_A_OFFSET #define G58_A_OFFSET 0 #endif @@ -1074,6 +1242,15 @@ #ifndef G59_Z_OFFSET #define G59_Z_OFFSET 0 #endif +#ifndef G59_U_OFFSET +#define G59_U_OFFSET 0 +#endif +#ifndef G59_V_OFFSET +#define G59_V_OFFSET 0 +#endif +#ifndef G59_W_OFFSET +#define G59_W_OFFSET 0 +#endif #ifndef G59_A_OFFSET #define G59_A_OFFSET 0 #endif @@ -1095,6 +1272,15 @@ #ifndef TT1_Z_OFFSET #define TT1_Z_OFFSET 0 #endif +#ifndef TT1_U_OFFSET +#define TT1_U_OFFSET 0 +#endif +#ifndef TT1_V_OFFSET +#define TT1_V_OFFSET 0 +#endif +#ifndef TT1_W_OFFSET +#define TT1_W_OFFSET 0 +#endif #ifndef TT1_A_OFFSET #define TT1_A_OFFSET 0 #endif @@ -1114,6 +1300,15 @@ #ifndef TT2_Z_OFFSET #define TT2_Z_OFFSET 0 #endif +#ifndef TT2_U_OFFSET +#define TT2_U_OFFSET 0 +#endif +#ifndef TT2_V_OFFSET +#define TT2_V_OFFSET 0 +#endif +#ifndef TT2_W_OFFSET +#define TT2_W_OFFSET 0 +#endif #ifndef TT2_A_OFFSET #define TT2_A_OFFSET 0 #endif @@ -1133,6 +1328,15 @@ #ifndef TT3_Z_OFFSET #define TT3_Z_OFFSET 0 #endif +#ifndef TT3_U_OFFSET +#define TT3_U_OFFSET 0 +#endif +#ifndef TT3_V_OFFSET +#define TT3_V_OFFSET 0 +#endif +#ifndef TT3_W_OFFSET +#define TT3_W_OFFSET 0 +#endif #ifndef TT3_A_OFFSET #define TT3_A_OFFSET 0 #endif @@ -1152,6 +1356,15 @@ #ifndef TT4_Z_OFFSET #define TT4_Z_OFFSET 0 #endif +#ifndef TT4_U_OFFSET +#define TT4_U_OFFSET 0 +#endif +#ifndef TT4_V_OFFSET +#define TT4_V_OFFSET 0 +#endif +#ifndef TT4_W_OFFSET +#define TT4_W_OFFSET 0 +#endif #ifndef TT4_A_OFFSET #define TT4_A_OFFSET 0 #endif @@ -1171,6 +1384,15 @@ #ifndef TT5_Z_OFFSET #define TT5_Z_OFFSET 0 #endif +#ifndef TT5_U_OFFSET +#define TT5_U_OFFSET 0 +#endif +#ifndef TT5_V_OFFSET +#define TT5_V_OFFSET 0 +#endif +#ifndef TT5_W_OFFSET +#define TT5_W_OFFSET 0 +#endif #ifndef TT5_A_OFFSET #define TT5_A_OFFSET 0 #endif @@ -1190,6 +1412,15 @@ #ifndef TT6_Z_OFFSET #define TT6_Z_OFFSET 0 #endif +#ifndef TT6_U_OFFSET +#define TT6_U_OFFSET 0 +#endif +#ifndef TT6_V_OFFSET +#define TT6_V_OFFSET 0 +#endif +#ifndef TT6_W_OFFSET +#define TT6_W_OFFSET 0 +#endif #ifndef TT6_A_OFFSET #define TT6_A_OFFSET 0 #endif @@ -1209,6 +1440,15 @@ #ifndef TT7_Z_OFFSET #define TT7_Z_OFFSET 0 #endif +#ifndef TT7_U_OFFSET +#define TT7_U_OFFSET 0 +#endif +#ifndef TT7_V_OFFSET +#define TT7_V_OFFSET 0 +#endif +#ifndef TT7_W_OFFSET +#define TT7_W_OFFSET 0 +#endif #ifndef TT7_A_OFFSET #define TT7_A_OFFSET 0 #endif @@ -1225,6 +1465,15 @@ #ifndef TT8_Y_OFFSET #define TT8_Y_OFFSET 0 #endif +#ifndef TT8_U_OFFSET +#define TT8_U_OFFSET 0 +#endif +#ifndef TT8_V_OFFSET +#define TT8_V_OFFSET 0 +#endif +#ifndef TT8_W_OFFSET +#define TT8_W_OFFSET 0 +#endif #ifndef TT8_Z_OFFSET #define TT8_Z_OFFSET 0 #endif @@ -1247,6 +1496,15 @@ #ifndef TT9_Z_OFFSET #define TT9_Z_OFFSET 0 #endif +#ifndef TT9_U_OFFSET +#define TT9_U_OFFSET 0 +#endif +#ifndef TT9_V_OFFSET +#define TT9_V_OFFSET 0 +#endif +#ifndef TT9_W_OFFSET +#define TT9_W_OFFSET 0 +#endif #ifndef TT9_A_OFFSET #define TT9_A_OFFSET 0 #endif @@ -1266,6 +1524,15 @@ #ifndef TT10_Z_OFFSET #define TT10_Z_OFFSET 0 #endif +#ifndef TT10_U_OFFSET +#define TT10_U_OFFSET 0 +#endif +#ifndef TT10_V_OFFSET +#define TT10_V_OFFSET 0 +#endif +#ifndef TT10_W_OFFSET +#define TT10_W_OFFSET 0 +#endif #ifndef TT10_A_OFFSET #define TT10_A_OFFSET 0 #endif @@ -1285,6 +1552,15 @@ #ifndef TT11_Z_OFFSET #define TT11_Z_OFFSET 0 #endif +#ifndef TT11_U_OFFSET +#define TT11_U_OFFSET 0 +#endif +#ifndef TT11_V_OFFSET +#define TT11_V_OFFSET 0 +#endif +#ifndef TT11_W_OFFSET +#define TT11_W_OFFSET 0 +#endif #ifndef TT11_A_OFFSET #define TT11_A_OFFSET 0 #endif @@ -1304,6 +1580,15 @@ #ifndef TT12_Z_OFFSET #define TT12_Z_OFFSET 0 #endif +#ifndef TT12_U_OFFSET +#define TT12_U_OFFSET 0 +#endif +#ifndef TT12_V_OFFSET +#define TT12_V_OFFSET 0 +#endif +#ifndef TT12_W_OFFSET +#define TT12_W_OFFSET 0 +#endif #ifndef TT12_A_OFFSET #define TT12_A_OFFSET 0 #endif @@ -1323,6 +1608,15 @@ #ifndef TT13_Z_OFFSET #define TT13_Z_OFFSET 0 #endif +#ifndef TT13_U_OFFSET +#define TT13_U_OFFSET 0 +#endif +#ifndef TT13_V_OFFSET +#define TT13_V_OFFSET 0 +#endif +#ifndef TT13_W_OFFSET +#define TT13_W_OFFSET 0 +#endif #ifndef TT13_A_OFFSET #define TT13_A_OFFSET 0 #endif @@ -1342,6 +1636,15 @@ #ifndef TT14_Z_OFFSET #define TT14_Z_OFFSET 0 #endif +#ifndef TT14_U_OFFSET +#define TT14_U_OFFSET 0 +#endif +#ifndef TT14_V_OFFSET +#define TT14_V_OFFSET 0 +#endif +#ifndef TT14_W_OFFSET +#define TT14_W_OFFSET 0 +#endif #ifndef TT14_A_OFFSET #define TT14_A_OFFSET 0 #endif @@ -1361,6 +1664,15 @@ #ifndef TT15_Z_OFFSET #define TT15_Z_OFFSET 0 #endif +#ifndef TT15_U_OFFSET +#define TT15_U_OFFSET 0 +#endif +#ifndef TT15_V_OFFSET +#define TT15_V_OFFSET 0 +#endif +#ifndef TT15_W_OFFSET +#define TT15_W_OFFSET 0 +#endif #ifndef TT15_A_OFFSET #define TT15_A_OFFSET 0 #endif @@ -1380,6 +1692,15 @@ #ifndef TT16_Z_OFFSET #define TT16_Z_OFFSET 0 #endif +#ifndef TT16_U_OFFSET +#define TT16_U_OFFSET 0 +#endif +#ifndef TT16_V_OFFSET +#define TT16_V_OFFSET 0 +#endif +#ifndef TT16_W_OFFSET +#define TT16_W_OFFSET 0 +#endif #ifndef TT16_A_OFFSET #define TT16_A_OFFSET 0 #endif @@ -1399,6 +1720,15 @@ #ifndef TT17_Z_OFFSET #define TT17_Z_OFFSET 0 #endif +#ifndef TT17_U_OFFSET +#define TT17_U_OFFSET 0 +#endif +#ifndef TT17_V_OFFSET +#define TT17_V_OFFSET 0 +#endif +#ifndef TT17_W_OFFSET +#define TT17_W_OFFSET 0 +#endif #ifndef TT17_A_OFFSET #define TT17_A_OFFSET 0 #endif @@ -1418,6 +1748,15 @@ #ifndef TT18_Z_OFFSET #define TT18_Z_OFFSET 0 #endif +#ifndef TT18_U_OFFSET +#define TT18_U_OFFSET 0 +#endif +#ifndef TT18_V_OFFSET +#define TT18_V_OFFSET 0 +#endif +#ifndef TT18_W_OFFSET +#define TT18_W_OFFSET 0 +#endif #ifndef TT18_A_OFFSET #define TT18_A_OFFSET 0 #endif @@ -1437,6 +1776,15 @@ #ifndef TT19_Z_OFFSET #define TT19_Z_OFFSET 0 #endif +#ifndef TT19_U_OFFSET +#define TT19_U_OFFSET 0 +#endif +#ifndef TT19_V_OFFSET +#define TT19_V_OFFSET 0 +#endif +#ifndef TT19_W_OFFSET +#define TT19_W_OFFSET 0 +#endif #ifndef TT19_A_OFFSET #define TT19_A_OFFSET 0 #endif @@ -1456,6 +1804,15 @@ #ifndef TT20_Z_OFFSET #define TT20_Z_OFFSET 0 #endif +#ifndef TT20_U_OFFSET +#define TT20_U_OFFSET 0 +#endif +#ifndef TT20_V_OFFSET +#define TT20_V_OFFSET 0 +#endif +#ifndef TT20_W_OFFSET +#define TT20_W_OFFSET 0 +#endif #ifndef TT20_A_OFFSET #define TT20_A_OFFSET 0 #endif @@ -1475,6 +1832,15 @@ #ifndef TT21_Z_OFFSET #define TT21_Z_OFFSET 0 #endif +#ifndef TT21_U_OFFSET +#define TT21_U_OFFSET 0 +#endif +#ifndef TT21_V_OFFSET +#define TT21_V_OFFSET 0 +#endif +#ifndef TT21_W_OFFSET +#define TT21_W_OFFSET 0 +#endif #ifndef TT21_A_OFFSET #define TT21_A_OFFSET 0 #endif @@ -1494,6 +1860,15 @@ #ifndef TT22_Z_OFFSET #define TT22_Z_OFFSET 0 #endif +#ifndef TT22_U_OFFSET +#define TT22_U_OFFSET 0 +#endif +#ifndef TT22_V_OFFSET +#define TT22_V_OFFSET 0 +#endif +#ifndef TT22_W_OFFSET +#define TT22_W_OFFSET 0 +#endif #ifndef TT22_A_OFFSET #define TT22_A_OFFSET 0 #endif @@ -1513,6 +1888,15 @@ #ifndef TT23_Z_OFFSET #define TT23_Z_OFFSET 0 #endif +#ifndef TT23_U_OFFSET +#define TT23_U_OFFSET 0 +#endif +#ifndef TT23_V_OFFSET +#define TT23_V_OFFSET 0 +#endif +#ifndef TT23_W_OFFSET +#define TT23_W_OFFSET 0 +#endif #ifndef TT23_A_OFFSET #define TT23_A_OFFSET 0 #endif @@ -1532,6 +1916,15 @@ #ifndef TT24_Z_OFFSET #define TT24_Z_OFFSET 0 #endif +#ifndef TT24_U_OFFSET +#define TT24_U_OFFSET 0 +#endif +#ifndef TT24_V_OFFSET +#define TT24_V_OFFSET 0 +#endif +#ifndef TT24_W_OFFSET +#define TT24_W_OFFSET 0 +#endif #ifndef TT24_A_OFFSET #define TT24_A_OFFSET 0 #endif @@ -1551,6 +1944,15 @@ #ifndef TT25_Z_OFFSET #define TT25_Z_OFFSET 0 #endif +#ifndef TT25_U_OFFSET +#define TT25_U_OFFSET 0 +#endif +#ifndef TT25_V_OFFSET +#define TT25_V_OFFSET 0 +#endif +#ifndef TT25_W_OFFSET +#define TT25_W_OFFSET 0 +#endif #ifndef TT25_A_OFFSET #define TT25_A_OFFSET 0 #endif @@ -1570,6 +1972,15 @@ #ifndef TT26_Z_OFFSET #define TT26_Z_OFFSET 0 #endif +#ifndef TT26_U_OFFSET +#define TT26_U_OFFSET 0 +#endif +#ifndef TT26_V_OFFSET +#define TT26_V_OFFSET 0 +#endif +#ifndef TT26_W_OFFSET +#define TT26_W_OFFSET 0 +#endif #ifndef TT26_A_OFFSET #define TT26_A_OFFSET 0 #endif @@ -1589,6 +2000,15 @@ #ifndef TT27_Z_OFFSET #define TT27_Z_OFFSET 0 #endif +#ifndef TT27_U_OFFSET +#define TT27_U_OFFSET 0 +#endif +#ifndef TT27_V_OFFSET +#define TT27_V_OFFSET 0 +#endif +#ifndef TT27_W_OFFSET +#define TT27_W_OFFSET 0 +#endif #ifndef TT27_A_OFFSET #define TT27_A_OFFSET 0 #endif @@ -1608,6 +2028,15 @@ #ifndef TT28_Z_OFFSET #define TT28_Z_OFFSET 0 #endif +#ifndef TT28_U_OFFSET +#define TT28_U_OFFSET 0 +#endif +#ifndef TT28_V_OFFSET +#define TT28_V_OFFSET 0 +#endif +#ifndef TT28_W_OFFSET +#define TT28_W_OFFSET 0 +#endif #ifndef TT28_A_OFFSET #define TT28_A_OFFSET 0 #endif @@ -1627,6 +2056,15 @@ #ifndef TT29_Z_OFFSET #define TT29_Z_OFFSET 0 #endif +#ifndef TT29_U_OFFSET +#define TT29_U_OFFSET 0 +#endif +#ifndef TT29_V_OFFSET +#define TT29_V_OFFSET 0 +#endif +#ifndef TT29_W_OFFSET +#define TT29_W_OFFSET 0 +#endif #ifndef TT29_A_OFFSET #define TT29_A_OFFSET 0 #endif @@ -1646,6 +2084,15 @@ #ifndef TT30_Z_OFFSET #define TT30_Z_OFFSET 0 #endif +#ifndef TT30_U_OFFSET +#define TT30_U_OFFSET 0 +#endif +#ifndef TT30_V_OFFSET +#define TT30_V_OFFSET 0 +#endif +#ifndef TT30_W_OFFSET +#define TT30_W_OFFSET 0 +#endif #ifndef TT30_A_OFFSET #define TT30_A_OFFSET 0 #endif @@ -1665,6 +2112,15 @@ #ifndef TT31_Z_OFFSET #define TT31_Z_OFFSET 0 #endif +#ifndef TT31_U_OFFSET +#define TT31_U_OFFSET 0 +#endif +#ifndef TT31_V_OFFSET +#define TT31_V_OFFSET 0 +#endif +#ifndef TT31_W_OFFSET +#define TT31_W_OFFSET 0 +#endif #ifndef TT31_A_OFFSET #define TT31_A_OFFSET 0 #endif @@ -1684,6 +2140,15 @@ #ifndef TT32_Z_OFFSET #define TT32_Z_OFFSET 0 #endif +#ifndef TT32_U_OFFSET +#define TT32_U_OFFSET 0 +#endif +#ifndef TT32_V_OFFSET +#define TT32_V_OFFSET 0 +#endif +#ifndef TT32_W_OFFSET +#define TT32_W_OFFSET 0 +#endif #ifndef TT32_A_OFFSET #define TT32_A_OFFSET 0 #endif diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 33bf381f..1b7ec8b8 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -172,6 +172,48 @@ #define Z_LATCH_BACKOFF 4 #define Z_ZERO_BACKOFF 2 +#define U_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values +#define U_VELOCITY_MAX 40000 // xvm G0 max velocity in mm/min +#define U_FEEDRATE_MAX U_VELOCITY_MAX // xfr G1 max feed rate in mm/min +#define U_TRAVEL_MIN 0 // xtn minimum travel for soft limits +#define U_TRAVEL_MAX 420 // xtm travel between switches or crashes +#define U_JERK_MAX JERK_MAX // xjm jerk * 1,000,000 +#define U_JERK_HIGH_SPEED 20000 // xjh +#define U_HOMING_INPUT 1 // xhi input used for homing or 0 to disable +#define U_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive +#define U_SEARCH_VELOCITY 3000 // xsv minus means move to minimum switch +#define U_LATCH_VELOCITY 100 // xlv mm/min +#define U_LATCH_BACKOFF 4 // xlb mm +#define U_ZERO_BACKOFF 2 // xzb mm + +#define V_AXIS_MODE AXIS_STANDARD +#define V_VELOCITY_MAX 40000 +#define V_FEEDRATE_MAX V_VELOCITY_MAX +#define V_TRAVEL_MIN 0 +#define V_TRAVEL_MAX 420 +#define V_JERK_MAX JERK_MAX +#define V_JERK_HIGH_SPEED 20000 +#define V_HOMING_INPUT 3 +#define V_HOMING_DIRECTION 0 +#define V_SEARCH_VELOCITY 3000 +#define V_LATCH_VELOCITY 100 +#define V_LATCH_BACKOFF 4 +#define V_ZERO_BACKOFF 2 + +#define W_AXIS_MODE AXIS_STANDARD +#define W_VELOCITY_MAX 1200 +#define W_FEEDRATE_MAX W_VELOCITY_MAX +#define W_TRAVEL_MAX 0 +#define W_TRAVEL_MIN -95 +#define W_JERK_MAX 500 +#define W_JERK_HIGH_SPEED 1000 +#define W_HOMING_INPUT 6 +#define W_HOMING_DIRECTION 1 +#define W_SEARCH_VELOCITY (W_VELOCITY_MAX * 0.66666) +#define W_LATCH_VELOCITY 25 +#define W_LATCH_BACKOFF 4 +#define W_ZERO_BACKOFF 2 + #define A_AXIS_MODE AXIS_STANDARD #define A_RADIUS 1 #define A_VELOCITY_MAX 360000 From 592f685164ef4fac4ff53018d5a35a7354c6c8ed Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 4 May 2017 15:41:14 -0400 Subject: [PATCH 254/283] Added uvw into axis manipulation helpers; added uvw into diagnostics --- g2core/canonical_machine.cpp | 3 ++- g2core/config.h | 4 ++-- g2core/config_app.cpp | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index aad4f8a7..a6f6bd30 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1754,6 +1754,7 @@ static int8_t _coord(nvObj_t *nv) // extract coordinate system from 3rd charac * - tofx tool offsets * - tt1x, tt32x tool table * - _tex, _tra diagnostic parameters + * - u,v,w handles U, V and W axes * * Note that this function will return an erroneous value if called by a non-axis tag, * such as 'coph' But it should not be called in these cases in any event. @@ -1775,7 +1776,7 @@ static int8_t _axis(const nvObj_t *nv) // otherwise it's an axis. Or undefined, which is usually a global. char *ptr; - char axes[] = {"xyzabc"}; + char axes[] = {"xyzuvwabc"}; if ((ptr = strchr(axes, c)) == NULL) { // not NULL indicates a prefixed axis c = *(cfgArray[nv->index].token + strlen(cfgArray[nv->index].token) -1); // get the last character diff --git a/g2core/config.h b/g2core/config.h index 1ade7dcc..dca2c4cc 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -69,10 +69,10 @@ * - axis tokens start with the axis letter and are typically 3 characters including the axis letter * - motor tokens start with the motor digit and are typically 3 characters including the motor digit * - non-axis or non-motor tokens are 2-6 characters and by convention generally should not start - * with: xyzabcuvw0123456789 (but there can be exceptions) + * with: xyzuvwabc0123456789 (but there can be exceptions) * * "Groups" are collections of values that mimic REST resources. Groups include: - * - axis groups prefixed by "xyzabc" ("uvw" are reserved) + * - axis groups prefixed by "xyzuvwabc" * - motor groups prefixed by "123456" ("789" are reserved) * - PWM groups prefixed by p1, p2 (p3 - p9 are reserved) * - coordinate system groups prefixed by g54, g55, g56, g57, g59, g28, g30, g92 diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 8e5f0f50..5e20db69 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1134,6 +1134,9 @@ const cfgItem_t cfgArray[] = { { "_te","_tex",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_X], 0 }, // X target endpoint { "_te","_tey",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_Y], 0 }, { "_te","_tez",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_Z], 0 }, + { "_te","_teu",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_U], 0 }, + { "_te","_tev",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_V], 0 }, + { "_te","_tew",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_W], 0 }, { "_te","_tea",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_A], 0 }, { "_te","_teb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_B], 0 }, { "_te","_tec",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->target[AXIS_C], 0 }, @@ -1141,6 +1144,9 @@ const cfgItem_t cfgArray[] = { { "_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_X], 0 }, // X target runtime { "_tr","_try",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_Y], 0 }, { "_tr","_trz",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_Z], 0 }, + { "_tr","_tru",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_U], 0 }, + { "_tr","_trv",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_V], 0 }, + { "_tr","_trw",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_W], 0 }, { "_tr","_tra",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_A], 0 }, { "_tr","_trb",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_B], 0 }, { "_tr","_trc",_f0, 2, tx_print_flt, get_flt, set_ro, (float *)&mr->gm.target[AXIS_C], 0 }, @@ -1258,6 +1264,9 @@ const cfgItem_t cfgArray[] = { { "","x", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // axis groups { "","y", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, { "","z", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","u", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","v", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, + { "","w", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, { "","a", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, { "","b", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, { "","c", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, From 101c351511727e29860596b8d249fd53bfbc175f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 4 May 2017 16:10:13 -0400 Subject: [PATCH 255/283] checkpoint --- g2core/canonical_machine.cpp | 2 +- g2core/config.h | 10 ++++++---- g2core/config_app.cpp | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index a6f6bd30..80d92e4a 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -533,7 +533,7 @@ stat_t cm_deferred_write_callback() nvObj_t nv; for (uint8_t i=1; i<=COORDS; i++) { for (uint8_t j=0; jcoord_offset[i][j]; nv_persist(&nv); // Note: nv_persist() only writes values that have changed diff --git a/g2core/config.h b/g2core/config.h index dca2c4cc..14e761a3 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -79,10 +79,12 @@ * - a system group is identified by "sys" and contains a collection of otherwise unrelated values * * "Uber-groups" are groups of groups that are only used for text-mode printing - e.g. - * - group of all axes groups - * - group of all motor groups - * - group of all offset groups - * - group of all groups + * - group of all motor groups (m) + * - group of all axes groups (q) + * - group of all offset groups (o) + * - group of all digital input groups (di) + * - group of all digital output groups (do) + * - group of all groups ($) */ /* --- Making changes and adding new values * diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 5e20db69..580f1373 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -1657,7 +1657,7 @@ static stat_t _do_motors(nvObj_t *nv) // print parameters for all motor groups static stat_t _do_axes(nvObj_t *nv) // print parameters for all axis groups { - char list[][TOKEN_LEN+1] = {"x","y","z","a","b","c",""}; // must have a terminating element + char list[][TOKEN_LEN+1] = {"x","y","z","u","v","w","a","b","c",""}; // must have a terminating element return (_do_group_list(nv, list)); } From 39171e8fff0e53eacec222c539c0bbcf83a73308 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Fri, 5 May 2017 13:44:16 -0400 Subject: [PATCH 256/283] Modifications to st_get_ma() and st_set_ma() to deal with axis remapping --- g2core/stepper.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index eb7d572c..2e914620 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -792,7 +792,7 @@ static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps) ***********************************************************************************/ /* HELPERS - * _motor() - motor number as an index or -1 if na + * _motor() - motor number as an index or -1 if na */ static int8_t _motor(const index_t index) @@ -832,9 +832,50 @@ static float _set_motor_steps_per_unit(nvObj_t *nv) * st_set_pl() - set motor power level */ -// motor axis mapping -stat_t st_get_ma(nvObj_t *nv) { return(get_integer(nv, st_cfg.mot[_motor(nv->index)].motor_map)); } -stat_t st_set_ma(nvObj_t *nv) { return(set_integer(nv, st_cfg.mot[_motor(nv->index)].motor_map, 0, AXES)); } +/* + * st_get_ma() - get motor axis mapping + * + * Legacy axis numbers are XYZABC for axis 0-5 + * External axis numbers are XYZABCUVW for axis 0-8 + * Internal axis numbers are XYZUVWABC for axis 0-8 (for various code reasons) + * + * This function retrieves an internal axis number and remaps it to an external axis number + */ +stat_t st_get_ma(nvObj_t *nv) +{ + uint8_t remap_axis[9] = { 0,1,2,6,7,8,3,4,5 }; + ritorno(get_integer(nv, st_cfg.mot[_motor(nv->index)].motor_map)); + nv->value_int = remap_axis[nv->value_int]; + return(STAT_OK); +} + +/* + * st_set_ma() - set motor axis mapping + * + * Legacy axis numbers are XYZABC for axis 0-5 + * External axis numbers are XYZABCUVW for axis 0-8 + * Internal axis numbers are XYZUVWABC for axis 0-8 (for various code reasons) + * + * This function accepts an external axis number and remaps it to an external axis number, + * writes the internal axis number and returns the external number in the JSON response. + */ +stat_t st_set_ma(nvObj_t *nv) +{ + if (nv->value_int < 0) { + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_LESS_THAN_MIN_VALUE); + } + if (nv->value_int > AXES) { + nv->valuetype = TYPE_NULL; + return (STAT_INPUT_EXCEEDS_MAX_VALUE); + } + uint8_t external_axis = nv->value_int; + uint8_t remap_axis[9] = { 0,1,2,6,7,8,3,4,5 }; + nv->value_int = remap_axis[nv->value_int]; + ritorno(set_integer(nv, st_cfg.mot[_motor(nv->index)].motor_map, 0, AXES)); + nv->value_int = external_axis; + return(STAT_OK); +} // step angle stat_t st_get_sa(nvObj_t *nv) { return(get_float(nv, st_cfg.mot[_motor(nv->index)].step_angle)); } From cc2a31e10cbfbc54589ccdd57cefbcf6dcf09183 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 6 May 2017 06:48:19 -0400 Subject: [PATCH 257/283] Added EXTERNAL axes to fix initializations --- g2core/g2core.cppproj | 4 ++-- g2core/g2core.h | 12 ++++++++++++ g2core/settings/settings_default.h | 12 ++++++------ g2core/settings/settings_makeblock.h | 10 +++++----- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 876b4307..b8ee2360 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -73,7 +73,7 @@ SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800036434 Atmel-ICE True @@ -100,7 +100,7 @@ True true - J41800019454 + J41800036434 0x284E0A60 10000000 diff --git a/g2core/g2core.h b/g2core/g2core.h index 80b52c56..045fddb5 100644 --- a/g2core/g2core.h +++ b/g2core/g2core.h @@ -72,6 +72,18 @@ typedef enum { AXIS_C } cmAxes; +typedef enum { // external representation of axes (used in initialization) + AXIS_X_EXTERNAL = 0, + AXIS_Y_EXTERNAL, + AXIS_Z_EXTERNAL, + AXIS_A_EXTERNAL, + AXIS_B_EXTERNAL, + AXIS_C_EXTERNAL, + AXIS_U_EXTERNAL, + AXIS_V_EXTERNAL, + AXIS_W_EXTERNAL +} cmAxesExternal; + typedef enum { OFS_I = 0, OFS_J, diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index b8e75645..00cd7777 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -222,7 +222,7 @@ // MOTOR 1 #ifndef M1_MOTOR_MAP -#define M1_MOTOR_MAP AXIS_X // {1ma: AXIS_X, AXIS_Y... +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // {1ma: AXIS_X, AXIS_Y... #endif #ifndef M1_STEP_ANGLE #define M1_STEP_ANGLE 1.8 // {1sa: degrees per step @@ -248,7 +248,7 @@ // MOTOR 2 #ifndef M2_MOTOR_MAP -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #endif #ifndef M2_STEP_ANGLE #define M2_STEP_ANGLE 1.8 @@ -274,7 +274,7 @@ // MOTOR 3 #ifndef M3_MOTOR_MAP -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #endif #ifndef M3_STEP_ANGLE #define M3_STEP_ANGLE 1.8 @@ -300,7 +300,7 @@ // MOTOR 4 #ifndef M4_MOTOR_MAP -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #endif #ifndef M4_STEP_ANGLE #define M4_STEP_ANGLE 1.8 @@ -326,7 +326,7 @@ // MOTOR 5 #ifndef M5_MOTOR_MAP -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #endif #ifndef M5_STEP_ANGLE #define M5_STEP_ANGLE 1.8 @@ -352,7 +352,7 @@ // MOTOR 6 #ifndef M6_MOTOR_MAP -#define M6_MOTOR_MAP AXIS_C +#define M6_MOTOR_MAP AXIS_C_EXTERNAL #endif #ifndef M6_STEP_ANGLE #define M6_STEP_ANGLE 1.8 diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 1b7ec8b8..110c2726 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -92,9 +92,9 @@ // 2=MOTOR_POWERED_IN_CYCLE, // 3=MOTOR_POWERED_ONLY_WHEN_MOVING #define M1_POWER_LEVEL 0.4 // 1pl: 0.0=no power, 1.0=max power -#define MOTOR_POWER_TIMEOUT 10.00 // motor power timeout in seconds +#define MOTOR_POWER_TIMEOUT 10.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 36.576 // 1tr 2.032mm pitch * 18 teeth per revolution #define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 @@ -102,7 +102,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm 0=MOTOR_DISABLED, 1=MOTOR_ALWAYS_POWERED, 2=MOTOR_POWERED_IN_CYCLE, 3=MOTOR_POWERED_ONLY_WHEN_MOVING #define M1_POWER_LEVEL 0.4 -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 36.576 #define M2_MICROSTEPS 8 @@ -110,7 +110,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.4 -#define M3_MOTOR_MAP AXIS_Z // Imaginary Z axis. For testing +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL // Imaginary Z axis. For testing #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 1.25 #define M3_MICROSTEPS 8 @@ -118,7 +118,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.4 -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 1.25 #define M4_MICROSTEPS 8 From 3c21a71a700904f2f47d40e013256afbe6bd623c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 6 May 2017 07:32:47 -0400 Subject: [PATCH 258/283] Updated profiles for external axes enums --- g2core/settings/settings_Printrbot_Play.h | 10 +++---- g2core/settings/settings_Printrbot_Plus.h | 10 +++---- .../settings/settings_Printrbot_Simple_1403.h | 10 +++---- .../settings/settings_Printrbot_Simple_1608.h | 10 +++---- g2core/settings/settings_Ultimaker.h | 16 ++++++------ g2core/settings/settings_makeblock.h | 4 +-- g2core/settings/settings_othermill.h | 26 +++++++++---------- g2core/settings/settings_othermill_test.h | 26 +++++++++---------- g2core/settings/settings_probotixV90.h | 8 +++--- g2core/settings/settings_shapeoko2.h | 8 +++--- g2core/settings/settings_shopbot_sbv300.h | 12 ++++----- g2core/settings/settings_shopbot_test.h | 12 ++++----- g2core/settings/settings_test.h | 10 +++---- g2core/settings/settings_zen7x12.h | 8 +++--- 14 files changed, 85 insertions(+), 85 deletions(-) mode change 100755 => 100644 g2core/settings/settings_zen7x12.h diff --git a/g2core/settings/settings_Printrbot_Play.h b/g2core/settings/settings_Printrbot_Play.h index f24fdfb3..47ce71ce 100644 --- a/g2core/settings/settings_Printrbot_Play.h +++ b/g2core/settings/settings_Printrbot_Play.h @@ -101,7 +101,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 40.64 // 1tr #define M1_MICROSTEPS 32 // 1mi 1,2,4,8,16,32 @@ -110,7 +110,7 @@ #define M1_POWER_LEVEL 0.4 // 1pl: 0.0=no power, 1.0=max power // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M3_MOTOR_MAP AXIS_Y +#define M3_MOTOR_MAP AXIS_Y_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 40.64 #define M3_MICROSTEPS 32 @@ -118,7 +118,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.4 -#define M2_MOTOR_MAP AXIS_Z +#define M2_MOTOR_MAP AXIS_Z_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 1.5875 #define M2_MICROSTEPS 32 @@ -127,7 +127,7 @@ #define M2_POWER_LEVEL 0.4 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 32 @@ -136,7 +136,7 @@ #define M4_POWER_LEVEL 0.4 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 32 diff --git a/g2core/settings/settings_Printrbot_Plus.h b/g2core/settings/settings_Printrbot_Plus.h index a0f890ad..81f6f5dc 100644 --- a/g2core/settings/settings_Printrbot_Plus.h +++ b/g2core/settings/settings_Printrbot_Plus.h @@ -101,7 +101,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 40.64 // 1tr #define M1_MICROSTEPS 32 // 1mi 1,2,4,8,16,32 @@ -110,7 +110,7 @@ #define M1_POWER_LEVEL 0.4 // 1pl: 0.0=no power, 1.0=max power // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M3_MOTOR_MAP AXIS_Y +#define M3_MOTOR_MAP AXIS_Y_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 40.64 #define M3_MICROSTEPS 32 @@ -118,7 +118,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.4 -#define M2_MOTOR_MAP AXIS_Z +#define M2_MOTOR_MAP AXIS_Z_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 1.5875 #define M2_MICROSTEPS 32 @@ -127,7 +127,7 @@ #define M2_POWER_LEVEL 0.4 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 32 @@ -136,7 +136,7 @@ #define M4_POWER_LEVEL 0.4 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 32 diff --git a/g2core/settings/settings_Printrbot_Simple_1403.h b/g2core/settings/settings_Printrbot_Simple_1403.h index 26114747..9ff22a41 100644 --- a/g2core/settings/settings_Printrbot_Simple_1403.h +++ b/g2core/settings/settings_Printrbot_Simple_1403.h @@ -101,7 +101,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 40.64 // 1tr #define M1_MICROSTEPS 32 // 1mi 1,2,4,8,16,32 @@ -110,7 +110,7 @@ #define M1_POWER_LEVEL 0.4 // 1pl: 0.0=no power, 1.0=max power // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M3_MOTOR_MAP AXIS_Y +#define M3_MOTOR_MAP AXIS_Y_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 40.64 #define M3_MICROSTEPS 32 @@ -118,7 +118,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.4 -#define M2_MOTOR_MAP AXIS_Z +#define M2_MOTOR_MAP AXIS_Z_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 1.5875 #define M2_MICROSTEPS 32 @@ -127,7 +127,7 @@ #define M2_POWER_LEVEL 0.4 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 32 @@ -136,7 +136,7 @@ #define M4_POWER_LEVEL 0.4 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 32 diff --git a/g2core/settings/settings_Printrbot_Simple_1608.h b/g2core/settings/settings_Printrbot_Simple_1608.h index 237340ba..2ee57ef2 100644 --- a/g2core/settings/settings_Printrbot_Simple_1608.h +++ b/g2core/settings/settings_Printrbot_Simple_1608.h @@ -110,7 +110,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 40.011604 // 1tr #define M1_MICROSTEPS 32 // 1mi 1,2,4,8,16,32 @@ -119,7 +119,7 @@ #define M1_POWER_LEVEL 0.35 // 1pl: 0.0=no power, 1.0=max power // 80 steps/mm at 1/16 microstepping = 40 mm/rev -#define M3_MOTOR_MAP AXIS_Y +#define M3_MOTOR_MAP AXIS_Y_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 40.011604 #define M3_MICROSTEPS 32 @@ -128,7 +128,7 @@ #define M3_POWER_LEVEL 0.35 // 2020 steps/mm at 1/16 microstepping = 1.58416 mm/rev -#define M2_MOTOR_MAP AXIS_Z +#define M2_MOTOR_MAP AXIS_Z_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 8 #define M2_MICROSTEPS 32 @@ -137,7 +137,7 @@ #define M2_POWER_LEVEL 0.3 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 32 @@ -146,7 +146,7 @@ #define M4_POWER_LEVEL 0.3 // 96 steps/mm at 1/16 microstepping = 33.3333 mm/rev -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 32 diff --git a/g2core/settings/settings_Ultimaker.h b/g2core/settings/settings_Ultimaker.h index 375d5edc..65d6f3c6 100644 --- a/g2core/settings/settings_Ultimaker.h +++ b/g2core/settings/settings_Ultimaker.h @@ -2,8 +2,8 @@ * settings_Ultimaker.h - Ultimaker motion demo * This file is part of the the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -85,7 +85,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) #define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 40.64 // 1tr #define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 @@ -93,7 +93,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard #define M1_POWER_LEVEL 0.375 // 1pl: 0.0=no power, 1.0=max power -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 40.64 #define M2_MICROSTEPS 8 @@ -101,7 +101,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.375 -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 3.00 #define M3_MICROSTEPS 8 @@ -109,7 +109,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.375 -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 8 @@ -117,7 +117,7 @@ #define M4_POWER_MODE MOTOR_POWER_MODE #define M4_POWER_LEVEL 0.375 -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 8 @@ -125,7 +125,7 @@ #define M5_POWER_MODE MOTOR_POWER_MODE #define M5_POWER_LEVEL 0.375 -#define M6_MOTOR_MAP AXIS_C +#define M6_MOTOR_MAP AXIS_C_EXTERNAL #define M6_STEP_ANGLE 1.8 #define M6_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M6_MICROSTEPS 8 diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 110c2726..a908ebfd 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -120,9 +120,9 @@ #define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV 1.25 +#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 8 -#define M4_POLARITY 0 +#define M4_POLARITY 1 #define M4_POWER_MODE MOTOR_POWER_MODE #define M4_POWER_LEVEL 0.4 diff --git a/g2core/settings/settings_othermill.h b/g2core/settings/settings_othermill.h index 6b3607d5..66e6bd2d 100644 --- a/g2core/settings/settings_othermill.h +++ b/g2core/settings/settings_othermill.h @@ -107,18 +107,18 @@ #define MOTOR_POWER_LEVEL_DISABLED 0.05 #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 4.8768 // 1tr -#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 -#define M1_POLARITY 1 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h -#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 4.8768 // 1tr +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max #define M1_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 4.8768 #define M2_MICROSTEPS 8 @@ -127,7 +127,7 @@ #define M2_POWER_LEVEL MOTOR_POWER_LEVEL_XY #define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #if HAS_CANSTACK_Z_AXIS #define M3_STEP_ANGLE 15 #define M3_TRAVEL_PER_REV 1.27254 @@ -141,7 +141,7 @@ #define M3_POWER_LEVEL MOTOR_POWER_LEVEL_Z #define M3_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_Z_IDLE -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 8 @@ -150,7 +150,7 @@ #define M4_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED #define M4_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 8 @@ -159,7 +159,7 @@ #define M5_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED #define M5_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED -#define M6_MOTOR_MAP AXIS_C +#define M6_MOTOR_MAP AXIS_C_EXTERNAL #define M6_STEP_ANGLE 1.8 #define M6_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M6_MICROSTEPS 8 diff --git a/g2core/settings/settings_othermill_test.h b/g2core/settings/settings_othermill_test.h index 2c8720af..375aa862 100644 --- a/g2core/settings/settings_othermill_test.h +++ b/g2core/settings/settings_othermill_test.h @@ -94,18 +94,18 @@ #define MOTOR_POWER_LEVEL_DISABLED 0.05 #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE -#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds +#define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma -#define M1_STEP_ANGLE 1.8 // 1sa -#define M1_TRAVEL_PER_REV 4.8768 // 1tr -#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 -#define M1_POLARITY 1 // 1po 0=normal, 1=reversed -#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h -#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma +#define M1_STEP_ANGLE 1.8 // 1sa +#define M1_TRAVEL_PER_REV 4.8768 // 1tr +#define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 +#define M1_POLARITY 1 // 1po 0=normal, 1=reversed +#define M1_POWER_MODE MOTOR_POWER_MODE // 1pm See enum cmMotorPowerMode in stepper.h +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL_XY // 0.00=off, 1.00=max #define M1_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 4.8768 #define M2_MICROSTEPS 8 @@ -114,7 +114,7 @@ #define M2_POWER_LEVEL MOTOR_POWER_LEVEL_XY #define M2_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_XY_IDLE -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 4.8768 #define M3_MICROSTEPS 8 @@ -123,7 +123,7 @@ #define M3_POWER_LEVEL MOTOR_POWER_LEVEL_Z #define M3_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_Z_IDLE -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 8 @@ -132,7 +132,7 @@ #define M4_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED #define M4_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M5_MICROSTEPS 8 @@ -141,7 +141,7 @@ #define M5_POWER_LEVEL MOTOR_POWER_LEVEL_DISABLED #define M5_POWER_LEVEL_IDLE MOTOR_POWER_LEVEL_DISABLED -#define M6_MOTOR_MAP AXIS_C +#define M6_MOTOR_MAP AXIS_C_EXTERNAL #define M6_STEP_ANGLE 1.8 #define M6_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M6_MICROSTEPS 8 diff --git a/g2core/settings/settings_probotixV90.h b/g2core/settings/settings_probotixV90.h index 33549c86..efdaf376 100644 --- a/g2core/settings/settings_probotixV90.h +++ b/g2core/settings/settings_probotixV90.h @@ -2,7 +2,7 @@ * settings_probotix.h - Probotix Fireball V90 machine profile * This file is part the g2core project * - * Copyright (c) 2011 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -83,7 +83,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) #define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 5.08 // 1tr #define M1_MICROSTEPS 8 // 1mi 1,2,4,8 @@ -91,7 +91,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard #define M1_POWER_LEVEL 0.75 -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 5.08 #define M2_MICROSTEPS 8 @@ -99,7 +99,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.75 -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 2.1166666 #define M3_MICROSTEPS 8 diff --git a/g2core/settings/settings_shapeoko2.h b/g2core/settings/settings_shapeoko2.h index 302ab860..fe14f5d7 100644 --- a/g2core/settings/settings_shapeoko2.h +++ b/g2core/settings/settings_shapeoko2.h @@ -2,7 +2,7 @@ * settings_shapeoko2.h - Shapeoko2 500mm table * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -86,7 +86,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) #define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 40.00 // 1tr #define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 @@ -94,7 +94,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled #define M1_POWER_LEVEL 0.500 -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 40.00 #define M2_MICROSTEPS 8 @@ -102,7 +102,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.500 -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 1.25 #define M3_MICROSTEPS 8 diff --git a/g2core/settings/settings_shopbot_sbv300.h b/g2core/settings/settings_shopbot_sbv300.h index 2472569f..348f97a2 100644 --- a/g2core/settings/settings_shopbot_sbv300.h +++ b/g2core/settings/settings_shopbot_sbv300.h @@ -91,7 +91,7 @@ #define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds #define MOTOR_POWER_LEVEL 0.375 // default motor power level 0.00 - 1.00 -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr #define M1_MICROSTEPS 10 // 1mi 1,2,4,8 @@ -99,7 +99,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled #define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV (0.5 * 25.4) #define M2_MICROSTEPS 10 @@ -107,7 +107,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL MOTOR_POWER_LEVEL -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV (0.5 * 25.4) #define M3_MICROSTEPS 10 @@ -115,7 +115,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL MOTOR_POWER_LEVEL -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV (0.5 * 25.4) #define M4_MICROSTEPS 10 @@ -124,7 +124,7 @@ #define M4_POWER_LEVEL MOTOR_POWER_LEVEL #if (MOTORS >= 5) -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV (0.5 * 25.4) #define M5_MICROSTEPS 10 @@ -132,7 +132,7 @@ #define M5_POWER_MODE MOTOR_POWER_MODE #define M5_POWER_LEVEL MOTOR_POWER_LEVEL -#define M6_MOTOR_MAP AXIS_C +#define M6_MOTOR_MAP AXIS_C_EXTERNAL #define M6_STEP_ANGLE 1.8 #define M6_TRAVEL_PER_REV (0.5 * 25.4) #define M6_MICROSTEPS 10 diff --git a/g2core/settings/settings_shopbot_test.h b/g2core/settings/settings_shopbot_test.h index 53c980a9..329d2906 100644 --- a/g2core/settings/settings_shopbot_test.h +++ b/g2core/settings/settings_shopbot_test.h @@ -93,7 +93,7 @@ #define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds #define MOTOR_POWER_LEVEL 0.375 // default motor power level 0.00 - 1.00 -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV (0.5 * 25.4) // 1tr #define M1_MICROSTEPS 8 // 1mi 1,2,4,8 @@ -101,7 +101,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm TRUE=low power idle enabled #define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl Irrelevant to Shopbot sbv300 -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV (0.5 * 25.4) #define M2_MICROSTEPS 8 @@ -109,7 +109,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL MOTOR_POWER_LEVEL -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV (0.5 * 25.4) #define M3_MICROSTEPS 8 @@ -117,7 +117,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL MOTOR_POWER_LEVEL -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 48 // was (0.5 * 25.4) Set to agree with sbv300 su = 33.333333 #define M4_MICROSTEPS 8 @@ -125,7 +125,7 @@ #define M4_POWER_MODE MOTOR_POWER_MODE #define M4_POWER_LEVEL MOTOR_POWER_LEVEL -#define M5_MOTOR_MAP AXIS_B +#define M5_MOTOR_MAP AXIS_B_EXTERNAL #define M5_STEP_ANGLE 1.8 #define M5_TRAVEL_PER_REV 48 // (0.5 * 25.4) #define M5_MICROSTEPS 8 @@ -133,7 +133,7 @@ #define M5_POWER_MODE MOTOR_POWER_MODE #define M5_POWER_LEVEL MOTOR_POWER_LEVEL -#define M6_MOTOR_MAP AXIS_C +#define M6_MOTOR_MAP AXIS_C_EXTERNAL #define M6_STEP_ANGLE 1.8 #define M6_TRAVEL_PER_REV 48 // (0.5 * 25.4) #define M6_MICROSTEPS 8 diff --git a/g2core/settings/settings_test.h b/g2core/settings/settings_test.h index 9a92a955..03e82919 100644 --- a/g2core/settings/settings_test.h +++ b/g2core/settings/settings_test.h @@ -2,7 +2,7 @@ * settings_test.h - settings for testing - subject to wild change * This file is part of the g2core project * - * Copyright (c) 2014 - 2016 Alden S. Hart Jr. + * Copyright (c) 2014 - 2017 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -89,7 +89,7 @@ #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see cmMotorPowerMode in stepper.h) #define MOTOR_POWER_TIMEOUT 2.00 // motor power timeout in seconds -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 5.08 // 1tr #define M1_MICROSTEPS 8 // 1mi 1,2,4,8 @@ -97,7 +97,7 @@ #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm standard #define M1_POWER_LEVEL 0.75 -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 5.08 #define M2_MICROSTEPS 8 @@ -105,7 +105,7 @@ #define M2_POWER_MODE MOTOR_POWER_MODE #define M2_POWER_LEVEL 0.75 -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 2.1166666 #define M3_MICROSTEPS 8 @@ -113,7 +113,7 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.50 -#define M4_MOTOR_MAP AXIS_A +#define M4_MOTOR_MAP AXIS_A_EXTERNAL #define M4_STEP_ANGLE 1.8 #define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev #define M4_MICROSTEPS 32 diff --git a/g2core/settings/settings_zen7x12.h b/g2core/settings/settings_zen7x12.h old mode 100755 new mode 100644 index f167a484..516014ca --- a/g2core/settings/settings_zen7x12.h +++ b/g2core/settings/settings_zen7x12.h @@ -2,7 +2,7 @@ * settings_zen7x12.h - Zen Toolworks 7x12 machine profile * This file is part of the g2core project * - * Copyright (c) 2011 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -46,7 +46,7 @@ // *** motor settings *** -#define M1_MOTOR_MAP AXIS_X // 1ma +#define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa #define M1_TRAVEL_PER_REV 1.25 // 1tr #define M1_MICROSTEPS 8 // 1mi 1,2,4,8 @@ -54,7 +54,7 @@ #define M1_POWER_MODE MOTOR_POWERED_IN_CYCLE // 1pm standard #define M1_POWER_LEVEL 0.5 // 1pl: 0.0=no power, 1.0=max power -#define M2_MOTOR_MAP AXIS_Y +#define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 #define M2_TRAVEL_PER_REV 1.25 #define M2_MICROSTEPS 8 @@ -62,7 +62,7 @@ #define M2_POWER_MODE MOTOR_POWERED_IN_CYCLE #define M2_POWER_LEVEL 0.5 -#define M3_MOTOR_MAP AXIS_Z +#define M3_MOTOR_MAP AXIS_Z_EXTERNAL #define M3_STEP_ANGLE 1.8 #define M3_TRAVEL_PER_REV 1.25 #define M3_MICROSTEPS 8 From 80e968ae068b2955231db8af84dd9af5aa751148 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 6 May 2017 08:18:45 -0400 Subject: [PATCH 259/283] Add flag checks for UVW axes; Fix aline coordinate rotations for new axis enumerations --- g2core/canonical_machine.cpp | 10 +++++++--- g2core/canonical_machine.h | 2 +- g2core/plan_line.cpp | 35 ++++++++++++++++++++--------------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 80d92e4a..fd5bf25a 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1143,7 +1143,9 @@ stat_t cm_straight_traverse(const float *target, const bool *flags, const uint8_ cm->gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE; // it's legal for a G0 to have no axis words but we don't want to process it - if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { + if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | + flags[AXIS_U] | flags[AXIS_V] | flags[AXIS_W] | + flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { return(STAT_OK); } cm_set_model_target(target, flags); @@ -1299,8 +1301,10 @@ stat_t cm_straight_feed(const float *target, const bool *flags, const uint8_t mo } cm->gm.motion_mode = MOTION_MODE_STRAIGHT_FEED; - // it's legal for a G1 to have no axis words but we don't want to process it - if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { + // it's legal for a G0 to have no axis words but we don't want to process it + if (!(flags[AXIS_X] | flags[AXIS_Y] | flags[AXIS_Z] | + flags[AXIS_U] | flags[AXIS_V] | flags[AXIS_W] | + flags[AXIS_A] | flags[AXIS_B] | flags[AXIS_C])) { return(STAT_OK); } diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index beaf85a8..b3c44599 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -318,7 +318,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple) float probe_results[PROBES_STORED][AXES]; // probing results - float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore rotary axes. + float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore UVW and ABC rotary axes float rotation_z_offset; // separately handle a z-offset to maintain consistent distance to bed float jogging_dest; // jogging destination as a relative move from current position diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 26f9ed58..1d23863e 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -143,8 +143,8 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); } stat_t mp_aline(GCodeState_t* _gm) { - float target_rotated[AXES] = {0,0,0,0,0,0}; - float axis_square[AXES] = {0,0,0,0,0,0}; + float target_rotated[AXES] = { 0,0,0,0,0,0,0,0,0 }; + float axis_square[AXES] = { 0,0,0,0,0,0,0,0,0 }; float axis_length[AXES]; bool flags[AXES]; float length_square = 0; @@ -169,23 +169,28 @@ stat_t mp_aline(GCodeState_t* _gm) // c being target[2], // x_1 being cm->rotation_matrix[1][0] - target_rotated[0] = _gm->target[0] * cm->rotation_matrix[0][0] + - _gm->target[1] * cm->rotation_matrix[0][1] + - _gm->target[2] * cm->rotation_matrix[0][2]; + target_rotated[AXIS_X] = _gm->target[AXIS_X] * cm->rotation_matrix[0][0] + + _gm->target[AXIS_Y] * cm->rotation_matrix[0][1] + + _gm->target[AXIS_Z] * cm->rotation_matrix[0][2]; - target_rotated[1] = _gm->target[0] * cm->rotation_matrix[1][0] + - _gm->target[1] * cm->rotation_matrix[1][1] + - _gm->target[2] * cm->rotation_matrix[1][2]; + target_rotated[AXIS_Y] = _gm->target[AXIS_X] * cm->rotation_matrix[1][0] + + _gm->target[AXIS_Y] * cm->rotation_matrix[1][1] + + _gm->target[AXIS_Z] * cm->rotation_matrix[1][2]; - target_rotated[2] = _gm->target[0] * cm->rotation_matrix[2][0] + - _gm->target[1] * cm->rotation_matrix[2][1] + - _gm->target[2] * cm->rotation_matrix[2][2] + - cm->rotation_z_offset; + target_rotated[AXIS_Z] = _gm->target[AXIS_X] * cm->rotation_matrix[2][0] + + _gm->target[AXIS_Y] * cm->rotation_matrix[2][1] + + _gm->target[AXIS_Z] * cm->rotation_matrix[2][2] + + cm->rotation_z_offset; + + // copy rotation axes for UVW (no changes) + target_rotated[AXIS_U] = _gm->target[AXIS_U]; + target_rotated[AXIS_V] = _gm->target[AXIS_V]; + target_rotated[AXIS_W] = _gm->target[AXIS_W]; // copy rotation axes for ABC (no changes) - target_rotated[3] = _gm->target[3]; - target_rotated[4] = _gm->target[4]; - target_rotated[5] = _gm->target[5]; + target_rotated[AXIS_A] = _gm->target[AXIS_A]; + target_rotated[AXIS_B] = _gm->target[AXIS_B]; + target_rotated[AXIS_B] = _gm->target[AXIS_C]; for (uint8_t axis = 0; axis < AXES; axis++) { axis_length[axis] = target_rotated[axis] - mp->position[axis]; From d0e7b81b1e70c0cbcfed55e7225fae7c47720e18 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 6 May 2017 09:04:06 -0400 Subject: [PATCH 260/283] First commit where UVW actually causes movement --- g2core/canonical_machine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index fd5bf25a..34df9481 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -475,7 +475,7 @@ float cm_get_display_position(const GCodeState_t *gcode_state, const uint8_t axi } else { position = mp_get_runtime_display_position(axis); } - if (axis <= AXIS_Z) { + if (axis <= AXIS_W) { // linears if (gcode_state->units_mode == INCHES) { position /= MM_PER_INCH; } @@ -720,8 +720,8 @@ void cm_set_model_target(const float target[], const bool flags[]) // copy position to target so it always starts correctly copy_vector(cm->gm.target, cm->gmx.position); - // process XYZABC for lower modes - for (axis=AXIS_X; axis<=AXIS_Z; axis++) { + // process linear axes (XYZUVW) first + for (axis=AXIS_X; axis<=AXIS_W; axis++) { if (!flags[axis] || cm->a[axis].axis_mode == AXIS_DISABLED) { continue; // skip axis if not flagged for update or its disabled } else if ((cm->a[axis].axis_mode == AXIS_STANDARD) || (cm->a[axis].axis_mode == AXIS_INHIBITED)) { @@ -733,7 +733,7 @@ void cm_set_model_target(const float target[], const bool flags[]) cm->return_flags[axis] = true; // used to make a synthetic G28/G30 intermediate move } } - // FYI: The ABC loop below relies on the XYZ loop having been run first + // FYI: The ABC loop below relies on the XYZUVW loop having been run first for (axis=AXIS_A; axis<=AXIS_C; axis++) { if (!flags[axis] || cm->a[axis].axis_mode == AXIS_DISABLED) { continue; // skip axis if not flagged for update or its disabled From de0604b41158d2aeb35cc9a56be732b8878f866b Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 16 Aug 2017 08:35:32 -0400 Subject: [PATCH 261/283] Checkpoint - tested X and Y movement; minor change to project file --- g2core/g2core.cppproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b8ee2360..0b608521 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 10000000 + 2000000 SWD com.atmel.avrdbg.tool.atmelice - J41800036434 + J41800019454 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800036434 + J41800019454 0x284E0A60 - 10000000 + 2000000 From 5b4919b2a070ef6fdedb9c82fcd5396662e8e910 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 16 Aug 2017 08:57:30 -0400 Subject: [PATCH 262/283] Updated Makeblock settings for dual Z (Z and W) --- g2core/settings/settings_makeblock.h | 35 +++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index a908ebfd..3c3d8cbe 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -85,7 +85,6 @@ // *** motor settings ************************************************************************************ - #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see stPowerMode in stepper.h) // 0=MOTOR_DISABLED, // 1=MOTOR_ALWAYS_POWERED, @@ -118,9 +117,9 @@ #define M3_POWER_MODE MOTOR_POWER_MODE #define M3_POWER_LEVEL 0.4 -#define M4_MOTOR_MAP AXIS_A_EXTERNAL +#define M4_MOTOR_MAP AXIS_W_EXTERNAL // Imaginary W axis. For testing #define M4_STEP_ANGLE 1.8 -#define M4_TRAVEL_PER_REV 360 // degrees moved per motor rev +#define M4_TRAVEL_PER_REV 1.25 #define M4_MICROSTEPS 8 #define M4_POLARITY 1 #define M4_POWER_MODE MOTOR_POWER_MODE @@ -229,6 +228,36 @@ #define A_LATCH_BACKOFF 10 #define A_ZERO_BACKOFF 2 +#define B_AXIS_MODE AXIS_STANDARD +#define B_RADIUS 1 +#define B_VELOCITY_MAX 360000 +#define B_FEEDRATE_MAX B_VELOCITY_MAX +#define B_TRAVEL_MIN -1 +#define B_TRAVEL_MAX -1 +#define B_JERK_MAX 100000 +#define B_JERK_HIGH_SPEED B_JERK_MAX +#define B_HOMING_INPUT 0 +#define B_HOMING_DIRECTION 0 +#define B_SEARCH_VELOCITY 600 +#define B_LATCH_VELOCITY 100 +#define B_LATCH_BACKOFF 10 +#define B_ZERO_BACKOFF 2 + +#define C_AXIS_MODE AXIS_STANDARD +#define C_RADIUS 1 +#define C_VELOCITY_MAX 360000 +#define C_FEEDRATE_MAX C_VELOCITY_MAX +#define C_TRAVEL_MIN -1 +#define C_TRAVEL_MAX -1 +#define C_JERK_MAX 100000 +#define C_JERK_HIGH_SPEED C_JERK_MAX +#define C_HOMING_INPUT 0 +#define C_HOMING_DIRECTION 0 +#define C_SEARCH_VELOCITY 600 +#define C_LATCH_VELOCITY 100 +#define C_LATCH_BACKOFF 10 +#define C_ZERO_BACKOFF 2 + //*** Input / output settings *** /* See gpio.h GPIO defines for options From 941d33ec34ea263bfb6674457ca7f31f20c0c8ef Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Thu, 17 Aug 2017 10:16:27 -0400 Subject: [PATCH 263/283] Added UVW into status reports; testing --- g2core/g2core_info.h | 2 +- g2core/settings/settings_makeblock.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index 1f3245ba..d751e7d2 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 100.26 // Merged fixes for #267 and PR #258 +#define G2CORE_FIRMWARE_BUILD 100.27 // Working on UVW #define G2CORE_FIRMWARE_VERSION 0.99 #ifdef GIT_VERSION diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 3c3d8cbe..1fa04d64 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -69,10 +69,13 @@ #define STATUS_REPORT_MIN_MS 200 // milliseconds - enforces a viable minimum #define STATUS_REPORT_INTERVAL_MS 250 // milliseconds - set $SV=0 to disable -#define STATUS_REPORT_DEFAULTS "line","stat","posx","posy","posz",\ +#define STATUS_REPORT_DEFAULTS "line","stat",\ + "posx","posy","posz",\ + "posu","posv","posw",\ "vel", "unit","feed","coor","momo",\ "plan","path","dist","prbe","prbz",\ "mpox","mpoy","mpoz",\ + "mpou","mpov","mpow",\ "admo","frmo","cycs","hold" // "_ts1","_cs1","_es1","_xs1","_fe1" From 7802e351e76809f20bd9442db8e88bf6bbf4d9ee Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Fri, 27 Oct 2017 13:52:34 -0500 Subject: [PATCH 264/283] Attempted fix for #298 (reading nested JSON fail) --- g2core/json_parser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index 3c48d084..531df60a 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -116,7 +116,9 @@ void json_parse_for_exec(char *str, bool execute) static stat_t _json_parser_execute(nvObj_t *nv) { do { - if (nv->valuetype == TYPE_NULL) { // means GET the value + if (nv->valuetype == TYPE_PARENT) { + // anything? + } else if (nv->valuetype == TYPE_NULL) { // means GET the value ritorno(nv_get(nv)); // ritorno returns w/status on any errors if (nv->valuetype == TYPE_PARENT) { // This will be true if you read a group. Exit now return (STAT_OK); From c3f1869271082a9f013f1f2f23a214b83cc89358 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 26 Mar 2018 09:21:03 -0400 Subject: [PATCH 265/283] Fixed typo in settings_default.h; fixed bug in B and C axes mapping in plan_line.cpp --- g2core/g2core.cppproj | 4 ++-- g2core/plan_line.cpp | 2 +- g2core/settings/settings_default.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0b608521..876b4307 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 2000000 + 10000000 SWD @@ -102,7 +102,7 @@ true J41800019454 0x284E0A60 - 2000000 + 10000000 diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 1d23863e..4d147206 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -190,7 +190,7 @@ stat_t mp_aline(GCodeState_t* _gm) // copy rotation axes for ABC (no changes) target_rotated[AXIS_A] = _gm->target[AXIS_A]; target_rotated[AXIS_B] = _gm->target[AXIS_B]; - target_rotated[AXIS_B] = _gm->target[AXIS_C]; + target_rotated[AXIS_C] = _gm->target[AXIS_C]; for (uint8_t axis = 0; axis < AXES; axis++) { axis_length[axis] = target_rotated[axis] - mp->position[axis]; diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 00cd7777..c97979f8 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -582,7 +582,7 @@ #define V_LATCH_BACKOFF 4.0 #endif #ifndef V_ZERO_BACKOFF -#define Y_ZERO_BACKOFF 2.0 +#define V_ZERO_BACKOFF 2.0 #endif // W AXIS From d03a10e8b8ed6698aa2ff4baae45a4cc96b6f215 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 26 Mar 2018 12:18:26 -0400 Subject: [PATCH 266/283] Updated copyright dates. Tested dev-304-uvw-9axis/edge merge. Passed baseline testing. Fails Spindle test SPIN-02. ToGo - GPIO, Feedhold, Probing, Homing and Planner cases. --- g2core/alarm.cpp | 4 ++-- g2core/board/Archim/hardware.h | 4 ++-- g2core/board/G2v9/G2v9k-pinout.h | 4 ++-- g2core/board/gquadratic/hardware.cpp | 2 +- g2core/board/gquadratic/hardware.h | 4 ++-- g2core/board/gquintic/gquintic-b-pinout.h | 4 ++-- g2core/canonical_machine.cpp | 4 ++-- g2core/canonical_machine.h | 4 ++-- g2core/config.cpp | 2 +- g2core/config.h | 2 +- g2core/config_app.cpp | 4 ++-- g2core/controller.cpp | 4 ++-- g2core/coolant.cpp | 2 +- g2core/coolant.h | 2 +- g2core/cycle_feedhold.cpp | 4 ++-- g2core/cycle_homing.cpp | 4 ++-- g2core/cycle_probing.cpp | 2 +- g2core/device/step_dir_driver/step_dir_driver.h | 4 ++-- g2core/error.h | 4 ++-- g2core/g2core.h | 4 ++-- g2core/g2core_info.h | 4 ++-- g2core/gcode.h | 2 +- g2core/gcode_parser.cpp | 4 ++-- g2core/gpio.cpp | 4 ++-- g2core/gpio.h | 4 ++-- g2core/json_parser.cpp | 4 ++-- g2core/json_parser.h | 4 ++-- g2core/kinematics.cpp | 4 ++-- g2core/main.cpp | 4 ++-- g2core/marlin_compatibility.cpp | 4 ++-- g2core/marlin_compatibility.h | 4 ++-- g2core/persistence.cpp | 2 +- g2core/plan_arc.cpp | 2 +- g2core/plan_arc.h | 2 +- g2core/plan_exec.cpp | 4 ++-- g2core/plan_line.cpp | 4 ++-- g2core/plan_zoid.cpp | 4 ++-- g2core/planner.cpp | 4 ++-- g2core/planner.h | 4 ++-- g2core/pwm.cpp | 2 +- g2core/report.cpp | 2 +- g2core/settings.h | 2 +- g2core/settings/settings_Printrbot_Play.h | 4 ++-- g2core/settings/settings_Printrbot_Plus.h | 4 ++-- g2core/settings/settings_Printrbot_Simple_1403.h | 4 ++-- g2core/settings/settings_Printrbot_Simple_1608.h | 4 ++-- g2core/settings/settings_Ultimaker.h | 4 ++-- g2core/settings/settings_default.h | 2 +- g2core/settings/settings_makeblock.h | 2 +- g2core/settings/settings_probotixV90.h | 2 +- g2core/settings/settings_shapeoko2.h | 2 +- g2core/settings/settings_shopbot_sbv300.h | 2 +- g2core/settings/settings_shopbot_test.h | 2 +- g2core/settings/settings_test.h | 2 +- g2core/settings/settings_zen7x12.h | 2 +- g2core/spindle.cpp | 2 +- g2core/spindle.h | 2 +- g2core/stepper.cpp | 4 ++-- g2core/stepper.h | 4 ++-- g2core/temperature.cpp | 4 ++-- g2core/text_parser.cpp | 2 +- g2core/util.cpp | 4 ++-- g2core/util.h | 4 ++-- g2core/xio.cpp | 4 ++-- g2core/xio.h | 4 ++-- 65 files changed, 106 insertions(+), 106 deletions(-) diff --git a/g2core/alarm.cpp b/g2core/alarm.cpp index a87a2d15..8c9bd395 100644 --- a/g2core/alarm.cpp +++ b/g2core/alarm.cpp @@ -2,8 +2,8 @@ * alarm.cpp - canonical machine alarm handlers * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S Hart, Jr. - * Copyright (c) 2014 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S Hart, Jr. + * Copyright (c) 2014 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 57560f43..10b1b3e9 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/G2v9/G2v9k-pinout.h b/g2core/board/G2v9/G2v9k-pinout.h index 047bf9a2..bd90b3a8 100644 --- a/g2core/board/G2v9/G2v9k-pinout.h +++ b/g2core/board/G2v9/G2v9k-pinout.h @@ -3,8 +3,8 @@ * For: /board/g2v9 * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Robert Giseburt - * Copyright (c) 2013 - 2017 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/gquadratic/hardware.cpp b/g2core/board/gquadratic/hardware.cpp index febd5e3d..3d740a6f 100644 --- a/g2core/board/gquadratic/hardware.cpp +++ b/g2core/board/gquadratic/hardware.cpp @@ -3,7 +3,7 @@ * For: /board/gQuadratic * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index d18efe5b..54d9cb61 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/gquintic/gquintic-b-pinout.h b/g2core/board/gquintic/gquintic-b-pinout.h index 895f901f..abec47cc 100644 --- a/g2core/board/gquintic/gquintic-b-pinout.h +++ b/g2core/board/gquintic/gquintic-b-pinout.h @@ -3,8 +3,8 @@ * For: /board/gQuintic * This file is part of the g2core project * - * Copyright (c) 2016 - 2017 Robert Giseburt - * Copyright (c) 2016 - 2017 Alden S. Hart Jr. + * Copyright (c) 2016 - 2018 Robert Giseburt + * Copyright (c) 2016 - 2018 Alden S. Hart Jr. * * This file is part of the Motate Library. * diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 34df9481..5b7cea1f 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -2,8 +2,8 @@ * canonical_machine.cpp - rs274/ngc canonical machine. * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S Hart, Jr. - * Copyright (c) 2014 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S Hart, Jr. + * Copyright (c) 2014 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index b3c44599..17ff57a2 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -2,8 +2,8 @@ * canonical_machine.h - rs274/ngc canonical machining functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart Jr. - * Copyright (c) 2016 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart Jr. + * Copyright (c) 2016 - 2018 Rob Giseburt * * This code is a loose implementation of Kramer, Proctor and Messina's * canonical machining functions as described in the NIST RS274/NGC v3 diff --git a/g2core/config.cpp b/g2core/config.cpp index 48ca1533..36f4c754 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -2,7 +2,7 @@ * config.cpp - application independent configuration handling * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/config.h b/g2core/config.h index 14e761a3..dac23f31 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -2,7 +2,7 @@ * config.h - configuration sub-system generic part (see config_app for application part) * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index bd305d21..483204f1 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -2,8 +2,8 @@ * config_app.cpp - application-specific part of configuration data * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/controller.cpp b/g2core/controller.cpp index bd60a7a8..263d1d03 100644 --- a/g2core/controller.cpp +++ b/g2core/controller.cpp @@ -2,8 +2,8 @@ * controller.cpp - g2core controller and top level parser * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index 6d3f6f1a..bcb50498 100644 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -2,7 +2,7 @@ * coolant.cpp - canonical machine coolant driver * This file is part of the g2core project * - * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/coolant.h b/g2core/coolant.h index 8755f48b..498a8a7e 100644 --- a/g2core/coolant.h +++ b/g2core/coolant.h @@ -2,7 +2,7 @@ * coolant.h - coolant driver * This file is part of the g2core project * - * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index fa70f437..8bd58ca1 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -2,8 +2,8 @@ * cycle_feedhold.cpp - canonical machine feedhold processing * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S Hart, Jr. - * Copyright (c) 2014 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S Hart, Jr. + * Copyright (c) 2014 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index 3259beeb..cfaccc63 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -2,8 +2,8 @@ * cycle_homing.cpp - homing cycle extension to canonical_machine * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/cycle_probing.cpp b/g2core/cycle_probing.cpp index fad4fc6b..c24f7434 100644 --- a/g2core/cycle_probing.cpp +++ b/g2core/cycle_probing.cpp @@ -2,7 +2,7 @@ * cycle_probing.c - probing cycle extension to canonical_machine.c * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S Hart, Jr., Sarah Tappon, Tom Cauchois, Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S Hart, Jr., Sarah Tappon, Tom Cauchois, Robert Giseburt * With contributions from Other Machine Company. * * This file ("the software") is free software: you can redistribute it and/or modify diff --git a/g2core/device/step_dir_driver/step_dir_driver.h b/g2core/device/step_dir_driver/step_dir_driver.h index c516d066..759b3c3d 100644 --- a/g2core/device/step_dir_driver/step_dir_driver.h +++ b/g2core/device/step_dir_driver/step_dir_driver.h @@ -2,8 +2,8 @@ * step_dir_driver.cpp - control over a Step/Direction/Enable stepper motor driver * This file is part of G2 project * - * Copyright (c) 2016 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Robert Giseburt + * Copyright (c) 2016 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/error.h b/g2core/error.h index 2bc5dca8..3b54c9ff 100644 --- a/g2core/error.h +++ b/g2core/error.h @@ -2,8 +2,8 @@ * error.h - g2core status codes * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/g2core.h b/g2core/g2core.h index 045fddb5..86db2965 100644 --- a/g2core/g2core.h +++ b/g2core/g2core.h @@ -2,8 +2,8 @@ * g2core.h - g2core main header file * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index d3b5d0eb..6f549a6d 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -2,8 +2,8 @@ * g2core_info.h - g2core build information * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/gcode.h b/g2core/gcode.h index 238168eb..1b04063b 100644 --- a/g2core/gcode.h +++ b/g2core/gcode.h @@ -2,7 +2,7 @@ * gcode.h - rs274/ngc Gcode model and parser support * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/gcode_parser.cpp b/g2core/gcode_parser.cpp index 894711d9..46131b3b 100644 --- a/g2core/gcode_parser.cpp +++ b/g2core/gcode_parser.cpp @@ -2,8 +2,8 @@ * gcode_parser.cpp - rs274/ngc Gcode parser * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index ff816e68..3eef664f 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -2,8 +2,8 @@ * gpio.cpp - digital IO handling functions * This file is part of the g2core project * - * Copyright (c) 2015 - 2107 Alden S. Hart, Jr. - * Copyright (c) 2015 - 2017 Robert Giseburt + * Copyright (c) 2015 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/gpio.h b/g2core/gpio.h index 80801eb8..b984087f 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -2,8 +2,8 @@ * gpio.h - Digital IO handling functions * This file is part of the g2core project * - * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2015 - 2017 Robert Giseburt + * Copyright (c) 2015 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/json_parser.cpp b/g2core/json_parser.cpp index c40f3f72..d24fd465 100644 --- a/g2core/json_parser.cpp +++ b/g2core/json_parser.cpp @@ -2,8 +2,8 @@ * json_parser.cpp - JSON parser * This file is part of the g2core project * - * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Rob Giseburt + * Copyright (c) 2011 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/json_parser.h b/g2core/json_parser.h index e88e4dde..381ba32a 100644 --- a/g2core/json_parser.h +++ b/g2core/json_parser.h @@ -2,8 +2,8 @@ * json_parser.h - JSON parser and JSON support * This file is part of the g2core project * - * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Rob Giseburt + * Copyright (c) 2011 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/kinematics.cpp b/g2core/kinematics.cpp index cc66d95d..3d4cf98f 100644 --- a/g2core/kinematics.cpp +++ b/g2core/kinematics.cpp @@ -2,8 +2,8 @@ * kinematics.cpp - inverse kinematics routines * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/main.cpp b/g2core/main.cpp index f3ff45aa..d69d0f78 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -2,8 +2,8 @@ * main.cpp - g2core - An embedded rs274/ngc CNC controller * This file is part of the g2core project. * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/marlin_compatibility.cpp b/g2core/marlin_compatibility.cpp index 278c3a33..44af95bc 100644 --- a/g2core/marlin_compatibility.cpp +++ b/g2core/marlin_compatibility.cpp @@ -2,8 +2,8 @@ * marlin_compatibility.cpp - support for marlin protocol and gcode * This file is part of the g2core project * - * Copyright (c) 2017 Alden S. Hart, Jr. - * Copyright (c) 2017 Rob Giseburt + * Copyright (c) 2017 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2017 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/marlin_compatibility.h b/g2core/marlin_compatibility.h index 168eb2ae..25d4bab1 100644 --- a/g2core/marlin_compatibility.h +++ b/g2core/marlin_compatibility.h @@ -2,8 +2,8 @@ * marlin_compatibility.cpp - support for marlin protocol and gcode * This file is part of the g2core project * - * Copyright (c) 2017 Alden S. Hart, Jr. - * Copyright (c) 2017 Rob Giseburt + * Copyright (c) 2017 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2017 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/persistence.cpp b/g2core/persistence.cpp index 362070a7..cce395c0 100644 --- a/g2core/persistence.cpp +++ b/g2core/persistence.cpp @@ -2,7 +2,7 @@ * persistence.cpp - persistence functions * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/plan_arc.cpp b/g2core/plan_arc.cpp index 9872b2c1..aca17e98 100644 --- a/g2core/plan_arc.cpp +++ b/g2core/plan_arc.cpp @@ -2,7 +2,7 @@ * plan_arc.c - arc planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/plan_arc.h b/g2core/plan_arc.h index 641fb86d..9fa9715a 100644 --- a/g2core/plan_arc.h +++ b/g2core/plan_arc.h @@ -2,7 +2,7 @@ * plan_arc.h - arc planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 73bb0899..7d2816e9 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -2,8 +2,8 @@ * plan_exec.cpp - execution function for acceleration managed lines * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 4d147206..7378b3e4 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -2,8 +2,8 @@ * plan_line.c - acceleration managed line planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index c6f2d4be..2e4881ee 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -2,8 +2,8 @@ * plan_zoid.cpp - acceleration managed line planning and motion execution - trapezoid planner * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/planner.cpp b/g2core/planner.cpp index fd72aa18..6afe54b5 100644 --- a/g2core/planner.cpp +++ b/g2core/planner.cpp @@ -2,8 +2,8 @@ * planner.cpp - Cartesian trajectory planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2012 - 2017 Rob Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Rob Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/planner.h b/g2core/planner.h index d2006685..3b8d0c93 100644 --- a/g2core/planner.h +++ b/g2core/planner.h @@ -2,8 +2,8 @@ * planner.h - cartesian trajectory planning and motion execution * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp index 3f69cdf9..4d5b6bda 100644 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -2,7 +2,7 @@ * pwm.cpp - pulse width modulation drivers * This file is part of the g2core project * - * Copyright (c) 2012 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/report.cpp b/g2core/report.cpp index 34ae4ecc..35a19c46 100644 --- a/g2core/report.cpp +++ b/g2core/report.cpp @@ -2,7 +2,7 @@ * report.cpp - Status reports and other reporting functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings.h b/g2core/settings.h index 82586f43..fa5077a5 100644 --- a/g2core/settings.h +++ b/g2core/settings.h @@ -2,7 +2,7 @@ * settings.h - default runtime settings * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_Printrbot_Play.h b/g2core/settings/settings_Printrbot_Play.h index 47ce71ce..f03c8c72 100644 --- a/g2core/settings/settings_Printrbot_Play.h +++ b/g2core/settings/settings_Printrbot_Play.h @@ -2,8 +2,8 @@ * settings_Printrbot_play.h * This file is part of the the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_Printrbot_Plus.h b/g2core/settings/settings_Printrbot_Plus.h index 81f6f5dc..b5934a8f 100644 --- a/g2core/settings/settings_Printrbot_Plus.h +++ b/g2core/settings/settings_Printrbot_Plus.h @@ -2,8 +2,8 @@ * settings_Printrbot_plus.h * This file is part of the the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_Printrbot_Simple_1403.h b/g2core/settings/settings_Printrbot_Simple_1403.h index 9ff22a41..043f0691 100644 --- a/g2core/settings/settings_Printrbot_Simple_1403.h +++ b/g2core/settings/settings_Printrbot_Simple_1403.h @@ -2,8 +2,8 @@ * settings_printrbot_simple_1403.h - 2013 Simple model * This file is part of the the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_Printrbot_Simple_1608.h b/g2core/settings/settings_Printrbot_Simple_1608.h index 2ee57ef2..9cdcf73f 100644 --- a/g2core/settings/settings_Printrbot_Simple_1608.h +++ b/g2core/settings/settings_Printrbot_Simple_1608.h @@ -2,8 +2,8 @@ * settings_printrbot_simple_1608.h - New Simple, 2016 version * This file is part of the the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_Ultimaker.h b/g2core/settings/settings_Ultimaker.h index 65d6f3c6..71604832 100644 --- a/g2core/settings/settings_Ultimaker.h +++ b/g2core/settings/settings_Ultimaker.h @@ -2,8 +2,8 @@ * settings_Ultimaker.h - Ultimaker motion demo * This file is part of the the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2010 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 4e1f1616..33898fd6 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -2,7 +2,7 @@ * settings_default.h - default machine profile - Set for Shapeoko2 * This file is part of the g2core project * - * Copyright (c) 2012 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 1fa04d64..44717a24 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -2,7 +2,7 @@ * settings_makeblock.h - makeblock engraving table * This file is part of the g2core project * - * Copyright (c) 2016 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_probotixV90.h b/g2core/settings/settings_probotixV90.h index efdaf376..30ff9688 100644 --- a/g2core/settings/settings_probotixV90.h +++ b/g2core/settings/settings_probotixV90.h @@ -2,7 +2,7 @@ * settings_probotix.h - Probotix Fireball V90 machine profile * This file is part the g2core project * - * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2011 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_shapeoko2.h b/g2core/settings/settings_shapeoko2.h index b3327a78..1590195c 100644 --- a/g2core/settings/settings_shapeoko2.h +++ b/g2core/settings/settings_shapeoko2.h @@ -2,7 +2,7 @@ * settings_shapeoko2.h - Shapeoko2 500mm table * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_shopbot_sbv300.h b/g2core/settings/settings_shopbot_sbv300.h index 348f97a2..ff6f5257 100644 --- a/g2core/settings/settings_shopbot_sbv300.h +++ b/g2core/settings/settings_shopbot_sbv300.h @@ -2,7 +2,7 @@ * settings_shopbot_sbv300.h - Shopbot sbv3000 * This file is part of the g2core project * - * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_shopbot_test.h b/g2core/settings/settings_shopbot_test.h index 329d2906..95630c53 100644 --- a/g2core/settings/settings_shopbot_test.h +++ b/g2core/settings/settings_shopbot_test.h @@ -2,7 +2,7 @@ * settings_shopbot_test.h - Shopbot Test * This file is part of the g2core project * - * Copyright (c) 2015 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2015 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_test.h b/g2core/settings/settings_test.h index 03e82919..f7f436e6 100644 --- a/g2core/settings/settings_test.h +++ b/g2core/settings/settings_test.h @@ -2,7 +2,7 @@ * settings_test.h - settings for testing - subject to wild change * This file is part of the g2core project * - * Copyright (c) 2014 - 2017 Alden S. Hart Jr. + * Copyright (c) 2014 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/settings/settings_zen7x12.h b/g2core/settings/settings_zen7x12.h index 516014ca..df173256 100644 --- a/g2core/settings/settings_zen7x12.h +++ b/g2core/settings/settings_zen7x12.h @@ -2,7 +2,7 @@ * settings_zen7x12.h - Zen Toolworks 7x12 machine profile * This file is part of the g2core project * - * Copyright (c) 2011 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2011 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index e480420e..2880a0ca 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -2,7 +2,7 @@ * spindle.cpp - canonical machine spindle driver * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/spindle.h b/g2core/spindle.h index 3b019fb8..2b6f21ed 100644 --- a/g2core/spindle.h +++ b/g2core/spindle.h @@ -2,7 +2,7 @@ * spindle.h - spindle driver * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index be073220..7ab94cd8 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -2,8 +2,8 @@ * stepper.cpp - stepper motor controls * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/stepper.h b/g2core/stepper.h index 37ab6496..1a664127 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -2,8 +2,8 @@ * stepper.h - stepper motor interface * This file is part of g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/temperature.cpp b/g2core/temperature.cpp index ec99b438..d7a3a8ee 100644 --- a/g2core/temperature.cpp +++ b/g2core/temperature.cpp @@ -2,8 +2,8 @@ * temperature.cpp - temperature control module - drives heaters or coolers * This file is part of the g2core project * - * Copyright (c) 2016 - 2017 Robert Giseburt - * Copyright (c) 2016 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Robert Giseburt + * Copyright (c) 2016 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/text_parser.cpp b/g2core/text_parser.cpp index 56723673..e4aa633c 100644 --- a/g2core/text_parser.cpp +++ b/g2core/text_parser.cpp @@ -2,7 +2,7 @@ * text_parser.cpp - text parser * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/util.cpp b/g2core/util.cpp index 91996996..61f4c4b0 100644 --- a/g2core/util.cpp +++ b/g2core/util.cpp @@ -2,8 +2,8 @@ * util.cpp - a random assortment of useful functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/util.h b/g2core/util.h index e531b272..1c7f20b6 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -2,8 +2,8 @@ * util.h - a random assortment of useful functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2017 Alden S. Hart, Jr. - * Copyright (c) 2016 - 2017 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2016 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/xio.cpp b/g2core/xio.cpp index b64e136e..725599c8 100644 --- a/g2core/xio.cpp +++ b/g2core/xio.cpp @@ -2,8 +2,8 @@ * xio.cpp - extended IO functions * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/xio.h b/g2core/xio.h index 2b735717..f4269d6f 100644 --- a/g2core/xio.h +++ b/g2core/xio.h @@ -2,8 +2,8 @@ * xio.h - extended IO functions * This file is part of the g2core project * - * Copyright (c) 2013 - 2017 Alden S. Hart Jr. - * Copyright (c) 2013 - 2017 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the From 5385fe0185353500a21a8230a0b3366675540b22 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 26 Mar 2018 15:41:24 -0400 Subject: [PATCH 267/283] Removed commented code replaced in the merge --- g2core/config_app.cpp | 295 ------------------------------------------ g2core/stepper.cpp | 90 ------------- g2core/stepper.h | 7 - 3 files changed, 392 deletions(-) diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index 483204f1..a407d6df 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -137,7 +137,6 @@ const cfgItem_t cfgArray[] = { { "", "_leds",_i0, 0, tx_print_nul, _get_leds,_set_leds, nullptr, 0 }, // TEMPORARY - change LEDs #endif -// <<<<<<< HEAD { "mpo","mpox",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // X machine position { "mpo","mpoy",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // Y machine position { "mpo","mpoz",_f0, 5, cm_print_mpo, cm_get_mpo, set_ro, nullptr, 0 }, // Z machine position @@ -202,56 +201,6 @@ const cfgItem_t cfgArray[] = { { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, // motor power readouts { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, -/* ======= - { "mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // X machine position - { "mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Y machine position - { "mpo","mpoz",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // Z machine position - { "mpo","mpoa",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // A machine position - { "mpo","mpob",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // B machine position - { "mpo","mpoc",_f0, 3, cm_print_mpo, cm_get_mpo, set_ro, (float *)&cs.null, 0 }, // C machine position - - { "pos","posx",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // X work position - { "pos","posy",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Y work position - { "pos","posz",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // Z work position - { "pos","posa",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // A work position - { "pos","posb",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // B work position - { "pos","posc",_f0, 3, cm_print_pos, cm_get_pos, set_ro, (float *)&cs.null, 0 }, // C work position - - { "ofs","ofsx",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // X work offset - { "ofs","ofsy",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Y work offset - { "ofs","ofsz",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // Z work offset - { "ofs","ofsa",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // A work offset - { "ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // B work offset - { "ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_ro, (float *)&cs.null, 0 }, // C work offset - - { "hom","home",_f0, 0, cm_print_home,cm_get_home,set_01,(float *)&cm.homing_state, 0 }, // homing state, invoke homing cycle - { "hom","homx",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_X], false }, // X homed - Homing status group - { "hom","homy",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_Y], false }, // Y homed - { "hom","homz",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_Z], false }, // Z homed - { "hom","homa",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_A], false }, // A homed - { "hom","homb",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_B], false }, // B homed - { "hom","homc",_f0, 0, cm_print_hom, get_ui8, set_01, (float *)&cm.homed[AXIS_C], false }, // C homed - - { "prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_ro, (float *)&cm.probe_state[0], 0 }, // probing state - { "prb","prbx",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_X], 0 }, - { "prb","prby",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_Y], 0 }, - { "prb","prbz",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_Z], 0 }, - { "prb","prba",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_A], 0 }, - { "prb","prbb",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_B], 0 }, - { "prb","prbc",_f0, 3, tx_print_nul, get_flt, set_ro, (float *)&cm.probe_results[0][AXIS_C], 0 }, - { "prb","prbr",_f0, 0, tx_print_nul, cm_get_prbr, cm_get_prbr, nullptr, 0 }, // enable probe report. Init in cm_init - - { "jog","jogx",_f0, 0, tx_print_nul, get_nul, cm_run_jogx, (float *)&cm.jogging_dest, 0}, - { "jog","jogy",_f0, 0, tx_print_nul, get_nul, cm_run_jogy, (float *)&cm.jogging_dest, 0}, - { "jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jogz, (float *)&cm.jogging_dest, 0}, - { "jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_joga, (float *)&cm.jogging_dest, 0}, -// { "jog","jogb",_f0, 0, tx_print_nul, get_nul, cm_run_jogb, (float *)&cm.jogging_dest, 0}, -// { "jog","jogc",_f0, 0, tx_print_nul, get_nul, cm_run_jogc, (float *)&cm.jogging_dest, 0}, - - { "pwr","pwr1",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, // motor power readouts - { "pwr","pwr2",_f0, 3, st_print_pwr, st_get_pwr, set_ro, (float *)&cs.null, 0}, ->>>>>>> refs/heads/edge -*/ #if (MOTORS > 2) { "pwr","pwr3",_f0, 3, st_print_pwr, st_get_pwr, set_ro, nullptr, 0}, #endif @@ -266,7 +215,6 @@ const cfgItem_t cfgArray[] = { #endif // Motor parameters -// <<<<<<< HEAD { "1","1ma",_iip, 0, st_print_ma, st_get_ma, st_set_ma, nullptr, M1_MOTOR_MAP }, { "1","1sa",_fip, 3, st_print_sa, st_get_sa, st_set_sa, nullptr, M1_STEP_ANGLE }, { "1","1tr",_fipc,5, st_print_tr, st_get_tr, st_set_tr, nullptr, M1_TRAVEL_PER_REV }, @@ -336,85 +284,6 @@ const cfgItem_t cfgArray[] = { { "6","6pl",_fip, 3, st_print_pl, st_get_pl, st_set_pl, nullptr, M6_POWER_LEVEL }, // { "6","6pi",_fip, 3, st_print_pi, st_get_pi, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, // { "6","6mt",_fip, 2, st_print_mt, st_get_mt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, - -/* ======= - { "1","1ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_1].motor_map, M1_MOTOR_MAP }, - { "1","1sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_1].step_angle, M1_STEP_ANGLE }, - { "1","1tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_1].travel_rev, M1_TRAVEL_PER_REV }, - { "1","1mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_1].microsteps, M1_MICROSTEPS }, - { "1","1su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_1].steps_per_unit, M1_STEPS_PER_UNIT }, - { "1","1po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_1].polarity, M1_POLARITY }, - { "1","1ep",_fip, 0, st_print_ep, st_get_ep, st_set_ep, (float *)&cs.null, M1_ENABLE_POLARITY }, - { "1","1pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M1_POWER_MODE }, - { "1","1pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_1].power_level, M1_POWER_LEVEL }, -// { "1","1pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_1].power_idle, M1_POWER_IDLE }, -// { "1","1mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_1].motor_timeout, M1_MOTOR_TIMEOUT }, -#if (MOTORS >= 2) - { "2","2ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_2].motor_map, M2_MOTOR_MAP }, - { "2","2sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_2].step_angle, M2_STEP_ANGLE }, - { "2","2tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_2].travel_rev, M2_TRAVEL_PER_REV }, - { "2","2mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_2].microsteps, M2_MICROSTEPS }, - { "2","2su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_2].steps_per_unit, M2_STEPS_PER_UNIT }, - { "2","2po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_2].polarity, M2_POLARITY }, - { "2","2ep",_fip, 0, st_print_ep, st_get_ep, st_set_ep, (float *)&cs.null, M2_ENABLE_POLARITY }, - { "2","2pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M2_POWER_MODE }, - { "2","2pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_2].power_level, M2_POWER_LEVEL}, -// { "2","2pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_2].power_idle, M2_POWER_IDLE }, -// { "2","2mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_2].motor_timeout, M2_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 3) - { "3","3ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_3].motor_map, M3_MOTOR_MAP }, - { "3","3sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_3].step_angle, M3_STEP_ANGLE }, - { "3","3tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_3].travel_rev, M3_TRAVEL_PER_REV }, - { "3","3mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_3].microsteps, M3_MICROSTEPS }, - { "3","3su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_3].steps_per_unit, M3_STEPS_PER_UNIT }, - { "3","3po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_3].polarity, M3_POLARITY }, - { "3","3ep",_fip, 0, st_print_ep, st_get_ep, st_set_ep, (float *)&cs.null, M3_ENABLE_POLARITY }, - { "3","3pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M3_POWER_MODE }, - { "3","3pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_3].power_level, M3_POWER_LEVEL }, -// { "3","3pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_3].power_idle, M3_POWER_IDLE }, -// { "3","3mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_3].motor_timeout, M3_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 4) - { "4","4ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_4].motor_map, M4_MOTOR_MAP }, - { "4","4sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_4].step_angle, M4_STEP_ANGLE }, - { "4","4tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_4].travel_rev, M4_TRAVEL_PER_REV }, - { "4","4mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_4].microsteps, M4_MICROSTEPS }, - { "4","4su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_4].steps_per_unit, M4_STEPS_PER_UNIT }, - { "4","4po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_4].polarity, M4_POLARITY }, - { "4","4ep",_fip, 0, st_print_ep, st_get_ep, st_set_ep, (float *)&cs.null, M4_ENABLE_POLARITY }, - { "4","4pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M4_POWER_MODE }, - { "4","4pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_4].power_level, M4_POWER_LEVEL }, -// { "4","4pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_4].power_idle, M4_POWER_IDLE }, -// { "4","4mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_4].motor_timeout, M4_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 5) - { "5","5ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_5].motor_map, M5_MOTOR_MAP }, - { "5","5sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_5].step_angle, M5_STEP_ANGLE }, - { "5","5tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_5].travel_rev, M5_TRAVEL_PER_REV }, - { "5","5mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_5].microsteps, M5_MICROSTEPS }, - { "5","5su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_5].steps_per_unit, M5_STEPS_PER_UNIT }, - { "5","5po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_5].polarity, M5_POLARITY }, - { "5","5ep",_fip, 0, st_print_ep, st_get_ep, st_set_ep, (float *)&cs.null, M5_ENABLE_POLARITY }, - { "5","5pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M5_POWER_MODE }, - { "5","5pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_5].power_level, M5_POWER_LEVEL }, -// { "5","5pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_5].power_idle, M5_POWER_IDLE }, -// { "5","5mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_5].motor_timeout, M5_MOTOR_TIMEOUT }, -#endif -#if (MOTORS >= 6) - { "6","6ma",_fip, 0, st_print_ma, get_ui8, st_set_ma, (float *)&st_cfg.mot[MOTOR_6].motor_map, M6_MOTOR_MAP }, - { "6","6sa",_fip, 3, st_print_sa, get_flt, st_set_sa, (float *)&st_cfg.mot[MOTOR_6].step_angle, M6_STEP_ANGLE }, - { "6","6tr",_fipc,4, st_print_tr, get_flt, st_set_tr, (float *)&st_cfg.mot[MOTOR_6].travel_rev, M6_TRAVEL_PER_REV }, - { "6","6mi",_fip, 0, st_print_mi, get_ui8, st_set_mi, (float *)&st_cfg.mot[MOTOR_6].microsteps, M6_MICROSTEPS }, - { "6","6su",_fipi,5, st_print_su, st_get_su,st_set_su, (float *)&st_cfg.mot[MOTOR_6].steps_per_unit, M6_STEPS_PER_UNIT }, - { "6","6po",_fip, 0, st_print_po, get_ui8, set_01, (float *)&st_cfg.mot[MOTOR_6].polarity, M6_POLARITY }, - { "6","6ep",_fip, 0, st_print_ep, st_get_ep, st_set_ep, (float *)&cs.null, M6_ENABLE_POLARITY }, - { "6","6pm",_fip, 0, st_print_pm, st_get_pm, st_set_pm, (float *)&cs.null, M6_POWER_MODE }, - { "6","6pl",_fip, 3, st_print_pl, get_flt, st_set_pl, (float *)&st_cfg.mot[MOTOR_6].power_level, M6_POWER_LEVEL }, -// { "6","6pi",_fip, 3, st_print_pi, get_flt, st_set_pi, (float *)&st_cfg.mot[MOTOR_6].power_idle, M6_POWER_IDLE }, -// { "6","6mt",_fip, 2, st_print_mt, get_flt, st_set_mt, (float *)&st_cfg.mot[MOTOR_6].motor_timeout, M6_MOTOR_TIMEOUT }, ->>>>>>> refs/heads/edge -*/ #endif // Axis parameters @@ -613,7 +482,6 @@ const cfgItem_t cfgArray[] = { { "in","in9", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #endif #if (D_IN_CHANNELS >= 10) -// <<<<<<< HEAD { "in","in10", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, #endif #if (D_IN_CHANNELS >= 11) @@ -621,17 +489,6 @@ const cfgItem_t cfgArray[] = { #endif #if (D_IN_CHANNELS >= 12) { "in","in12", _i0, 0, io_print_in, io_get_input, set_ro, nullptr, 0 }, -/* ======= - { "in","in10", _f0,0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, -#endif -#if (D_IN_CHANNELS >= 11) - { "in","in11", _f0,0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, -#endif -#if (D_IN_CHANNELS >= 12) - { "in","in12", _f0,0, io_print_in, io_get_input, set_ro, (float *)&cs.null, 0 }, ->>>>>>> refs/heads/edge -*/ - #endif // digital output configs @@ -829,37 +686,11 @@ const cfgItem_t cfgArray[] = { { "g30","g30c",_fic, 5, cm_print_cpos, cm_get_g30, set_ro, nullptr, 0 }, // this is a 128bit UUID for identifying a previously committed job state -// <<<<<<< HEAD { "jid","jida",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0 }, { "jid","jidb",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0 }, { "jid","jidc",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0 }, { "jid","jidd",_d0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0 }, -/* ======= - { "jid","jida",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[0], 0}, - { "jid","jidb",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[1], 0}, - { "jid","jidc",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[2], 0}, - { "jid","jidd",_f0, 0, tx_print_nul, get_data, set_data, (float *)&cfg.job_id[3], 0}, - - // General system parameters - { "sys","jt", _fipn, 2, cm_print_jt, get_flt, cm_set_jt,(float *)&cm.junction_integration_time,JUNCTION_INTEGRATION_TIME }, - { "sys","ct", _fipnc,4, cm_print_ct, get_flt, set_flup, (float *)&cm.chordal_tolerance, CHORDAL_TOLERANCE }, - { "sys","sl", _fipn, 0, cm_print_sl, get_ui8, set_01, (float *)&cm.soft_limit_enable, SOFT_LIMIT_ENABLE }, - { "sys","lim", _fipn,0, cm_print_lim, get_ui8, set_01, (float *)&cm.limit_enable, HARD_LIMIT_ENABLE }, - { "sys","saf", _fipn,0, cm_print_saf, get_ui8, set_01, (float *)&cm.safety_interlock_enable, SAFETY_INTERLOCK_ENABLE }, - { "sys","m48e",_fipn,0, cm_print_m48e,get_ui8, set_01, (float *)&cm.gmx.m48_enable, 0 }, // M48/M49 feedrate & spindle override enable - { "sys","mfoe",_fipn,0, cm_print_mfoe,get_ui8, set_01, (float *)&cm.gmx.mfo_enable, FEED_OVERRIDE_ENABLE}, - { "sys","mfo", _fipn,3, cm_print_mfo, get_flt,cm_set_mfo,(float *)&cm.gmx.mfo_factor, FEED_OVERRIDE_FACTOR}, - { "sys","mtoe",_fipn,0, cm_print_mtoe,get_ui8, set_01, (float *)&cm.gmx.mto_enable, TRAVERSE_OVERRIDE_ENABLE}, - { "sys","mto", _fipn,3, cm_print_mto, get_flt,cm_set_mto,(float *)&cm.gmx.mto_factor, TRAVERSE_OVERRIDE_FACTOR}, - - // Power management - { "sys","mt", _fipn,2, st_print_mt, get_flt, st_set_mt,(float *)&st_cfg.motor_power_timeout, MOTOR_POWER_TIMEOUT}, - { "", "me", _f0, 0, st_print_me, st_set_me, st_set_me,(float *)&cs.null, 0 }, // SET to enable motors (null value sets to maintain compatability) - { "", "md", _f0, 0, st_print_md, st_set_md, st_set_md,(float *)&cs.null, 0 }, // SET to disable motors (null value sets to maintain compatability) ->>>>>>> refs/heads/edge -*/ - // Spindle functions { "sp","spmo", _iip, 0, sp_print_spmo, sp_get_spmo, sp_set_spmo, nullptr, SPINDLE_MODE }, { "sp","spph", _bip, 0, sp_print_spph, sp_get_spph, sp_set_spph, nullptr, SPINDLE_PAUSE_ON_HOLD }, @@ -1423,7 +1254,6 @@ const cfgItem_t cfgArray[] = { // - Optional DIAGNOSTIC_PARAMETERS // - Uber groups (count these separately) -// <<<<<<< HEAD #define FIXED_GROUPS 4 { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // system group { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PWM 1 group @@ -1452,17 +1282,6 @@ const cfgItem_t cfgArray[] = { #if (MOTORS >= 4) { "","4", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif - -/* ======= - { "","sys",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // system group - { "","p1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PWM 1 group - // 2 - { "","1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor groups - { "","2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, ->>>>>>> refs/heads/edge -*/ #if (MOTORS >= 5) { "","5", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif @@ -1470,7 +1289,6 @@ const cfgItem_t cfgArray[] = { { "","6", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, #endif -// <<<<<<< HEAD #define DIGITAL_IN_GROUPS 10 { "","in", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // input state { "","di1", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // input configs @@ -1563,88 +1381,6 @@ const cfgItem_t cfgArray[] = { { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 2 group { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // PID 3 group -/* ======= - // +4 = 6 - { "","x", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis groups - { "","y", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","z", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","a", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","b", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","c", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +6 = 12 - { "","in", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input state - { "","di1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // input configs - { "","di2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","di9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +10 = 22 - { "","out", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output state - { "","do1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // output configs - { "","do2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do5", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do6", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do7", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do8", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do9", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do10", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do11", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do12", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","do13", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - // +14 = 36 - { "","g54",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // coord offset groups - { "","g55",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g56",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g57",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g58",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g59",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, - { "","g92",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // origin offsets - { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position - { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position - // +9 = 45 - { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tool offsets - { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt4",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt5",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt6",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt7",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt8",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt9",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt10",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt11",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt12",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt13",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - // +17 = 62 - { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group - { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group - { "","ofs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work offset group - { "","hom",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis homing state group - { "","prb",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // probing state group - { "","pwr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor power enagled group - { "","jog",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis jogging state group - { "","jid",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // job ID group - // +8 = 70 - { "","he1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 1 group - { "","he2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 2 group - { "","he3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 3 group - { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 1 group - { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 2 group - { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 3 group - // +6 = 76 ->>>>>>> refs/heads/edge -*/ - #ifdef __USER_DATA #define USER_DATA_GROUPS 4 { "","uda", _f0, 0, tx_print_nul, get_grp, set_grp, nullptr, 0 }, // user data group @@ -1726,7 +1462,6 @@ bool nv_index_lt_groups(index_t index) { return ((index <= NV_INDEX_START_GROUPS static void _convert(nvObj_t *nv, float conversion_factor) { -// <<<<<<< HEAD if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type if (isnan((double)nv->value_flt) || isinf((double)nv->value_flt)) { return; } // trap illegal float values ///+++ transform these checks into NaN or INF strings with an error return? @@ -1742,13 +1477,6 @@ static void _convert(nvObj_t *nv, float conversion_factor) } } } -/* ======= - if (cm_get_units_mode(MODEL) == INCHES) { // if in inches... - nv->value *= MM_PER_INCH; // convert to canonical millimeter units - } - *((float *)GET_TABLE_WORD(target)) = nv->value; // write value as millimeters or degrees ->>>>>>> refs/heads/edge -*/ nv->precision = GET_TABLE_WORD(precision); nv->valuetype = TYPE_FLOAT; } @@ -1858,31 +1586,8 @@ stat_t set_int32(nvObj_t *nv, int32_t &value, int32_t low, int32_t high) stat_t get_string(nvObj_t *nv, const char *str) { -// <<<<<<< HEAD nv->valuetype = TYPE_STRING; return (nv_copy_string(nv, str)); -/* ======= - if (nv->valuetype != TYPE_FLOAT) { return; } // can be called non-destructively for any value type - if (isnan((double)nv->value) || isinf((double)nv->value)) { return; } // trap illegal float values - ///+++ transform these checks into NaN or INF strings with an error return? - - // We may need one of two types of units conversion, but only if in inches mode - if (cm_get_units_mode(MODEL) == INCHES) { - cmAxisType type = cm_get_axis_type(nv->index); // linear, rotary or global - if (cfgArray[nv->index].flags & F_CONVERT) { // standard units conversion - if ((type == AXIS_TYPE_LINEAR) || (type == AXIS_TYPE_SYSTEM)) { - nv->value *= INCHES_PER_MM; - } - } else if (cfgArray[nv->index].flags & F_ICONVERT) {// inverse units conversion - if ((type == AXIS_TYPE_LINEAR) || (type == AXIS_TYPE_SYSTEM)) { - nv->value *= MM_PER_INCH; - } - } - } - nv->precision = GET_TABLE_WORD(precision); - nv->valuetype = TYPE_FLOAT; ->>>>>>> refs/heads/edge -*/ } /* diff --git a/g2core/stepper.cpp b/g2core/stepper.cpp index 7ab94cd8..3c32b30f 100644 --- a/g2core/stepper.cpp +++ b/g2core/stepper.cpp @@ -441,17 +441,8 @@ static void _load_move() return; // exit if the runtime is busy } -// <<<<<<< HEAD // If there are no moves to load start motor power timeouts if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) { -/* ======= - // ...start motor power timeouts - // for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) { - // Motors[motor]->motionStopped(); - // } - // loop unrolled version ->>>>>>> refs/heads/edge -*/ motor_1.motionStopped(); // ...start motor power timeouts motor_2.motionStopped(); #if (MOTORS > 2) @@ -944,15 +935,9 @@ stat_t st_set_su(nvObj_t *nv) if (cm_get_axis_type(nv) == AXIS_TYPE_LINEAR) { nv->value_flt *= INCHES_PER_MM; } -// <<<<<<< HEAD } uint8_t m = _motor(nv->index); st_cfg.mot[m].steps_per_unit = nv->value_flt; -/* ======= - } - set_flt(nv); ->>>>>>> refs/heads/edge -*/ st_cfg.mot[m].units_per_step = 1.0/st_cfg.mot[m].steps_per_unit; // Scale TR so all the other values make sense @@ -962,53 +947,9 @@ stat_t st_set_su(nvObj_t *nv) return(STAT_OK); } -// <<<<<<< HEAD // polarity stat_t st_get_po(nvObj_t *nv) { return(get_integer(nv, st_cfg.mot[_motor(nv->index)].polarity)); } stat_t st_set_po(nvObj_t *nv) { return(set_integer(nv, st_cfg.mot[_motor(nv->index)].polarity, 0, 1)); } -/* ======= -stat_t st_set_ep(nvObj_t *nv) // set motor enable polarity -{ - if (nv->value < IO_ACTIVE_LOW) { return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > IO_ACTIVE_HIGH) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - - uint8_t motor = _get_motor(nv->index); - if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; - - Motors[motor]->setEnablePolarity((ioMode)nv->value); - return (STAT_OK); -} - -stat_t st_get_ep(nvObj_t *nv) // get motor enable polarity -{ - if (nv->value < IO_ACTIVE_LOW) { return (STAT_INPUT_LESS_THAN_MIN_VALUE); } - if (nv->value > IO_ACTIVE_HIGH) { return (STAT_INPUT_EXCEEDS_MAX_VALUE); } - - uint8_t motor = _get_motor(nv->index); - if (motor > MOTORS) { return STAT_INPUT_VALUE_RANGE_ERROR; }; - - nv->value = (float)Motors[motor]->getEnablePolarity(); - nv->valuetype = TYPE_INT; - return (STAT_OK); -} - -stat_t st_set_pm(nvObj_t *nv) // set motor power mode -{ - if (nv->value < 0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value >= MOTOR_POWER_MODE_MAX_VALUE) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - uint8_t motor = _get_motor(nv->index); - if (motor > MOTORS) { - nv->valuetype = TYPE_NULL; - return STAT_INPUT_VALUE_RANGE_ERROR; - }; ->>>>>>> refs/heads/edge -*/ // power management mode stat_t st_get_pm(nvObj_t *nv) @@ -1020,22 +961,10 @@ stat_t st_get_pm(nvObj_t *nv) stat_t st_set_pm(nvObj_t *nv) { -// <<<<<<< HEAD // Test the value without setting it, then setPowerMode() now // to both set and take effect immediately. ritorno(set_integer(nv, (uint8_t &)cs.null, 0, MOTOR_POWER_MODE_MAX_VALUE )); Motors[_motor(nv->index)]->setPowerMode((stPowerMode)nv->value_int); -/* ======= - uint8_t motor = _get_motor(nv->index); - if (motor > MOTORS) { - nv->valuetype = TYPE_NULL; - return STAT_INPUT_VALUE_RANGE_ERROR; - }; - - nv->value = (float)Motors[motor]->getPowerMode(); - nv->valuetype = TYPE_INT; ->>>>>>> refs/heads/edge -*/ return (STAT_OK); } @@ -1050,30 +979,11 @@ stat_t st_set_pm(nvObj_t *nv) stat_t st_get_pl(nvObj_t *nv) { return(get_float(nv, st_cfg.mot[_motor(nv->index)].power_level)); } stat_t st_set_pl(nvObj_t *nv) { -// <<<<<<< HEAD uint8_t m = _motor(nv->index); ritorno(set_float_range(nv, st_cfg.mot[m].power_level, 0.0, 1.0)); st_cfg.mot[m].power_level_scaled = (nv->value_flt * POWER_LEVEL_SCALE_FACTOR); st_run.mot[m].power_level_dynamic = (st_cfg.mot[m].power_level_scaled); Motors[m]->setPowerLevel(st_cfg.mot[m].power_level_scaled); -/* ======= - if (nv->value < (float)0.0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_LESS_THAN_MIN_VALUE); - } - if (nv->value > (float)1.0) { - nv->valuetype = TYPE_NULL; - return (STAT_INPUT_EXCEEDS_MAX_VALUE); - } - set_flt(nv); // set power_setting value in the motor config struct (st) - - uint8_t motor = _get_motor(nv->index); - st_cfg.mot[motor].power_level_scaled = (nv->value * POWER_LEVEL_SCALE_FACTOR); - st_run.mot[motor].power_level_dynamic = (st_cfg.mot[motor].power_level_scaled); - Motors[motor]->setPowerLevel(st_cfg.mot[motor].power_level_scaled); - ->>>>>>> refs/heads/edge -*/ return(STAT_OK); } diff --git a/g2core/stepper.h b/g2core/stepper.h index 1a664127..a89888f7 100644 --- a/g2core/stepper.h +++ b/g2core/stepper.h @@ -597,15 +597,8 @@ stat_t st_get_mi(nvObj_t *nv); stat_t st_set_mi(nvObj_t *nv); stat_t st_get_su(nvObj_t *nv); stat_t st_set_su(nvObj_t *nv); -// <<<<<<< HEAD stat_t st_get_po(nvObj_t *nv); stat_t st_set_po(nvObj_t *nv); -/* ======= -stat_t st_set_ep(nvObj_t *nv); -stat_t st_get_ep(nvObj_t *nv); -stat_t st_set_pm(nvObj_t *nv); ->>>>>>> refs/heads/edge -*/ stat_t st_get_pm(nvObj_t *nv); stat_t st_set_pm(nvObj_t *nv); stat_t st_get_pl(nvObj_t *nv); From 809174d80223a332bca67293c132c79a8ac6249f Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Mon, 26 Mar 2018 16:10:31 -0400 Subject: [PATCH 268/283] Changed initialization to work better with 9 axis configs --- g2core/cycle_jogging.cpp | 4 ++-- g2core/plan_line.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index e9e4251b..e9571576 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -177,8 +177,8 @@ static stat_t _jogging_axis_ramp_jog(int8_t axis) // run the jog ramp } static stat_t _jogging_axis_move(int8_t axis, float target, float velocity) { - float vect[] = {0, 0, 0, 0, 0, 0}; - bool flags[] = {false, false, false, false, false, false}; + float vect[] = { 0,0,0,0,0,0 }; + bool flags[] = { false,false,false,false,false,false }; vect[axis] = target; flags[axis] = true; diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 7378b3e4..860da6ca 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -143,8 +143,8 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); } stat_t mp_aline(GCodeState_t* _gm) { - float target_rotated[AXES] = { 0,0,0,0,0,0,0,0,0 }; - float axis_square[AXES] = { 0,0,0,0,0,0,0,0,0 }; + float target_rotated[AXES]; // all these arrays initialize to all zeroes by compiler settings + float axis_square[AXES]; float axis_length[AXES]; bool flags[AXES]; float length_square = 0; From 105626f3b1fa7744936e2f7965f67c28b13cd220 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 27 Mar 2018 07:48:55 -0400 Subject: [PATCH 269/283] Updated copyright dates; changed all AXES defines to 9 axes; NB: Ignore gQuintic and gQuadratic profiles - these will be added in a later PR and are not checked in Travis --- g2core/Makefile | 4 +-- g2core/board/Archim/Archim-pinout.h | 4 +-- g2core/board/Archim/hardware.h | 2 +- g2core/board/ArduinoDue/gShield-pinout.h | 4 +-- g2core/board/ArduinoDue/hardware.cpp | 4 +-- g2core/board/ArduinoDue/hardware.h | 6 ++--- .../board/ArduinoDue/shopbotShield-pinout.h | 4 +-- g2core/board/G2v9/hardware.cpp | 4 +-- g2core/board/G2v9/hardware.h | 4 +-- g2core/board/G2v9/motate_pin_assignments.h | 4 +-- g2core/board/gquadratic/hardware.h | 2 +- .../board/gquadratic/motate_pin_assignments.h | 4 +-- g2core/board/gquintic/hardware.h | 6 ++--- .../board/gquintic/motate_pin_assignments.h | 4 +-- g2core/board/printrboardg2/hardware.cpp | 27 +++++++++---------- g2core/board/printrboardg2/hardware.h | 8 +++--- .../printrboardg2/motate_pin_assignments.h | 4 +-- .../printrboardg2/printrboardG2v3-pinout.h | 4 +-- g2core/board/sbv300/hardware.cpp | 4 +-- g2core/board/sbv300/hardware.h | 6 ++--- g2core/board/sbv300/motate_pin_assignments.h | 4 +-- g2core/board/sbv300/sbv300-pinout.h | 4 +-- g2core/config_app.h | 4 +-- g2core/controller.h | 4 +-- g2core/encoder.cpp | 2 +- g2core/encoder.h | 2 +- g2core/g2core.cppproj | 4 +-- g2core/help.cpp | 2 +- g2core/help.h | 2 +- g2core/kinematics.h | 2 +- g2core/persistence.h | 2 +- g2core/pwm.h | 2 +- g2core/report.h | 2 +- g2core/text_parser.h | 2 +- 34 files changed, 73 insertions(+), 74 deletions(-) mode change 100755 => 100644 g2core/config_app.h mode change 100755 => 100644 g2core/encoder.cpp mode change 100755 => 100644 g2core/encoder.h mode change 100755 => 100644 g2core/help.cpp mode change 100755 => 100644 g2core/help.h mode change 100755 => 100644 g2core/kinematics.h mode change 100755 => 100644 g2core/persistence.h diff --git a/g2core/Makefile b/g2core/Makefile index e88b3d68..626dce0b 100644 --- a/g2core/Makefile +++ b/g2core/Makefile @@ -1,8 +1,8 @@ # # Makefile # -# Copyright (c) 2012 - 2016 Robert Giseburt -# Copyright (c) 2013 - 2016 Alden S. Hart Jr. +# Copyright (c) 2012 - 2018 Robert Giseburt +# Copyright (c) 2013 - 2018 Alden S. Hart Jr. # # This file is part of the g2core project. # diff --git a/g2core/board/Archim/Archim-pinout.h b/g2core/board/Archim/Archim-pinout.h index 566d26e1..94ba89d2 100644 --- a/g2core/board/Archim/Archim-pinout.h +++ b/g2core/board/Archim/Archim-pinout.h @@ -3,8 +3,8 @@ * For: /board/Archim * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file is part of the Motate Library. * diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 10b1b3e9..32d342e7 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -44,7 +44,7 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 4 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (index starts at 1) diff --git a/g2core/board/ArduinoDue/gShield-pinout.h b/g2core/board/ArduinoDue/gShield-pinout.h index d10dfeba..75e42d50 100644 --- a/g2core/board/ArduinoDue/gShield-pinout.h +++ b/g2core/board/ArduinoDue/gShield-pinout.h @@ -3,8 +3,8 @@ * For: /board/ArduinoDue * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file is part of the Motate Library. * diff --git a/g2core/board/ArduinoDue/hardware.cpp b/g2core/board/ArduinoDue/hardware.cpp index 1e34811e..3263acee 100644 --- a/g2core/board/ArduinoDue/hardware.cpp +++ b/g2core/board/ArduinoDue/hardware.cpp @@ -3,8 +3,8 @@ * For: /board/g2v9 * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h index 3c722b8c..b87323ce 100644 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -44,7 +44,7 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 4 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (index starts at 1) diff --git a/g2core/board/ArduinoDue/shopbotShield-pinout.h b/g2core/board/ArduinoDue/shopbotShield-pinout.h index 769e0668..6806946e 100644 --- a/g2core/board/ArduinoDue/shopbotShield-pinout.h +++ b/g2core/board/ArduinoDue/shopbotShield-pinout.h @@ -3,8 +3,8 @@ * For: /board/ArduinoDue * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/hardware.cpp index 6522ee56..8f54bdff 100644 --- a/g2core/board/G2v9/hardware.cpp +++ b/g2core/board/G2v9/hardware.cpp @@ -3,8 +3,8 @@ * For: /board/g2v9 * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index e2038126..ab6c404d 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/G2v9/motate_pin_assignments.h b/g2core/board/G2v9/motate_pin_assignments.h index d280fbb8..120ae6af 100644 --- a/g2core/board/G2v9/motate_pin_assignments.h +++ b/g2core/board/G2v9/motate_pin_assignments.h @@ -3,8 +3,8 @@ * For: /board/g2v9 * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index 54d9cb61..45caf19c 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -45,7 +45,7 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 3 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (1-6) diff --git a/g2core/board/gquadratic/motate_pin_assignments.h b/g2core/board/gquadratic/motate_pin_assignments.h index 7ee305ba..5dd9a2d9 100644 --- a/g2core/board/gquadratic/motate_pin_assignments.h +++ b/g2core/board/gquadratic/motate_pin_assignments.h @@ -3,8 +3,8 @@ * For: /board/gQuadratic * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index 04da7910..f1861596 100644 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -45,7 +45,7 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 5 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (index starts at 1) diff --git a/g2core/board/gquintic/motate_pin_assignments.h b/g2core/board/gquintic/motate_pin_assignments.h index 57f73a0b..fc0eb27c 100644 --- a/g2core/board/gquintic/motate_pin_assignments.h +++ b/g2core/board/gquintic/motate_pin_assignments.h @@ -3,8 +3,8 @@ * For: /board/gQuintic * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/printrboardg2/hardware.cpp b/g2core/board/printrboardg2/hardware.cpp index cf70c826..0d1085b5 100644 --- a/g2core/board/printrboardg2/hardware.cpp +++ b/g2core/board/printrboardg2/hardware.cpp @@ -3,8 +3,8 @@ * For: /board/printrboardg2 * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -255,7 +255,7 @@ stat_t hw_flash(nvObj_t *nv) stat_t _get_leds(nvObj_t *nv) { - nv->valuetype = TYPE_INT; + nv->valuetype = TYPE_INTEGER; float red, green, blue; @@ -263,34 +263,34 @@ stat_t _get_leds(nvObj_t *nv) // black if (fp_EQ(red, 0.0) && fp_EQ(green, 0.0) && fp_EQ(blue, 0.0)) { - nv->value = 0; + nv->value_int = 0; // white } else if (fp_EQ(red, 1.0) && fp_EQ(green, 1.0) && fp_EQ(blue, 1.0)) { - nv->value = 1; + nv->value_int = 1; // red } else if (fp_EQ(red, 1.0) && fp_EQ(green, 0.0) && fp_EQ(blue, 0.0)) { - nv->value = 2; + nv->value_int = 2; // green } else if (fp_EQ(red, 0.0) && fp_EQ(green, 1.0) && fp_EQ(blue, 0.0)) { - nv->value = 3; + nv->value_int = 3; // blue } else if (fp_EQ(red, 0.0) && fp_EQ(green, 0.0) && fp_EQ(blue, 1.0)) { - nv->value = 4; + nv->value_int = 4; // orange } else if (fp_EQ(red, 1.0) && fp_EQ(green, 0.5) && fp_EQ(blue, 0.0)) { - nv->value = 5; + nv->value_int = 5; // yellow } else if (fp_EQ(red, 1.0) && fp_EQ(green, 1.0) && fp_EQ(blue, 0.0)) { - nv->value = 6; + nv->value_int = 6; } - return (STAT_OK); } stat_t _set_leds(nvObj_t *nv) { - uint32_t value = nv->value; - if ((nv->value < 0) || (nv->value > 6)) { + uint32_t value = nv->value_int; +// if ((nv->value_int < 0) || (nv->value_int > 6)) { + if ((value < 0) || (value > 6)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } @@ -330,7 +330,6 @@ stat_t _set_leds(nvObj_t *nv) LEDs::display_color[pixel].startTransition(100, 1.0, 1.0, 0.0); } } - return (STAT_OK); } diff --git a/g2core/board/printrboardg2/hardware.h b/g2core/board/printrboardg2/hardware.h index d2aff8f2..30a7e205 100644 --- a/g2core/board/printrboardg2/hardware.h +++ b/g2core/board/printrboardg2/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -44,12 +44,12 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 4 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (index starts at 1) #define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define TOOLS 32 // number of entries in tool table (index starts at 1) /************************* * Motate Setup * diff --git a/g2core/board/printrboardg2/motate_pin_assignments.h b/g2core/board/printrboardg2/motate_pin_assignments.h index 74e862e5..d937a600 100644 --- a/g2core/board/printrboardg2/motate_pin_assignments.h +++ b/g2core/board/printrboardg2/motate_pin_assignments.h @@ -3,8 +3,8 @@ * For: /board/printrboardg2 * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/printrboardg2/printrboardG2v3-pinout.h b/g2core/board/printrboardg2/printrboardG2v3-pinout.h index cc2db4a0..7f3da298 100644 --- a/g2core/board/printrboardg2/printrboardG2v3-pinout.h +++ b/g2core/board/printrboardg2/printrboardG2v3-pinout.h @@ -3,8 +3,8 @@ * For: /board/printrboardg2 * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file is part of the Motate Library. * diff --git a/g2core/board/sbv300/hardware.cpp b/g2core/board/sbv300/hardware.cpp index 18e691b1..d652ec60 100644 --- a/g2core/board/sbv300/hardware.cpp +++ b/g2core/board/sbv300/hardware.cpp @@ -3,8 +3,8 @@ * For: /board/sbv300 * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h index 706ce3cc..28af4baf 100644 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -5,8 +5,8 @@ * * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the @@ -44,7 +44,7 @@ // Axes, motors & PWM channels must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 6 // number of axes supported in this version +#define AXES 9 // number of axes supported in this version #define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) #define MOTORS 4 // number of motors on the board #define COORDS 6 // number of supported coordinate systems (1-6) diff --git a/g2core/board/sbv300/motate_pin_assignments.h b/g2core/board/sbv300/motate_pin_assignments.h index 4df93de6..e8950ef2 100644 --- a/g2core/board/sbv300/motate_pin_assignments.h +++ b/g2core/board/sbv300/motate_pin_assignments.h @@ -3,8 +3,8 @@ * For: /board/sbv300 * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file is part of the Motate Library. * diff --git a/g2core/board/sbv300/sbv300-pinout.h b/g2core/board/sbv300/sbv300-pinout.h index c003b9ca..80260c62 100644 --- a/g2core/board/sbv300/sbv300-pinout.h +++ b/g2core/board/sbv300/sbv300-pinout.h @@ -3,8 +3,8 @@ * For: /board/sbv300 * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Robert Giseburt - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/config_app.h b/g2core/config_app.h old mode 100755 new mode 100644 index 190b339f..bfd3931c --- a/g2core/config_app.h +++ b/g2core/config_app.h @@ -2,8 +2,8 @@ * config_app.h - application-specific part of configuration sub-system * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/controller.h b/g2core/controller.h index 7efadaab..69e35f36 100644 --- a/g2core/controller.h +++ b/g2core/controller.h @@ -2,8 +2,8 @@ * controller.h - g2core controller and main dispatch loop * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. - * Copyright (c) 2013 - 2016 Robert Giseburt + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Robert Giseburt * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/encoder.cpp b/g2core/encoder.cpp old mode 100755 new mode 100644 index 184f9183..905a672d --- a/g2core/encoder.cpp +++ b/g2core/encoder.cpp @@ -2,7 +2,7 @@ * encoder.c - encoder interface * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/encoder.h b/g2core/encoder.h old mode 100755 new mode 100644 index 6d4b0f44..1d1d0dc7 --- a/g2core/encoder.h +++ b/g2core/encoder.h @@ -2,7 +2,7 @@ * encoder.h - encoder interface * This file is part of g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 876b4307..0b608521 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 2000000 SWD @@ -102,7 +102,7 @@ true J41800019454 0x284E0A60 - 10000000 + 2000000 diff --git a/g2core/help.cpp b/g2core/help.cpp old mode 100755 new mode 100644 index 6c39190c..7463aba6 --- a/g2core/help.cpp +++ b/g2core/help.cpp @@ -2,7 +2,7 @@ * help.cpp - collected help routines * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/help.h b/g2core/help.h old mode 100755 new mode 100644 index 1efc14c5..d192f614 --- a/g2core/help.h +++ b/g2core/help.h @@ -2,7 +2,7 @@ * help.h - collected help and assorted display routines * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/kinematics.h b/g2core/kinematics.h old mode 100755 new mode 100644 index 2bfeec3c..4305c36b --- a/g2core/kinematics.h +++ b/g2core/kinematics.h @@ -2,7 +2,7 @@ * kinematics.h - inverse kinematics routines * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/persistence.h b/g2core/persistence.h old mode 100755 new mode 100644 index 8e9341c5..3a64d27e --- a/g2core/persistence.h +++ b/g2core/persistence.h @@ -2,7 +2,7 @@ * persistence.h - persistence code * This file is part of the g2code project * - * Copyright (c) 2013 - 2016 Alden S. Hart Jr. + * Copyright (c) 2013 - 2018 Alden S. Hart Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/pwm.h b/g2core/pwm.h index eb4f1549..d367a873 100644 --- a/g2core/pwm.h +++ b/g2core/pwm.h @@ -2,7 +2,7 @@ * pwm.h - pulse width modulation drivers * This file is part of the g2core project * - * Copyright (c) 2012 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2012 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/report.h b/g2core/report.h index 3cd72805..d81daf5f 100644 --- a/g2core/report.h +++ b/g2core/report.h @@ -2,7 +2,7 @@ * report.h - Status reports and other reporting functions * This file is part of the g2core project * - * Copyright (c) 2010 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2010 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the diff --git a/g2core/text_parser.h b/g2core/text_parser.h index 2b37ea11..3743dec8 100644 --- a/g2core/text_parser.h +++ b/g2core/text_parser.h @@ -2,7 +2,7 @@ * text_parser.h - text parser and text mode support * This file is part of the g2core project * - * Copyright (c) 2013 - 2016 Alden S. Hart, Jr. + * Copyright (c) 2013 - 2018 Alden S. Hart, Jr. * * This file ("the software") is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 as published by the From 74bfad1b068f18864af045ec438bf4f812c0ff2d Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 27 Mar 2018 08:39:53 -0400 Subject: [PATCH 270/283] Cleaned up projects and added to gitignore --- .gitignore | 115 +++++++++++++++++++++--------------------- g2core/g2core.cppproj | 18 +++++-- 2 files changed, 72 insertions(+), 61 deletions(-) mode change 100755 => 100644 .gitignore diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index 0a6475fe..479f9f89 --- a/.gitignore +++ b/.gitignore @@ -1,57 +1,58 @@ -# From https://github.com/github/gitignore/blob/master/Objective-C.gitignore -DerivedData - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata - -## Other -*.xccheckout -*.moved-aside -*.xcuserstate -*.xcscmblueprint - -*.o -*.d -*.bin -*.elf -*.hex -*.eep -*.lss -*.map -*.srec -*.aws -*.atsuo -*.cproj -*.log -.project -.cproject -*.launch -.settings -\bin -\build -build/ -bin/ -.DS_Store -TcfTransactionLog.csv -*.xcbkptlist -*.xccheckout -.gdb_history -JLink.log -Tools/gcc-arm-none-eabi* -openocd.cfg -openocd.log -*/mb.txt -Tools/gcc-arm-none-eabi-*.tar.bz2 -*/TinyG2.componentinfo.xml -g2core/g2core.componentinfo.xml -.tags - -g2core/compile_commands.json +# From https://github.com/github/gitignore/blob/master/Objective-C.gitignore +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +*.o +*.d +*.bin +*.elf +*.hex +*.eep +*.log +*.lss +*.map +*.srec +*.aws +*.atsuo +*.cproj +*.log +.project +.cproject +*.launch +.settings +\bin +\build +build/ +bin/ +.DS_Store +TcfTransactionLog.csv +*.xcbkptlist +*.xccheckout +.gdb_history +JLink.log +Tools/gcc-arm-none-eabi* +openocd.cfg +openocd.log +*/mb.txt +Tools/gcc-arm-none-eabi-*.tar.bz2 +*/TinyG2.componentinfo.xml +g2core/g2core.componentinfo.xml +.tags + +g2core/compile_commands.json diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 0b608521..b21c4c5e 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -1701,13 +1701,10 @@ compile - - compile - compile - + compile @@ -1725,6 +1722,9 @@ compile + + compile + compile @@ -1740,6 +1740,12 @@ compile + + compile + + + compile + compile @@ -1890,6 +1896,9 @@ compile + + compile + compile @@ -1941,6 +1950,7 @@ + From a1f87090044ff69be8059d9bfaa66ae9c65afb62 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Tue, 27 Mar 2018 12:54:49 -0400 Subject: [PATCH 271/283] Updated readme --- README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7055faaa..0eb445e8 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,21 @@ G2 [Edge](https://github.com/synthetos/g2/tree/edge) is the branch for beta test That said, Edge is for the adventurous. It is not guaranteed to be stable, but we do our best to achieve this. For production uses we recommend using the [Master branch](https://github.com/synthetos/g2/tree/master). ## Firmware Build 101 `{fb:101.xx}` +### Feature Enhancements New features added. See linked issues and pull requests for details -- Added [UVW axes](https://github.com/synthetos/g2/issues/304) for full 9 axis control +- Added [UVW axes](https://github.com/synthetos/g2/wiki/9-Axis-UVW-Operation) for 9 axis control. [See also: Issue 304](https://github.com/synthetos/g2/issues/304) +- Added [Enhanced Feedhold Functions](https://github.com/synthetos/g2/wiki/Feedhold,-Resume,-and-Other-Simple-Commands) +- Added explicit [Job Kill ^d](https://github.com/synthetos/g2/wiki/Feedhold,-Resume,-and-Other-Simple-Commands#job-kill) - has the effect of an M30 (program end) +- Documented [Communications Startup Tests](https://github.com/synthetos/g2/wiki/g2core-Communications#enqack---checking-for-clean-startup) + +### Internal Changes and Bug Fixes +Many things have changed in the internals for this very large pull request. The following list highlights some of these changes but is not meant to be comprehensive. +- Added explicit typing and type testing to JSON variables. +- As part of the above, 32bit integers are not float casts, and therefore retain full accuracy. Line numbers may now reliably go to 2,000,000,000 +- Movement towards getters and setters as initial stage of refactoring the Big Table :) +- Bugfix: Fixed root finding problem in feedhold exit velocity calculation +- Bugfix: fixed bug in B and C axis assignment in coordinate rotation code + ## Firmware Build 100 `{fb:100.xx}` ### Feature Enhancements @@ -19,7 +32,7 @@ The fb:100 release is a major change from the fb:089 and earlier branches. It re - 3d printing support, including [Marlin Compatibility](https://github.com/synthetos/g2/wiki/Marlin-Compatibility) - GPIO system enhancements - Planner enhancements and other operating improvements for high-speed operation -- Intital support for new processors, including the ARM M7 +- Initial support for new processors, including the ARM M7 ### Project Changes The project is now called g2core (even if the repo remains g2). As of this release the g2core code base is split from the TinyG code base. TinyG will continue to be supported for the Xmega 8-bit platform, and new features will be added, specifically as related to continued support for CNC milling applications. The g2core project will focus on various ARM platforms, as it currently does, and add functions that are not possible in the 8-bit platform. From 2ac43a188bfed682ce7461c83e25a2ed201f5822 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Wed, 28 Mar 2018 05:29:35 -0400 Subject: [PATCH 272/283] Change to Atmel Studio config. No code changes --- g2core/g2core.cppproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index b21c4c5e..1888f313 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800019454 + J41800021206 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800019454 + J41800021206 0x284E0A60 - 2000000 + 10000000 From 8ce7741ea3c877b21a798c2faaece2e3265b021c Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 14 Apr 2018 10:17:08 -0400 Subject: [PATCH 273/283] No functional changes --- g2core/g2core.cppproj | 4 ++-- g2core/plan_exec.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 1888f313..950c9546 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,7 +68,7 @@ - 10000000 + 2000000 SWD @@ -102,7 +102,7 @@ true J41800021206 0x284E0A60 - 10000000 + 2000000 diff --git a/g2core/plan_exec.cpp b/g2core/plan_exec.cpp index 7d2816e9..9e78ac85 100644 --- a/g2core/plan_exec.cpp +++ b/g2core/plan_exec.cpp @@ -170,7 +170,7 @@ static void _init_forward_diffs(float v_0, float v_1); */ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity) { - mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you + mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so pointer doesn't change on you mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this) debug_trap_if_true((block->exit_velocity > block->cruise_velocity), From 38ca38b2ed84ef461162205057d229eac58eb9f9 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Apr 2018 05:07:23 -0400 Subject: [PATCH 274/283] =?UTF-8?q?Fixed=20bug=20caused=20by=20length=5Fsq?= =?UTF-8?q?uare=20vector=20being=20uninitialized;=20moved=20base=20applica?= =?UTF-8?q?tion=20settings=20from=20hardware.h=20to=20g2core.h=20(still=20?= =?UTF-8?q?need=20to=20do=20all=20the=20hardware.h=E2=80=99s);=20some=20co?= =?UTF-8?q?smetic=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/board/G2v9/hardware.cpp | 4 +- g2core/board/G2v9/hardware.h | 32 ++++++------- g2core/cycle_homing.cpp | 4 +- g2core/g2core.h | 5 ++ g2core/gpio.h | 5 +- g2core/plan_line.cpp | 12 +++-- g2core/plan_zoid.cpp | 2 +- g2core/settings/settings_othermill.h | 68 ++-------------------------- g2core/util.h | 10 ++++ 9 files changed, 46 insertions(+), 96 deletions(-) diff --git a/g2core/board/G2v9/hardware.cpp b/g2core/board/G2v9/hardware.cpp index 8f54bdff..d6405b60 100644 --- a/g2core/board/G2v9/hardware.cpp +++ b/g2core/board/G2v9/hardware.cpp @@ -64,12 +64,12 @@ stat_t hardware_periodic() void hw_hard_reset(void) { - Motate::System::reset(/*boootloader: */ false); // arg=0 resets the system + Motate::System::reset(/*bootloader: */ false); // arg=0 resets the system } void hw_flash_loader(void) { - Motate::System::reset(/*boootloader: */ true); // arg=1 erases FLASH and enters FLASH loader + Motate::System::reset(/*bootloader: */ true); // arg=1 erases FLASH and enters FLASH loader } /* diff --git a/g2core/board/G2v9/hardware.h b/g2core/board/G2v9/hardware.h index ab6c404d..bbc7de9f 100644 --- a/g2core/board/G2v9/hardware.h +++ b/g2core/board/G2v9/hardware.h @@ -40,24 +40,28 @@ #define G2CORE_HARDWARE_PLATFORM "g2v9" #define G2CORE_HARDWARE_VERSION "k" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 4 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (index starts at 1) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -67,14 +71,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index cfaccc63..e2c86e07 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -362,8 +362,8 @@ static void _motion_end_callback(float* vect, bool* flag) } static stat_t _homing_axis_move(int8_t axis, float target, float velocity) { - float vect[] = {0,0,0,0,0,0}; - bool flags[] = {0,0,0,0,0,0}; + float vect[] = INIT_AXES_ZEROES; + bool flags[] = INIT_AXES_ZEROES; hm.waiting_for_motion_end = true; diff --git a/g2core/g2core.h b/g2core/g2core.h index 86db2965..9534ff7b 100644 --- a/g2core/g2core.h +++ b/g2core/g2core.h @@ -60,6 +60,11 @@ typedef uint16_t magic_t; // magic number size // Note: If you change COORDS you must adjust the entries in cfgArray table in config.c +#define AXES 9 // number of axes supported in this version +#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) +#define COORDS 6 // number of supported coordinate systems (index starts at 1) +#define TOOLS 32 // number of entries in tool table (index starts at 1) + typedef enum { AXIS_X = 0, AXIS_Y, diff --git a/g2core/gpio.h b/g2core/gpio.h index b984087f..5069312b 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -33,15 +33,14 @@ */ //--- change as required for board and switch hardware ---// +#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing + #define D_IN_CHANNELS 9 // v9 // number of digital inputs supported //#define D_OUT_CHANNELS 13 // number of digital outputs supported #define D_OUT_CHANNELS 9 // number of digital outputs supported #define A_IN_CHANNELS 0 // number of analog inputs supported #define A_OUT_CHANNELS 0 // number of analog outputs supported -//#define INPUT_LOCKOUT_MS 50 // milliseconds to go dead after input firing -#define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing - //--- do not change from here down ---// typedef enum { diff --git a/g2core/plan_line.cpp b/g2core/plan_line.cpp index 860da6ca..5eecf976 100644 --- a/g2core/plan_line.cpp +++ b/g2core/plan_line.cpp @@ -143,10 +143,11 @@ bool mp_runtime_is_idle() { return (!st_runtime_isbusy()); } stat_t mp_aline(GCodeState_t* _gm) { - float target_rotated[AXES]; // all these arrays initialize to all zeroes by compiler settings - float axis_square[AXES]; - float axis_length[AXES]; - bool flags[AXES]; + float target_rotated[] = INIT_AXES_ZEROES; + float axis_square[] = INIT_AXES_ZEROES; + float axis_length[] = INIT_AXES_ZEROES; + bool flags[] = INIT_AXES_FALSE; + float length_square = 0; float length; @@ -199,6 +200,7 @@ stat_t mp_aline(GCodeState_t* _gm) length_square += axis_square[axis]; } else { axis_length[axis] = 0; // make it truly zero if it was tiny + axis_square[axis] = 0; // Fix bug that can kill feedholds by corrupting block_time in _calculate_times } } length = sqrt(length_square); @@ -650,7 +652,7 @@ static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const floa if (bf->axis_flags[axis]) { if (bf->gm.motion_mode == MOTION_MODE_STRAIGHT_TRAVERSE) { tmp_time = fabs(axis_length[axis]) / cm->a[axis].velocity_max; - } else { // gm.motion_mode == MOTION_MODE_STRAIGHT_FEED + } else {// gm.motion_mode == MOTION_MODE_STRAIGHT_FEED tmp_time = fabs(axis_length[axis]) / cm->a[axis].feedrate_max; } max_time = max(max_time, tmp_time); diff --git a/g2core/plan_zoid.cpp b/g2core/plan_zoid.cpp index 2e4881ee..939a0abb 100644 --- a/g2core/plan_zoid.cpp +++ b/g2core/plan_zoid.cpp @@ -127,7 +127,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e } debug_trap_if_zero(bf->length, "mp_calculate_ramps() - got L=0"); debug_trap_if_zero(bf->cruise_velocity, "mp_calculate_ramps() - got Vc=0"); - + // Timings from *here* // initialize parameters to know values diff --git a/g2core/settings/settings_othermill.h b/g2core/settings/settings_othermill.h index 66e6bd2d..5a14d0c1 100644 --- a/g2core/settings/settings_othermill.h +++ b/g2core/settings/settings_othermill.h @@ -54,9 +54,9 @@ #define FEEDHOLD_Z_LIFT 3 // mm to lift Z on feedhold #define PROBE_REPORT_ENABLE true -// WARNING: Older Othermill machines use a 15deg can stack for their Z axis. -// new machines use a stepper which has the same config as the other axis. -#define HAS_CANSTACK_Z_AXIS 0 +// WARNING: Very old, pre-release Othermills may have a 15deg can stack for their Z axis. +// All other machines use a stepper which has the same config as the other axis. +#define HAS_CANSTACK_Z_AXIS false /* // Switch definitions for interlock & E-stop #define ENABLE_INTERLOCK_AND_ESTOP @@ -218,61 +218,6 @@ #define Z_LATCH_BACKOFF 2 #define Z_ZERO_BACKOFF 0.4 - -/* -#define JERK_MAX 500 // 500 million mm/(min^3) -#define JERK_HIGH_SPEED 1000 // 1000 million mm/(min^3) // Jerk during homing needs to stop *fast* -#define VELOCITY_MAX 1500 -#define SEARCH_VELOCITY (VELOCITY_MAX / 3) -#define LATCH_VELOCITY 25 // reeeeally slow for accuracy - -#define X_AXIS_MODE AXIS_STANDARD // xam see canonical_machine.h cmAxisMode for valid values -#define X_VELOCITY_MAX VELOCITY_MAX // xvm G0 max velocity in mm/min -#define X_FEEDRATE_MAX X_VELOCITY_MAX // xfr G1 max feed rate in mm/min -#define X_TRAVEL_MIN 0 // xtn minimum travel for soft limits -#define X_TRAVEL_MAX 145.6 // xtr travel between switches or crashes -#define X_JERK_MAX JERK_MAX // xjm -#define X_JERK_HIGH_SPEED JERK_HIGH_SPEED // xjh -#define X_HOMING_INPUT 1 // xhi input used for homing or 0 to disable -#define X_HOMING_DIRECTION 0 // xhd 0=search moves negative, 1= search moves positive -#define X_SEARCH_VELOCITY SEARCH_VELOCITY // xsv -#define X_LATCH_VELOCITY LATCH_VELOCITY // xlv mm/min -#define X_LATCH_BACKOFF 1 // xlb mm -#define X_ZERO_BACKOFF 0.4 // xzb mm - -#define Y_AXIS_MODE AXIS_STANDARD -#define Y_VELOCITY_MAX VELOCITY_MAX -#define Y_FEEDRATE_MAX Y_VELOCITY_MAX -#define Y_TRAVEL_MIN 0 -#define Y_TRAVEL_MAX 119.1 -#define Y_JERK_MAX JERK_MAX -#define Y_JERK_HIGH_SPEED JERK_HIGH_SPEED -#define Y_HOMING_INPUT 3 -#define Y_HOMING_DIRECTION 0 -#define Y_SEARCH_VELOCITY SEARCH_VELOCITY -#define Y_LATCH_VELOCITY LATCH_VELOCITY -#define Y_LATCH_BACKOFF 1 -#define Y_ZERO_BACKOFF 0.4 - -#define Z_AXIS_MODE AXIS_STANDARD -#if HAS_CANSTACK_Z_AXIS -#define Z_VELOCITY_MAX 1000 -#else -#define Z_VELOCITY_MAX VELOCITY_MAX -#endif -#define Z_FEEDRATE_MAX Z_VELOCITY_MAX -#define Z_TRAVEL_MIN -60.1 -#define Z_TRAVEL_MAX 0 -#define Z_JERK_MAX JERK_MAX -#define Z_JERK_HIGH_SPEED JERK_HIGH_SPEED -#define Z_HOMING_INPUT 6 -#define Z_HOMING_DIRECTION 1 -#define Z_SEARCH_VELOCITY SEARCH_VELOCITY -#define Z_LATCH_VELOCITY LATCH_VELOCITY -#define Z_LATCH_BACKOFF 1 -#define Z_ZERO_BACKOFF 0.4 -*/ - //*** Input / output settings *** /* See gpio.h GPIO defines for options @@ -356,10 +301,3 @@ #define P1_CCW_PHASE_HI 0.1 #define P1_PWM_PHASE_OFF 0.1 -/* -#define P1_USE_MAPPING_CUBIC -#define P1_MAPPING_CUBIC_X3 2.1225328766717546e-013 -#define P1_MAPPING_CUBIC_X2 -7.2900167282605129e-009 -#define P1_MAPPING_CUBIC_X1 8.5854646785876479e-005 -#define P1_MAPPING_CUBIC_X0 -2.1301489219406905e-001 -*/ \ No newline at end of file diff --git a/g2core/util.h b/g2core/util.h index 1c7f20b6..ef29a515 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -74,6 +74,16 @@ uint8_t vector_equal(const float a[], const float b[]); float *set_vector(float x, float y, float z, float a, float b, float c); float *set_vector_by_axis(float value, uint8_t axis); +// *** canned initializers *** + +#if (AXES == 9) +#define INIT_AXES_ZEROES {0,0,0,0,0,0,0,0,0} +#define INIT_AXES_TRUE {1,1,1,1,1,1,1,1,1} +#define INIT_AXES_FALSE INIT_AXES_ZEROES +#else +#warning UNSUPPORTED AXES SETTING! +#endif + //*** math utilities *** float min3(float x1, float x2, float x3); From 2c53a2854c4de2978732eb4c20aaecb972840039 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Apr 2018 05:18:34 -0400 Subject: [PATCH 275/283] =?UTF-8?q?Updated=20hardware.h=E2=80=99s=20to=20u?= =?UTF-8?q?se=20changed=20system=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g2core/board/Archim/hardware.h | 32 +++++++++++-------------- g2core/board/ArduinoDue/hardware.h | 34 +++++++++++---------------- g2core/board/gquadratic/hardware.h | 32 +++++++++++-------------- g2core/board/gquintic/hardware.h | 33 +++++++++++--------------- g2core/board/printrboardg2/hardware.h | 32 +++++++++++-------------- g2core/board/sbv300/hardware.h | 32 +++++++++++-------------- 6 files changed, 84 insertions(+), 111 deletions(-) diff --git a/g2core/board/Archim/hardware.h b/g2core/board/Archim/hardware.h index 32d342e7..a0769d54 100644 --- a/g2core/board/Archim/hardware.h +++ b/g2core/board/Archim/hardware.h @@ -40,24 +40,28 @@ #define G2CORE_HARDWARE_PLATFORM "Archim" #define G2CORE_HARDWARE_VERSION "na" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 4 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (index starts at 1) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -67,14 +71,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ diff --git a/g2core/board/ArduinoDue/hardware.h b/g2core/board/ArduinoDue/hardware.h index b87323ce..8fe8e641 100644 --- a/g2core/board/ArduinoDue/hardware.h +++ b/g2core/board/ArduinoDue/hardware.h @@ -40,26 +40,28 @@ #define G2CORE_HARDWARE_PLATFORM "ArduinoDue" #define G2CORE_HARDWARE_VERSION "na" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 4 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (index starts at 1) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ -// ARM specific code start here - #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -69,14 +71,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ diff --git a/g2core/board/gquadratic/hardware.h b/g2core/board/gquadratic/hardware.h index 45caf19c..c5a5c8a7 100644 --- a/g2core/board/gquadratic/hardware.h +++ b/g2core/board/gquadratic/hardware.h @@ -41,24 +41,28 @@ #define G2CORE_HARDWARE_PLATFORM "gQuadtratic" #define G2CORE_HARDWARE_VERSION "b" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 3 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (1-6) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -68,14 +72,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ diff --git a/g2core/board/gquintic/hardware.h b/g2core/board/gquintic/hardware.h index f1861596..ccfa44fe 100644 --- a/g2core/board/gquintic/hardware.h +++ b/g2core/board/gquintic/hardware.h @@ -35,30 +35,33 @@ #ifndef HARDWARE_H_ONCE #define HARDWARE_H_ONCE - /*--- Hardware platform enumerations ---*/ #define G2CORE_HARDWARE_PLATFORM "gQuintic" #define G2CORE_HARDWARE_VERSION "b" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 5 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (index starts at 1) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -68,14 +71,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ diff --git a/g2core/board/printrboardg2/hardware.h b/g2core/board/printrboardg2/hardware.h index 30a7e205..9854773b 100644 --- a/g2core/board/printrboardg2/hardware.h +++ b/g2core/board/printrboardg2/hardware.h @@ -40,24 +40,28 @@ #define G2CORE_HARDWARE_PLATFORM "printerboardg2" #define G2CORE_HARDWARE_VERSION "c" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 4 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (index starts at 1) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -67,14 +71,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ diff --git a/g2core/board/sbv300/hardware.h b/g2core/board/sbv300/hardware.h index 28af4baf..37960dc4 100644 --- a/g2core/board/sbv300/hardware.h +++ b/g2core/board/sbv300/hardware.h @@ -40,24 +40,28 @@ #define G2CORE_HARDWARE_PLATFORM "sbv300" #define G2CORE_HARDWARE_VERSION "k" -/***** Axes, motors & PWM channels used by the application *****/ -// Axes, motors & PWM channels must be defines (not enums) so expressions like this: +/***** Motors & PWM channels supported by this hardware *****/ +// These must be defines (not enums) so expressions like this: // #if (MOTORS >= 6) will work -#define AXES 9 // number of axes supported in this version -#define HOMING_AXES 4 // number of axes that can be homed (assumes Zxyabc sequence) -#define MOTORS 4 // number of motors on the board -#define COORDS 6 // number of supported coordinate systems (1-6) -#define PWMS 2 // number of supported PWM channels -#define TOOLS 32 // number of entries in tool table (index starts at 1) +#define MOTORS 4 // number of motors supported the hardware +#define PWMS 2 // number of PWM channels supported the hardware + +/************************* + * Global System Defines * + *************************/ + +#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) +#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) +#define SYS_ID_LEN 24 // total length including dashes and NUL /************************* * Motate Setup * *************************/ #include "MotatePins.h" -#include "MotateTimers.h" // for TimerChanel<> and related... -#include "MotateServiceCall.h" // for ServiceCall<> +#include "MotateTimers.h" // for TimerChanel<> and related... +#include "MotateServiceCall.h" // for ServiceCall<> using Motate::TimerChannel; using Motate::ServiceCall; @@ -67,14 +71,6 @@ using Motate::Pin; using Motate::PWMOutputPin; using Motate::OutputPin; -/************************* - * Global System Defines * - *************************/ - -#define MILLISECONDS_PER_TICK 1 // MS for system tick (systick * N) -#define SYS_ID_DIGITS 16 // actual digits in system ID (up to 16) -#define SYS_ID_LEN 24 // total length including dashes and NUL - /************************************************************************************ **** ARM SAM3X8E SPECIFIC HARDWARE ************************************************* ************************************************************************************/ From 8e7e62cb9aec5b312c2d0eda3a682691825753b3 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Apr 2018 06:07:30 -0400 Subject: [PATCH 276/283] Replaced explicit axes array initializations with conditional one from util.h; Fixed range error in cm_get_axis_char() --- g2core/canonical_machine.cpp | 15 +++++++-------- g2core/cycle_jogging.cpp | 4 ++-- g2core/util.h | 6 ++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index 5b7cea1f..f462af5f 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1061,8 +1061,7 @@ stat_t cm_set_absolute_origin(const float origin[], bool flag[]) for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { -// REMOVED value[axis] = cm->offset[cm->gm.coord_system][axis] + _to_millimeters(origin[axis]); // G2 Issue #26 - value[axis] = _to_millimeters(origin[axis]); // replaced the above + value[axis] = _to_millimeters(origin[axis]); cm->gmx.position[axis] = value[axis]; // set model position cm->gm.target[axis] = value[axis]; // reset model target mp_set_planner_position(axis, value[axis]); // set mm position @@ -1197,7 +1196,7 @@ stat_t _goto_stored_position(const float stored_position[], // always in mm cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_ON_DISPLAY_WITH_OFFSETS); // Position stored in abs coords cm_set_distance_mode(ABSOLUTE_DISTANCE_MODE); // Must run in absolute distance mode - bool flags2[] = { 1,1,1,1,1,1 }; + bool flags2[] = INIT_AXES_TRUE; stat_t status = cm_straight_traverse(target, flags2, PROFILE_NORMAL); // Go to stored position cm_set_absolute_override(MODEL, ABSOLUTE_OVERRIDE_OFF); cm_set_distance_mode(saved_distance_mode); // Restore distance mode @@ -1697,8 +1696,8 @@ stat_t cm_json_wait(char *json_string) stat_t cm_run_home(nvObj_t *nv) { if (nv->value_int) { // if true - float axes[] = { 1,1,1,1,1,1 }; - bool flags[] = { 1,1,1,1,1,1 }; + float axes[] = INIT_AXES_ONES; + bool flags[] = INIT_AXES_TRUE; cm_homing_cycle_start(axes, flags); } return (STAT_OK); @@ -1738,7 +1737,7 @@ stat_t cm_run_jog(nvObj_t *nv) * _coord() - return coordinate system number (53=0...59=6) or -1 if error * _axis() - return axis # or -1 if not an axis (works for mapped motors as well) * cm_get_axis_type() - return linear axis (0), rotary axis (1) or error (-1) - * cm_get_axis_char() - return ASCII char for axis number provided + * cm_get_axis_char() - return ASCII char for internal axis number provided */ static int8_t _coord(nvObj_t *nv) // extract coordinate system from 3rd character @@ -1803,9 +1802,9 @@ cmAxisType cm_get_axis_type(const nvObj_t *nv) return (AXIS_TYPE_LINEAR); } -char cm_get_axis_char(const int8_t axis) +char cm_get_axis_char(const int8_t axis) // Uses internal axis numbering { - char axis_char[] = "XYZABC"; + char axis_char[] = "XYZUVWABC"; if ((axis < 0) || (axis > AXES)) return (' '); return (axis_char[axis]); } diff --git a/g2core/cycle_jogging.cpp b/g2core/cycle_jogging.cpp index e9571576..caba8451 100644 --- a/g2core/cycle_jogging.cpp +++ b/g2core/cycle_jogging.cpp @@ -177,8 +177,8 @@ static stat_t _jogging_axis_ramp_jog(int8_t axis) // run the jog ramp } static stat_t _jogging_axis_move(int8_t axis, float target, float velocity) { - float vect[] = { 0,0,0,0,0,0 }; - bool flags[] = { false,false,false,false,false,false }; + float vect[] = INIT_AXES_ZEROES; + bool flags[] = INIT_AXES_FALSE; vect[axis] = target; flags[axis] = true; diff --git a/g2core/util.h b/g2core/util.h index ef29a515..ac2cb9a5 100644 --- a/g2core/util.h +++ b/g2core/util.h @@ -32,13 +32,10 @@ * - support for debugging routines */ -#include "hardware.h" // for AXES - #ifndef UTIL_H_ONCE #define UTIL_H_ONCE #include -//#include "sam.h" #include "MotateTimers.h" using Motate::delay; using Motate::SysTickTimer; @@ -78,8 +75,9 @@ float *set_vector_by_axis(float value, uint8_t axis); #if (AXES == 9) #define INIT_AXES_ZEROES {0,0,0,0,0,0,0,0,0} -#define INIT_AXES_TRUE {1,1,1,1,1,1,1,1,1} +#define INIT_AXES_ONES {1,1,1,1,1,1,1,1,1} #define INIT_AXES_FALSE INIT_AXES_ZEROES +#define INIT_AXES_TRUE INIT_AXES_ONES #else #warning UNSUPPORTED AXES SETTING! #endif From 2ec0edfcf53d0554d3fadf78f6bcdbcda8df237a Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sun, 15 Apr 2018 12:35:40 -0400 Subject: [PATCH 277/283] Fixed homing problem with root cause in new feedhold code. Deleted NORMALLY_OPEN and NORMALLY_CLOSED defines (Use IO_ACTIVE_LOW and IO_ACTIVE_HIGH - respectively - instead.) --- g2core/canonical_machine.cpp | 3 ++- g2core/canonical_machine.h | 5 +++-- g2core/cycle_feedhold.cpp | 9 ++++++++- g2core/cycle_homing.cpp | 1 - g2core/gpio.cpp | 6 ++++-- g2core/gpio.h | 5 +++-- g2core/settings/settings_othermill.h | 10 +++++----- g2core/settings/settings_othermill_test.h | 10 +++++----- 8 files changed, 30 insertions(+), 19 deletions(-) diff --git a/g2core/canonical_machine.cpp b/g2core/canonical_machine.cpp index f462af5f..ab26d1b8 100644 --- a/g2core/canonical_machine.cpp +++ b/g2core/canonical_machine.cpp @@ -1061,7 +1061,8 @@ stat_t cm_set_absolute_origin(const float origin[], bool flag[]) for (uint8_t axis = AXIS_X; axis < AXES; axis++) { if (flag[axis]) { - value[axis] = _to_millimeters(origin[axis]); +// REMOVED value[axis] = cm->offset[cm->gm.coord_system][axis] + _to_millimeters(origin[axis]); // G2 Issue #26 + value[axis] = _to_millimeters(origin[axis]); // replaced the above cm->gmx.position[axis] = value[axis]; // set model position cm->gm.target[axis] = value[axis]; // reset model target mp_set_planner_position(axis, value[axis]); // set mm position diff --git a/g2core/canonical_machine.h b/g2core/canonical_machine.h index 17ff57a2..d37579eb 100644 --- a/g2core/canonical_machine.h +++ b/g2core/canonical_machine.h @@ -127,7 +127,8 @@ typedef enum { // feedhold final operation FEEDHOLD_EXIT_END, // perform program end FEEDHOLD_EXIT_ALARM, // perform alarm FEEDHOLD_EXIT_SHUTDOWN, // perform shutdown - FEEDHOLD_EXIT_INTERLOCK // report as interlock + FEEDHOLD_EXIT_INTERLOCK, // report as interlock + FEEDHOLD_EXIT_RESET_POSITION // reset machine positions to hold point } cmFeedholdExit; typedef enum { // feedhold state machine @@ -318,7 +319,7 @@ typedef struct cmMachine { // struct to manage canonical machin cmProbeState probe_state[PROBES_STORED]; // probing state machine (simple) float probe_results[PROBES_STORED][AXES]; // probing results - float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore UVW and ABC rotary axes + float rotation_matrix[3][3]; // three-by-three rotation matrix. We ignore UVW and ABC axes float rotation_z_offset; // separately handle a z-offset to maintain consistent distance to bed float jogging_dest; // jogging destination as a relative move from current position diff --git a/g2core/cycle_feedhold.cpp b/g2core/cycle_feedhold.cpp index 8bd58ca1..f33366c5 100644 --- a/g2core/cycle_feedhold.cpp +++ b/g2core/cycle_feedhold.cpp @@ -58,6 +58,7 @@ static stat_t _run_program_end(void); static stat_t _run_alarm(void); static stat_t _run_shutdown(void); static stat_t _run_interlock(void); +static stat_t _run_reset_position(void); /**************************************************************************************** * OPERATIONS AND ACTIONS @@ -314,6 +315,12 @@ static stat_t _run_program_end() return (STAT_OK); } +static stat_t _run_reset_position() +{ + cm_reset_position_to_absolute_position(cm); + return (STAT_OK); +} + static stat_t _run_alarm() { return (STAT_OK); } static stat_t _run_shutdown() { return (STAT_OK); } static stat_t _run_interlock() { return (STAT_OK); } @@ -530,6 +537,7 @@ void cm_request_feedhold(cmFeedholdType type, cmFeedholdExit exit) case FEEDHOLD_EXIT_ALARM: { op.add_action(_run_alarm); break; } case FEEDHOLD_EXIT_SHUTDOWN: { op.add_action(_run_shutdown); break; } case FEEDHOLD_EXIT_INTERLOCK: { op.add_action(_run_interlock); break; } + case FEEDHOLD_EXIT_RESET_POSITION: { op.add_action(_run_reset_position); break; } default: {} } return; @@ -638,7 +646,6 @@ static stat_t _feedhold_skip() { if (cm1.hold_state == FEEDHOLD_OFF) { // if entered while OFF start a feedhold cm1.hold_type = FEEDHOLD_TYPE_SKIP; -// cm1.hold_exit = FEEDHOLD_EXIT_FLUSH; // default exit for SKIP is FLUSH... cm1.hold_state = FEEDHOLD_SYNC; // ...FLUSH can be overridden by setting hold_exit after this function } if (cm1.hold_state < FEEDHOLD_MOTION_STOPPED) { diff --git a/g2core/cycle_homing.cpp b/g2core/cycle_homing.cpp index e2c86e07..ba1c487f 100644 --- a/g2core/cycle_homing.cpp +++ b/g2core/cycle_homing.cpp @@ -49,7 +49,6 @@ struct hmHomingSingleton { // persistent homing runtime variables bool set_coordinates; // G28.4 flag. true = set coords to zero at the end of homing cycle stat_t (*func)(int8_t axis); // binding for callback function state machine -// float axes[AXES]; // local storage for axis words and associated flags bool axis_flags[AXES]; // local storage for axis flags // per-axis parameters diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 3eef664f..8469d302 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -103,6 +103,7 @@ struct ioDigitalInputExt { bool pin_value = (bool)input_pin; int8_t pin_value_corrected = (pin_value ^ ((int)in->mode ^ 1)); // correct for NO or NC mode in->state = (ioState)pin_value_corrected; + in->ext_pin_number = ext_pin_number; // diagnostic only. Not used by code } void pin_changed() { @@ -131,7 +132,7 @@ struct ioDigitalInputExt { // lockout the pin for lockout_ms in->lockout_timer.set(in->lockout_ms); - // record the changed state + // record the changed state (we know it changed or we would have exited beforehand) in->state = (ioState)pin_value_corrected; if (pin_value_corrected == INPUT_ACTIVE) { in->edge = INPUT_EDGE_LEADING; @@ -143,7 +144,8 @@ struct ioDigitalInputExt { if (in->homing_mode) { if (in->edge == INPUT_EDGE_LEADING) { // we only want the leading edge to fire en_take_encoder_snapshot(); - cm_request_feedhold(FEEDHOLD_TYPE_SKIP, FEEDHOLD_EXIT_STOP); +// cm_request_feedhold(FEEDHOLD_TYPE_SKIP, FEEDHOLD_EXIT_STOP); + cm_request_feedhold(FEEDHOLD_TYPE_SKIP, FEEDHOLD_EXIT_RESET_POSITION); } return; } diff --git a/g2core/gpio.h b/g2core/gpio.h index 5069312b..ba3f18c1 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -49,8 +49,8 @@ typedef enum { IO_MODE_DISABLED = 2 // input is disabled } ioMode; #define IO_MODE_MAX IO_MODE_DISABLED -#define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent -#define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent +//#define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent +//#define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent // *** NOTE: The active hi/low values currently agree with spindle and coolant values // The above will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 @@ -108,6 +108,7 @@ typedef enum { * GPIO structures */ typedef struct ioDigitalInput { // one struct per digital input + int8_t ext_pin_number; // for easier debugging - not actually used ioMode mode; // -1=disabled, 0=active low (NO), 1= active high (NC) inputAction action; // 0=none, 1=stop, 2=halt, 3=stop_steps, 4=reset inputFunc function; // function to perform when activated / deactivated diff --git a/g2core/settings/settings_othermill.h b/g2core/settings/settings_othermill.h index 5a14d0c1..88e9719a 100644 --- a/g2core/settings/settings_othermill.h +++ b/g2core/settings/settings_othermill.h @@ -243,7 +243,7 @@ */ // Xmin on v9 board // X homing - see X axis setup -#define DI1_MODE NORMALLY_CLOSED +#define DI1_MODE IO_ACTIVE_HIGH // Normally Closed #define DI1_ACTION INPUT_ACTION_NONE #define DI1_FUNCTION INPUT_FUNCTION_NONE @@ -253,22 +253,22 @@ #define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN // Ymin // Y homing - see Y axis setup -#define DI3_MODE NORMALLY_CLOSED +#define DI3_MODE IO_ACTIVE_HIGH #define DI3_ACTION INPUT_ACTION_NONE #define DI3_FUNCTION INPUT_FUNCTION_NONE // Ymax // Safety interlock #define DI4_MODE IO_ACTIVE_HIGH -#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) +#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) #define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK // Zmin // Z probe -#define DI5_MODE IO_ACTIVE_LOW +#define DI5_MODE IO_ACTIVE_LOW // Normally Open #define DI5_ACTION INPUT_ACTION_NONE #define DI5_FUNCTION INPUT_FUNCTION_PROBE // Zmax // Z homing - see Z axis for setup -#define DI6_MODE NORMALLY_CLOSED +#define DI6_MODE IO_ACTIVE_HIGH #define DI6_ACTION INPUT_ACTION_NONE #define DI6_FUNCTION INPUT_FUNCTION_NONE diff --git a/g2core/settings/settings_othermill_test.h b/g2core/settings/settings_othermill_test.h index 375aa862..8c66b58a 100644 --- a/g2core/settings/settings_othermill_test.h +++ b/g2core/settings/settings_othermill_test.h @@ -269,7 +269,7 @@ */ // Xmin on v9 board // X homing - see X axis setup -#define DI1_MODE NORMALLY_CLOSED +#define DI1_MODE IO_ACTIVE_HIGH // Normally CLosed #define DI1_ACTION INPUT_ACTION_NONE #define DI1_FUNCTION INPUT_FUNCTION_NONE @@ -279,22 +279,22 @@ #define DI2_FUNCTION INPUT_FUNCTION_SHUTDOWN // Ymin // Y homing - see Y axis setup -#define DI3_MODE NORMALLY_CLOSED +#define DI3_MODE IO_ACTIVE_HIGH #define DI3_ACTION INPUT_ACTION_NONE #define DI3_FUNCTION INPUT_FUNCTION_NONE // Ymax // Safety interlock #define DI4_MODE IO_ACTIVE_HIGH -#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) +#define DI4_ACTION INPUT_ACTION_NONE // (hold is performed by Interlock function) #define DI4_FUNCTION INPUT_FUNCTION_INTERLOCK // Zmin // Z probe -#define DI5_MODE IO_ACTIVE_LOW +#define DI5_MODE IO_ACTIVE_LOW // Normally Open #define DI5_ACTION INPUT_ACTION_NONE #define DI5_FUNCTION INPUT_FUNCTION_PROBE // Zmax // Z homing - see Z axis for setup -#define DI6_MODE NORMALLY_CLOSED +#define DI6_MODE IO_ACTIVE_HIGH #define DI6_ACTION INPUT_ACTION_NONE #define DI6_FUNCTION INPUT_FUNCTION_NONE From f0bf681ce098f7b7d9a3843351c0412c7d071a52 Mon Sep 17 00:00:00 2001 From: Justin Clift Date: Mon, 16 Apr 2018 15:06:27 +0100 Subject: [PATCH 278/283] Add licence, as per #176 This file is the text from G2core-License on the wiki, with whitespace added between sections for better visual display as text. https://github.com/synthetos/g2/wiki/G2core-License --- LICENSE | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..07573afc --- /dev/null +++ b/LICENSE @@ -0,0 +1,75 @@ +## Intent + +The g2core **project** is a motion control **application** built on a set of underlying **components**. We want the licensing to reflect this, and to treat using the application as a whole somewhat differently than using the components as a library. The intent of the g2core licensing is summarized as: +* Ensure that the g2core project remains open source +* Encourage contribution to the project and ensure that most changes and enhancements are returned to the community +* Make it easy to use g2core components in free and commercial projects/products- i.e. encourage use of g2core components as a library +* Notwithstanding the above, make the application when used as a whole retain GPLv2 provisions + +G2core licensing is based on GPLv2 with the [BeRTOS extension](http://www.bertos.org/discover/license) to enable using component files without invoking GPL copyleft. To this end, all files in the project are licensed under GPLv2. Those files that are considered "components" carry the BeRTOS exception, that allows their use without opening source code that they come in contact with. + +G2core also includes [Motate](https://github.com/synthetos/Motate) hardware abstraction components that are licensed under the same scheme. + +Most of what follows is shamelessly cribbed from the BeRTOS site. + + +## Info + +### You are free to... + +- Include g2core components within any product, distributed under any license, including commercial licenses and/or closed-source licenses +- Modify g2core components as you want under the following conditions: + - Attribution - You must declare in a written statement in documentation and source code that you are using g2core components in your application and offer to provide the (possibly modified) g2core source code + - Share-alike - If you modify g2core components, you may distribute them only under the original license + - Contribution - If you modify g2core components, you must contribute the modifications back to the g2core project + + +### What you can do with g2core components... + +If you are a company or individual doing commercial embedded products, you can: +- Download and use g2core components as you want +- Sell products based on g2core components without paying royalties or other fees +- Sell products based on g2core components without opening or giving away your other application source code + + +### What you must do with g2core components... + +If you sell or otherwise distribute code/products that use g2core components you must: +* Provide attribution that you are using g2core components in the documentation and source code. Text like this is sufficient: +
+"This product uses g2core components (http://www.synthetos.com), Copyright 2018"
+
+* If you modified g2core components offer the modified versions for download from your website. Alternately, you can contribute your modifications to the g2core project, where they may be integrated in whole or in part, and/or hosted independently under the project if not integrated. + + +## Example Text That Includes the BeRTOS Exception + +
+/*
+ * gpio.h - Digital IO  handling functions
+ * This file is part of the g2core project
+ *
+ * Copyright (c) 2015 - 2018 Alden S. Hart, Jr.
+ * Copyright (c) 2015 - 2018 Robert Giseburt
+ *
+ * This file ("the software") is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 as published by the
+ * Free Software Foundation. You should have received a copy of the GNU General Public
+ * License, version 2 along with the software.  If not, see http://www.gnu.org/licenses.
+ *
+ * As a special exception, you may use this file as part of a software library without
+ * restriction. Specifically, if other files instantiate templates or use macros or
+ * inline functions from this file, or you compile this file and link it with  other
+ * files to produce an executable, this file does not by itself cause the resulting
+ * executable to be covered by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be covered by the
+ * GNU General Public License.
+ *
+ * THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY
+ * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
From 9eea64602c6986d69cb19837430bd00041fc24a7 Mon Sep 17 00:00:00 2001 From: Justin Clift Date: Mon, 16 Apr 2018 17:10:32 +0100 Subject: [PATCH 279/283] Update A, B, C axes radius defaults to use motors 4, 5, & 6 As per issue #134 --- g2core/settings/settings_default.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 8a227349..0a06a37a 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -524,7 +524,7 @@ * Note that you need floating point values to always have a .0 at the end! #define A_AXIS_MODE AXIS_RADIUS -#define A_RADIUS (M1_TRAVEL_PER_REV/(2*3.14159628)) +#define A_RADIUS (M4_TRAVEL_PER_REV/(2*3.14159628)) #define A_VELOCITY_MAX ((X_VELOCITY_MAX/M1_TRAVEL_PER_REV)*360) // set to the same speed as X axis #define A_FEEDRATE_MAX A_VELOCITY_MAX #define A_TRAVEL_MIN -1.0 // min/max the same means infinite, no limit @@ -545,7 +545,7 @@ #define A_AXIS_MODE AXIS_DISABLED #endif #ifndef A_RADIUS -#define A_RADIUS (M1_TRAVEL_PER_REV/(2*3.14159628)) +#define A_RADIUS (M4_TRAVEL_PER_REV/(2*3.14159628)) #endif #ifndef A_VELOCITY_MAX #define A_VELOCITY_MAX ((X_VELOCITY_MAX/M1_TRAVEL_PER_REV)*360) // set to the same speed as X axis @@ -589,7 +589,7 @@ #define B_AXIS_MODE AXIS_DISABLED #endif #ifndef B_RADIUS -#define B_RADIUS (M1_TRAVEL_PER_REV/(2*3.14159628)) +#define B_RADIUS (M5_TRAVEL_PER_REV/(2*3.14159628)) #endif #ifndef B_VELOCITY_MAX #define B_VELOCITY_MAX ((X_VELOCITY_MAX/M1_TRAVEL_PER_REV)*360) @@ -616,10 +616,10 @@ #define B_HOMING_DIRECTION 0 #endif #ifndef B_SEARCH_VELOCITY -#define B_SEARCH_VELOCITY (A_VELOCITY_MAX * 0.500) +#define B_SEARCH_VELOCITY (B_VELOCITY_MAX * 0.500) #endif #ifndef B_LATCH_VELOCITY -#define B_LATCH_VELOCITY (A_VELOCITY_MAX * 0.100) +#define B_LATCH_VELOCITY (B_VELOCITY_MAX * 0.100) #endif #ifndef B_LATCH_BACKOFF #define B_LATCH_BACKOFF 5.0 @@ -633,7 +633,7 @@ #define C_AXIS_MODE AXIS_DISABLED #endif #ifndef C_RADIUS -#define C_RADIUS (M1_TRAVEL_PER_REV/(2*3.14159628)) +#define C_RADIUS (M6_TRAVEL_PER_REV/(2*3.14159628)) #endif #ifndef C_VELOCITY_MAX #define C_VELOCITY_MAX ((X_VELOCITY_MAX/M1_TRAVEL_PER_REV)*360) @@ -660,10 +660,10 @@ #define C_HOMING_DIRECTION 0 #endif #ifndef C_SEARCH_VELOCITY -#define C_SEARCH_VELOCITY (A_VELOCITY_MAX * 0.500) +#define C_SEARCH_VELOCITY (C_VELOCITY_MAX * 0.500) #endif #ifndef C_LATCH_VELOCITY -#define C_LATCH_VELOCITY (A_VELOCITY_MAX * 0.100) +#define C_LATCH_VELOCITY (C_VELOCITY_MAX * 0.100) #endif #ifndef C_LATCH_BACKOFF #define C_LATCH_BACKOFF 5.0 From 636781db161bf13501c6df2a90c7892fd6db9b9d Mon Sep 17 00:00:00 2001 From: rk Date: Thu, 19 Apr 2018 14:56:30 +0100 Subject: [PATCH 280/283] Fix coolant-init (partly fixes #336) --- g2core/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/g2core/main.cpp b/g2core/main.cpp index d69d0f78..5210ffed 100644 --- a/g2core/main.cpp +++ b/g2core/main.cpp @@ -30,6 +30,7 @@ #include "report.h" #include "planner.h" #include "stepper.h" +#include "coolant.h" #include "encoder.h" #include "spindle.h" #include "temperature.h" @@ -121,6 +122,8 @@ void application_init_startup(void) gcode_parser_init(); // baseline Gcode parser spindle_init(); // should be after PWM and canonical machine inits and config_init() spindle_reset(); + coolant_init(); + coolant_reset(); temperature_init(); gpio_reset(); } From d4fd75d4857300038fa973b001c700298f349652 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 12 May 2018 07:29:32 -0400 Subject: [PATCH 281/283] Re-introduced NORMALLY_OPEN (corresponds to IO_ACTIVE_LOW) and NORMALLY_CLOSED (corresponds to IO_ACTIVE_LOW) assignments. The NORMALLY_ forms are still used in some settings.h profiles, but are deprecated as depending on wiring a NC switch may be active LOW or HIGH. The NORMALLY_ terms will be removed in the upcoming GPIO Enhancements release. --- g2core/g2core.cppproj | 8 ++++---- g2core/gpio.h | 4 ++-- g2core/settings/settings_makeblock.h | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/g2core/g2core.cppproj b/g2core/g2core.cppproj index 950c9546..a0e1621e 100644 --- a/g2core/g2core.cppproj +++ b/g2core/g2core.cppproj @@ -68,12 +68,12 @@ - 2000000 + 10000000 SWD com.atmel.avrdbg.tool.atmelice - J41800021206 + J41800004259 Atmel-ICE True @@ -100,9 +100,9 @@ True true - J41800021206 + J41800004259 0x284E0A60 - 2000000 + 10000000 diff --git a/g2core/gpio.h b/g2core/gpio.h index ba3f18c1..9f1acf7c 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -49,8 +49,8 @@ typedef enum { IO_MODE_DISABLED = 2 // input is disabled } ioMode; #define IO_MODE_MAX IO_MODE_DISABLED -//#define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent -//#define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent +#define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent +#define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent // *** NOTE: The active hi/low values currently agree with spindle and coolant values // The above will all need to be changed to ACTIVE_HIGH = 0, ACTIVE_LOW = 1 diff --git a/g2core/settings/settings_makeblock.h b/g2core/settings/settings_makeblock.h index 44717a24..1c0e4f04 100644 --- a/g2core/settings/settings_makeblock.h +++ b/g2core/settings/settings_makeblock.h @@ -88,13 +88,13 @@ // *** motor settings ************************************************************************************ +#define MOTOR_POWER_LEVEL 0.2 // power level: 0.0=no power, 1.0=max power #define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // default motor power mode (see stPowerMode in stepper.h) // 0=MOTOR_DISABLED, // 1=MOTOR_ALWAYS_POWERED, // 2=MOTOR_POWERED_IN_CYCLE, // 3=MOTOR_POWERED_ONLY_WHEN_MOVING -#define M1_POWER_LEVEL 0.4 // 1pl: 0.0=no power, 1.0=max power -#define MOTOR_POWER_TIMEOUT 10.00 // motor power timeout in seconds +#define MOTOR_POWER_TIMEOUT 5.00 // motor power timeout in seconds #define M1_MOTOR_MAP AXIS_X_EXTERNAL // 1ma #define M1_STEP_ANGLE 1.8 // 1sa @@ -102,7 +102,7 @@ #define M1_MICROSTEPS 8 // 1mi 1,2,4,8,16,32 #define M1_POLARITY 0 // 1po 0=normal, 1=reversed #define M1_POWER_MODE MOTOR_POWER_MODE // 1pm 0=MOTOR_DISABLED, 1=MOTOR_ALWAYS_POWERED, 2=MOTOR_POWERED_IN_CYCLE, 3=MOTOR_POWERED_ONLY_WHEN_MOVING -#define M1_POWER_LEVEL 0.4 +#define M1_POWER_LEVEL MOTOR_POWER_LEVEL // 1pl: 0.0=no power, 1.0=max power #define M2_MOTOR_MAP AXIS_Y_EXTERNAL #define M2_STEP_ANGLE 1.8 @@ -110,7 +110,7 @@ #define M2_MICROSTEPS 8 #define M2_POLARITY 0 #define M2_POWER_MODE MOTOR_POWER_MODE -#define M2_POWER_LEVEL 0.4 +#define M2_POWER_LEVEL MOTOR_POWER_LEVEL #define M3_MOTOR_MAP AXIS_Z_EXTERNAL // Imaginary Z axis. For testing #define M3_STEP_ANGLE 1.8 @@ -118,7 +118,7 @@ #define M3_MICROSTEPS 8 #define M3_POLARITY 0 #define M3_POWER_MODE MOTOR_POWER_MODE -#define M3_POWER_LEVEL 0.4 +#define M3_POWER_LEVEL MOTOR_POWER_LEVEL #define M4_MOTOR_MAP AXIS_W_EXTERNAL // Imaginary W axis. For testing #define M4_STEP_ANGLE 1.8 @@ -126,7 +126,7 @@ #define M4_MICROSTEPS 8 #define M4_POLARITY 1 #define M4_POWER_MODE MOTOR_POWER_MODE -#define M4_POWER_LEVEL 0.4 +#define M4_POWER_LEVEL MOTOR_POWER_LEVEL // *** axis settings ********************************************************************************** From b832180712e9a98efb447eb408fbe95a8ed6ee94 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 12 May 2018 11:46:23 -0400 Subject: [PATCH 282/283] Updated Readme for Firmware Build 101 --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0eb445e8..f147423b 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ New features added. See linked issues and pull requests for details - Added explicit [Job Kill ^d](https://github.com/synthetos/g2/wiki/Feedhold,-Resume,-and-Other-Simple-Commands#job-kill) - has the effect of an M30 (program end) - Documented [Communications Startup Tests](https://github.com/synthetos/g2/wiki/g2core-Communications#enqack---checking-for-clean-startup) + ### Internal Changes and Bug Fixes Many things have changed in the internals for this very large pull request. The following list highlights some of these changes but is not meant to be comprehensive. - Added explicit typing and type testing to JSON variables. @@ -23,7 +24,9 @@ Many things have changed in the internals for this very large pull request. The - Movement towards getters and setters as initial stage of refactoring the Big Table :) - Bugfix: Fixed root finding problem in feedhold exit velocity calculation - Bugfix: fixed bug in B and C axis assignment in coordinate rotation code - +- PR #334 A, B, C axes radius defaults to use motors 4, 5, & 6 +- PR #336, Issue #336 partial solution to coolant initialization +- PR #299, Issue #298 fix for reading nested JSON value errors ## Firmware Build 100 `{fb:100.xx}` ### Feature Enhancements From 06f28752b0d32e778032efde882a436563dacbc0 Mon Sep 17 00:00:00 2001 From: Alden Hart Date: Sat, 12 May 2018 12:40:33 -0400 Subject: [PATCH 283/283] Updated firmware build number --- g2core/g2core_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g2core/g2core_info.h b/g2core/g2core_info.h index 6f549a6d..ec360e16 100644 --- a/g2core/g2core_info.h +++ b/g2core/g2core_info.h @@ -21,7 +21,7 @@ #ifndef G2CORE_INFO_H_ONCE #define G2CORE_INFO_H_ONCE -#define G2CORE_FIRMWARE_BUILD 101.00 // Added UVW axes (9 axis control) +#define G2CORE_FIRMWARE_BUILD 101.02 // Added UVW axes (9 axis control), Enhanced feedhold actions #define G2CORE_FIRMWARE_VERSION 0.99 #ifdef GIT_VERSION