dynamic-graph-py.cc 12 KB
Newer Older
Thomas Moulard's avatar
Thomas Moulard committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph-python is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// dynamic-graph-python is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Lesser Public License for more details.  You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
florent's avatar
florent committed
15
16
17

#include <Python.h>
#include <iostream>
florent's avatar
florent committed
18
#include <sstream>
florent's avatar
florent committed
19
20
#include <string>

21
#include <dynamic-graph/debug.h>
22
#include <dynamic-graph/exception-factory.h>
florent's avatar
florent committed
23
#include <dynamic-graph/signal-base.h>
florent's avatar
florent committed
24

25
#include "exception.hh"
26
#include "signal-wrapper.hh"
27

28
29
namespace dynamicgraph {
  namespace python {
30

31
32
33
    // Declare functions defined in other source files
    namespace signalBase {
      extern PyObject* create(PyObject* self, PyObject* args);
34
      extern PyObject* createSignalWrapper(PyObject* self, PyObject* args);
35
      extern PyObject* getTime(PyObject* self, PyObject* args);
36
      extern PyObject* setTime(PyObject* self, PyObject* args);
37
      extern PyObject* getName(PyObject* self, PyObject* args);
38
      extern PyObject* getClassName(PyObject* self, PyObject* args);
39
      extern PyObject* display(PyObject* self, PyObject* args);
40
      extern PyObject* displayDependencies(PyObject* self, PyObject* args);
florent's avatar
florent committed
41
42
      extern PyObject* getValue(PyObject* self, PyObject* args);
      extern PyObject* setValue(PyObject* self, PyObject* args);
43
      extern PyObject* recompute(PyObject* self, PyObject* args);
44
      extern PyObject* unplug(PyObject* self, PyObject* args);
Florent Lamiraux's avatar
Florent Lamiraux committed
45
46
      extern PyObject* isPlugged(PyObject* self, PyObject* args);
      extern PyObject* getPlugged(PyObject* self, PyObject* args);
47
48
49
    }
    namespace entity {
      extern PyObject* create(PyObject* self, PyObject* args);
50
      extern PyObject* display(PyObject* self, PyObject* args);
51
      extern PyObject* display(PyObject* self, PyObject* args);
52
      extern PyObject* getName(PyObject* self, PyObject* args);
Joseph Mirabel's avatar
Joseph Mirabel committed
53
      extern PyObject* getClassName(PyObject* self, PyObject* args);
54
      extern PyObject* hasSignal(PyObject* self, PyObject* args);
55
      extern PyObject* getSignal(PyObject* self, PyObject* args);
56
      extern PyObject* listSignals(PyObject* self, PyObject* args);
florent's avatar
florent committed
57
      extern PyObject* executeCommand(PyObject* self, PyObject* args);
58
      extern PyObject* listCommands(PyObject* self, PyObject* args);
59
      extern PyObject* getCommandDocstring(PyObject* self, PyObject* args);
60
      extern PyObject* getDocString(PyObject* self, PyObject* args);
61
62
      extern PyObject* setLoggerVerbosityLevel(PyObject*self, PyObject *args);
      extern PyObject* getLoggerVerbosityLevel(PyObject *self, PyObject *args);
63
64
65
66
      extern PyObject* setTimeSample(PyObject*self, PyObject *args);
      extern PyObject* getTimeSample(PyObject *self, PyObject *args);
      extern PyObject* setStreamPrintPeriod(PyObject*self, PyObject *args);
      extern PyObject* getStreamPrintPeriod(PyObject *self, PyObject *args);
67
68
    }

florent's avatar
florent committed
69
    namespace factory {
70
      extern PyObject* getEntityClassList(PyObject* self, PyObject* args);
florent's avatar
florent committed
71
    }
72
    namespace signalCaster {
73
74
75
76
      extern PyObject* getSignalTypeList(PyObject* self, PyObject* args);
    }
    namespace pool {
      extern PyObject* writeGraph (PyObject* self, PyObject* args);
77
      extern PyObject* getEntityList(PyObject* self, PyObject* args);
78
    }
79
80
81
82
83
84
85
86
    namespace debug {
      extern PyObject* addLoggerFileOutputStream(PyObject* self, PyObject* args);
      extern PyObject* addLoggerCoutOutputStream(PyObject* self, PyObject* args);
      extern PyObject* closeLoggerFileOutputStream(PyObject* self, PyObject* args);
      extern PyObject* realTimeLoggerSpinOnce(PyObject* self, PyObject* args);
      extern PyObject* realTimeLoggerDestroy(PyObject* self, PyObject* args);
      extern PyObject* realTimeLoggerInstance(PyObject* self, PyObject* args);
    }
87

88
    PyObject* dgpyError;
89
90
91
92
93

