Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • devel
  • master
  • pr/116
  • pre-commit-ci-update-config
  • topic/xenial
  • v2.5
  • v2.5.1
  • v2.5.2
  • v2.5.3
  • v2.5.4
  • v2.5.5
  • v3.0.0
  • v3.0.1
  • v3.0.2
  • v3.1.0
  • v3.2.0
  • v3.3.0
  • v3.3.1
  • v3.3.2
  • v3.4.0
  • v3.4.1
  • v3.5.0
  • v3.5.1
  • v3.5.2
  • v3.5.3
  • v4.0.0
  • v4.0.1
  • v4.0.10
  • v4.0.11
  • v4.0.2
  • v4.0.3
  • v4.0.4
  • v4.0.5
  • v4.0.6
  • v4.0.7
  • v4.0.8
  • v4.0.9
37 results

Target

Select target project
  • ostasse/dynamic-graph-python
  • gsaurel/dynamic-graph-python
  • stack-of-tasks/dynamic-graph-python
3 results
Select Git revision
  • devel
  • master
  • topic/repl
  • v2.5
  • v2.5.1
  • v2.5.2
  • v2.5.3
  • v2.5.4
  • v2.5.5
  • v3.0.0
  • v3.0.1
  • v3.0.2
  • v3.1.0
  • v3.2.0
  • v3.3.0
  • v3.3.1
  • v3.3.2
  • v3.4.0
  • v3.4.1
  • v3.5.0
  • v3.5.1
  • v3.5.2
  • v3.5.3
  • v4.0.0
  • v4.0.1
  • v4.0.10
  • v4.0.11
  • v4.0.2
  • v4.0.3
  • v4.0.4
  • v4.0.5
  • v4.0.6
  • v4.0.7
  • v4.0.8
  • v4.0.9
