Work in process

This commit is contained in:
Alden Hart
2017-03-10 06:21:42 -05:00
parent d87b3a3e4c
commit 6f49052679
6 changed files with 253 additions and 61 deletions
+9 -9
View File
@@ -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: {
+24 -24
View File
@@ -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);
+1
View File
@@ -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)
+211 -26
View File
@@ -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
+2 -2
View File
@@ -68,7 +68,7 @@
<com_atmel_avrdbg_tool_atmelice>
<ToolOptions>
<InterfaceProperties>
<SwdClock>10000000</SwdClock>
<SwdClock>2000000</SwdClock>
</InterfaceProperties>
<InterfaceName>SWD</InterfaceName>
</ToolOptions>
@@ -102,7 +102,7 @@
<preserveEEPROM>true</preserveEEPROM>
<avrtoolserialnumber>J41800019454</avrtoolserialnumber>
<avrdeviceexpectedsignature>0x284E0A60</avrdeviceexpectedsignature>
<avrtoolinterfaceclock>10000000</avrtoolinterfaceclock>
<avrtoolinterfaceclock>2000000</avrtoolinterfaceclock>
<custom>
<ToolOptions xmlns="">
<InterfaceProperties>
+6
View File
@@ -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);
}