    /**
       \brief plug a signal into another one.
    */
    PyObject*
Thomas Moulard's avatar
Thomas Moulard committed
94
    plug(PyObject* /*self*/, PyObject* args)
95
    {
florent's avatar
florent committed
96
97
98
99
100
101
102
103
      PyObject* objOut = NULL;
      PyObject* objIn = NULL;
      void* pObjOut;
      void* pObjIn;

      if (!PyArg_ParseTuple(args,"OO", &objOut, &objIn))
	return NULL;

104
105
106
107
      if (!PyCObject_Check(objOut)) {
	PyErr_SetString(PyExc_TypeError,
			"first argument should be a pointer to"
			" signalBase<int>.");
florent's avatar
florent committed
108
	return NULL;
109
110
111
112
113
      }
      if (!PyCObject_Check(objIn)) {
	PyErr_SetString(PyExc_TypeError,
			"second argument should be a pointer to"
			" signalBase<int>.");
114
	return NULL;
115
      }
116

florent's avatar
florent committed
117
118
119
120
      pObjIn = PyCObject_AsVoidPtr(objIn);
	SignalBase<int>* signalIn = (SignalBase<int>*)pObjIn;
      pObjOut = PyCObject_AsVoidPtr(objOut);
	SignalBase<int>* signalOut = (SignalBase<int>*)pObjOut;
121
      std::ostringstream os;
florent's avatar
florent committed
122

123
      try {
florent's avatar
florent committed
124
	signalIn->plug(signalOut);
125
      } CATCH_ALL_EXCEPTIONS();
126
127
128
129
      return Py_BuildValue("");
    }

    PyObject*
Thomas Moulard's avatar
Thomas Moulard committed
130
    enableTrace(PyObject* /*self*/, PyObject* args)
131
    {
132
      PyObject* boolean;
133
134
      char* filename = NULL;

135
136
137
138
139
140
141
      if (PyArg_ParseTuple(args,"Os", &boolean, &filename)) {
	if (!PyBool_Check(boolean)) {
	  PyErr_SetString(PyExc_TypeError, "enableTrace takes as first "
			  "argument True or False,\n""           and as "
			  "second argument a filename.");
	  return NULL;
	}
142
	if (PyObject_IsTrue(boolean)) {
143
144
	  try {
	    DebugTrace::openFile(filename);
145
	  } CATCH_ALL_EXCEPTIONS();
146
147
148
	} else {
	  try {
	    DebugTrace::closeFile(filename);
149
	  } CATCH_ALL_EXCEPTIONS();
150
	}
151
152
153
154
155
156
      } else {
	return NULL;
      }
      return Py_BuildValue("");
    }
  }
florent's avatar
florent committed
157
158
159
160
161
}