35 results
Show changes
Showing
with 494 additions and 788 deletions
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS. // Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <iostream>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
#include <iostream>
#include "dynamic-graph/python/dynamic-graph-py.hh" #include "dynamic-graph/python/dynamic-graph-py.hh"
using dynamicgraph::Entity; using dynamicgraph::Entity;
...@@ -16,22 +17,10 @@ namespace factory { ...@@ -16,22 +17,10 @@ namespace factory {
/** /**
\brief Get name of entity \brief Get name of entity
*/ */
PyObject* getEntityClassList(PyObject* /*self*/, PyObject* args) { bp::tuple getEntityClassList() {
if (!PyArg_ParseTuple(args, "")) return NULL;
std::vector<std::string> classNames; std::vector<std::string> classNames;
dynamicgraph::FactoryStorage::getInstance()->listEntities(classNames); dynamicgraph::FactoryStorage::getInstance()->listEntities(classNames);
return to_py_tuple(classNames.begin(), classNames.end());
Py_ssize_t classNumber = classNames.size();
// Build a tuple object
PyObject* classTuple = PyTuple_New(classNumber);
for (Py_ssize_t iEntity = 0; iEntity < (Py_ssize_t)classNames.size(); ++iEntity) {
PyObject* className = Py_BuildValue("s", classNames[iEntity].c_str());
PyTuple_SetItem(classTuple, iEntity, className);
}
return Py_BuildValue("O", classTuple);
} }
} // namespace factory } // namespace factory
......
// Copyright 2011, 2012, Florent Lamiraux, LAAS-CNRS. // Copyright 2011, 2012, Florent Lamiraux, LAAS-CNRS.
#include <dynamic-graph/pool.h>
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
#include <dynamic-graph/pool.h>
#include <vector> #include <vector>
#include "dynamic-graph/python/exception.hh"
#include "dynamic-graph/python/dynamic-graph-py.hh" #include "dynamic-graph/python/dynamic-graph-py.hh"
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
#if PY_MAJOR_VERSION == 2
extern PyObject* dgpyError;
# endif
namespace pool { namespace pool {
PyObject* writeGraph( void writeGraph(const char* filename) {
#if PY_MAJOR_VERSION >= 3 PoolStorage::getInstance()->writeGraph(filename);
PyObject* m, PyObject* args }
#else
PyObject*, PyObject* args const std::map<std::string, Entity*>* getEntityMap() {
#endif return &PoolStorage::getInstance()->getEntityMap();
) {
char* filename;
if (!PyArg_ParseTuple(args, "s", &filename)) return NULL;
try {
PoolStorage::getInstance()->writeGraph(filename);
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
} }
/** /**
\brief Get list of entities \brief Get list of entities
*/ */
PyObject* getEntityList( bp::list getEntityList() {
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
if (!PyArg_ParseTuple(args, "")) return NULL;
std::vector<std::string> entityNames; std::vector<std::string> entityNames;
try { bp::list res;
const PoolStorage::Entities& listOfEntities = dynamicgraph::PoolStorage::getInstance()->getEntityMap(); const PoolStorage::Entities& listOfEntities =
PoolStorage::getInstance()->getEntityMap();
Py_ssize_t classNumber = listOfEntities.size();
// Build a tuple object
PyObject* classTuple = PyTuple_New(classNumber);
Py_ssize_t iEntity = 0;
for (PoolStorage::Entities::const_iterator entity_it = listOfEntities.begin(); entity_it != listOfEntities.end();
++entity_it) {
const std::string& aname = entity_it->second->getName();
PyObject* className = Py_BuildValue("s", aname.c_str()); for (const auto& el : listOfEntities) res.append(el.second->getName());
PyTuple_SetItem(classTuple, iEntity, className); return res;
iEntity++;
}
return Py_BuildValue("O", classTuple);
}
CATCH_ALL_EXCEPTIONS(m);
return NULL;
} }
} // namespace pool } // namespace pool
......
...@@ -14,16 +14,15 @@ from __future__ import print_function ...@@ -14,16 +14,15 @@ from __future__ import print_function
import sys import sys
from .entity import Entity from .entity import Entity
from .matlab import matlab
from .signal_base import SignalBase from .signal_base import SignalBase
# Enables shortcut "name" # Enables shortcut "name"
def sig_short_name(self): def sig_short_name(self):
return self.getName().split(':')[-1] return self.getName().split(":")[-1]
setattr(SignalBase, 'name', property(sig_short_name)) setattr(SignalBase, "name", property(sig_short_name))
# Enables shortcuts "m" # Enables shortcuts "m"
...@@ -39,7 +38,7 @@ class PrettySignalPrint: ...@@ -39,7 +38,7 @@ class PrettySignalPrint:
self.sig = sig self.sig = sig
def __str__(self): def __str__(self):
return self.sig.name + " = " + str(matlab(self.sig.value)) return self.sig.name + " = " + str(self.sig.value)
def __repr__(self): def __repr__(self):
return str(self) return str(self)
...@@ -57,14 +56,12 @@ def sigMatPrint(sig): ...@@ -57,14 +56,12 @@ def sigMatPrint(sig):
return PrettySignalPrint(sig) return PrettySignalPrint(sig)
setattr(SignalBase, 'm', property(PrettySignalPrint)) setattr(SignalBase, "m", property(PrettySignalPrint))
# print('Pretty matlab print set')
# Enable the same as 'm', but directly on the signal object. # Enable the same as 'm', but directly on the signal object.
def sigRepr(self): def sigRepr(self):
return self.name + ' = ' + str(matlab(self.value)) return self.name + " = " + str(self.value)
def sigCall(sig, iter): def sigCall(sig, iter):
...@@ -77,9 +74,9 @@ def sigTimeIncr(sig, iter): ...@@ -77,9 +74,9 @@ def sigTimeIncr(sig, iter):
print(sigRepr(sig)) print(sigRepr(sig))
setattr(SignalBase, '__repr__', sigRepr) setattr(SignalBase, "__repr__", sigRepr)
setattr(SignalBase, '__call__', sigCall) setattr(SignalBase, "__call__", sigCall)
setattr(SignalBase, '__add__', sigTimeIncr) setattr(SignalBase, "__add__", sigTimeIncr)
# Enables shortcut "deps" # Enables shortcut "deps"
...@@ -100,12 +97,12 @@ class SignalDepPrint: ...@@ -100,12 +97,12 @@ class SignalDepPrint:
return self return self
setattr(SignalBase, 'deps', property(SignalDepPrint)) setattr(SignalBase, "deps", property(SignalDepPrint))
setattr(Entity, 'sigs', property(Entity.displaySignals)) setattr(Entity, "sigs", property(Entity.displaySignals))
setattr(Entity, '__repr__', Entity.__str__) setattr(Entity, "__repr__", Entity.__str__)
sys.ps1 = '% ' sys.ps1 = "% "
# Enable function that can be call without()def optionalparentheses(f): # Enable function that can be call without()def optionalparentheses(f):
...@@ -119,7 +116,7 @@ def optionalparentheses(f): ...@@ -119,7 +116,7 @@ def optionalparentheses(f):
if isinstance(res, str): if isinstance(res, str):
return res return res
else: else:
return '' return ""
def __call__(self, *arg): def __call__(self, *arg):
return self.functor(*arg) return self.functor(*arg)
......
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS. // Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <iostream> #include <dynamic-graph/linear-algebra.h>
#include <sstream>
#include <dynamic-graph/signal-base.h> #include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/signal-ptr.h> #include <dynamic-graph/signal-ptr.h>
#include <dynamic-graph/signal-caster.h> #include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/linear-algebra.h> #include <dynamic-graph/signal.h>
#include <dynamic-graph/pool.h> #include <dynamic-graph/value.h>
#include <dynamic-graph/factory.h>
#include <boost/python.hpp>
#include <iostream>
#include <sstream>
#include "dynamic-graph/python/dynamic-graph-py.hh" #include "dynamic-graph/python/dynamic-graph-py.hh"
#include "dynamic-graph/python/convert-dg-to-py.hh"
#include "dynamic-graph/python/exception.hh"
#include "dynamic-graph/python/signal-wrapper.hh" #include "dynamic-graph/python/signal-wrapper.hh"
#include "dynamic-graph/python/signal.hh"
using dynamicgraph::SignalBase; using dynamicgraph::SignalBase;
namespace bp = boost::python;
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
#if PY_MAJOR_VERSION == 2 typedef int time_type;
extern PyObject* dgpyError;
# endif typedef Eigen::AngleAxis<double> VectorUTheta;
typedef Eigen::Quaternion<double> Quaternion;
using namespace convert;
typedef Eigen::VectorXd Vector;
namespace signalBase { typedef Eigen::Vector3d Vector3;
typedef Eigen::Matrix<double, 7, 1> Vector7;
typedef Eigen::MatrixXd Matrix;
typedef Eigen::Matrix<double, 3, 3> MatrixRotation;
typedef Eigen::Matrix<double, 4, 4> Matrix4;
typedef Eigen::Transform<double, 3, Eigen::Affine> MatrixHomogeneous;
typedef Eigen::Matrix<double, 6, 6> MatrixTwist;
template <typename Time>
void exposeSignalBase(const char* name) {
typedef SignalBase<Time> S_t;
bp::class_<S_t, boost::noncopyable>(name, bp::no_init)
.add_property("time",
bp::make_function(
&S_t::getTime,
bp::return_value_policy<bp::copy_const_reference>()),
&S_t::setTime)
.add_property("name",
bp::make_function(
&S_t::getName,
bp::return_value_policy<bp::copy_const_reference>()))
.def("getName", &S_t::getName,
bp::return_value_policy<bp::copy_const_reference>())
.def(
"getClassName",
+[](const S_t& s) -> std::string {
std::string ret;
s.getClassName(ret);
return ret;
})
.def("plug", &S_t::plug, "Plug the signal to another signal")
.def("unplug", &S_t::unplug, "Unplug the signal")
.def("isPlugged", &S_t::isPlugged, "Whether the signal is plugged")
.def("getPlugged", &S_t::getPluged,
bp::return_value_policy<bp::reference_existing_object>(),
"To which signal the signal is plugged")
.def("recompute", &S_t::recompute, "Recompute the signal at given time")
.def(
"__str__",
+[](const S_t& s) -> std::string {
std::ostringstream oss;
s.display(oss);
return oss.str();
})
.def(
"displayDependencies",
+[](const S_t& s, int time) -> std::string {
std::ostringstream oss;
s.displayDependencies(oss, time);
return oss.str();
},
"Print the signal dependencies in a string");
}
template <>
auto exposeSignal<MatrixHomogeneous, time_type>(const std::string& name) {
typedef Signal<MatrixHomogeneous, time_type> S_t;
bp::class_<S_t, bp::bases<SignalBase<time_type> >, boost::noncopyable> obj(
name.c_str(), bp::init<std::string>());
obj.add_property(
"value",
+[](const S_t& signal) -> Matrix4 {
return signal.accessCopy().matrix();
},
+[](S_t& signal, const Matrix4& v) {
// TODO it isn't hard to support pinocchio::SE3 type here.
// However, this adds a dependency to pinocchio.
signal.setConstant(MatrixHomogeneous(v));
},
"the signal value.");
return obj;
}
static void destroy(PyObject* self); void exposeSignals() {
exposeSignalBase<time_type>("SignalBase");
/** exposeSignalsOfType<bool, time_type>("Bool");
\brief Create an instance of SignalBase exposeSignalsOfType<int, time_type>("Int");
*/ exposeSignalsOfType<double, time_type>("Double");
PyObject* create(PyObject* /*self*/, PyObject* args) {
char* name = NULL;
if (!PyArg_ParseTuple(args, "s", &name)) return NULL; exposeSignalsOfType<Vector, time_type>("Vector");
exposeSignalsOfType<Vector3, time_type>("Vector3");
exposeSignalsOfType<Vector7, time_type>("Vector7");
SignalBase<int>* obj = NULL; exposeSignalsOfType<Matrix, time_type>("Matrix");
obj = new SignalBase<int>(std::string(name)); exposeSignalsOfType<MatrixRotation, time_type>("MatrixRotation");
exposeSignalsOfType<MatrixHomogeneous, time_type>("MatrixHomogeneous");
exposeSignalsOfType<MatrixTwist, time_type>("MatrixTwist");
// Return the pointer exposeSignalsOfType<Quaternion, time_type>("Quaternion");
return PyCapsule_New((void*)obj, "dynamic_graph.Signal", destroy); exposeSignalsOfType<VectorUTheta, time_type>("VectorUTheta");
} }
namespace signalBase {
template <class T> template <class T>
SignalWrapper<T, int>* createSignalWrapperTpl(const char* name, PyObject* o, std::string& error) { SignalWrapper<T, int>* createSignalWrapperTpl(const char* name, bp::object o,
std::string& error) {
typedef SignalWrapper<T, int> SignalWrapper_t; typedef SignalWrapper<T, int> SignalWrapper_t;
if (!SignalWrapper_t::checkCallable(o, error)) { if (!SignalWrapper_t::checkCallable(o, error)) {
return NULL; return NULL;
...@@ -58,27 +141,7 @@ SignalWrapper<T, int>* createSignalWrapperTpl(const char* name, PyObject* o, std ...@@ -58,27 +141,7 @@ SignalWrapper<T, int>* createSignalWrapperTpl(const char* name, PyObject* o, std
} }
PythonSignalContainer* getPythonSignalContainer() { PythonSignalContainer* getPythonSignalContainer() {
const std::string instanceName = "python_signals"; Entity* obj = entity::create("PythonSignalContainer", "python_signals");
const std::string className = "PythonSignalContainer";
Entity* obj;
#if PY_MAJOR_VERSION >= 3
PyObject* m = PyState_FindModule(&dynamicgraph::python::dynamicGraphModuleDef);
#endif
if (PoolStorage::getInstance()->existEntity(instanceName, obj)) {
if (obj->getClassName() != className) {
std::string msg("Found an object named " + std::string(instanceName) +
",\n"
"but this object is of type " +
std::string(obj->getClassName()) + " and not " + std::string(className));
PyErr_SetString(DGPYERROR(m), msg.c_str());
return NULL;
}
} else {
try {
obj = FactoryStorage::getInstance()->newEntity(std::string(className), std::string(instanceName));
}
CATCH_ALL_EXCEPTIONS(m);
}
return dynamic_cast<PythonSignalContainer*>(obj); return dynamic_cast<PythonSignalContainer*>(obj);
} }
...@@ -90,22 +153,11 @@ PythonSignalContainer* getPythonSignalContainer() { ...@@ -90,22 +153,11 @@ PythonSignalContainer* getPythonSignalContainer() {
/** /**
\brief Create an instance of SignalWrapper \brief Create an instance of SignalWrapper
*/ */
PyObject* createSignalWrapper( SignalBase<int>* createSignalWrapper(const char* name, const char* type,
#if PY_MAJOR_VERSION >= 3 bp::object object) {
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PythonSignalContainer* psc = getPythonSignalContainer(); PythonSignalContainer* psc = getPythonSignalContainer();
if (psc == NULL) return NULL; if (psc == NULL) return NULL;
char* name = NULL;
char* type = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "ssO", &name, &type, &object)) return NULL;
SignalBase<int>* obj = NULL; SignalBase<int>* obj = NULL;
std::string error; std::string error;
SIGNAL_WRAPPER_TYPE(if, BOOL, bool) SIGNAL_WRAPPER_TYPE(if, BOOL, bool)
...@@ -121,380 +173,14 @@ PyObject* createSignalWrapper( ...@@ -121,380 +173,14 @@ PyObject* createSignalWrapper(
error = "Type not understood"; error = "Type not understood";
} }
if (obj == NULL) { if (obj == NULL) throw std::runtime_error(error);
PyErr_SetString(DGPYERROR(m), error.c_str());
return NULL;
}
// Register signal into the python signal container // Register signal into the python signal container
psc->signalRegistration(*obj); psc->signalRegistration(*obj);
// Return the pointer // Return the pointer
return PyCapsule_New((void*)obj, "dynamic_graph.SignalWrapper", destroy); return obj;
}
/**
\brief Destroy an instance of InvertedPendulum
*/
static void destroy(PyObject* self) {
SignalBase<int>* obj = (SignalBase<int>*)self;
delete obj;
}
PyObject* getTime(PyObject* /*self*/, PyObject* args) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* obj = (SignalBase<int>*)pointer;
int time = obj->getTime();
return Py_BuildValue("i", time);
}
PyObject* setTime(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
int time;
if (!PyArg_ParseTuple(args, "Oi", &object, &time)) return NULL;
if (!PyCapsule_CheckExact(object)) {
PyErr_SetString(DGPYERROR(m), "object should be a C object");
return NULL;
}
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* obj = (SignalBase<int>*)pointer;
obj->setTime(time);
return Py_BuildValue("");
}
PyObject* display(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* obj = (SignalBase<int>*)pointer;
std::ostringstream oss;
try {
obj->display(oss);
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", oss.str().c_str());
}
PyObject* displayDependencies(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
int time;
if (!PyArg_ParseTuple(args, "OI", &object, &time)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* obj = (SignalBase<int>*)pointer;
std::ostringstream oss;
try {
obj->displayDependencies(oss, time);
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", oss.str().c_str());
}
PyObject* getValue(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
try {
{ // --- VECTOR SIGNALS -----------------
// Two cases: the signal embeds directly a vector, or embeds
// an object deriving from vector.In the first case,
// the signal is directly cast into sig<vector>.
// In the second case, the derived object can be access as a vector
// using the signal-ptr<vector> type.
Signal<dynamicgraph::Vector, int>* sigvec = dynamic_cast<Signal<dynamicgraph::Vector, int>*>(signal);
if (NULL != sigvec) {
return vectorToPython(sigvec->accessCopy());
}
// Extraction of object derinving from vector: plug signal into
// a vector signal and get the value from the signal-ptr instead
// of the original vector.
SignalPtr<dynamicgraph::Vector, int> sigptr(NULL, "vector-caster");
try {
sigptr.plug(signal);
return vectorToPython(sigptr.accessCopy());
} catch (dynamicgraph::ExceptionSignal& ex) {
if (ex.getCode() != dynamicgraph::ExceptionSignal::PLUG_IMPOSSIBLE) throw;
}
}
{ // --- MATRIX SIGNALS --------------------
// Two cases: the signal embeds directly a matrix, or embeds
// an object deriving from matrix.In the first case,
// the signal is directly cast into sig<matrix>.
// In the second case, the derived object can be access as a matrix
// using the signal-ptr<matrix> type.
Signal<dynamicgraph::Matrix, int>* sigmat = dynamic_cast<Signal<dynamicgraph::Matrix, int>*>(signal);
if (NULL != sigmat) {
return matrixToPython(sigmat->accessCopy());
}
SignalPtr<dynamicgraph::Matrix, int> sigptr(NULL, "matrix-caster");
try {
sigptr.plug(signal);
return matrixToPython(sigptr.accessCopy());
} catch (dynamicgraph::ExceptionSignal& ex) {
if (ex.getCode() != dynamicgraph::ExceptionSignal::PLUG_IMPOSSIBLE) throw;
}
}
{ // --- HOMOGENEOUS MATRIX SIGNALS --------------------
// Two cases: the signal embeds directly a matrix, or embeds
// an object deriving from matrix.In the first case,
// the signal is directly cast into sig<matrix>.
// In the second case, the derived object can be access as a matrix
// using the signal-ptr<matrix> type.
// TODO: See if matrix homogeneous can be properly put in linear-algebra.h
typedef Eigen::Transform<double, 3, Eigen::Affine> MatrixHomogeneous;
Signal<MatrixHomogeneous, int>* sigmat = dynamic_cast<Signal<MatrixHomogeneous, int>*>(signal);
if (NULL != sigmat) {
return matrixToPython(sigmat->accessCopy().matrix());
}
SignalPtr<Eigen::Transform<double, 3, Eigen::Affine>, int> sigptr(NULL, "matrix-caster");
try {
sigptr.plug(signal);
return matrixToPython(sigptr.accessCopy().matrix());
} catch (dynamicgraph::ExceptionSignal& ex) {
if (ex.getCode() != dynamicgraph::ExceptionSignal::PLUG_IMPOSSIBLE) throw;
}
}
Signal<double, int>* sigdouble = dynamic_cast<Signal<double, int>*>(signal);
if (NULL != sigdouble) {
return Py_BuildValue("d", sigdouble->accessCopy());
}
}
CATCH_ALL_EXCEPTIONS(m);
/* Non specific signal: use a generic way. */
std::ostringstream value;
try {
signal->get(value);
}
CATCH_ALL_EXCEPTIONS(m);
std::string valueString = value.str();
return Py_BuildValue("s", valueString.c_str());
}
PyObject* getName(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
std::string name;
try {
name = signal->getName();
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", name.c_str());
}
PyObject* getClassName(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
std::string name;
try {
signal->getClassName(name);
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", name.c_str());
}
PyObject* setValue(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
char* valueString = NULL;
if (!PyArg_ParseTuple(args, "Os", &object, &valueString)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
std::ostringstream os;
os << valueString;
std::istringstream value(os.str());
try {
signal->set(value);
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* recompute(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
unsigned int time;
if (!PyArg_ParseTuple(args, "OI", &object, &time)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
try {
signal->recompute(time);
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* unplug(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
try {
signal->unplug();
}
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* isPlugged(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
bool plugged = false;
try {
plugged = signal->isPlugged();
}
CATCH_ALL_EXCEPTIONS(m);
if (plugged)
return PyBool_FromLong(1);
else
return PyBool_FromLong(0);
} }
PyObject* getPlugged(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
if (!PyCapsule_CheckExact(object)) return NULL;
pointer = PyCapsule_GetPointer(object, "dynamic_graph.Signal");
SignalBase<int>* signal = (SignalBase<int>*)pointer;
SignalBase<int>* otherSignal = 0;
try {
bool plugged = signal->isPlugged();
otherSignal = signal->getPluged();
if (!plugged || otherSignal == 0) {
std::string msg = std::string("Signal ") + signal->getName() + std::string(" is not plugged.");
throw std::runtime_error(msg);
}
}
CATCH_ALL_EXCEPTIONS(m);
// Return the pointer to the signal without destructor since the signal
// is not owned by the calling object.
return PyCapsule_New((void*)otherSignal, "dynamic_graph.Signal", NULL);
}
} // namespace signalBase } // namespace signalBase
} // namespace python } // namespace python
} // namespace dynamicgraph } // namespace dynamicgraph
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <iostream>
#include <sstream>
#include <dynamic-graph/signal-caster.h>
#include "dynamic-graph/python/dynamic-graph-py.hh"
namespace dynamicgraph {
namespace python {
namespace signalCaster {
PyObject* getSignalTypeList(PyObject* /*self*/, PyObject* args) {
if (!PyArg_ParseTuple(args, "")) return NULL;
std::vector<std::string> typeList = dynamicgraph::SignalCaster::getInstance()->listTypenames();
Py_ssize_t typeNumber = typeList.size();
// Build a tuple object
PyObject* typeTuple = PyTuple_New(typeNumber);
for (Py_ssize_t iType = 0; iType < typeNumber; ++iType) {
PyObject* className = Py_BuildValue("s", typeList[iType].c_str());
PyTuple_SetItem(typeTuple, iType, className);
}
return Py_BuildValue("O", typeTuple);
}
} // namespace signalCaster
} // namespace python
} // namespace dynamicgraph
// Copyright (c) 2018, Joseph Mirabel // Copyright (c) 2018, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr) // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
#include <dynamic-graph/factory.h>
#include <dynamic-graph/command-bind.h>
#include "dynamic-graph/python/signal-wrapper.hh" #include "dynamic-graph/python/signal-wrapper.hh"
#include <dynamic-graph/command-bind.h>
#include <dynamic-graph/factory.h>
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
namespace signalWrapper { void PythonSignalContainer::signalRegistration(
void convert(PyObject* o, bool& v) { v = (o == Py_True); } const SignalArray<int>& signals) {
void convert(PyObject* o, int& v) { v = (int)PyLong_AsLong(o); }
void convert(PyObject* o, float& v) { v = (float)PyFloat_AS_DOUBLE(o); }
void convert(PyObject* o, double& v) { v = PyFloat_AS_DOUBLE(o); }
void convert(PyObject* o, Vector& v) {
v.resize(PyTuple_Size(o));
for (int i = 0; i < v.size(); ++i) convert(PyTuple_GetItem(o, i), v[i]);
}
} // namespace signalWrapper
PythonSignalContainer::PythonSignalContainer(const std::string& name) : Entity(name) {
std::string docstring;
docstring =
" \n"
" Remove a signal\n"
" \n"
" Input:\n"
" - name of the signal\n"
" \n";
addCommand("rmSignal", command::makeCommandVoid1(*this, &PythonSignalContainer::rmSignal, docstring));
}
void PythonSignalContainer::signalRegistration(const SignalArray<int>& signals) {
Entity::signalRegistration(signals); Entity::signalRegistration(signals);
} }
void PythonSignalContainer::rmSignal(const std::string& name) { Entity::signalDeregistration(name); } void PythonSignalContainer::rmSignal(const std::string& name) {
Entity::signalDeregistration(name);
}
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(PythonSignalContainer, "PythonSignalContainer"); DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(PythonSignalContainer,
"PythonSignalContainer");
template <class T, class Time> template <class T, class Time>
bool SignalWrapper<T, Time>::checkCallable(PyObject* c, std::string& error) { bool SignalWrapper<T, Time>::checkCallable(pyobject c, std::string& error) {
if (PyCallable_Check(c) == 0) { if (PyCallable_Check(c.ptr()) == 0) {
PyObject* str = PyObject_Str(c); error = boost::python::extract<std::string>(c.attr("__str__")());
error = obj_to_str(str);
error += " is not callable"; error += " is not callable";
Py_DECREF(str);
return false; return false;
} }
return true; return true;
......
""" # Copyright (C) 2020 CNRS
Copyright (C) 2010 CNRS #
# Author: Joseph Mirabel
Author: Florent Lamiraux
"""
from __future__ import print_function from __future__ import print_function
# I kept what follows for backward compatibility but I think it should be
# removed
import re import re
from .wrap import (create_signal_wrapper, signal_base_display, signal_base_display_dependencies, from .wrap import SignalBase # noqa
signal_base_get_class_name, signal_base_get_name, signal_base_get_time, signal_base_get_value, from .wrap import create_signal_wrapper as SignalWrapper # noqa
signal_base_getPlugged, signal_base_isPlugged, signal_base_recompute, signal_base_set_time,
signal_base_set_value, signal_base_unplug)
def stringToTuple(vector): def stringToTuple(vector):
...@@ -19,17 +17,22 @@ def stringToTuple(vector): ...@@ -19,17 +17,22 @@ def stringToTuple(vector):
Transform a string of format '[n](x_1,x_2,...,x_n)' into a tuple of numbers. Transform a string of format '[n](x_1,x_2,...,x_n)' into a tuple of numbers.
""" """
# Find vector length # Find vector length
a = re.match(r'\[(\d+)\]', vector) a = re.match(r"\[(\d+)\]", vector)
size = int(a.group(1)) size = int(a.group(1))
# remove '[n]' prefix # remove '[n]' prefix
vector = vector[len(a.group(0)):] vector = vector[len(a.group(0)) :]
# remove '(' and ')' at beginning and end # remove '(' and ')' at beginning and end
vector = vector.lstrip('(').rstrip(')\n') vector = vector.lstrip("(").rstrip(")\n")
# split string by ',' # split string by ','
vector = vector.split(',') vector = vector.split(",")
# check size # check size
if len(vector) != size: if len(vector) != size:
raise TypeError('displayed size ' + str(size) + ' of vector does not fit actual size: ' + str(len(vector))) raise TypeError(
"displayed size "
+ str(size)
+ " of vector does not fit actual size: "
+ str(len(vector))
)
res = map(float, vector) res = map(float, vector)
return tuple(res) return tuple(res)
...@@ -39,10 +42,10 @@ def tupleToString(vector): ...@@ -39,10 +42,10 @@ def tupleToString(vector):
Transform a tuple of numbers into a string of format Transform a tuple of numbers into a string of format
'[n](x_1, x_2, ..., x_n)' '[n](x_1, x_2, ..., x_n)'
""" """
string = '[%d](' % len(vector) string = "[%d](" % len(vector)
for x in vector[:-1]: for x in vector[:-1]:
string += '%f,' % x string += "%f," % x
string += '%f)' % vector[-1] string += "%f)" % vector[-1]
return string return string
...@@ -53,20 +56,30 @@ def stringToMatrix(string): ...@@ -53,20 +56,30 @@ def stringToMatrix(string):
of tuple of numbers. of tuple of numbers.
""" """
# Find matrix size # Find matrix size
a = re.search(r'\[(\d+),(\d+)]', string) a = re.search(r"\[(\d+),(\d+)]", string)
nRows = int(a.group(1)) nRows = int(a.group(1))
nCols = int(a.group(2)) nCols = int(a.group(2))
# Remove '[n,m]' prefix # Remove '[n,m]' prefix
string = string[len(a.group(0)):] string = string[len(a.group(0)) :]
rows = string.split('),(') rows = string.split("),(")
if len(rows) != nRows: if len(rows) != nRows:
raise TypeError('displayed nb rows ' + nRows + ' of matrix does not fit actual nb rows: ' + str(len(rows))) raise TypeError(
"displayed nb rows "
+ nRows
+ " of matrix does not fit actual nb rows: "
+ str(len(rows))
)
m = [] m = []
for rstr in rows: for rstr in rows:
rstr = rstr.lstrip('(').rstrip(')\n') rstr = rstr.lstrip("(").rstrip(")\n")
r = map(float, rstr.split(',')) r = map(float, rstr.split(","))
if len(r) != nCols: if len(r) != nCols:
raise TypeError('one row length ' + len(r) + ' of matrix does not fit displayed nb cols: ' + nCols) raise TypeError(
"one row length "
+ len(r)
+ " of matrix does not fit displayed nb cols: "
+ nCols
)
m.append(tuple(r)) m.append(tuple(r))
return tuple(m) return tuple(m)
...@@ -78,19 +91,19 @@ def matrixToString(matrix): ...@@ -78,19 +91,19 @@ def matrixToString(matrix):
""" """
nRows = len(matrix) nRows = len(matrix)
if nRows == 0: if nRows == 0:
return '[0,0](())' return "[0,0](())"
nCols = len(matrix[0]) nCols = len(matrix[0])
string = '[%d,%d](' % (nRows, nCols) string = "[%d,%d](" % (nRows, nCols)
for r in range(nRows): for r in range(nRows):
string += '(' string += "("
for c in range(nCols): for c in range(nCols):
string += str(float(matrix[r][c])) string += str(float(matrix[r][c]))
if c != nCols - 1: if c != nCols - 1:
string += ',' string += ","
string += ')' string += ")"
if r != nRows - 1: if r != nRows - 1:
string += ',' string += ","
string += ')' string += ")"
return string return string
...@@ -104,18 +117,18 @@ def objectToString(obj): ...@@ -104,18 +117,18 @@ def objectToString(obj):
- an integer, - an integer,
- a boolean, - a boolean,
""" """
if (hasattr(obj, "__iter__")): if hasattr(obj, "__iter__"):
# matrix or vector # matrix or vector
if len(obj) == 0: if len(obj) == 0:
return "" return ""
else: else:
if (hasattr(obj[0], "__iter__")): if hasattr(obj[0], "__iter__"):
# matrix # matrix
return matrixToString(obj) return matrixToString(obj)
else: else:
# vector # vector
return tupleToString(obj) return tupleToString(obj)
elif hasattr(obj, 'name'): elif hasattr(obj, "name"):
return obj.name return obj.name
else: else:
return str(obj) return str(obj)
...@@ -153,136 +166,3 @@ def stringToObject(string): ...@@ -153,136 +166,3 @@ def stringToObject(string):
return float(string) return float(string)
except Exception: except Exception:
return string return string
class SignalBase(object):
"""
This class binds dynamicgraph::SignalBase<int> C++ class
"""
obj = None
def __init__(self, name="", obj=None):
"""
Constructor: if not called by a child class, create and store a pointer
to a C++ SignalBase<int> object.
"""
if obj:
self.obj = obj
else:
raise RuntimeError("A pointer is required to create SignalBase object.")
if obj is None:
self.className = self.getClassName()
self.name = self.getName()
@property
def time(self):
"""
Get time of signal
"""
return signal_base_get_time(self.obj)
@time.setter
def time(self, val):
"""
Set Time of signal
Input:
- an integer
"""
return signal_base_set_time(self.obj, val)
@property
def value(self):
"""
Setter and getter for the value of a signal
Binds C++ SignalBase<int>::get() and set() methods. Values are passed
through string streams.
A string is interpreted as respectively:
* a matrix (tuple of tuple) if string fits '[n,m]((x_11,x_12,...,x_1m),...,(x_n1,x_n2,...,x_nm))' format where
n and m are integers, x_ij are floating point numbers,
* a tuple if string fits '[n](x_1, x_2, ..., x_n)' format,
* an integer,
* a floating point number.
If string fits none of the above formats, no conversion is performed.
For instance, is s binds a signal of type vector,
>>> s.value = (2.5, .1, 1e2)
will call SignalBase<int>::set("[3](2.5,0.1,100.0)") and
>>> s.value
(2.5, 0.1, 100.0)
"""
string = signal_base_get_value(self.obj)
return stringToObject(string)
@value.setter
def value(self, val):
"""
Set the signal as a constant signal with given value.
If the signal is plugged, it will be unplugged
"""
string = objectToString(val)
return signal_base_set_value(self.obj, string)
def getName(self):
"""
Get name of signal
"""
return signal_base_get_name(self.obj)
@property
def name(self):
"""
Get name of signal
"""
return signal_base_get_name(self.obj)
def getClassName(self):
"""
Get class name of signal
"""
return signal_base_get_class_name(self.obj)
def recompute(self, time):
"""
Force signal to recompute the value at given time.
"""
return signal_base_recompute(self.obj, time)
def unplug(self):
"""
Unplug a PTR signal.
"""
return signal_base_unplug(self.obj)
def isPlugged(self):
"""
Return whether a signal is plugged.
"""
return signal_base_isPlugged(self.obj)
def getPlugged(self):
"""
Return the plugged signal.
"""
return SignalBase(obj=signal_base_getPlugged(self.obj))
def __str__(self):
"""
Print signal in a string
"""
return signal_base_display(self.obj)
def displayDependencies(self, iter):
"""
Print signal dependencies in a string
"""
return (signal_base_display_dependencies(self.obj, iter))
class SignalWrapper(SignalBase):
def __init__(self, name, type, func):
super(SignalWrapper, self).__init__(name, create_signal_wrapper(name, type, func))
...@@ -8,8 +8,8 @@ def addTrace(robot, trace, entityName, signalName, autoRecompute=True): ...@@ -8,8 +8,8 @@ def addTrace(robot, trace, entityName, signalName, autoRecompute=True):
""" """
Add a signal to a tracer and recompute it automatically if necessary. Add a signal to a tracer and recompute it automatically if necessary.
""" """
signal = '{0}.{1}'.format(entityName, signalName) signal = "{0}.{1}".format(entityName, signalName)
filename = '{0}-{1}'.format(entityName, signalName) filename = "{0}-{1}".format(entityName, signalName).replace("/", "_")
trace.add(signal, filename) trace.add(signal, filename)
if autoRecompute: if autoRecompute:
robot.device.after.addSignal(signal) robot.device.after.addSignal(signal)
#include <dynamic-graph/tracer.h>
#include "dynamic-graph/python/module.hh"
BOOST_PYTHON_MODULE(wrap) {
using dynamicgraph::Tracer;
bp::import("dynamic_graph");
dynamicgraph::python::exposeEntity<Tracer>().def("addSignal",
&Tracer::addSignalToTrace);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.