📄 emctaskmain.cc
字号:
__FILE__, __LINE__); } } // clear out the pending command emcTaskCommand = 0; interp_list.clear(); // clear out the interpreter state emcStatus->task.interpState = EMC_TASK_INTERP_IDLE; emcStatus->task.execState = EMC_TASK_EXEC_DONE; stepping = 0; steppingWait = 0; // now queue up command to resynch interpreter emcTaskQueueCommand(&taskPlanSynchCmd); retval = 0; } retval = emcTaskSetMode(mode_msg->mode); break; case EMC_TASK_SET_STATE_TYPE: state_msg = (EMC_TASK_SET_STATE *) cmd; retval = emcTaskSetState(state_msg->state); break; // interpreter commands case EMC_TASK_PLAN_OPEN_TYPE: open_msg = (EMC_TASK_PLAN_OPEN *) cmd; retval = emcTaskPlanOpen(open_msg->file); if (EMC_DEBUG & EMC_DEBUG_INTERP) { rcs_print("emcTaskPlanOpen(%s) returned %d\n", open_msg->file, retval); } if (retval > INTERP_MIN_ERROR) { retval = -1; } if (-1 == retval) { emcOperatorError(0, _("can't open %s"), open_msg->file); } else { strcpy(emcStatus->task.file, open_msg->file); retval = 0; } break; case EMC_TASK_PLAN_EXECUTE_TYPE: stepping = 0; steppingWait = 0; execute_msg = (EMC_TASK_PLAN_EXECUTE *) cmd; if (execute_msg->command[0] != 0) { if (emcStatus->task.mode == EMC_TASK_MODE_MDI) { interp_list.set_line_number(--pseudoMdiLineNumber); } execRetval = emcTaskPlanExecute(execute_msg->command); if (EMC_DEBUG & EMC_DEBUG_INTERP) { rcs_print("emcTaskPlanExecute(%s) returned %d\n", execute_msg->command, execRetval); } if (execRetval == 2 /* INTERP_ENDFILE */ ) { // this is an end-of-file // need to flush execution, so signify no more reading // until all is done emcTaskPlanSetWait(); if (EMC_DEBUG & EMC_DEBUG_INTERP) { rcs_print("emcTaskPlanSetWait() called\n"); } // and resynch the interpreter WM emcTaskQueueCommand(&taskPlanSynchCmd); // it's success, so retval really is 0 retval = 0; } else if (execRetval != 0) { retval = -1; } else { // other codes are OK retval = 0; } } break; case EMC_TASK_PLAN_RUN_TYPE: stepping = 0; steppingWait = 0; if (!taskplanopen && emcStatus->task.file[0] != 0) { emcTaskPlanOpen(emcStatus->task.file); } run_msg = (EMC_TASK_PLAN_RUN *) cmd; programStartLine = run_msg->line; emcStatus->task.interpState = EMC_TASK_INTERP_READING; retval = 0; break; case EMC_TASK_PLAN_PAUSE_TYPE: emcTrajPause(); if (emcStatus->task.interpState != EMC_TASK_INTERP_PAUSED) { interpResumeState = emcStatus->task.interpState; } emcStatus->task.interpState = EMC_TASK_INTERP_PAUSED; retval = 0; break; case EMC_TASK_PLAN_RESUME_TYPE: emcTrajResume(); emcStatus->task.interpState = (enum EMC_TASK_INTERP_ENUM) interpResumeState; stepping = 0; steppingWait = 0; retval = 0; break; case EMC_TASK_PLAN_END_TYPE: retval = 0; break; case EMC_TASK_PLAN_INIT_TYPE: retval = emcTaskPlanInit(); if (EMC_DEBUG & EMC_DEBUG_INTERP) { rcs_print("emcTaskPlanInit() returned %d\n", retval); } if (retval > INTERP_MIN_ERROR) { retval = -1; } break; case EMC_TASK_PLAN_SYNCH_TYPE: retval = emcTaskPlanSynch(); if (EMC_DEBUG & EMC_DEBUG_INTERP) { rcs_print("emcTaskPlanSynch() returned %d\n", retval); } if (retval > INTERP_MIN_ERROR) { retval = -1; } break; default: // unrecognized command if (EMC_DEBUG & EMC_DEBUG_TASK_ISSUE) { rcs_print_error("ignoring issue of unknown command %d:%s\n", cmd->type, emc_symbol_lookup(cmd->type)); } retval = 0; // don't consider this an error break; } if (retval == -1) { if (EMC_DEBUG & EMC_DEBUG_TASK_ISSUE) { rcs_print_error("error executing command %d:%s\n", cmd->type, emc_symbol_lookup(cmd->type)); } }/*! \todo FIXME - debug */ if (EMC_DEBUG & EMC_DEBUG_TASK_ISSUE) { printf("emcTaskIssueCommand() returning: %d\n", retval); } return retval;}/* emcTaskCheckPostconditions() is called for commands on the interp_list. Immediate commands, i.e., commands sent from calls to emcTaskIssueCommand() in emcTaskPlan() directly, are not handled here. The return value is a state for emcTaskExecute() to wait on, e.g., EMC_TASK_EXEC_WAITING_FOR_MOTION, after the command has finished and before any other commands can be sent out. */static int emcTaskCheckPostconditions(NMLmsg * cmd){ if (0 == cmd) { return EMC_TASK_EXEC_DONE; } switch (cmd->type) { case EMC_OPERATOR_ERROR_TYPE: case EMC_OPERATOR_TEXT_TYPE: case EMC_OPERATOR_DISPLAY_TYPE: return EMC_TASK_EXEC_DONE; break; case EMC_SYSTEM_CMD_TYPE: return EMC_TASK_EXEC_WAITING_FOR_SYSTEM_CMD; break; case EMC_TRAJ_LINEAR_MOVE_TYPE: case EMC_TRAJ_CIRCULAR_MOVE_TYPE: case EMC_TRAJ_SET_VELOCITY_TYPE: case EMC_TRAJ_SET_ACCELERATION_TYPE: case EMC_TRAJ_SET_TERM_COND_TYPE: case EMC_TRAJ_SET_SPINDLESYNC_TYPE: case EMC_TRAJ_SET_OFFSET_TYPE: case EMC_TRAJ_SET_ORIGIN_TYPE: case EMC_TRAJ_PROBE_TYPE: case EMC_TRAJ_CLEAR_PROBE_TRIPPED_FLAG_TYPE: case EMC_TRAJ_SET_TELEOP_ENABLE_TYPE: case EMC_TRAJ_SET_TELEOP_VECTOR_TYPE: return EMC_TASK_EXEC_DONE; break; case EMC_TOOL_PREPARE_TYPE: case EMC_TOOL_LOAD_TYPE: case EMC_TOOL_UNLOAD_TYPE: case EMC_TOOL_LOAD_TOOL_TABLE_TYPE: case EMC_TOOL_SET_OFFSET_TYPE: case EMC_SPINDLE_ON_TYPE: case EMC_SPINDLE_OFF_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: return EMC_TASK_EXEC_DONE; break; case EMC_TASK_PLAN_RUN_TYPE: case EMC_TASK_PLAN_PAUSE_TYPE: case EMC_TASK_PLAN_END_TYPE: case EMC_TASK_PLAN_INIT_TYPE: case EMC_TASK_PLAN_SYNCH_TYPE: case EMC_TASK_PLAN_EXECUTE_TYPE: return EMC_TASK_EXEC_DONE; break; case EMC_TRAJ_DELAY_TYPE: return EMC_TASK_EXEC_WAITING_FOR_DELAY; break; case EMC_MOTION_SET_AOUT_TYPE: case EMC_MOTION_SET_DOUT_TYPE: return EMC_TASK_EXEC_DONE; break; default: // unrecognized command if (EMC_DEBUG & EMC_DEBUG_TASK_ISSUE) { rcs_print_error("postconditions: unrecognized command %d:%s\n", cmd->type, emc_symbol_lookup(cmd->type)); } return EMC_TASK_EXEC_DONE; break; } return EMC_TASK_EXEC_DONE; // unreached}/* STEPPING_CHECK() is a macro that prefaces a switch-case with a check for stepping. If stepping is active, it waits until the step has been given, then falls through to the rest of the case statement.*/#define STEPPING_CHECK() \if (stepping) { \ if (! steppingWait) { \ steppingWait = 1; \ steppedLine = emcStatus->task.currentLine; \ } \ else { \ if (emcStatus->task.currentLine != steppedLine) { \ break; \ } \ } \}// executor functionstatic int emcTaskExecute(void){ int retval = 0; int status; // status of child from EMC_SYSTEM_CMD pid_t pid; // pid returned from waitpid() // first check for an abandoned system command and abort it if (emcSystemCmdPid != 0 && emcStatus->task.execState != EMC_TASK_EXEC_WAITING_FOR_SYSTEM_CMD) { if (EMC_DEBUG & EMC_DEBUG_TASK_ISSUE) { rcs_print("emcSystemCmd: abandoning process %d\n", emcSystemCmdPid); } kill(emcSystemCmdPid, SIGINT); emcSystemCmdPid = 0; } switch (emcStatus->task.execState) { case EMC_TASK_EXEC_ERROR: /*! \todo FIXME-- duplicate code for abort, also near end of main, when aborting on subordinate errors, and in emcTaskIssueCommand() */ // abort everything emcTaskAbort(); // without emcTaskPlanClose(), a new run command resumes at // aborted line-- feature that may be considered later { int was_open = taskplanopen; emcTaskPlanClose(); if (EMC_DEBUG & EMC_DEBUG_INTERP && was_open) { rcs_print("emcTaskPlanClose() called at %s:%d\n", __FILE__, __LINE__); } } // clear out pending command emcTaskCommand = 0; interp_list.clear(); // clear out the interpreter state emcStatus->task.interpState = EMC_TASK_INTERP_IDLE; emcStatus->task.execState = EMC_TASK_EXEC_DONE; stepping = 0; steppingWait = 0; // now queue up command to resynch interpreter emcTaskQueueCommand(&taskPlanSynchCmd); retval = -1; break; case EMC_TASK_EXEC_DONE: STEPPING_CHECK(); if (!emcStatus->motion.traj.queueFull && emcStatus->task.interpState != EMC_TASK_INTERP_PAUSED) { if (0 == emcTaskCommand) { // need a new command emcTaskCommand = interp_list.get(); // interp_list now has line number associated with this-- get // it if (0 != emcTaskCommand) { emcStatus->task.currentLine = interp_list.get_line_number(); // and set it for all subsystems which use queued ids emcTrajSetMotionId(emcStatus->task.currentLine); if (emcStatus->motion.traj.queueFull) { emcStatus->task.execState = EMC_TASK_EXEC_WAITING_FOR_MOTION_QUEUE; } else { emcStatus->task.execState = (enum EMC_TASK_EXEC_ENUM) emcTaskCheckPreconditions(emcTaskCommand); } } } else { // have an outstanding command if (0 != emcTaskIssueCommand(emcTaskCommand)) { emcStatus->task.execState = EMC_TASK_EXEC_ERROR; retval = -1; } else { emcStatus->task.execState = (enum EMC_TASK_EXEC_ENUM) emcTaskCheckPostconditions(emcTaskCommand); } emcTaskCommand = 0; // reset it } } break; case EMC_TASK_EXEC_WAITING_FOR_MOTION_QUEUE: STEPPING_CHECK(); if (!emcStatus->motion.traj.queueFull) { if (0 != emcTaskCommand) { emcStatus->task.execState = (enum EMC_TASK_EXEC_ENUM) emcTaskCheckPreconditions(emcTaskCommand); } else { emcStatus->task.execState = EMC_TASK_EXEC_DONE; } } break; case EMC_TASK_EXEC_WAITING_FOR_PAUSE: STEPPING_CHECK(); if (emcStatus->task.interpState != EMC_TASK_INTERP_PAUSED) { if (0 != emcTaskCommand) { if (emcStatus->motion.traj.queue > 0) { emcStatus->task.execState = EMC_TASK_EXEC_WAITING_FOR_MOTION_QUEUE; } else { emcStatus->task.execState = (enum EMC_TASK_EXEC_ENUM) emcTaskCheckPreconditions(emcTaskCommand); } } else { emcStatus->task.execState = EMC_TASK_EXEC_DONE; } } break; case EMC_TASK_EXEC_WAITING_FOR_MOTION: STEPPING_CHECK(); if (emcStatus->motion.status == RCS_ERROR) { // emcOperatorError(0, "error in motion controller"); emcStatus->task.execState = EMC_TASK_EXEC_ERROR; } else if (emcStatus->motion.status == RCS_DONE) { emcStatus->task.execState = EMC_TASK_EXEC_DONE; } break; case EMC_TASK_EXEC_WAITING_FOR_IO: STEPPING_CHECK(); if (emcStatus->io.status == RCS_ERROR) { // emcOperatorError(0, "error in IO controller"); emcStatus->task.execState = EMC_TASK_EXEC_ERROR; } else if (emcStatus->io.status == RCS_DONE) { emcStatus->task.execState = EMC_TASK_EXEC_DONE; } break; case EMC_TASK_EXEC_WAITING_FOR_MOTION_AND_IO: STEPPING_CHECK(); if (emcStatus->motion.status == RCS_ERROR) { // emcOperatorError(0, "error in motion controller"); emcStatus->task.execState = EMC_TASK_EXEC_ERROR; } else if (emcStatus->io.status == RCS_ERROR) { // emcOperatorError(0, "error in IO controller"); emcStatus->task.execState = EMC_TASK_EXEC_ERROR; } else if (emcStatus->motion.status == RCS_DONE && emcStatus->io.status == RCS_DONE) { emcStatus->task.execState = EMC_TASK_EXEC_DONE; } break; case EMC_TASK_EXEC_WAITING_FOR_DELAY: STEPPING_CHECK();#if defined(LINUX_KERNEL_2_2) if (taskExecDelayTimeout <= 0.0) { emcStatus->task.execState = EMC_TASK_EXEC_DONE; } else { taskExecDelayTimeout -= EMC_TASK_CYCLE_TIME; }#else if (etime() >= taskExecDelayTimeout) { emcStatus->task.execState = EMC_TASK_EXEC_DONE; }#endif break; case EMC_TASK_EXEC_WAITING_FOR_SYSTEM_CMD: STEPPING_CHECK(); // if we got here without a system command pending, say we're done if (0 == emcSystemCmdPid) { emcStatus->task.execState = EMC_TASK_EXEC_DONE; break; } // check the status of the system command pid = waitpid(emcSystemCmdPid, &status, WNOHANG); if (0 == pid) { // child is still executing break; } if (-1 == pid) { // execution error if (EMC_DEBUG & EMC_DEBUG_TASK_ISSUE) { rcs_print("emcSystemCmd: error waiting for %d\n", emcSystemCmdPid); } emcSystemCmdPid = 0; emcStatus->task.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -