case EMC_TASK_MODE_AUTO: // ON, AUTO
switch (emcStatus->task.interpState) {
case EMC_TASK_INTERP_IDLE: // ON, AUTO, IDLE
switch (type) {
case 0:
case EMC_NULL_TYPE:
// no command
break;
// immediate commands
case EMC_AXIS_SET_BACKLASH_TYPE:
case EMC_AXIS_SET_HOMING_PARAMS_TYPE:
case EMC_AXIS_SET_FERROR_TYPE:
case EMC_AXIS_SET_MIN_FERROR_TYPE:
case EMC_AXIS_UNHOME_TYPE:
case EMC_TRAJ_PAUSE_TYPE:
case EMC_TRAJ_RESUME_TYPE:
case EMC_TRAJ_ABORT_TYPE:
case EMC_TRAJ_SET_SCALE_TYPE:
case EMC_TRAJ_SET_MAX_VELOCITY_TYPE:
case EMC_TRAJ_SET_SPINDLE_SCALE_TYPE:
case EMC_TRAJ_SET_FO_ENABLE_TYPE:
case EMC_TRAJ_SET_FH_ENABLE_TYPE:
case EMC_TRAJ_SET_SO_ENABLE_TYPE:
case EMC_SPINDLE_SPEED_TYPE:
case EMC_SPINDLE_ORIENT_TYPE:
case EMC_SPINDLE_WAIT_ORIENT_COMPLETE_TYPE:
case EMC_SPINDLE_ON_TYPE:
case EMC_SPINDLE_OFF_TYPE:
case EMC_SPINDLE_BRAKE_RELEASE_TYPE:
case EMC_SPINDLE_BRAKE_ENGAGE_TYPE:
case EMC_SPINDLE_INCREASE_TYPE:
case EMC_SPINDLE_DECREASE_TYPE:
case EMC_SPINDLE_CONSTANT_TYPE:
case EMC_COOLANT_MIST_ON_TYPE:
case EMC_COOLANT_MIST_OFF_TYPE:
case EMC_COOLANT_FLOOD_ON_TYPE:
case EMC_COOLANT_FLOOD_OFF_TYPE:
case EMC_LUBE_ON_TYPE:
case EMC_LUBE_OFF_TYPE:
case EMC_TASK_SET_MODE_TYPE:
case EMC_TASK_SET_STATE_TYPE:
case EMC_TASK_ABORT_TYPE:
case EMC_TASK_PLAN_INIT_TYPE:
case EMC_TASK_PLAN_OPEN_TYPE:
case EMC_TASK_PLAN_RUN_TYPE:
case EMC_TASK_PLAN_EXECUTE_TYPE:
case EMC_TASK_PLAN_PAUSE_TYPE:
case EMC_TASK_PLAN_RESUME_TYPE:
case EMC_TASK_PLAN_SET_OPTIONAL_STOP_TYPE:
case EMC_TASK_PLAN_SET_BLOCK_DELETE_TYPE:
case EMC_TASK_PLAN_OPTIONAL_STOP_TYPE:
case EMC_TRAJ_CLEAR_PROBE_TRIPPED_FLAG_TYPE:
case EMC_TRAJ_PROBE_TYPE:
case EMC_AUX_INPUT_WAIT_TYPE:
case EMC_TRAJ_RIGID_TAP_TYPE:
case EMC_SET_DEBUG_TYPE:
retval = emcTaskIssueCommand(emcCommand);
break;
case EMC_TASK_PLAN_STEP_TYPE:
// handles case where first action is to step the program
taskPlanRunCmd.line = 1; // run from start
/*! \todo FIXME-- can have GUI set this; send a run instead of a
step */
retval = emcTaskIssueCommand(&taskPlanRunCmd);
if(retval != 0) break;
emcTrajPause();
if (emcStatus->task.interpState != EMC_TASK_INTERP_PAUSED) {
interpResumeState = emcStatus->task.interpState;
}
emcStatus->task.interpState = EMC_TASK_INTERP_PAUSED;
emcStatus->task.task_paused = 1;
retval = 0;
break;
case EMC_TOOL_LOAD_TOOL_TABLE_TYPE:
case EMC_TOOL_SET_OFFSET_TYPE:
// send to IO
emcTaskQueueCommand(emcCommand);
// signify no more reading
emcTaskPlanSetWait();
// then resynch interpreter
emcTaskQueueCommand(&taskPlanSynchCmd);
break;
// otherwise we can't handle it
default:
emcOperatorError(0, _
("can't do that (%s) in auto mode with the interpreter idle"),
emc_symbol_lookup(type));
retval = -1;
break;
} // switch (type) in ON, AUTO, IDLE
break; // EMC_TASK_INTERP_IDLE
/********解析器读取Gcode和解析Gcode,把解析结果放进解析队列*********/
case EMC_TASK_INTERP_READING: // ON, AUTO, READING
switch (type) {
case 0:
case EMC_NULL_TYPE:
// no command
break;
// immediate commands
case EMC_AXIS_SET_BACKLASH_TYPE:
case EMC_AXIS_SET_HOMING_PARAMS_TYPE:
case EMC_AXIS_SET_FERROR_TYPE:
case EMC_AXIS_SET_MIN_FERROR_TYPE:
case EMC_AXIS_UNHOME_TYPE:
case EMC_TRAJ_PAUSE_TYPE:
case EMC_TRAJ_RESUME_TYPE:
case EMC_TRAJ_ABORT_TYPE:
case EMC_TRAJ_SET_SCALE_TYPE:
case EMC_TRAJ_SET_MAX_VELOCITY_TYPE:
case EMC_TRAJ_SET_SPINDLE_SCALE_TYPE:
case EMC_TRAJ_SET_FO_ENABLE_TYPE:
case EMC_TRAJ_SET_FH_ENABLE_TYPE:
case EMC_TRAJ_SET_SO_ENABLE_TYPE:
case EMC_SPINDLE_INCREASE_TYPE:
case EMC_SPINDLE_DECREASE_TYPE:
case EMC_SPINDLE_CONSTANT_TYPE:
case EMC_TASK_PLAN_PAUSE_TYPE:
case EMC_TASK_PLAN_RESUME_TYPE:
case EMC_TASK_PLAN_SET_OPTIONAL_STOP_TYPE:
case EMC_TASK_PLAN_SET_BLOCK_DELETE_TYPE:
case EMC_TASK_PLAN_OPTIONAL_STOP_TYPE:
case EMC_TASK_SET_MODE_TYPE:
case EMC_TASK_SET_STATE_TYPE:
case EMC_TASK_ABORT_TYPE:
case EMC_TRAJ_CLEAR_PROBE_TRIPPED_FLAG_TYPE:
case EMC_TRAJ_PROBE_TYPE:
case EMC_AUX_INPUT_WAIT_TYPE:
case EMC_TRAJ_RIGID_TAP_TYPE:
case EMC_SET_DEBUG_TYPE:
case EMC_COOLANT_MIST_ON_TYPE:
case EMC_COOLANT_MIST_OFF_TYPE:
case EMC_COOLANT_FLOOD_ON_TYPE:
case EMC_COOLANT_FLOOD_OFF_TYPE:
case EMC_LUBE_ON_TYPE:
case EMC_LUBE_OFF_TYPE:
retval = emcTaskIssueCommand(emcCommand);
return retval;
break;
case EMC_TASK_PLAN_STEP_TYPE:
stepping = 1; // set stepping mode in case it's not
steppingWait = 0; // clear the wait
break;
// otherwise we can't handle it
default:
emcOperatorError(0, _
("can't do that (%s) in auto mode with the interpreter reading"),
emc_symbol_lookup(type));
retval = -1;
break;
} // switch (type) in ON, AUTO, READING
// handle interp readahead logic
readahead_reading();
/******************************************************************************************************************************************/
int Interp::_execute(const char *command)
{
int status;
int n;
int MDImode = 0;
block_pointer eblock = &EXECUTING_BLOCK(_setup);
extern const char *call_statenames[];
extern const char *call_typenames[];
extern const char *o_ops[];
if (NULL != command) {
MDImode = 1;
status = read(command);
if (status != INTERP_OK) {
// if (status > INTERP_MIN_ERROR)
// _setup.remap_level = 0;
return status;
}
}
logDebug("execute:%s %s='%s' mdi_int=%d o_type=%s o_name=%s cl=%d rl=%d type=%s state=%s",
MDImode ? "MDI" : "auto",
command ? "command" : "line",
command ? command : _setup.linetext,
_setup.mdi_interrupt, o_ops[eblock->o_type], eblock->o_name,
_setup.call_level,_setup.remap_level,
eblock->call_type < 0 ? "*unset*" : call_typenames[eblock->call_type],
call_statenames[_setup.call_state]);
// process control functions -- will skip if skipping
if ((eblock->o_name != 0) || _setup.mdi_interrupt) {
status = convert_control_functions(eblock, &_setup);
CHP(status); // relinquish control if INTERP_EXCUTE_FINISH, INTERP_ERROR etc
// let MDI code call subroutines.
// !!!KL not clear what happens if last execution failed while in
// !!!KL a subroutine
// NOTE: the last executed file will still be open, because "close"
// is really a lazy close.
// we had an INTERP_OK, so no need to set up another call to finish after sync()
if (_setup.mdi_interrupt) {
_setup.mdi_interrupt = false;
MDImode = 1;
}
logDebug("!!!KL Open file is:%s:", _setup.filename);
logDebug("MDImode = %d", MDImode);
while(MDImode && _setup.call_level) // we are still in a subroutine
{
status = read(0); // reads from current file and calls parse
if (status > INTERP_MIN_ERROR)
CHP(status);
status = execute(); // special handling for mdi errors
if (status != INTERP_OK) {
if (status == INTERP_EXECUTE_FINISH) {
_setup.mdi_interrupt = true;
}
CHP(status);
}
}
_setup.mdi_interrupt = false;
if (MDImode)
FINISH();
return INTERP_OK;
}
// skip if skipping
if(_setup.skipping_o)
{
logDebug("skipping to: %s", _setup.skipping_o);
return INTERP_OK;
}
for (n = 0; n < _setup.parameter_occurrence; n++)
{ // copy parameter settings from parameter buffer into parameter table
_setup.parameters[_setup.parameter_numbers[n]]
= _setup.parameter_values[n];
}
// logDebug("_setup.named_parameter_occurrence = %d",
// _setup.named_parameter_occurrence);
for (n = 0; n < _setup.named_parameter_occurrence; n++)
{ // copy parameter settings from parameter buffer into parameter table
logDebug("storing param:|%s|", _setup.named_parameters[n]);
CHP(store_named_param(&_setup, _setup.named_parameters[n],
_setup.named_parameter_values[n]));
}
_setup.named_parameter_occurrence = 0;
if (_setup.line_length != 0) { /* line not blank */
// at this point we have a parsed block
// if items are to be remapped the flow is as follows:
//
// 1. push this block onto the remap stack because this might take several
// interp invcocations to finish, while other blocks will be parsed and
// executed by the oword subs. The top-of-stack block is the 'current
// remapped block' or CONTROLLING_BLOCK.
//
// 2. execute the remap stack top level block, ticking off all items which are done.
//
// 3. when a remap operation is encountered, this will result in a call like so:
// 'o<replacement>call'.
//
// this replacement call is parsed with read() into _setup.blocks[0] by the
// corresponding routine (see e.g. handling of T in interp_execute.cc)
// through calling into convert_remapped_code()
//
// 4. The oword call code might execute an optional prologue handler which is called
// when the subroutine environment is set up (parameters set, execution of
// body to begin). This is the way to set local named parameters e.g. for canned cycles.
//
// 5. The oword endsub/return code might call an epilogue handler
// which finishes any work at the Python level on endsub/return, and thereafter
// calls back into remap_finished().
//
// 6. The execution stops after parsing, and returns with an indication of the
// execution phase. We use negative values of enum steps to distinguish them
// from normal INTERP_* type codes which are all >= 0.
//
// 7. In MDI mode, we have to kick execution by replicating code from above
// to get the osub call going.
//
// 8. In Auto mode, we do an initial execute(0) to get things going, thereafer
// task will do it for us.
//
// 9. When a replacment sub finishes, remap_finished() continues execution of
// the current remapped block until done.
//
if (eblock->remappings.size() > 0) {
std::set<int>::iterator it;
int next_remap = *eblock->remappings.begin();
logRemap("found remap %d in '%s', level=%d filename=%s line=%d",
next_remap,_setup.blocktext,_setup.call_level,_setup.filename,_setup.sequence_number);
CHP(enter_remap());
block_pointer cblock = &CONTROLLING_BLOCK(_setup);
cblock->phase = next_remap;
// execute up to the first remap including read() of its handler
// this also sets cblock->executing_remap
status = execute_block(cblock, &_setup); /××××××××××××××G代码解析以及压入队列中×××××××××××××××××××/
........status = execute_block(eblock, &_setup);
/*******G代码解析以及压入队列中*****************/
write_g_codes(eblock, &_setup);
write_m_codes(eblock, &_setup);
write_settings(&_setup);
if ((status == INTERP_EXIT) &&
(_setup.remap_level > 0) &&
(_setup.call_level > 0)) {
// an M2 was encountered while executing a handler.
logRemap("standard case status=%s remap_level=%d call_level=%d blocktext='%s' MDImode=%d",
interp_status(status),_setup.remap_level,_setup.call_level, _setup.blocktext,MDImode);
logRemap("_setup.filename = %s, fn[0]=%s, fn[1]=%s",
_setup.filename,
_setup.sub_context[0].filename,
_setup.sub_context[1].filename);
}
}
if ((status != INTERP_OK) &&
(status != INTERP_EXECUTE_FINISH) && (status != INTERP_EXIT))
ERP(status);
} else /* blank line is OK */
status = INTERP_OK;
return status;
}
/******************************************************************************************************************************************/
break; // EMC_TASK_INTERP_READING
case EMC_TASK_INTERP_PAUSED: // ON, AUTO, PAUSED
switch (type) {
case 0:
case EMC_NULL_TYPE:
// no command
break;
// immediate commands
case EMC_AXIS_SET_BACKLASH_TYPE:
case EMC_AXIS_SET_HOMING_PARAMS_TYPE:
case EMC_AXIS_SET_FERROR_TYPE:
case EMC_AXIS_SET_MIN_FERROR_TYPE:
case EMC_AXIS_UNHOME_TYPE:
case EMC_TRAJ_PAUSE_TYPE:
case EMC_TRAJ_RESUME_TYPE:
case EMC_TRAJ_ABORT_TYPE:
case EMC_TRAJ_SET_SCALE_TYPE:
case EMC_TRAJ_SET_MAX_VELOCITY_TYPE:
case EMC_TRAJ_SET_SPINDLE_SCALE_TYPE:
case EMC_TRAJ_SET_FO_ENABLE_TYPE:
case EMC_TRAJ_SET_FH_ENABLE_TYPE:
case EMC_TRAJ_SET_SO_ENABLE_TYPE:
case EMC_SPINDLE_SPEED_TYPE:
case EMC_SPINDLE_ORIENT_TYPE:
case EMC_SPINDLE_WAIT_ORIENT_COMPLETE_TYPE:
case EMC_SPINDLE_ON_TYPE:
case EMC_SPINDLE_OFF_TYPE:
case EMC_SPINDLE_BRAKE_RELEASE_TYPE:
case EMC_SPINDLE_BRAKE_ENGAGE_TYPE:
case EMC_SPINDLE_INCREASE_TYPE:
case EMC_SPINDLE_DECREASE_TYPE:
case EMC_SPINDLE_CONSTANT_TYPE:
case EMC_COOLANT_MIST_ON_TYPE:
case EMC_COOLANT_MIST_OFF_TYPE:
case EMC_COOLANT_FLOOD_ON_TYPE:
case EMC_COOLANT_FLOOD_OFF_TYPE:
case EMC_LUBE_ON_TYPE:
case EMC_LUBE_OFF_TYPE:
case EMC_TASK_SET_MODE_TYPE:
case EMC_TASK_SET_STATE_TYPE:
case EMC_TASK_ABORT_TYPE:
case EMC_TASK_PLAN_EXECUTE_TYPE:
case EMC_TASK_PLAN_PAUSE_TYPE:
case EMC_TASK_PLAN_RESUME_TYPE:
case EMC_TASK_PLAN_SET_OPTIONAL_STOP_TYPE:
case EMC_TASK_PLAN_SET_BLOCK_DELETE_TYPE:
case EMC_TASK_PLAN_OPTIONAL_STOP_TYPE:
case EMC_TRAJ_CLEAR_PROBE_TRIPPED_FLAG_TYPE:
case EMC_TRAJ_PROBE_TYPE:
case EMC_AUX_INPUT_WAIT_TYPE:
case EMC_TRAJ_RIGID_TAP_TYPE:
case EMC_SET_DEBUG_TYPE:
retval = emcTaskIssueCommand(emcCommand);
break;
case EMC_TASK_PLAN_STEP_TYPE:
stepping = 1;
steppingWait = 0;
if (emcStatus->motion.traj.paused &&
emcStatus->motion.traj.queue > 0) {
// there are pending motions paused; step them
emcTrajStep();
} else {
emcStatus->task.interpState = (enum EMC_TASK_INTERP_ENUM) interpResumeState;
}
emcStatus->task.task_paused = 1;
break;
// otherwise we can't handle it
default:
emcOperatorError(0, _
("can't do that (%s) in auto mode with the interpreter paused"),
emc_symbol_lookup(type));
retval = -1;
break;
} // switch (type) in ON, AUTO, PAUSED
break; // EMC_TASK_INTERP_PAUSED
case EMC_TASK_INTERP_WAITING:
// interpreter ran to end
// handle input commands
switch (type) {
case 0:
case EMC_NULL_TYPE:
// no command
break;
// immediate commands
case EMC_AXIS_SET_BACKLASH_TYPE:
case EMC_AXIS_SET_HOMING_PARAMS_TYPE:
case EMC_AXIS_SET_FERROR_TYPE:
case EMC_AXIS_SET_MIN_FERROR_TYPE:
case EMC_AXIS_UNHOME_TYPE:
case EMC_TRAJ_PAUSE_TYPE:
case EMC_TRAJ_RESUME_TYPE:
case EMC_TRAJ_ABORT_TYPE:
case EMC_TRAJ_SET_SCALE_TYPE:
case EMC_TRAJ_SET_MAX_VELOCITY_TYPE:
case EMC_TRAJ_SET_SPINDLE_SCALE_TYPE:
case EMC_TRAJ_SET_FO_ENABLE_TYPE:
case EMC_TRAJ_SET_FH_ENABLE_TYPE:
case EMC_TRAJ_SET_SO_ENABLE_TYPE:
case EMC_SPINDLE_INCREASE_TYPE:
case EMC_SPINDLE_DECREASE_TYPE:
case EMC_SPINDLE_CONSTANT_TYPE:
case EMC_TASK_PLAN_EXECUTE_TYPE:
case EMC_TASK_PLAN_PAUSE_TYPE:
case EMC_TASK_PLAN_RESUME_TYPE:
case EMC_TASK_PLAN_SET_OPTIONAL_STOP_TYPE:
case EMC_TASK_PLAN_SET_BLOCK_DELETE_TYPE:
case EMC_TASK_PLAN_OPTIONAL_STOP_TYPE:
case EMC_TASK_SET_MODE_TYPE:
case EMC_TASK_SET_STATE_TYPE:
case EMC_TASK_ABORT_TYPE:
case EMC_TRAJ_CLEAR_PROBE_TRIPPED_FLAG_TYPE:
case EMC_TRAJ_PROBE_TYPE:
case EMC_AUX_INPUT_WAIT_TYPE:
case EMC_TRAJ_RIGID_TAP_TYPE:
case EMC_SET_DEBUG_TYPE:
case EMC_COOLANT_MIST_ON_TYPE:
case EMC_COOLANT_MIST_OFF_TYPE:
case EMC_COOLANT_FLOOD_ON_TYPE:
case EMC_COOLANT_FLOOD_OFF_TYPE:
case EMC_LUBE_ON_TYPE:
case EMC_LUBE_OFF_TYPE:
retval = emcTaskIssueCommand(emcCommand);
break;
case EMC_TASK_PLAN_STEP_TYPE:
stepping = 1; // set stepping mode in case it's not
steppingWait = 0; // clear the wait
break;
// otherwise we can't handle it
default:
emcOperatorError(0, _
("can't do that (%s) in auto mode with the interpreter waiting"),
emc_symbol_lookup(type));
retval = -1;
break;
} // switch (type) in ON, AUTO, WAITING
// handle interp readahead logic
readahead_waiting();
break; // end of case EMC_TASK_INTERP_WAITING
default:
// coding error
rcs_print_error("invalid mode(%d)", emcStatus->task.mode);
retval = -1;
break;
} // switch (mode) in ON, AUTO
break; // case EMC_TASK_MODE_AUTO