/**
   \brief List of python functions
*/
162
static PyMethodDef dynamicGraphMethods[] = {
florent's avatar
florent committed
163
  {"w_plug",  dynamicgraph::python::plug, METH_VARARGS,
164
   "plug an output signal into an input signal"},
165
  {"enableTrace",  dynamicgraph::python::enableTrace, METH_VARARGS,
166
167
168
169
   "Enable or disable tracing debug info in a file"},
  // Signals
  {"create_signal_base", dynamicgraph::python::signalBase::create, METH_VARARGS,
   "create a SignalBase C++ object"},
170
171
  {"create_signal_wrapper", dynamicgraph::python::signalBase::createSignalWrapper, METH_VARARGS,
   "create a SignalWrapper C++ object"},
florent's avatar
florent committed
172
  {"signal_base_get_time", dynamicgraph::python::signalBase::getTime,
173
   METH_VARARGS, "Get time of  a SignalBase"},
174
175
  {"signal_base_set_time", dynamicgraph::python::signalBase::setTime,
   METH_VARARGS, "Set time of  a SignalBase"},
176
177
  {"signal_base_get_name", dynamicgraph::python::signalBase::getName,
   METH_VARARGS, "Get the name of a signal"},
178
179
  {"signal_base_get_class_name", dynamicgraph::python::signalBase::getClassName,
   METH_VARARGS, "Get the class name of a signal"},
180
181
  {"signal_base_display", dynamicgraph::python::signalBase::display,
   METH_VARARGS, "Print the signal in a string"},
182
183
  {"signal_base_display_dependencies", dynamicgraph::python::signalBase::displayDependencies,
   METH_VARARGS, "Print the signal dependencies in a string"},
florent's avatar
florent committed
184
  {"signal_base_get_value", dynamicgraph::python::signalBase::getValue,
185
   METH_VARARGS, "Read the value of a signal"},
186
  {"signal_base_set_value", dynamicgraph::python::signalBase::setValue,
florent's avatar
florent committed
187
   METH_VARARGS, "Set the value of a signal"},
188
189
  {"signal_base_recompute", dynamicgraph::python::signalBase::recompute,
   METH_VARARGS, "Recompute the signal at given time"},
190
191
  {"signal_base_unplug", dynamicgraph::python::signalBase::unplug,
   METH_VARARGS, "Unplug the signal"},
Florent Lamiraux's avatar
Florent Lamiraux committed
192
193
194
195
  {"signal_base_isPlugged", dynamicgraph::python::signalBase::isPlugged,
   METH_VARARGS, "Whether the signal is plugged"},
  {"signal_base_getPlugged", dynamicgraph::python::signalBase::getPlugged,
   METH_VARARGS, "To which signal the signal is plugged"},
196
197
198
  // Entity
  {"create_entity", dynamicgraph::python::entity::create, METH_VARARGS,
   "create an Entity C++ object"},
199
200
  {"display_entity", dynamicgraph::python::entity::display, METH_VARARGS,
   "print an Entity C++ object"},
201
202
  {"entity_get_name", dynamicgraph::python::entity::getName, METH_VARARGS,
   "get the name of an Entity"},
Joseph Mirabel's avatar
Joseph Mirabel committed
203
204
  {"entity_get_class_name", dynamicgraph::python::entity::getClassName, METH_VARARGS,
   "get the class name of an Entity"},
205
206
  {"entity_has_signal", dynamicgraph::python::entity::hasSignal, METH_VARARGS,
   "return True if the entity has a signal with the given name"},
207
208
  {"entity_get_signal", dynamicgraph::python::entity::getSignal, METH_VARARGS,
   "get signal by name from an Entity"},
209
210
211
  {"entity_list_signals", dynamicgraph::python::entity::listSignals,
   METH_VARARGS,
   "Return the list of signals of an entity."},
florent's avatar
florent committed
212
213
214
215
  {"entity_execute_command",
   dynamicgraph::python::entity::executeCommand,
   METH_VARARGS,
   "execute a command"},
216
217
218
219
  {"entity_list_commands",
   dynamicgraph::python::entity::listCommands,
   METH_VARARGS,
   "list the commands of an entity"},
220
221
222
223
  {"entity_get_command_docstring",
   dynamicgraph::python::entity::getCommandDocstring,
   METH_VARARGS,
   "get the docstring of an entity command"},
224
225
226
227
  {"entity_get_docstring",
   dynamicgraph::python::entity::getDocString,
   METH_VARARGS,
   "get the doc string of an entity type"},
florent's avatar
florent committed
228
229
230
231
  {"factory_get_entity_class_list",
   dynamicgraph::python::factory::getEntityClassList,
   METH_VARARGS,
   "return the list of entity classes"},
232
233
234
235
  {"signal_caster_get_type_list",
   dynamicgraph::python::signalCaster::getSignalTypeList,
   METH_VARARGS,
   "return the list of signal type names"},
236
237
238
239
  {"writeGraph",
   dynamicgraph::python::pool::writeGraph,
   METH_VARARGS,
   "Write the graph of entities in a filename."},
240
241
242
243
  {"get_entity_list",
   dynamicgraph::python::pool::getEntityList,
   METH_VARARGS,
   "return the list of instanciated entities"},
244
245
246
247
248
249
250
  {"entity_set_logger_verbosity",
   dynamicgraph::python::entity::setLoggerVerbosityLevel,
   METH_VARARGS,
   "set the verbosity level of the entity"},
  {"entity_get_logger_verbosity",
   dynamicgraph::python::entity::getLoggerVerbosityLevel,
   METH_VARARGS,
251
   "get the verbosity level of the entity"},
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
  {"addLoggerFileOutputStream",
   dynamicgraph::python::debug::addLoggerFileOutputStream,
   METH_VARARGS,
   "add a output file stream to the logger by filename"},
  {"addLoggerCoutOutputStream",
   dynamicgraph::python::debug::addLoggerCoutOutputStream,
   METH_VARARGS,
   "add std::cout as output stream to the logger"},
  {"closeLoggerFileOutputStream",
   dynamicgraph::python::debug::closeLoggerFileOutputStream,
   METH_VARARGS,
   "close all the loggers file output streams."},
  {"entity_set_time_sample",
   dynamicgraph::python::entity::setTimeSample,
   METH_VARARGS,
   "set the time sample for printing debugging information"},
  {"entity_get_time_sample",
   dynamicgraph::python::entity::getTimeSample,
   METH_VARARGS,
   "get the time sample for printing debugging information"},
  {"entity_set_stream_print_period",
   dynamicgraph::python::entity::setStreamPrintPeriod,
   METH_VARARGS,
   "set the period at which debugging information are printed"},
  {"entity_get_stream_print_period",
   dynamicgraph::python::entity::getStreamPrintPeriod,
   METH_VARARGS,
   "get the period at which debugging information are printed"},
  {"real_time_logger_destroy",
   dynamicgraph::python::debug::realTimeLoggerDestroy,
   METH_VARARGS,
   "Destroy the real time logger."},
  {"real_time_logger_spin_once",
   dynamicgraph::python::debug::realTimeLoggerSpinOnce,
   METH_VARARGS,
   "Destroy the real time logger."},
  {"real_time_logger_instance",
   dynamicgraph::python::debug::realTimeLoggerInstance,
   METH_VARARGS,
   "Starts the real time logger."},
florent's avatar
florent committed
292
293
294
295
296
297
298
299
  {NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC
initwrap(void)
{
    PyObject *m;

300
    m = Py_InitModule("wrap", dynamicGraphMethods);
florent's avatar
florent committed
301
302
    if (m == NULL)
        return;
303

florent's avatar
florent committed
304
    std::string msg("dynamic_graph.error");
florent's avatar
florent committed
305

306
    dynamicgraph::python::dgpyError =
florent's avatar
florent committed
307
      PyErr_NewException(const_cast<char*>(msg.c_str()), NULL, NULL);
308
309
    Py_INCREF(dynamicgraph::python::dgpyError);
    PyModule_AddObject(m, "error", dynamicgraph::python::dgpyError);
florent's avatar
florent committed
310
}