📄 emcmodule.cc
字号:
PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "emc.error_channel", /*tp_name*/ sizeof(pyErrorChannel), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)Error_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ Error_methods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ (initproc)Error_init, /*tp_init*/ 0, /*tp_alloc*/ PyType_GenericNew, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/};#include <GL/gl.h>struct color { unsigned char r, g, b, a; bool operator==(const color &o) const { return r == o.r && g == o.g && b == o.b && a == o.a; } bool operator!=(const color &o) const { return r != o.r || g != o.g || b != o.b || a != o.a; }} color;struct logger_point { float x, y, z; struct color c;};#define NUMCOLORS (6)#define MAX_POINTS (100000)typedef struct { PyObject_HEAD int npts, mpts, lpts; struct logger_point *p; struct color colors[NUMCOLORS]; bool exit, clear, changed; pyStatChannel *st;} pyPositionLogger;static const double epsilon = 1e-8;static inline bool colinear(float xa, float ya, float za, float xb, float yb, float zb, float xc, float yc, float zc) { double dx1 = xa-xb, dx2 = xb-xc; double dy1 = ya-yb, dy2 = yb-yc; double dz1 = za-zb, dz2 = zb-zc; double dp = sqrt(dx1*dx1 + dy1*dy1 + dz1*dz1); double dq = sqrt(dx2*dx2 + dy2*dy2 + dz2*dz2); if( fabs(dp) < epsilon || fabs(dq) < epsilon ) return true; double dot = (dx1*dx2 + dy1*dy2 + dz1*dz2) / dp / dq; if( fabs(1-dot) < epsilon) return true; return false;}static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;static void LOCK() { pthread_mutex_lock(&mutex); }static void UNLOCK() { pthread_mutex_unlock(&mutex); }static int Logger_init(pyPositionLogger *self, PyObject *a, PyObject *k) { struct color *c = self->colors; self->p = (logger_point*)malloc(0); self->npts = self->mpts = 0; self->exit = self->clear = 0; self->changed = 1; self->st = 0; if(!PyArg_ParseTuple(a, "O!(BBBB)(BBBB)(BBBB)(BBBB)(BBBB)(BBBB)", &Stat_Type, &self->st, &c[0].r,&c[0].g, &c[0].b, &c[0].a, &c[1].r,&c[1].g, &c[1].b, &c[1].a, &c[2].r,&c[2].g, &c[2].b, &c[2].a, &c[3].r,&c[3].g, &c[3].b, &c[3].a, &c[4].r,&c[4].g, &c[4].b, &c[4].a, &c[5].r,&c[5].g, &c[5].b, &c[5].a )) return -1; Py_INCREF(self->st); return 0;}static void Logger_dealloc(pyPositionLogger *s) { free(s->p); Py_XDECREF(s->st); PyObject_Del(s);}static PyObject *Logger_start(pyPositionLogger *s, PyObject *o) { double interval; struct timespec ts; if(!PyArg_ParseTuple(o, "d:logger.start", &interval)) return NULL; ts.tv_sec = (int)interval; ts.tv_nsec = (long int)(1e9 * (interval - ts.tv_sec)); Py_INCREF(s->st); s->exit = 0; s->clear = 0; s->npts = 0; Py_BEGIN_ALLOW_THREADS while(!s->exit) { if(s->clear) { s->npts = 0; s->lpts = 0; s->clear = 0; } if(s->st->c->valid() && s->st->c->peek() == EMC_STAT_TYPE) { EMC_STAT *status = static_cast<EMC_STAT*>(s->st->c->get_address()); int colornum = 2; double x, y, z; colornum = status->motion.traj.motion_type; if(colornum < 0 || colornum > NUMCOLORS) colornum = 0; x = status->motion.traj.position.tran.x - status->task.toolOffset.tran.x; y = status->motion.traj.position.tran.y - status->task.toolOffset.tran.y; z = status->motion.traj.position.tran.z - status->task.toolOffset.tran.z; struct color c = s->colors[colornum]; struct logger_point *op = &s->p[s->npts-1]; struct logger_point *oop = &s->p[s->npts-2]; bool add_point = s->npts < 2 || c != op->c || !colinear( x, y, z, op->x, op->y, op->z, oop->x, oop->y, oop->z); if(add_point) { // 1 or 2 points may be added, make room whenever // fewer than 2 are left bool changed_color = s->npts && c != op->c; if(s->npts+2 > s->mpts) { LOCK(); if(s->mpts >= MAX_POINTS) { int adjust = MAX_POINTS / 10; if(adjust < 2) adjust = 2; s->npts -= adjust; memmove(s->p, s->p + adjust, sizeof(struct logger_point) * s->npts); } else { s->mpts = 2 * s->mpts + 2; s->changed = 1; s->p = (struct logger_point*) realloc(s->p, sizeof(struct logger_point) * s->mpts); } UNLOCK(); op = &s->p[s->npts-1]; oop = &s->p[s->npts-2]; } if(changed_color) { { struct logger_point &np = s->p[s->npts]; np.x = op->x; np.y = op->y; np.z = op->z; np.c = c; } { struct logger_point &np = s->p[s->npts+1]; np.x = x; np.y = y; np.z = z; np.c = c; } s->npts += 2; } else { struct logger_point &np = s->p[s->npts]; np.x = x; np.y = y; np.z = z; np.c = c; s->npts++; } } else { struct logger_point &np = s->p[s->npts-1]; np.x = x; np.y = y; np.z = z; } } nanosleep(&ts, NULL); } Py_END_ALLOW_THREADS Py_DECREF(s->st); Py_INCREF(Py_None); return Py_None;}static PyObject* Logger_clear(pyPositionLogger *s, PyObject *o) { s->clear = true; Py_INCREF(Py_None); return Py_None;}static PyObject* Logger_stop(pyPositionLogger *s, PyObject *o) { s->exit = true; Py_INCREF(Py_None); return Py_None;}static PyObject* Logger_call(pyPositionLogger *s, PyObject *o) { if(!s->clear) { LOCK(); if(s->changed) { glVertexPointer(3, GL_FLOAT, sizeof(struct logger_point), &s->p->x); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct logger_point), &s->p->c); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); s->changed = 0; } s->lpts = s->npts; glDrawArrays(GL_LINE_STRIP, 0, s->npts); UNLOCK(); } Py_INCREF(Py_None); return Py_None;}static PyObject *Logger_last(pyPositionLogger *s, PyObject *o) { PyObject *result = NULL; LOCK(); if(!s->lpts) { Py_INCREF(Py_None); result = Py_None; } else { result = PyTuple_New(3); struct logger_point &p = s->p[s->lpts-1]; PyTuple_SET_ITEM(result, 0, PyFloat_FromDouble(p.x)); PyTuple_SET_ITEM(result, 1, PyFloat_FromDouble(p.y)); PyTuple_SET_ITEM(result, 2, PyFloat_FromDouble(p.z)); } UNLOCK(); return result;}static PyMemberDef Logger_members[] = { {"npts", T_INT, offsetof(pyPositionLogger, npts), READONLY}, {0, 0, 0, 0},};static PyMethodDef Logger_methods[] = { {"start", (PyCFunction)Logger_start, METH_VARARGS, "Start the position logger and run every ARG seconds"}, {"clear", (PyCFunction)Logger_clear, METH_NOARGS, "Clear the position logger"}, {"stop", (PyCFunction)Logger_stop, METH_NOARGS, "Stop the position logger"}, {"call", (PyCFunction)Logger_call, METH_NOARGS, "Plot the backplot now"}, {"last", (PyCFunction)Logger_last, METH_NOARGS, "Return the most recent point on the plot or None"}, {NULL, NULL, 0, NULL},};static PyTypeObject PositionLoggerType = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "emc.positionlogger", /*tp_name*/ sizeof(pyPositionLogger), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)Logger_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ Logger_methods, /*tp_methods*/ Logger_members, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ (initproc)Logger_init, /*tp_init*/ 0, /*tp_alloc*/ PyType_GenericNew, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/};static PyMethodDef emc_methods[] = { {NULL}};/* ENUM defines an integer constant with the same name as the C constant. * ENUMX defines an integer constant with the first i characters of the C * constant name removed (so that ENUMX(4,RCS_TASK_MODE_MDI) creates a constant * named TASK_MODE_MDI) */#define ENUM(e) PyModule_AddIntConstant(m, const_cast<char*>(#e), e)#define ENUMX(x,e) PyModule_AddIntConstant(m, x + const_cast<char*>(#e), e)PyMODINIT_FUNCinitemc(void) { emcInitGlobals(); verbose_nml_error_messages = 0; clear_rcs_print_flag(~0); m = Py_InitModule3("emc", emc_methods, "Interface to EMC"); PyType_Ready(&Stat_Type); PyType_Ready(&Command_Type); PyType_Ready(&Error_Type); PyType_Ready(&Ini_Type); error = PyErr_NewException("emc.error", PyExc_RuntimeError, NULL); PyModule_AddObject(m, "stat", (PyObject*)&Stat_Type); PyModule_AddObject(m, "command", (PyObject*)&Command_Type); PyModule_AddObject(m, "error_channel", (PyObject*)&Error_Type); PyModule_AddObject(m, "ini", (PyObject*)&Ini_Type); PyModule_AddObject(m, "error", error); PyType_Ready(&PositionLoggerType); PyModule_AddObject(m, "positionlogger", (PyObject*)&PositionLoggerType); pthread_mutex_init(&mutex, NULL); PyModule_AddStringConstant(m, "nmlfile", DEFAULT_NMLFILE); PyModule_AddIntConstant(m, "OPERATOR_ERROR", EMC_OPERATOR_ERROR_TYPE); PyModule_AddIntConstant(m, "OPERATOR_TEXT", EMC_OPERATOR_TEXT_TYPE); PyModule_AddIntConstant(m, "OPERATOR_DISPLAY", EMC_OPERATOR_DISPLAY_TYPE); PyModule_AddIntConstant(m, "NML_ERROR", NML_ERROR_TYPE); PyModule_AddIntConstant(m, "NML_TEXT", NML_TEXT_TYPE); PyModule_AddIntConstant(m, "NML_DISPLAY", NML_DISPLAY_TYPE); PyStructSequence_InitType(&ToolResultType, &tool_result_desc); PyModule_AddObject(m, "tool", (PyObject*)&ToolResultType); PyModule_AddObject(m, "version", PyString_FromString(PACKAGE_VERSION)); ENUMX(4, EMC_AXIS_LINEAR); ENUMX(4, EMC_AXIS_ANGULAR); ENUMX(9, EMC_TASK_INTERP_IDLE); ENUMX(9, EMC_TASK_INTERP_READING); ENUMX(9, EMC_TASK_INTERP_PAUSED); ENUMX(9, EMC_TASK_INTERP_WAITING); ENUMX(9, EMC_TASK_MODE_MDI); ENUMX(9, EMC_TASK_MODE_MANUAL); ENUMX(9, EMC_TASK_MODE_AUTO); ENUMX(9, EMC_TASK_STATE_OFF); ENUMX(9, EMC_TASK_STATE_ON); ENUMX(9, EMC_TASK_STATE_ESTOP); ENUMX(9, EMC_TASK_STATE_ESTOP_RESET); ENUMX(6, LOCAL_SPINDLE_FORWARD); ENUMX(6, LOCAL_SPINDLE_REVERSE); ENUMX(6, LOCAL_SPINDLE_OFF); ENUMX(6, LOCAL_SPINDLE_INCREASE); ENUMX(6, LOCAL_SPINDLE_DECREASE); ENUMX(6, LOCAL_SPINDLE_CONSTANT); ENUMX(6, LOCAL_MIST_ON); ENUMX(6, LOCAL_MIST_OFF); ENUMX(6, LOCAL_FLOOD_ON); ENUMX(6, LOCAL_FLOOD_OFF); ENUMX(6, LOCAL_BRAKE_ENGAGE); ENUMX(6, LOCAL_BRAKE_RELEASE); ENUMX(6, LOCAL_JOG_STOP); ENUMX(6, LOCAL_JOG_CONTINUOUS); ENUMX(6, LOCAL_JOG_INCREMENT); ENUMX(6, LOCAL_AUTO_RUN); ENUMX(6, LOCAL_AUTO_PAUSE); ENUMX(6, LOCAL_AUTO_RESUME); ENUMX(6, LOCAL_AUTO_STEP); ENUMX(4, EMC_TRAJ_MODE_FREE); ENUMX(4, EMC_TRAJ_MODE_COORD); ENUMX(4, EMC_TRAJ_MODE_TELEOP); ENUM(KINEMATICS_IDENTITY); ENUM(KINEMATICS_FORWARD_ONLY); ENUM(KINEMATICS_INVERSE_ONLY); ENUM(KINEMATICS_BOTH); ENUMX(4, EMC_DEBUG_INVALID); ENUMX(4, EMC_DEBUG_CONFIG); ENUMX(4, EMC_DEBUG_DEFAULTS); ENUMX(4, EMC_DEBUG_VERSIONS); ENUMX(4, EMC_DEBUG_TASK_ISSUE); ENUMX(4, EMC_DEBUG_IO_POINTS); ENUMX(4, EMC_DEBUG_NML); ENUMX(4, EMC_DEBUG_MOTION_TIME); ENUMX(4, EMC_DEBUG_INTERP); ENUMX(4, EMC_DEBUG_RCS); ENUMX(4, EMC_DEBUG_TRAJ); ENUMX(4, EMC_DEBUG_INTERP_LIST); ENUMX(9, EMC_TASK_EXEC_ERROR); ENUMX(9, EMC_TASK_EXEC_DONE); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_MOTION); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_MOTION_QUEUE); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_IO); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_PAUSE); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_MOTION_AND_IO); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_DELAY); ENUMX(9, EMC_TASK_EXEC_WAITING_FOR_SYSTEM_CMD);}// # vim:sw=4:sts=4:et:ts=8:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -