diff options
author | Michael Haberler <git@mah.priv.at> | 2011-07-29 09:22:59 +0200 |
---|---|---|
committer | Michael Haberler <git@mah.priv.at> | 2011-10-28 08:25:56 +0200 |
commit | 603620b814d1fd6acd030e2a6763dbf08606a04d (patch) | |
tree | 60c1f0982aa6d542e3304132b3448c325e8a41b4 | |
parent | 6e98f7a68825d1f29ac56c43cd7403768a5791ab (diff) | |
download | linuxcnc-603620b814d1fd6acd030e2a6763dbf08606a04d.tar.gz linuxcnc-603620b814d1fd6acd030e2a6763dbf08606a04d.zip |
proof of concept
-rw-r--r-- | configs/sim/nstools.tbl | 48 | ||||
-rw-r--r-- | configs/sim/py.ini | 5 | ||||
-rw-r--r-- | configs/sim/pysubs/customtask.py | 52 | ||||
-rw-r--r-- | configs/sim/pysubs/plugins.py | 5 | ||||
-rw-r--r-- | configs/sim/pysubs/task.py | 11 | ||||
-rw-r--r-- | src/emc/pythonplugin/python_plugin.cc | 3 | ||||
-rw-r--r-- | src/emc/pythonplugin/python_plugin.hh | 6 | ||||
-rw-r--r-- | src/emc/sai/Submakefile | 4 | ||||
-rw-r--r-- | src/emc/sai/dummyemcstat.cc | 6 | ||||
-rw-r--r-- | src/emc/task/Submakefile | 1 | ||||
-rw-r--r-- | src/emc/task/emctask.cc | 44 | ||||
-rw-r--r-- | src/emc/task/emctaskmain.cc | 13 | ||||
-rw-r--r-- | src/emc/task/iotaskintf.cc | 193 | ||||
-rw-r--r-- | src/emc/task/task.hh | 3 | ||||
-rw-r--r-- | src/emc/task/taskmodule.cc | 124 |
15 files changed, 381 insertions, 137 deletions
diff --git a/configs/sim/nstools.tbl b/configs/sim/nstools.tbl index bedf193ea..b8dd66dcd 100644 --- a/configs/sim/nstools.tbl +++ b/configs/sim/nstools.tbl @@ -1,24 +1,24 @@ -T1 P31 D1 Z101 -T2 P32 D2 Z102 -T3 P33 D3 Z103 -T4 P34 D4 Z104 ;added 20110413 -T5 P35 D5 Z105 ;added 20110413 -T6 P36 D6 Z106 ;added 20110413 -T7 P37 D7 Z107 ;added 20110413 -T8 P38 D8 Z108 ;added 20110413 -T9 P39 D9 Z109 ;added 20110413 -T10 P40 D10 Z110 ;added 20110413 -T11 P41 D11 Z111 ;added 20110413 -T12 P42 Z112 D4 ;3d taster elektronisch -T13 P43 Z113 D13 ;3-schneider schaftfräser -T14 P44 Z114 D10 ;3 schneiden stufenbohrer 5.5 auf 10 -T15 P45 Z115 D10 ;tin bohrer -T16 P46 Z116 D12.5 ;3 schneiden stufenbohrer 6.8 auf 12.5 -T17 P47 Z117 D6.5 ;stufenbohrer 4.2 auf 6.5 mit 45 grad übergang -T18 P48 Z118 D4 ;schaftfräser 4 schneider -T19 P49 Z119 D11 ;bohrer -T20 P50 Z120 D50.1 ;messerkopf 4 platten -T21 P51 Z121 D7.8 ;bohrer poliert -T22 P52 Z122 D16.15 ;messerkopf zweischneider -T23 P53 Z123 D3.3 ;bohrer poliert -T24 P54 Z124 D12 ;positionierstift +T3 P0 D3.000000 Z+103.000000 +T1 P2 D1.000000 Z+101.000000 +T2 P3 D2.000000 Z+102.000000 +T4 P4 D4.000000 Z+104.000000 +T5 P5 D5.000000 X+4711.000000 Z+105.000000 +T6 P6 D6.000000 Z+106.000000 +T7 P7 D7.000000 Z+107.000000 +T8 P8 D8.000000 Z+108.000000 +T9 P9 D9.000000 Z+109.000000 +T10 P10 D10.000000 Z+110.000000 +T11 P11 D11.000000 Z+111.000000 +T12 P12 D4.000000 Z+112.000000 +T13 P13 D13.000000 Z+113.000000 +T14 P14 D10.000000 Z+114.000000 +T15 P15 D10.000000 Z+115.000000 +T16 P16 D12.500000 Z+116.000000 +T17 P17 D6.500000 Z+117.000000 +T18 P18 D4.000000 Z+118.000000 +T19 P19 D11.000000 Z+119.000000 +T20 P20 D50.100000 Z+120.000000 +T21 P21 D7.800000 Z+121.000000 +T22 P22 D16.150000 Z+122.000000 +T23 P23 D3.300000 Z+123.000000 +T24 P24 D12.000000 Z+124.000000 diff --git a/configs/sim/py.ini b/configs/sim/py.ini index ecce8cd13..003d55c8e 100644 --- a/configs/sim/py.ini +++ b/configs/sim/py.ini @@ -20,11 +20,11 @@ MACHINE = EMC-HAL-SIM-AXIS #DEBUG = 0x7FFFDEFF #no interp,oword #DEBUG = 0x00008000 # py only #DEBUG = 0x0000E000 # py + remap + Oword -#DEBUG = 0x0000C000 # py + remap +DEBUG = 0x0000C000 # py + remap #DEBUG = 0x0000C100 # py + remap + Interpreter #DEBUG = 0x0000C140 # py + remap + Interpreter + NML msgs #DEBUG = 0x0000C040 # py + remap + NML -DEBUG = 0x0003E100 # py + remap + Interpreter + oword + signals + namedparams +#DEBUG = 0x0003E100 # py + remap + Interpreter + oword + signals + namedparams #DEBUG = 0x00008000 #DEBUG = 0 # 0x00000100 # 0x00000001 Ausgabe ungültige Meldungen @@ -124,6 +124,7 @@ RELOAD_ON_CHANGE=1 #LOG_FILE= py.log LOG_LEVEL = 3 +TASK=task = task.customtask.CustomTask() # Part program interpreter section -------------------------------------------- [RS274NGC] #PRINT_CODES = 1 diff --git a/configs/sim/pysubs/customtask.py b/configs/sim/pysubs/customtask.py new file mode 100644 index 000000000..c65909981 --- /dev/null +++ b/configs/sim/pysubs/customtask.py @@ -0,0 +1,52 @@ +import emctask + + +# int test(int arg); +# int emcToolPrepare(int p, int tool); +# int emcToolLoad(); +# int emcToolUnload(); +# int emcToolSetNumber(int number); + +# virtual but not yet wrapped +# void load_tool(int pocket); +# int saveToolTable(const char *filename, CANON_TOOL_TABLE toolTable[]); + +class CustomTask(emctask.Task): + def __init__(self): + emctask.Task.__init__(self) + print "Py CustomTask.init" + + + # example Python pre & post-call hooks + def test(self, arg): + # do your pre-call Python thing + print "Py pre test(%d)" % (arg) + # call the default ethod (C) + rc = super(CustomTask,self).test(arg) + # do your post-call Python thing + print "Py post test(%d)" % (arg) + return rc + + def emcToolPrepare(self,p,tool): + print "--Py pre-hook: emcToolPrepare()",p, tool + emctask.operator_text("foo!",id=4711) + rc = super(CustomTask,self).emcToolPrepare(p,tool) + emctask.operator_error("bar!") + print "--Py post-hook: emcToolPrepare()",p, tool + return rc + + def emcToolLoad(self): + print "--Py pre-hook: emcToolLoad()" + rc = super(CustomTask,self).emcToolLoad() + return rc + + def emcToolUnload(self): + print "--Py pre-hook: emcToolUnload()" + rc = super(CustomTask,self).emcTooUnload() + return rc + + + def emcToolSetNumber(self,n): + print "--Py pre-hook: emcToolSetNumber()",n + rc = super(CustomTask,self).emcToolSetNumber(n) + return rc diff --git a/configs/sim/pysubs/plugins.py b/configs/sim/pysubs/plugins.py index 950d2ac65..014247509 100644 --- a/configs/sim/pysubs/plugins.py +++ b/configs/sim/pysubs/plugins.py @@ -1,9 +1,12 @@ import interpreter import canon have_emctask = False -if 'emctask' in sys.builtin_module_names: +try: import emctask have_task = True +except ImportError: + pass + import task import oword diff --git a/configs/sim/pysubs/task.py b/configs/sim/pysubs/task.py index ef9eeb109..11652c46c 100644 --- a/configs/sim/pysubs/task.py +++ b/configs/sim/pysubs/task.py @@ -1,8 +1,16 @@ +import sys import hal import canon import interpreter try: + import emctask + import customtask + print "-- emctask & customtask imported" +except ImportError: + pass + +try: import cPickle as pickle except ImportError: import pickle @@ -110,8 +118,7 @@ class EnqueueCall(object): self._name = name return self._encode - - execute = Execute() enqueue = EnqueueCall(execute) + diff --git a/src/emc/pythonplugin/python_plugin.cc b/src/emc/pythonplugin/python_plugin.cc index a5c4139d7..cfa148fca 100644 --- a/src/emc/pythonplugin/python_plugin.cc +++ b/src/emc/pythonplugin/python_plugin.cc @@ -161,7 +161,8 @@ int PythonPlugin::reload() } // decode a Python exception into a string. -std::string PythonPlugin::handle_pyerror() +// Free function usable without working plugin instance. +std::string handle_pyerror() { PyObject *exc, *val, *tb; bp::object formatted_list, formatted; diff --git a/src/emc/pythonplugin/python_plugin.hh b/src/emc/pythonplugin/python_plugin.hh index e83d3ca6f..6bff3eed4 100644 --- a/src/emc/pythonplugin/python_plugin.hh +++ b/src/emc/pythonplugin/python_plugin.hh @@ -11,6 +11,9 @@ namespace bp = boost::python; #include <sys/types.h> +extern std::string handle_pyerror(); + + // PY_EXCEPTION: both exception_msg and error_msg are set // PY_ERROR: error_msg is set enum pp_status { @@ -51,6 +54,7 @@ public: void initialize(bool reload = false, Interp *interp = NULL); std::string last_exception() { return exception_msg; }; std::string last_errmsg() { return error_msg; }; + bp::object main_namespace; private: PythonPlugin(const char *iniFilename, // no public constructor @@ -62,7 +66,6 @@ private: ~PythonPlugin() {}; int reload(); - std::string handle_pyerror(); std::vector<std::string> inittab_entries; int status; time_t module_mtime; // toplevel module - last modification time @@ -73,7 +76,6 @@ private: const char *module_basename; // toplevel module const char *plugin_dir; // directory prefix const char *abs_path; // normalized path to toplevel module, ProgramName - bp::object main_namespace; std::string exception_msg; std::string error_msg; int log_level; diff --git a/src/emc/sai/Submakefile b/src/emc/sai/Submakefile index 157ea1731..e786dbc69 100644 --- a/src/emc/sai/Submakefile +++ b/src/emc/sai/Submakefile @@ -1,9 +1,9 @@ TARGETS += ../bin/rs274 SAISRCS := $(addprefix emc/sai/, saicanon.cc driver.cc dummyemcstat.cc builtin_modules.cc) \ - emc/rs274ngc/tool_parse.cc emc/task/taskmodule.cc + emc/rs274ngc/tool_parse.cc emc/task/taskmodule.cc emc/task/taskclass.cc USERSRCS += $(SAISRCS) -$(call TOOBJSDEPS,$(SAISRCS)) : +$(call TOOBJSDEPS,$(SAISRCS)) : ../bin/rs274: $(call TOOBJS, $(SAISRCS)) ../lib/librs274.so.0 ../lib/libemc.a ../lib/libnml.so.0 $(ECHO) Linking $(notdir $@) $(CC) $(LDFLAGS) -o $@ $^ $(ULFLAGS) /usr/lib/libpython2.6.a diff --git a/src/emc/sai/dummyemcstat.cc b/src/emc/sai/dummyemcstat.cc index 373be116a..43336e22b 100644 --- a/src/emc/sai/dummyemcstat.cc +++ b/src/emc/sai/dummyemcstat.cc @@ -4,5 +4,7 @@ #include "emc.hh" // EMC NML #include "emc_nml.hh" -static EMC_STAT dummy_emcstat; -EMC_STAT *emcStatus = &dummy_emcstat; + +EMC_STAT *emcStatus = new EMC_STAT; + +EMC_IO_STAT *emcIoStatus = new EMC_IO_STAT; diff --git a/src/emc/task/Submakefile b/src/emc/task/Submakefile index 1c04d809f..6631f0d22 100644 --- a/src/emc/task/Submakefile +++ b/src/emc/task/Submakefile @@ -22,6 +22,7 @@ MILLTASKSRCS := \ emc/rs274ngc/tool_parse.cc \ emc/task/taskmodule.cc \ emc/task/signalhandler.cc \ + emc/task/taskclass.cc \ $(ULAPISRCS) USERSRCS += $(MILLTASKSRCS) diff --git a/src/emc/task/emctask.cc b/src/emc/task/emctask.cc index 71aa90d78..53e78c883 100644 --- a/src/emc/task/emctask.cc +++ b/src/emc/task/emctask.cc @@ -31,6 +31,8 @@ #include "rcs_print.hh" #include "task.hh" // emcTaskCommand etc #include "python_plugin.hh" +#include "taskclass.hh" + #define TASK_MODULE "task" #define TASK_INIT "task_init" @@ -41,6 +43,7 @@ extern PythonPlugin *python_plugin; static int emcPythonReturnValue(const char *funcname, bp::object &retval); + #define USER_DEFINED_FUNCTION_MAX_DIRS 5 #define MAX_M_DIRS (USER_DEFINED_FUNCTION_MAX_DIRS+1) //note:the +1 is for the PROGRAM_PREFIX or default directory==nc_files @@ -660,21 +663,54 @@ int emcAbortCleanup(int reason, const char *message) return status; } -int emcTaskOnce() + Task *task_methods; + +int emcTaskOnce(const char *python_taskinit) { bp::object retval; bp::tuple arg; bp::dict kwarg; + int plugin_status; + Task *tmp = NULL; // At this point, the interpreter must be done configuring and have instantiated the // Python plugin if (PYUSABLE && python_plugin->is_callable(TASK_MODULE, TASK_INIT)) { python_plugin->call(TASK_MODULE, TASK_INIT, arg, kwarg, retval); - return emcPythonReturnValue(TASK_INIT, retval); - } else { - fprintf(stderr,"emcTaskOnce: Python task plugin not available|n"); + plugin_status = emcPythonReturnValue(TASK_INIT, retval); + if (plugin_status != PLUGIN_OK) // FIXME - NO_CALLABLE? + printf("plugin_status = %d '%s'\n'%s'\n", plugin_status, + python_plugin->last_errmsg().c_str(), + python_plugin->last_exception().c_str()); + if (PYUSABLE && (python_taskinit != NULL)) { + // fprintf(stderr, "---------- should run '%s'\n", python_taskinit); + try { + bp::object result = bp::exec(python_taskinit, python_plugin->main_namespace, python_plugin->main_namespace); + tmp = bp::extract< Task * >(python_plugin->main_namespace["task"]); + // tmp = bp::extract< Task * >(result); //hm, doesnt work for bp::eval() ? + + } catch( bp::error_already_set ) { + std::string msg = handle_pyerror(); + printf("exec(%s): %s\n", python_taskinit,msg.c_str()); + PyErr_Clear(); + } + if (tmp == NULL) { + printf("no Python Task() instance available\n"); + } + } } + if (tmp == NULL) + tmp = new Task(); + try { + tmp->test(4711); + } catch( bp::error_already_set ) { + std::string msg = handle_pyerror(); + printf("call t->test(): %s\n", msg.c_str()); + PyErr_Clear(); + } + // fprintf(stderr,"emcTaskOnce: Python task plugin not available|n"); + task_methods = tmp; return 0; } diff --git a/src/emc/task/emctaskmain.cc b/src/emc/task/emctaskmain.cc index f13dd73bf..60eec5f6b 100644 --- a/src/emc/task/emctaskmain.cc +++ b/src/emc/task/emctaskmain.cc @@ -78,6 +78,7 @@ fpu_control_t __fpu_control = _FPU_IEEE & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_M #include "timer.hh" #include "nml_oi.hh" #include "task.hh" // emcTaskCommand etc +#include "taskclass.hh" /* time after which the user interface is declared dead * because it would'nt read any more messages @@ -135,6 +136,7 @@ static int pseudoMdiLineNumber = INT_MIN; // for operator display on iocontrol signalling a toolchanger fault if io.fault is set // %d receives io.reason static const char *io_error = "toolchanger error %d"; +static const char *python_taskinit; extern void setup_signal_handlers(); // backtrace, gdb-in-new-window supportx @@ -2895,10 +2897,10 @@ static int emctask_startup() rcs_print_error("can't initialize interpreter\n"); return -1; } - // let her know she's running under task - emcTaskOnce(); + // inistantiate task methods object, too + emcTaskOnce(python_taskinit); - if (done) { + if (done || (task_methods == NULL)) { emctask_shutdown(); exit(1); } @@ -3080,6 +3082,11 @@ static int iniLoad(const char *filename) if (NULL != (inistring = inifile.Find("IO_ERROR", "TASK"))) { io_error = strdup(inistring); } + + // configurable template for iocontrol reason display + if (NULL != (inistring = inifile.Find( "TASK","PYTHON"))) { + python_taskinit = strdup(inistring); + } // close it inifile.Close(); diff --git a/src/emc/task/iotaskintf.cc b/src/emc/task/iotaskintf.cc index be2823bcd..bd1e0ca7c 100644 --- a/src/emc/task/iotaskintf.cc +++ b/src/emc/task/iotaskintf.cc @@ -4,7 +4,6 @@ - /******************************************************************** * Description: iotaskintf.cc * NML interface functions for IO @@ -35,6 +34,9 @@ #include "inifile.hh" #include "initool.hh" #include "tool_parse.h" +#include "python_plugin.hh" +#include "taskclass.hh" +#include <string> // we just keep emcIoStatus to keep task happy @@ -123,47 +125,62 @@ int emcIoSetDebug(int debug) return 0; } +int handle_exception(const char *method) +{ + std::string msg = handle_pyerror(); + printf("executing %s(): %s\n", method,msg.c_str()); + PyErr_Clear(); + return RCS_ERROR; +} + int emcToolPrepare(int p, int tool) { + int retval; + try { + retval = task_methods->emcToolPrepare(p,tool); + } catch( bp::error_already_set ) { + retval = handle_exception("emcToolPrepare"); + } + return 0; - // it doesn't make sense to prep the spindle pocket - if (random_toolchanger && p == 0) - return 0; + // // it doesn't make sense to prep the spindle pocket + // if (random_toolchanger && p == 0) + // return 0; - /* set tool number first */ - int prep_number; - //*(iocontrol_data->tool_prep_pocket) = p; - if (!random_toolchanger && p == 0) { - // *(iocontrol_data->tool_prep_number) = 0; - prep_number = 0; - } else { - // *(iocontrol_data->tool_prep_number) = emcIoStatus->tool.toolTable[p].toolno; - prep_number = emcIoStatus->tool.toolTable[p].toolno; - } - fprintf(stderr,"emcToolPrepare: raise prepare, prep_number=%d, wait for prepared\n",prep_number); + // /* set tool number first */ + // int prep_number; + // //*(iocontrol_data->tool_prep_pocket) = p; + // if (!random_toolchanger && p == 0) { + // // *(iocontrol_data->tool_prep_number) = 0; + // prep_number = 0; + // } else { + // // *(iocontrol_data->tool_prep_number) = emcIoStatus->tool.toolTable[p].toolno; + // prep_number = emcIoStatus->tool.toolTable[p].toolno; + // } + // fprintf(stderr,"emcToolPrepare: raise prepare, prep_number=%d, wait for prepared\n",prep_number); - emcIoStatus->tool.pocketPrepped = p; // *(iocontrol_data->tool_prep_pocket); //check if tool has been prepared - emcIoStatus->status = RCS_DONE; + // emcIoStatus->tool.pocketPrepped = p; // *(iocontrol_data->tool_prep_pocket); //check if tool has been prepared + // emcIoStatus->status = RCS_DONE; - // *(iocontrol_data->tool_prepare) = 0; + // // *(iocontrol_data->tool_prepare) = 0; - // if ((proto > V1) && *(iocontrol_data->toolchanger_faulted)) { // informational - // rtapi_print_msg(RTAPI_MSG_DBG, "%s: prepare: toolchanger faulted (reason=%d), next M6 will %s\n", - // progname,toolchanger_reason, - // toolchanger_reason > 0 ? "set fault code and reason" : "abort program"); - // } - // // then set the prepare pin to tell external logic to get started - // *(iocontrol_data->tool_prepare) = 1; - // *(iocontrol_data->state) = ST_PREPARING; + // // if ((proto > V1) && *(iocontrol_data->toolchanger_faulted)) { // informational + // // rtapi_print_msg(RTAPI_MSG_DBG, "%s: prepare: toolchanger faulted (reason=%d), next M6 will %s\n", + // // progname,toolchanger_reason, + // // toolchanger_reason > 0 ? "set fault code and reason" : "abort program"); + // // } + // // // then set the prepare pin to tell external logic to get started + // // *(iocontrol_data->tool_prepare) = 1; + // // *(iocontrol_data->state) = ST_PREPARING; - // // delay fetching the next message until prepare done - // if (!(input_status & TI_PREPARE_COMPLETE)) { - // emcIoStatus->status = RCS_EXEC; - // } + // // // delay fetching the next message until prepare done + // // if (!(input_status & TI_PREPARE_COMPLETE)) { + // // emcIoStatus->status = RCS_EXEC; + // // } - return 0; + // return 0; } @@ -179,53 +196,64 @@ int emcToolStartChange() int emcToolLoad() { - - fprintf(stderr,"emcToolLoad()\n"); - - // it doesn't make sense to load a tool from the spindle pocket - if (random_toolchanger && emcIoStatus->tool.pocketPrepped == 0) { - return 0; + int retval; + try { + retval = task_methods->emcToolLoad(); + } catch( bp::error_already_set ) { + retval = handle_exception("emcToolLoad"); } + emcIoStatus->status = retval; + return 0; - // it's not necessary to load the tool already in the spindle - if (!random_toolchanger && emcIoStatus->tool.pocketPrepped > 0 && - emcIoStatus->tool.toolInSpindle == emcIoStatus->tool.toolTable[emcIoStatus->tool.pocketPrepped].toolno) { - return 0; - } + // fprintf(stderr,"emcToolLoad()\n"); + + // // it doesn't make sense to load a tool from the spindle pocket + // if (random_toolchanger && emcIoStatus->tool.pocketPrepped == 0) { + // return 0; + // } - if (emcIoStatus->tool.pocketPrepped != -1) { - fprintf(stderr,"emcToolLoad() raise change, wait for changed\n"); - - // Assume changed=true: - if(!random_toolchanger && emcIoStatus->tool.pocketPrepped == 0) { - emcIoStatus->tool.toolInSpindle = 0; - } else { - // the tool now in the spindle is the one that was prepared - emcIoStatus->tool.toolInSpindle = emcIoStatus->tool.toolTable[emcIoStatus->tool.pocketPrepped].toolno; - } - // *(iocontrol_data->tool_number) = emcIoStatus->tool.toolInSpindle; //likewise in HAL - load_tool(emcIoStatus->tool.pocketPrepped); - emcIoStatus->tool.pocketPrepped = -1; //reset the tool preped number, -1 to permit tool 0 to be loaded - // *(iocontrol_data->tool_prep_number) = 0; //likewise in HAL - // *(iocontrol_data->tool_prep_pocket) = 0; //likewise in HAL - // *(iocontrol_data->tool_change) = 0; //also reset the tool change signal - emcIoStatus->status = RCS_DONE; // we finally finished to do tool-changing, signal task with RCS_DONE - emcIoStatus->tool.pocketPrepped = -1; // reset the tool prepped number, -1 to permit tool 0 to be loaded + // // it's not necessary to load the tool already in the spindle + // if (!random_toolchanger && emcIoStatus->tool.pocketPrepped > 0 && + // emcIoStatus->tool.toolInSpindle == emcIoStatus->tool.toolTable[emcIoStatus->tool.pocketPrepped].toolno) { + // return 0; + // } - } else { - fprintf(stderr,"emcToolLoad() no pocket prepped, failing\n"); - emcIoStatus->status = RCS_ERROR; + // if (emcIoStatus->tool.pocketPrepped != -1) { + // fprintf(stderr,"emcToolLoad() raise change, wait for changed\n"); + + // // Assume changed=true: + // if(!random_toolchanger && emcIoStatus->tool.pocketPrepped == 0) { + // emcIoStatus->tool.toolInSpindle = 0; + // } else { + // // the tool now in the spindle is the one that was prepared + // emcIoStatus->tool.toolInSpindle = emcIoStatus->tool.toolTable[emcIoStatus->tool.pocketPrepped].toolno; + // } + // // *(iocontrol_data->tool_number) = emcIoStatus->tool.toolInSpindle; //likewise in HAL + // load_tool(emcIoStatus->tool.pocketPrepped); + // emcIoStatus->tool.pocketPrepped = -1; //reset the tool preped number, -1 to permit tool 0 to be loaded + // // *(iocontrol_data->tool_prep_number) = 0; //likewise in HAL + // // *(iocontrol_data->tool_prep_pocket) = 0; //likewise in HAL + // // *(iocontrol_data->tool_change) = 0; //also reset the tool change signal + // emcIoStatus->status = RCS_DONE; // we finally finished to do tool-changing, signal task with RCS_DONE + // emcIoStatus->tool.pocketPrepped = -1; // reset the tool prepped number, -1 to permit tool 0 to be loaded + + // } else { + // fprintf(stderr,"emcToolLoad() no pocket prepped, failing\n"); + // emcIoStatus->status = RCS_ERROR; - } - return 0; + // } + // return 0; } int emcToolUnload() { - - fprintf(stderr,"emcToolUnLoad()\n"); - emcIoStatus->status = RCS_DONE; - + int retval; + try { + retval = task_methods->emcToolUnload(); + } catch( bp::error_already_set ) { + retval = handle_exception("emcToolUnload"); + } + emcIoStatus->status = retval; return 0; } @@ -280,16 +308,25 @@ int emcToolSetOffset(int pocket, int toolno, EmcPose offset, double diameter, int emcToolSetNumber(int number) { - fprintf(stderr,"emcToolSetNumber(%d)\n",number); - if (number == 0) { - emcIoStatus->tool.toolInSpindle = 0; - emcIoStatus->tool.pocketPrepped = -1; //????? reset the tool prepped number, -1 to permit tool 0 to be loaded - } else { - emcIoStatus->tool.toolInSpindle = emcIoStatus->tool.toolTable[number].toolno; + + int retval; + try { + retval = task_methods->emcToolSetNumber(number); + } catch( bp::error_already_set ) { + retval = handle_exception("emcToolSetNumber"); } - load_tool(number); - emcIoStatus->status = RCS_DONE; - return 0; + return retval; + + // fprintf(stderr,"emcToolSetNumber(%d)\n",number); + // if (number == 0) { + // emcIoStatus->tool.toolInSpindle = 0; + // emcIoStatus->tool.pocketPrepped = -1; //????? reset the tool prepped number, -1 to permit tool 0 to be loaded + // } else { + // emcIoStatus->tool.toolInSpindle = emcIoStatus->tool.toolTable[number].toolno; + // } + // load_tool(number); + // emcIoStatus->status = RCS_DONE; + // return 0; } // Status functions diff --git a/src/emc/task/task.hh b/src/emc/task/task.hh index 579302488..81775cd7b 100644 --- a/src/emc/task/task.hh +++ b/src/emc/task/task.hh @@ -1,11 +1,12 @@ #ifndef EMC_TASK_HH #define EMC_TASK_HH +#include "taskclass.hh" extern NMLmsg *emcTaskCommand; extern int stepping; extern int steppingWait; extern int emcTaskQueueCommand(NMLmsg *cmd); extern int emcPluginCall(EMC_EXEC_PLUGIN_CALL *call_msg); -extern int emcTaskOnce(); +extern int emcTaskOnce(const char *python_taskinit); #endif diff --git a/src/emc/task/taskmodule.cc b/src/emc/task/taskmodule.cc index e06788b55..db0391549 100644 --- a/src/emc/task/taskmodule.cc +++ b/src/emc/task/taskmodule.cc @@ -1,17 +1,13 @@ - // EMC_AXIS_STAT axis[EMC_AXIS_MAX]; - // int synch_di[EMC_MAX_DIO]; // motion inputs queried by interp - // int synch_do[EMC_MAX_DIO]; // motion outputs queried by interp - // double analog_input[EMC_MAX_AIO]; //motion analog inputs queried by interp - // double analog_output[EMC_MAX_AIO]; //motion analog outputs queried by interp -//task_stat: - -// reuse interp converters - - +// TODO: reuse interp converters #include <boost/python.hpp> +#include <boost/python/module.hpp> +#include <boost/python/class.hpp> +#include <boost/ref.hpp> + #include "rs274ngc.hh" #include "interp_internal.hh" +#include "taskclass.hh" namespace bp = boost::python; @@ -27,6 +23,64 @@ namespace pp = pyplusplus::containers::static_sized; extern EMC_STAT *emcStatus; +struct TaskWrap : public Task, public bp::wrapper<Task> { + + TaskWrap() : Task() {} + // TaskWrap() {} + + int test(int arg) { + if (bp::override f = this->get_override("test")) + return f(arg); + else + return Task::test(arg); + } + int default_test(int arg) { + return this->Task::test(arg); + } + + int emcToolPrepare(int p, int tool) { + if (bp::override f = this->get_override("emcToolPrepare")) + return f(p, tool); + else + return Task::emcToolPrepare(p, tool); + } + int default_emcToolPrepare(int p, int tool) { + return this->Task::emcToolPrepare(p, tool); + } + + int emcToolLoad() { + if (bp::override f = this->get_override("emcToolLoad")) + return f(); + else + return Task::emcToolLoad(); + } + int default_emcToolLoad() { + return this->Task::emcToolLoad(); + } + int emcToolUnload() { + if (bp::override f = this->get_override("emcToolUnload")) + return f(); + else + return Task::emcToolUnload(); + } + int default_emcToolUnload() { + return this->Task::emcToolUnload(); + } + int emcToolSetNumber(int number) { + if (bp::override f = this->get_override("emcToolSetNumber")) + return f(number); + else + return Task::emcToolSetNumber(number); + } + int default_emcToolSetNumber(int number) { + return this->Task::emcToolSetNumber(number); + } +}; + + + + + typedef pp::array_1_t< EMC_AXIS_STAT, EMC_AXIS_MAX> axis_array, (*axis_w)( EMC_MOTION_STAT &m ); typedef pp::array_1_t< int, EMC_MAX_DIO> synch_dio_array, (*synch_dio_w)( EMC_MOTION_STAT &m ); typedef pp::array_1_t< double, EMC_MAX_AIO> analog_io_array, (*analog_io_w)( EMC_MOTION_STAT &m ); @@ -67,14 +121,23 @@ static active_settings_array activeSettings_wrapper ( EMC_TASK_STAT & m) { return active_settings_array(m.activeSettings); } -// TODO: wrap optional id argument #pragma GCC diagnostic ignored "-Wformat-security" -static void operator_error(const char *s) { - int id = 0; - emcOperatorError(id,s); +static void operator_error(const char *message, int id = 0) { + emcOperatorError(id,message); +} +static void operator_text(const char *message, int id = 0) { + emcOperatorText(id,message); +} +static void operator_display(const char *message, int id = 0) { + emcOperatorDisplay(id,message); } #pragma GCC diagnostic warning "-Wformat-security" +BOOST_PYTHON_FUNCTION_OVERLOADS(operator_error_overloads, operator_error, 1,2) +BOOST_PYTHON_FUNCTION_OVERLOADS(operator_text_overloads, operator_text, 1,2) +BOOST_PYTHON_FUNCTION_OVERLOADS(operator_display_overloads, operator_display, 1,2) + + BOOST_PYTHON_MODULE(emctask) { using namespace boost::python; using namespace boost; @@ -83,7 +146,38 @@ BOOST_PYTHON_MODULE(emctask) { "Task introspection\n" ; - def("operator_error", &operator_error); + def("operator_error", + operator_error, + operator_error_overloads ( args("id"), + "send an error messsage to the operator screen with an optional message id" )); + def("operator_text", + operator_text, + operator_text_overloads ( args("id"), + "send a informational messsage to the operator screen" )); + def("operator_display", + operator_display, + operator_display_overloads ( args("id"), + "send a messsage to the operator display" )); + + scope().attr("RCS_EXEC") = (int)RCS_EXEC; + scope().attr("RCS_DONE") = (int)RCS_DONE; + scope().attr("RCS_ERROR") = (int)RCS_ERROR; + + class_<Task, shared_ptr<Task>, noncopyable>("__Task", " Pretend I Don't exist", no_init) + .def("test", &Task::test) + .def("emcToolPrepare", &Task::emcToolPrepare) + .def("emcToolLoad", &Task::emcToolLoad) + .def("emcToolUnload", &Task::emcToolUnload) + .def("emcToolSetNumber", &Task::emcToolSetNumber) + ; + + class_<TaskWrap, shared_ptr<TaskWrap>, noncopyable >("Task") + .def("test", &Task::test, &TaskWrap::default_test) + .def("emcToolPrepare", &Task::emcToolPrepare, &TaskWrap::default_emcToolPrepare) + .def("emcToolLoad", &Task::emcToolLoad, &TaskWrap::default_emcToolLoad) + .def("emcToolUnload", &Task::emcToolUnload, &TaskWrap::default_emcToolUnload) + .def("emcToolSetNumber", &Task::emcToolSetNumber, &TaskWrap::default_emcToolSetNumber) + ; class_<PmCartesian, noncopyable>("PmCartesian","EMC cartesian postition",no_init) .def_readwrite("x",&PmCartesian::x) |