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_READINGcase 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