/ src / emc / task / taskmodule.cc
taskmodule.cc
  1  /*    This is a component of LinuxCNC
  2   *    Copyright 2011, 2012, 2014 Jeff Epler <jepler@unpythonic.net>,
  3   *    Michael Haberler <git@mah.priv.at>
  4   *
  5   *    This program is free software; you can redistribute it and/or modify
  6   *    it under the terms of the GNU General Public License as published by
  7   *    the Free Software Foundation; either version 2 of the License, or
  8   *    (at your option) any later version.
  9   *
 10   *    This program is distributed in the hope that it will be useful,
 11   *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13   *    GNU General Public License for more details.
 14   *
 15   *    You should have received a copy of the GNU General Public License
 16   *    along with this program; if not, write to the Free Software
 17   *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 18   */
 19  // TODO: reuse interp converters
 20  
 21  #define BOOST_PYTHON_MAX_ARITY 7
 22  #include <boost/python/class.hpp>
 23  #include <boost/python/def.hpp>
 24  #include <boost/python/implicit.hpp>
 25  #include <boost/python/module.hpp>
 26  #include <boost/python/overloads.hpp>
 27  #include <boost_pyenum_macros.hh>
 28  #include <boost/python/scope.hpp>
 29  #include "python_plugin.hh"
 30  #include "rs274ngc.hh"
 31  #include "interp_internal.hh"
 32  #include "taskclass.hh"
 33  #include "initool.hh"
 34  #include "emcglb.h"		// EMC_INIFILE
 35  
 36  namespace bp = boost::python;
 37  
 38  #include "array1.hh"
 39  
 40  namespace pp = pyplusplus::containers::static_sized;
 41  
 42  #include "interp_array_types.hh"  // import activeMCodes,activeGCodes,activeSettings, toolTable
 43  
 44  #include "rcs.hh"		// NML classes, nmlErrorFormat()
 45  #include "emc.hh"		// EMC NML
 46  #include "emc_nml.hh"
 47  
 48  extern void emctask_quit(int sig);
 49  extern EMC_STAT *emcStatus;
 50  typedef boost::shared_ptr< EMC_STAT > emcstatus_ptr;
 51  extern int return_int(const char *funcname, PyObject *retval);
 52  
 53  
 54  // man, is this ugly. I'm taking suggestions to make this better
 55  
 56  static int handle_exception(const char *name)
 57  {
 58      std::string msg = handle_pyerror();
 59      printf("%s(): %s\n", name, msg.c_str());
 60      PyErr_Clear();
 61      return -1;
 62  }
 63  
 64  #define EXPAND(method)						\
 65      int method() {						\
 66  	if (bp::override f = this->get_override(#method)) {	\
 67  	    try {						\
 68  		return f();					\
 69  	    }							\
 70  	    catch( bp::error_already_set ) {			\
 71  		return handle_exception(#method);		\
 72  	    }							\
 73  	}							\
 74  	else							\
 75  	    return  Task::method();				\
 76      }
 77  
 78  
 79  #define EXPAND1(method,type,name)					\
 80      int method(type name) {						\
 81  	if (bp::override f = this->get_override(#method)) {		\
 82  	    try {							\
 83  		return f(name);						\
 84  	    }								\
 85  	    catch( bp::error_already_set ) {				\
 86  		return handle_exception(#method);			\
 87  	    }								\
 88  	} else								\
 89  	    return  Task::method(name);					\
 90      }
 91  
 92  
 93  #define EXPAND2(method,type,name,type2,name2)				\
 94      int method(type name,type2 name2) {					\
 95  	if (bp::override f = this->get_override(#method)) {		\
 96  	    try {							\
 97  		return f(name,name2);					\
 98  	    }								\
 99  	    catch( bp::error_already_set ) {				\
100  		return handle_exception(#method);			\
101  	    }								\
102  	} else								\
103  	    return  Task::method(name,name2);				\
104      }
105  
106  struct TaskWrap : public Task, public bp::wrapper<Task> {
107  
108      TaskWrap() : Task() {}
109  
110      EXPAND(emcIoInit)
111      EXPAND(emcIoHalt)
112      EXPAND1(emcIoAbort,int,reason)
113  
114      EXPAND(emcToolStartChange)
115      EXPAND(emcAuxEstopOn)
116      EXPAND(emcAuxEstopOff)
117      EXPAND(emcCoolantMistOn)
118      EXPAND(emcCoolantMistOff)
119      EXPAND(emcCoolantFloodOn)
120      EXPAND(emcCoolantFloodOff)
121      EXPAND(emcLubeOn)
122      EXPAND(emcLubeOff)
123      EXPAND1(emcIoSetDebug,int,debug)
124  
125      EXPAND2(emcToolPrepare,int, p, int, tool)
126      EXPAND(emcToolLoad)
127      EXPAND1(emcToolLoadToolTable, const char *, file)
128      EXPAND(emcToolUnload)
129      EXPAND1(emcToolSetNumber,int,number)
130  
131      int emcIoPluginCall(int len,const char *msg) {
132  	if (bp::override f = this->get_override("emcIoPluginCall")) {
133  	    try {
134  		// binary picklings may contain zeroes
135  		std::string buffer(msg,len);
136  		return f(len,buffer);
137  	    }
138  	    catch( bp::error_already_set ) {
139  		return handle_exception("emcIoPluginCall");
140  	    }
141  	} else
142  	    return  Task::emcIoPluginCall(len,msg);
143      }
144  
145      int emcToolSetOffset(int pocket, int toolno, EmcPose offset, double diameter,
146  			 double frontangle, double backangle, int orientation) {
147  	if (bp::override f = this->get_override("emcToolSetOffset"))
148  	    try {
149  		return f(pocket,toolno,offset,diameter,frontangle,backangle,orientation);
150  	    }
151  	    catch( bp::error_already_set ) {
152  		return handle_exception("emcToolSetOffset");
153  	    }
154  	else
155  	    return  Task::emcToolSetOffset(pocket,toolno,offset,diameter,frontangle,backangle,orientation);
156      }
157  
158      int emcIoUpdate(EMC_IO_STAT * stat) {
159  	if (bp::override f = this->get_override("emcIoUpdate"))
160  	    try {
161  		return f(); /// bug in Boost.Python, fixed in 1.44 I guess: return_int("foo",f());
162  	    }
163  	    catch( bp::error_already_set ) {
164  		return handle_exception("emcIoUpdate");
165  	    }
166  	else
167  	    return  Task::emcIoUpdate(stat);
168      }
169  
170  };
171  
172  typedef pp::array_1_t< EMC_AXIS_STAT, EMCMOT_MAX_AXIS> axis_array, (*axis_w)( EMC_MOTION_STAT &m );
173  typedef pp::array_1_t< EMC_SPINDLE_STAT, EMCMOT_MAX_SPINDLES> spindle_array, (*spindle_w)( EMC_MOTION_STAT &m );
174  typedef pp::array_1_t< int, EMCMOT_MAX_DIO> synch_dio_array, (*synch_dio_w)( EMC_MOTION_STAT &m );
175  typedef pp::array_1_t< double, EMCMOT_MAX_AIO> analog_io_array, (*analog_io_w)( EMC_MOTION_STAT &m );
176  
177  typedef pp::array_1_t< int, ACTIVE_G_CODES> active_g_codes_array, (*active_g_codes_tw)( EMC_TASK_STAT &t );
178  typedef pp::array_1_t< int, ACTIVE_M_CODES> active_m_codes_array, (*active_m_codes_tw)( EMC_TASK_STAT &t );
179  typedef pp::array_1_t< double, ACTIVE_SETTINGS> active_settings_array, (*active_settings_tw)( EMC_TASK_STAT &t );
180  
181  typedef pp::array_1_t< CANON_TOOL_TABLE, CANON_POCKETS_MAX> tool_array, (*tool_w)( EMC_TOOL_STAT &t );
182  
183  static  tool_array tool_wrapper ( EMC_TOOL_STAT & t) {
184      return tool_array(t.toolTable);
185  }
186  
187  static  axis_array axis_wrapper ( EMC_MOTION_STAT & m) {
188      return axis_array(m.axis);
189  }
190  
191  static  spindle_array spindle_wrapper ( EMC_MOTION_STAT & m) {
192      return spindle_array(m.spindle);
193  }
194  
195  static  synch_dio_array synch_di_wrapper ( EMC_MOTION_STAT & m) {
196      return synch_dio_array(m.synch_di);
197  }
198  
199  static  synch_dio_array synch_do_wrapper ( EMC_MOTION_STAT & m) {
200      return synch_dio_array(m.synch_do);
201  }
202  
203  static  analog_io_array analog_input_wrapper ( EMC_MOTION_STAT & m) {
204      return analog_io_array(m.analog_input);
205  }
206  
207  static  analog_io_array analog_output_wrapper ( EMC_MOTION_STAT & m) {
208      return analog_io_array(m.analog_output);
209  }
210  
211  static  active_g_codes_array activeGCodes_wrapper (  EMC_TASK_STAT & m) {
212      return active_g_codes_array(m.activeGCodes);
213  }
214  
215  static  active_m_codes_array activeMCodes_wrapper ( EMC_TASK_STAT & m) {
216      return active_m_codes_array(m.activeMCodes);
217  }
218  
219  static  active_settings_array activeSettings_wrapper ( EMC_TASK_STAT & m) {
220      return active_settings_array(m.activeSettings);
221  }
222  
223  static const char *get_file( EMC_TASK_STAT &t) { return t.file; }
224  static const char *get_command( EMC_TASK_STAT &t) { return t.command; }
225  
226  static void operator_error(const char *message, int id = 0) {
227      emcOperatorError(id,"%s",message);
228  }
229  static void operator_text(const char *message, int id = 0) {
230      emcOperatorText(id,"%s",message);
231  }
232  static void operator_display(const char *message, int id = 0) {
233      emcOperatorDisplay(id,"%s",message);
234  }
235  
236  
237  #pragma GCC diagnostic push
238  #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
239  #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
240  #endif
241  BOOST_PYTHON_FUNCTION_OVERLOADS(operator_error_overloads, operator_error, 1,2)
242  BOOST_PYTHON_FUNCTION_OVERLOADS(operator_text_overloads, operator_text, 1,2)
243  BOOST_PYTHON_FUNCTION_OVERLOADS(operator_display_overloads, operator_display, 1,2)
244  #pragma GCC diagnostic pop
245  
246  
247  static const char *ini_filename() { return emc_inifile; }
248  
249  BOOST_PYTHON_MODULE(emctask) {
250      using namespace boost::python;
251      using namespace boost;
252  
253      scope().attr("__doc__") =
254          "Task introspection\n"
255          ;
256  
257      def("emctask_quit", emctask_quit);
258      def("ini_filename", ini_filename);
259      // def("iniTool", iniTool);
260  
261      def("operator_error",
262  	operator_error,
263  	operator_error_overloads ( args("id"),
264  				   "send an error message to the operator screen with an optional message id"  ));
265      def("operator_text",
266  	operator_text,
267  	operator_text_overloads ( args("id"),
268  				   "send a informational message to the operator screen"  ));
269      def("operator_display",
270  	operator_display,
271  	operator_display_overloads ( args("id"),
272  				   "send a message to the operator display"  ));
273  
274      BOOST_PYENUM_(RCS_STATUS)
275              .BOOST_PYENUM_VAL(RCS_EXEC)
276              .BOOST_PYENUM_VAL(RCS_DONE)
277              .BOOST_PYENUM_VAL(RCS_ERROR)
278              ;
279  
280      BOOST_PYENUM_(EMC_TASK_MODE_ENUM)
281              .BOOST_PYENUM_VAL(EMC_TASK_MODE_MANUAL)
282              .BOOST_PYENUM_VAL(EMC_TASK_MODE_AUTO)
283              .BOOST_PYENUM_VAL(EMC_TASK_MODE_MDI)
284              ;
285  
286      BOOST_PYENUM_(EMC_TASK_STATE_ENUM)
287              .BOOST_PYENUM_VAL(EMC_TASK_STATE_ESTOP)
288              .BOOST_PYENUM_VAL(EMC_TASK_STATE_ESTOP_RESET)
289              .BOOST_PYENUM_VAL(EMC_TASK_STATE_OFF)
290              .BOOST_PYENUM_VAL(EMC_TASK_STATE_ON)
291              ;
292  
293      BOOST_PYENUM_(EMC_TASK_EXEC_ENUM)
294              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_ERROR)
295              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_DONE)
296              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_WAITING_FOR_MOTION)
297              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_WAITING_FOR_MOTION_QUEUE)
298              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_WAITING_FOR_IO)
299              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_WAITING_FOR_MOTION_AND_IO)
300              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_WAITING_FOR_DELAY)
301              .BOOST_PYENUM_VAL(EMC_TASK_EXEC_WAITING_FOR_SYSTEM_CMD)
302              ;
303  
304      BOOST_PYENUM_(EMC_TASK_INTERP_ENUM)
305              .BOOST_PYENUM_VAL(EMC_TASK_INTERP_IDLE)
306              .BOOST_PYENUM_VAL(EMC_TASK_INTERP_READING)
307              .BOOST_PYENUM_VAL(EMC_TASK_INTERP_PAUSED)
308              .BOOST_PYENUM_VAL(EMC_TASK_INTERP_WAITING)
309              ;
310  
311  
312      BOOST_PYENUM_(EMC_IO_ABORT_REASON_ENUM)
313              .BOOST_PYENUM_VAL(EMC_ABORT_TASK_EXEC_ERROR)
314              .BOOST_PYENUM_VAL(EMC_ABORT_AUX_ESTOP)
315              .BOOST_PYENUM_VAL(EMC_ABORT_MOTION_OR_IO_RCS_ERROR)
316              .BOOST_PYENUM_VAL(EMC_ABORT_TASK_STATE_OFF)
317              .BOOST_PYENUM_VAL(EMC_ABORT_TASK_STATE_ESTOP_RESET)
318              .BOOST_PYENUM_VAL(EMC_ABORT_TASK_STATE_ESTOP)
319              .BOOST_PYENUM_VAL(EMC_ABORT_TASK_STATE_NOT_ON)
320              .BOOST_PYENUM_VAL(EMC_ABORT_TASK_ABORT)
321              .BOOST_PYENUM_VAL(EMC_ABORT_USER)
322              ;
323  
324      class_<TaskWrap, shared_ptr<TaskWrap>, noncopyable >("Task")
325  
326  	.def_readonly("use_iocontrol", &Task::use_iocontrol)
327  	.def_readonly("random_toolchanger", &Task::random_toolchanger)
328  	.def_readonly("tooltable_filename", &Task::tooltable_filename)
329  	;
330  
331  #pragma GCC diagnostic push
332  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
333      class_ <EMC_TRAJ_STAT, noncopyable>("EMC_TRAJ_STAT",no_init)
334  	.def_readwrite("linearUnits", &EMC_TRAJ_STAT::linearUnits )
335  	.def_readwrite("angularUnits", &EMC_TRAJ_STAT::angularUnits )
336  	.def_readwrite("cycleTime", &EMC_TRAJ_STAT::cycleTime )
337  	.def_readwrite("axes", &EMC_TRAJ_STAT::axes )
338  	.def_readwrite("axis_mask", &EMC_TRAJ_STAT::axis_mask )
339  	.def_readwrite("mode", &EMC_TRAJ_STAT::mode )
340  	.def_readwrite("enabled", &EMC_TRAJ_STAT::enabled )
341  	.def_readwrite("inpos", &EMC_TRAJ_STAT::inpos )
342  	.def_readwrite("queue", &EMC_TRAJ_STAT::queue )
343  	.def_readwrite("activeQueue", &EMC_TRAJ_STAT::activeQueue )
344  	.def_readwrite("queueFull", &EMC_TRAJ_STAT::queueFull )
345  	.def_readwrite("id", &EMC_TRAJ_STAT::id )
346  	.def_readwrite("paused", &EMC_TRAJ_STAT::paused )
347  	.def_readwrite("scale", &EMC_TRAJ_STAT::scale )
348  	.def_readwrite("position", &EMC_TRAJ_STAT::position )
349  	.def_readwrite("actualPosition", &EMC_TRAJ_STAT::actualPosition )
350  	.def_readwrite("velocity", &EMC_TRAJ_STAT::velocity )
351  	.def_readwrite("acceleration", &EMC_TRAJ_STAT::acceleration)
352  	.def_readwrite("maxVelocity", &EMC_TRAJ_STAT::maxVelocity )
353  	.def_readwrite("maxAcceleration", &EMC_TRAJ_STAT::maxAcceleration )
354  	.def_readwrite("probedPosition", &EMC_TRAJ_STAT::probedPosition )
355  	.def_readwrite("probe_tripped", &EMC_TRAJ_STAT::probe_tripped )
356  	.def_readwrite("probing", &EMC_TRAJ_STAT::probing )
357  	.def_readwrite("probeval", &EMC_TRAJ_STAT::probeval )
358  	.def_readwrite("kinematics_type", &EMC_TRAJ_STAT::kinematics_type )
359  	.def_readwrite("motion_type", &EMC_TRAJ_STAT::motion_type )
360  	.def_readwrite("distance_to_go", &EMC_TRAJ_STAT::distance_to_go )
361  	.def_readwrite("dtg", &EMC_TRAJ_STAT::dtg )
362  	.def_readwrite("current_vel", &EMC_TRAJ_STAT::current_vel )
363  	.def_readwrite("feed_override_enabled", &EMC_TRAJ_STAT::feed_override_enabled )
364  	.def_readwrite("adaptive_feed_enabled", &EMC_TRAJ_STAT::adaptive_feed_enabled )
365  	.def_readwrite("feed_hold_enabled", &EMC_TRAJ_STAT::feed_hold_enabled )
366  	;
367  #pragma GCC diagnostic pop
368      class_ <EMC_JOINT_STAT, noncopyable>("EMC_JOINT_STAT",no_init)
369  	.def_readwrite("units", &EMC_JOINT_STAT::units)
370  	.def_readwrite("backlash", &EMC_JOINT_STAT::backlash)
371  	.def_readwrite("minPositionLimit", &EMC_JOINT_STAT::minPositionLimit)
372  	.def_readwrite("maxPositionLimit" ,&EMC_JOINT_STAT::maxPositionLimit)
373  	.def_readwrite("maxFerror", &EMC_JOINT_STAT::maxFerror)
374  	.def_readwrite("minFerror", &EMC_JOINT_STAT::minFerror)
375  	.def_readwrite("ferrorCurrent", &EMC_JOINT_STAT::ferrorCurrent)
376  	.def_readwrite("ferrorHighMark", &EMC_JOINT_STAT::ferrorHighMark)
377  	.def_readwrite("output", &EMC_JOINT_STAT::output)
378  	.def_readwrite("input", &EMC_JOINT_STAT::input)
379  	.def_readwrite("velocity", &EMC_JOINT_STAT::velocity)
380  	.def_readwrite("inpos",  &EMC_JOINT_STAT::inpos)
381  	.def_readwrite("homing",  &EMC_JOINT_STAT::homing)
382  	.def_readwrite("homed",  &EMC_JOINT_STAT::homed)
383  	.def_readwrite("fault",  &EMC_JOINT_STAT::fault)
384  	.def_readwrite("enabled",  &EMC_JOINT_STAT::enabled)
385  	.def_readwrite("minSoftLimit",  &EMC_JOINT_STAT::minSoftLimit)
386  	.def_readwrite("maxSoftLimit",  &EMC_JOINT_STAT::maxSoftLimit)
387  	.def_readwrite("minHardLimit",  &EMC_JOINT_STAT::minHardLimit)
388  	.def_readwrite("maxHardLimit",  &EMC_JOINT_STAT::maxHardLimit)
389  	.def_readwrite("overrideLimits",  &EMC_JOINT_STAT::overrideLimits)
390  	;
391  
392      class_ <EMC_SPINDLE_STAT, noncopyable>("EMC_SPINDLE_STAT",no_init)
393  	.def_readwrite("speed", &EMC_SPINDLE_STAT::speed )
394  	.def_readwrite("direction", &EMC_SPINDLE_STAT::direction )
395  	.def_readwrite("brake", &EMC_SPINDLE_STAT::brake )
396  	.def_readwrite("increasing", &EMC_SPINDLE_STAT::increasing )
397  	.def_readwrite("enabled", &EMC_SPINDLE_STAT::enabled )
398  	.def_readwrite("spindle_override_enabled", &EMC_SPINDLE_STAT::spindle_override_enabled )
399  	.def_readwrite("spindle_scale", &EMC_SPINDLE_STAT::spindle_scale )
400  	.def_readwrite("spindle_orient_state", &EMC_SPINDLE_STAT::orient_state )
401  	.def_readwrite("spindle_orient_fault", &EMC_SPINDLE_STAT::orient_fault )
402  	;
403  
404      class_ <EMC_COOLANT_STAT , noncopyable>("EMC_COOLANT_STAT ",no_init)
405  	.def_readwrite("mist", &EMC_COOLANT_STAT::mist )
406  	.def_readwrite("flood", &EMC_COOLANT_STAT::flood )
407  	;
408  
409      class_ <EMC_LUBE_STAT, noncopyable>("EMC_LUBE_STAT",no_init)
410  	.def_readwrite("on", &EMC_LUBE_STAT::on )
411  	.def_readwrite("level", &EMC_LUBE_STAT::level )
412  	;
413  
414      class_ <EMC_MOTION_STAT, noncopyable>("EMC_MOTION_STAT",no_init)
415  	.def_readwrite("traj", &EMC_MOTION_STAT::traj)
416  	.add_property( "axis",
417  		       bp::make_function( axis_w(&axis_wrapper),
418  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
419  	.add_property( "spindle",
420  			   bp::make_function( spindle_w(&spindle_wrapper),
421  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
422  	.add_property( "synch_di",
423  		       bp::make_function( synch_dio_w(&synch_di_wrapper),
424  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
425  	.add_property( "synch_do",
426  		       bp::make_function( synch_dio_w(&synch_do_wrapper),
427  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
428  	.add_property( "analog_input",
429  		       bp::make_function( analog_io_w(&analog_input_wrapper),
430  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
431  	.add_property( "analog_output",
432  		       bp::make_function( analog_io_w(&analog_output_wrapper),
433  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
434  	;
435  
436  
437      class_ <EMC_TASK_STAT, noncopyable>("EMC_TASK_STAT",no_init)
438  	.def_readwrite("mode",  &EMC_TASK_STAT::mode)
439  	.def_readwrite("state",  &EMC_TASK_STAT::state)
440  	.def_readwrite("execState",  &EMC_TASK_STAT::execState)
441  	.def_readwrite("interpState",  &EMC_TASK_STAT::interpState)
442  	.def_readwrite("motionLine", &EMC_TASK_STAT::motionLine)
443  	.def_readwrite("currentLine", &EMC_TASK_STAT::currentLine)
444  	.def_readwrite("readLine", &EMC_TASK_STAT::readLine)
445  	.def_readwrite("optional_stop_state", &EMC_TASK_STAT::optional_stop_state)
446  	.def_readwrite("block_delete_state", &EMC_TASK_STAT::block_delete_state)
447  	.def_readwrite("input_timeout", &EMC_TASK_STAT::input_timeout)
448  
449  	//  read-only
450  	.add_property("file",  &get_file)
451  	.add_property("command",   &get_command)
452  
453  	.def_readwrite("g5x_offset", &EMC_TASK_STAT::g5x_offset)
454  	.def_readwrite("g5x_index", &EMC_TASK_STAT::g5x_index)
455  	.def_readwrite("g92_offset", &EMC_TASK_STAT::g92_offset)
456  	.def_readwrite("rotation_xy", &EMC_TASK_STAT::rotation_xy)
457  	.def_readwrite("toolOffset", &EMC_TASK_STAT::toolOffset)
458  	.add_property( "activeGCodes",
459  		       bp::make_function( active_g_codes_tw(&activeGCodes_wrapper),
460  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
461  	.add_property( "activeMCodes",
462  		       bp::make_function( active_m_codes_tw(&activeMCodes_wrapper),
463  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
464  	.add_property( "activeSettings",
465  		       bp::make_function( active_settings_tw(&activeSettings_wrapper),
466  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
467  	.def_readwrite("programUnits", &EMC_TASK_STAT::programUnits)
468  	.def_readwrite("interpreter_errcode", &EMC_TASK_STAT::interpreter_errcode)
469  	.def_readwrite("task_paused", &EMC_TASK_STAT::task_paused)
470  	.def_readwrite("delayLeft", &EMC_TASK_STAT::delayLeft)
471  	;
472  
473      class_ <EMC_TOOL_STAT, noncopyable>("EMC_TOOL_STAT",no_init)
474  	.def_readwrite("pocketPrepped", &EMC_TOOL_STAT::pocketPrepped )
475  	.def_readwrite("toolInSpindle", &EMC_TOOL_STAT::toolInSpindle )
476  	.add_property( "toolTable",
477  		       bp::make_function( tool_w(&tool_wrapper),
478  					  bp::with_custodian_and_ward_postcall< 0, 1 >()))
479  	;
480  
481      class_ <EMC_AUX_STAT, noncopyable>("EMC_AUX_STAT",no_init)
482  	.def_readwrite("estop", &EMC_AUX_STAT::estop)
483  	;
484  
485      class_ <EMC_IO_STAT, noncopyable>("EMC_IO_STAT",no_init)
486  	.def_readwrite("cycleTime", &EMC_IO_STAT::cycleTime )
487  	.def_readwrite("debug", &EMC_IO_STAT::debug )
488  	.def_readwrite("reason", &EMC_IO_STAT::reason )
489  	.def_readwrite("fault", &EMC_IO_STAT::fault )
490  	.def_readwrite("tool", &EMC_IO_STAT::tool)
491  	.def_readwrite("aux", &EMC_IO_STAT::aux)
492  	.def_readwrite("coolant", &EMC_IO_STAT::coolant)
493  	.def_readwrite("lube", &EMC_IO_STAT::lube)
494  	.def_readwrite("status", &EMC_IO_STAT::status)
495  	;
496  
497  
498      class_ <EMC_STAT, emcstatus_ptr, noncopyable>("EMC_STAT",no_init)
499  	.def_readwrite("task", &EMC_STAT::task)
500  	.def_readwrite("motion", &EMC_STAT::motion)
501  	.def_readwrite("io", &EMC_STAT::io)
502  	.def_readwrite("debug", &EMC_STAT::debug)
503  
504  	;
505  
506  
507  
508      // this assumes that at module init time emcStatus is valid (non-NULL)
509      scope().attr("emcstat") = emcstatus_ptr(emcStatus);
510  
511      implicitly_convertible<EMC_TASK_STATE_ENUM, int>();
512  
513      pp::register_array_1< double, EMCMOT_MAX_AIO> ("AnalogIoArray");
514      pp::register_array_1< int, EMCMOT_MAX_DIO> ("DigitalIoArray");
515      pp::register_array_1< EMC_AXIS_STAT,EMCMOT_MAX_AXIS,
516  	bp::return_internal_reference< 1, bp::default_call_policies > > ("AxisArray");
517  }
518  
519