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

Target

Select target project
  • ostasse/dynamic-graph-python
  • gsaurel/dynamic-graph-python
  • stack-of-tasks/dynamic-graph-python
3 results
Show changes
Showing
with 391 additions and 278 deletions
[tool.black]
exclude = "cmake"
extend-exclude = "tests/test_python-syntax_error.py"
[flake8]
exclude = cmake,tests/test_python-syntax_error.py
max-line-length = 88
ignore = E226, E704, E24, E121, W504, E126, E123, W503, E203
# Python bindings # Python bindings
ADD_SUBDIRECTORY(dynamic_graph) add_subdirectory(dynamic_graph)
SET(PYTHON_SOURCES set(PYTHON_SOURCES __init__.py attrpath.py entity.py signal_base.py
__init__.py script_shortcuts.py tools.py)
attrpath.py
entity.py
signal_base.py
script_shortcuts.py
tools.py
)
FOREACH(source ${PYTHON_SOURCES}) foreach(source ${PYTHON_SOURCES})
PYTHON_INSTALL_ON_SITE(dynamic_graph ${source}) python_install_on_site(dynamic_graph ${source})
ENDFOREACH(source) endforeach(source)
# --- ADD the wrap on the dg modules # --- ADD the wrap on the dg modules
LINK_DIRECTORIES(${DYNAMIC_GRAPH_PLUGINDIR}) link_directories(${DYNAMIC_GRAPH_PLUGINDIR})
DYNAMIC_GRAPH_PYTHON_MODULE("tracer" dynamic-graph::tracer tracer-wrap dynamic_graph_python_module(
SOURCE_PYTHON_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer/wrap.cc) "tracer" dynamic-graph::tracer tracer-wrap SOURCE_PYTHON_MODULE
DYNAMIC_GRAPH_PYTHON_MODULE("tracer_real_time" dynamic-graph::tracer-real-time tracer_real_time-wrap ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer/wrap.cc)
SOURCE_PYTHON_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer_real_time/wrap.cc) dynamic_graph_python_module(
"tracer_real_time" dynamic-graph::tracer-real-time tracer_real_time-wrap
SOURCE_PYTHON_MODULE
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer_real_time/wrap.cc)
# Copyright 2010-2020, Florent Lamiraux, Thomas Moulard, Olivier Stasse, Guilhem Saurel, JRL, CNRS/AIST, LAAS-CNRS # Copyright 2010-2021, Florent Lamiraux, Thomas Moulard, Olivier Stasse, Guilhem
# Saurel, JRL, CNRS/AIST, LAAS-CNRS
SET(PYTHON_MODULE wrap) set(PYTHON_MODULE wrap)
ADD_LIBRARY(${PYTHON_MODULE} MODULE add_library(
debug-py.cc ${PYTHON_MODULE} MODULE debug-py.cc dynamic-graph-py.cc factory-py.cc
dynamic-graph-py.cc pool-py.cc signal-base-py.cc signal-wrapper.cc)
factory-py.cc
pool-py.cc
signal-base-py.cc
signal-wrapper.cc
)
TARGET_LINK_LIBRARIES(${PYTHON_MODULE} PUBLIC ${PROJECT_NAME} eigenpy::eigenpy) target_link_libraries(${PYTHON_MODULE} PUBLIC ${PROJECT_NAME} eigenpy::eigenpy)
TARGET_LINK_BOOST_PYTHON(${PYTHON_MODULE} PRIVATE)
# Remove prefix lib # Remove prefix lib
SET_TARGET_PROPERTIES(${PYTHON_MODULE} PROPERTIES PREFIX "") set_target_properties(${PYTHON_MODULE} PROPERTIES PREFIX "")
INSTALL(TARGETS ${PYTHON_MODULE} if(UNIX AND NOT APPLE)
set_target_properties(${PYTHON_MODULE} PROPERTIES INSTALL_RPATH
"\$ORIGIN/../../..")
endif()
install(
TARGETS ${PYTHON_MODULE}
EXPORT ${TARGETS_EXPORT_NAME} EXPORT ${TARGETS_EXPORT_NAME}
DESTINATION ${PYTHON_SITELIB}/dynamic_graph) DESTINATION ${PYTHON_SITELIB}/dynamic_graph)
...@@ -5,9 +5,6 @@ Author: Florent Lamiraux ...@@ -5,9 +5,6 @@ Author: Florent Lamiraux
from __future__ import print_function from __future__ import print_function
import sys
from . import entity # noqa from . import entity # noqa
from . import signal_base # noqa from . import signal_base # noqa
from .wrap import * # noqa from .wrap import * # noqa
...@@ -18,10 +18,11 @@ class CommandPath(object): ...@@ -18,10 +18,11 @@ class CommandPath(object):
to store entity commands. It has no members except those automatically to store entity commands. It has no members except those automatically
defined at run time (which should be CommandPath or functions). defined at run time (which should be CommandPath or functions).
""" """
mother = None mother = None
def __getattr__(self, name): def __getattr__(self, name):
privateName = name + '_obj' privateName = name + "_obj"
if privateName in self.__dict__: if privateName in self.__dict__:
obj = getattr(self, privateName) obj = getattr(self, privateName)
obj.mother = self.mother obj.mother = self.mother
...@@ -38,7 +39,7 @@ def createCommandModule(target, name): ...@@ -38,7 +39,7 @@ def createCommandModule(target, name):
return __ return __
privateName = name + '_obj' privateName = name + "_obj"
setattr(target, privateName, CommandPath()) setattr(target, privateName, CommandPath())
if not isinstance(target, CommandPath): if not isinstance(target, CommandPath):
...@@ -46,8 +47,8 @@ def createCommandModule(target, name): ...@@ -46,8 +47,8 @@ def createCommandModule(target, name):
class CommandLauncher(object): class CommandLauncher(object):
""" """ """
"""
mother = None mother = None
fun = None fun = None
...@@ -60,7 +61,7 @@ class CommandLauncher(object): ...@@ -60,7 +61,7 @@ class CommandLauncher(object):
def createCommandLauncher(target, name, fun): def createCommandLauncher(target, name, fun):
if isinstance(target, CommandPath): if isinstance(target, CommandPath):
privateName = name + '_obj' privateName = name + "_obj"
setattr(target, privateName, CommandLauncher(fun)) setattr(target, privateName, CommandLauncher(fun))
else: else:
setattr(target, name, fun) setattr(target, name, fun)
...@@ -74,7 +75,7 @@ def setattrpath(target, path, attribute): ...@@ -74,7 +75,7 @@ def setattrpath(target, path, attribute):
pathk = target pathk = target
read = True read = True
if isinstance(path, str): if isinstance(path, str):
path = path.split('.') path = path.split(".")
for tokenk in path[0:-1]: for tokenk in path[0:-1]:
if (not read) | (tokenk not in pathk.__dict__): if (not read) | (tokenk not in pathk.__dict__):
read = False read = False
...@@ -94,7 +95,7 @@ def getattrpath(target, path): ...@@ -94,7 +95,7 @@ def getattrpath(target, path):
""" """
pathk = target pathk = target
if isinstance(path, str): if isinstance(path, str):
path = path.split('.') path = path.split(".")
for tokenk in path: for tokenk in path:
privateName = tokenk + "_obj" privateName = tokenk + "_obj"
if hasattr(pathk, privateName): if hasattr(pathk, privateName):
...@@ -103,7 +104,12 @@ def getattrpath(target, path): ...@@ -103,7 +104,12 @@ def getattrpath(target, path):
if hasattr(pathk, tokenk): if hasattr(pathk, tokenk):
pathk = getattr(pathk, tokenk) pathk = getattr(pathk, tokenk)
else: else:
raise Exception('Path does not exist -- while accessing "' + tokenk + '" in ' + '.'.join(path)) raise Exception(
'Path does not exist -- while accessing "'
+ tokenk
+ '" in '
+ ".".join(path)
)
return pathk return pathk
...@@ -114,11 +120,11 @@ def existattrpath(target, path): ...@@ -114,11 +120,11 @@ def existattrpath(target, path):
""" """
pathk = target pathk = target
if isinstance(path, str): if isinstance(path, str):
path = path.split('.') path = path.split(".")
for tokenk in path[0:-1]: for tokenk in path[0:-1]:
print('check ', tokenk) print("check ", tokenk)
privateName = tokenk + "_obj" privateName = tokenk + "_obj"
if (privateName not in pathk.__dict__): if privateName not in pathk.__dict__:
return False return False
pathk = getattr(pathk, privateName) pathk = getattr(pathk, privateName)
name = path[-1] name = path[-1]
......
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS. // Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <iostream> #include "dynamic-graph/python/convert-dg-to-py.hh"
#include <sstream>
#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <dynamic-graph/signal-base.h> #include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/signal-caster.h> #include <dynamic-graph/signal-caster.h>
#include <dynamic-graph/signal.h>
#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <iostream>
#include <sstream>
#include "dynamic-graph/python/convert-dg-to-py.hh"
#include "dynamic-graph/python/python-compat.hh" #include "dynamic-graph/python/python-compat.hh"
namespace dynamicgraph { namespace dynamicgraph {
...@@ -51,7 +51,8 @@ command::Value toValue(bp::object o, const command::Value::Type& valueType) { ...@@ -51,7 +51,8 @@ command::Value toValue(bp::object o, const command::Value::Type& valueType) {
// TODO the vector of values cannot be built since // TODO the vector of values cannot be built since
// - the value type inside the vector are not know // - the value type inside the vector are not know
// - inferring the value type from the Python type is not implemented. // - inferring the value type from the Python type is not implemented.
throw std::invalid_argument("not implemented: cannot create a vector of values"); throw std::invalid_argument(
"not implemented: cannot create a vector of values");
break; break;
default: default:
std::cerr << "Only int, double and string are supported." << std::endl; std::cerr << "Only int, double and string are supported." << std::endl;
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
#include <iostream> #include <iostream>
#define ENABLE_RT_LOG #define ENABLE_RT_LOG
#include <dynamic-graph/entity.h>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/real-time-logger.h> #include <dynamic-graph/real-time-logger.h>
#include <boost/shared_ptr.hpp>
#include <map> #include <map>
#include <dynamic-graph/pool.h>
#include <dynamic-graph/entity.h>
#include <vector> #include <vector>
#include <boost/shared_ptr.hpp>
#include "dynamic-graph/python/dynamic-graph-py.hh" #include "dynamic-graph/python/dynamic-graph-py.hh"
typedef boost::shared_ptr<std::ofstream> ofstreamShrPtr; typedef boost::shared_ptr<std::ofstream> ofstreamShrPtr;
......
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS. // Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <iostream> #include "dynamic-graph/python/dynamic-graph-py.hh"
#include <sstream>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <eigenpy/eigenpy.hpp>
#include <Eigen/Geometry>
#include <eigenpy/geometry.hpp>
#include <dynamic-graph/command.h>
#include <dynamic-graph/debug.h> #include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
#include <dynamic-graph/command.h> #include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
#include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/tracer.h> #include <dynamic-graph/tracer.h>
#include "dynamic-graph/python/dynamic-graph-py.hh" #include <Eigen/Geometry>
#include "dynamic-graph/python/signal-wrapper.hh" #include <boost/python.hpp>
#include <boost/python/raw_function.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <eigenpy/eigenpy.hpp>
#include <eigenpy/geometry.hpp>
#include <iostream>
#include <sstream>
#include "dynamic-graph/python/convert-dg-to-py.hh" #include "dynamic-graph/python/convert-dg-to-py.hh"
#include "dynamic-graph/python/module.hh" #include "dynamic-graph/python/module.hh"
#include "dynamic-graph/python/signal-wrapper.hh"
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
...@@ -33,7 +32,9 @@ namespace python { ...@@ -33,7 +32,9 @@ namespace python {
/** /**
\brief plug a signal into another one. \brief plug a signal into another one.
*/ */
void plug(SignalBase<int>* signalOut, SignalBase<int>* signalIn) { signalIn->plug(signalOut); } void plug(SignalBase<int>* signalOut, SignalBase<int>* signalIn) {
signalIn->plug(signalOut);
}
void enableTrace(bool enable, const char* filename) { void enableTrace(bool enable, const char* filename) {
if (enable) if (enable)
...@@ -49,7 +50,8 @@ namespace bp = boost::python; ...@@ -49,7 +50,8 @@ namespace bp = boost::python;
namespace dg = dynamicgraph; namespace dg = dynamicgraph;
typedef bp::return_value_policy<bp::manage_new_object> manage_new_object; typedef bp::return_value_policy<bp::manage_new_object> manage_new_object;
typedef bp::return_value_policy<bp::reference_existing_object> reference_existing_object; typedef bp::return_value_policy<bp::reference_existing_object>
reference_existing_object;
typedef dg::PoolStorage::Entities MapOfEntities; typedef dg::PoolStorage::Entities MapOfEntities;
...@@ -59,9 +61,14 @@ struct MapOfEntitiesPairToPythonConverter { ...@@ -59,9 +61,14 @@ struct MapOfEntitiesPairToPythonConverter {
} }
}; };
MapOfEntities* getEntityMap() { return const_cast<MapOfEntities*>(&dg::PoolStorage::getInstance()->getEntityMap()); } MapOfEntities* getEntityMap() {
return const_cast<MapOfEntities*>(
&dg::PoolStorage::getInstance()->getEntityMap());
}
dg::SignalBase<int>* getSignal(dg::Entity& e, const std::string& name) { return &e.getSignal(name); } dg::SignalBase<int>* getSignal(dg::Entity& e, const std::string& name) {
return &e.getSignal(name);
}
class PythonEntity : public dg::Entity { class PythonEntity : public dg::Entity {
DYNAMIC_GRAPH_ENTITY_DECL(); DYNAMIC_GRAPH_ENTITY_DECL();
...@@ -69,8 +76,12 @@ class PythonEntity : public dg::Entity { ...@@ -69,8 +76,12 @@ class PythonEntity : public dg::Entity {
public: public:
using dg::Entity::Entity; using dg::Entity::Entity;
void signalRegistration(dg::SignalBase<int>& signal) { dg::Entity::signalRegistration(signal); } void signalRegistration(dg::SignalBase<int>& signal) {
void signalDeregistration(const std::string& name) { dg::Entity::signalDeregistration(name); } dg::Entity::signalRegistration(signal);
}
void signalDeregistration(const std::string& name) {
dg::Entity::signalDeregistration(name);
}
}; };
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(PythonEntity, "PythonEntity"); DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(PythonEntity, "PythonEntity");
...@@ -86,57 +97,73 @@ void exposeEntityBase() { ...@@ -86,57 +97,73 @@ void exposeEntityBase() {
.export_values(); .export_values();
bp::class_<Entity, boost::noncopyable>("Entity", bp::no_init) bp::class_<Entity, boost::noncopyable>("Entity", bp::no_init)
.add_property("name", bp::make_function(&Entity::getName, bp::return_value_policy<bp::copy_const_reference>())) .add_property("name",
bp::make_function(
&Entity::getName,
bp::return_value_policy<bp::copy_const_reference>()))
.add_property("className", .add_property("className",
bp::make_function(&Entity::getClassName, bp::return_value_policy<bp::copy_const_reference>()), bp::make_function(
&Entity::getClassName,
bp::return_value_policy<bp::copy_const_reference>()),
"the class name of the Entity") "the class name of the Entity")
.add_property("__doc__", &Entity::getDocString) .add_property("__doc__", &Entity::getDocString)
.def("setLoggerVerbosityLevel", &Entity::setLoggerVerbosityLevel) .def("setLoggerVerbosityLevel", &Entity::setLoggerVerbosityLevel)
.def("getLoggerVerbosityLevel", &Entity::getLoggerVerbosityLevel) .def("getLoggerVerbosityLevel", &Entity::getLoggerVerbosityLevel)
.add_property("loggerVerbosityLevel", &Entity::setLoggerVerbosityLevel, &Entity::getLoggerVerbosityLevel, .add_property("loggerVerbosityLevel", &Entity::setLoggerVerbosityLevel,
&Entity::getLoggerVerbosityLevel,
"the verbosity level of the entity") "the verbosity level of the entity")
.def("setTimeSample", &Entity::setTimeSample) .def("setTimeSample", &Entity::setTimeSample)
.def("getTimeSample", &Entity::getTimeSample) .def("getTimeSample", &Entity::getTimeSample)
.add_property("timeSample", &Entity::getTimeSample, &Entity::setTimeSample, .add_property("timeSample", &Entity::getTimeSample,
&Entity::setTimeSample,
"the time sample for printing debugging information") "the time sample for printing debugging information")
.def("setStreamPrintPeriod", &Entity::setStreamPrintPeriod) .def("setStreamPrintPeriod", &Entity::setStreamPrintPeriod)
.def("getStreamPrintPeriod", &Entity::getStreamPrintPeriod) .def("getStreamPrintPeriod", &Entity::getStreamPrintPeriod)
.add_property("streamPrintPeriod", &Entity::getStreamPrintPeriod, &Entity::setStreamPrintPeriod, .add_property("streamPrintPeriod", &Entity::getStreamPrintPeriod,
&Entity::setStreamPrintPeriod,
"set the period at which debugging information are printed") "set the period at which debugging information are printed")
.def("__str__", .def(
+[](const Entity& e) -> std::string { "__str__",
std::ostringstream os; +[](const Entity& e) -> std::string {
e.display(os); std::ostringstream os;
return os.str(); e.display(os);
}) return os.str();
.def("signals", })
+[](const Entity& e) -> bp::list { .def(
bp::list ret; "signals",
for (auto& el : e.getSignalMap()) ret.append(bp::ptr(el.second)); +[](const Entity& e) -> bp::list {
return ret; bp::list ret;
}, for (auto& el : e.getSignalMap()) ret.append(bp::ptr(el.second));
"Return the list of signals.") return ret;
//.def("signal", +[](Entity& e, const std::string &name) { return &e.getSignal(name); }, },
"Return the list of signals.")
//.def("signal", +[](Entity& e, const std::string &name) { return
//&e.getSignal(name); },
// reference_existing_object()) // reference_existing_object())
.def("signal", &getSignal, reference_existing_object(), "get signal by name from an Entity", bp::arg("name")) .def("signal", &getSignal, reference_existing_object(),
.def("hasSignal", &Entity::hasSignal, "return True if the entity has a signal with the given name") "get signal by name from an Entity", bp::arg("name"))
.def("hasSignal", &Entity::hasSignal,
.def("displaySignals", "return True if the entity has a signal with the given name")
+[](const Entity& e) {
Entity::SignalMap signals(e.getSignalMap()); .def(
std::cout << "--- <" << e.getName(); "displaySignals",
if (signals.empty()) +[](const Entity& e) {
std::cout << "> has no signal\n"; Entity::SignalMap signals(e.getSignalMap());
else std::cout << "--- <" << e.getName();
std::cout << "> signal list:\n"; if (signals.empty())
for (const auto& el : signals) el.second->display(std::cout << " |-- <") << '\n'; std::cout << "> has no signal\n";
}, else
"Print the list of signals into standard output: temporary.") std::cout << "> signal list:\n";
for (const auto& el : signals)
el.second->display(std::cout << " |-- <") << '\n';
},
"Print the list of signals into standard output: temporary.")
/* /*
.def("__getattr__", +[](Entity& e, const std::string &name) -> SignalBase<int>* { return &e.getSignal(name); }, .def("__getattr__", +[](Entity& e, const std::string &name) ->
SignalBase<int>* { return &e.getSignal(name); },
reference_existing_object()) reference_existing_object())
def __getattr__(self, name): def __getattr__(self, name):
try: try:
...@@ -145,16 +172,16 @@ void exposeEntityBase() { ...@@ -145,16 +172,16 @@ void exposeEntityBase() {
try: try:
object.__getattr__(self, name) object.__getattr__(self, name)
except AttributeError: except AttributeError:
raise AttributeError("'%s' entity has no attribute %s\n" % (self.name, name) + raise AttributeError("'%s' entity has no attribute %s\n" %
' entity attributes are usually either\n' + ' - commands,\n' + (self.name, name) + ' entity attributes are usually either\n' + ' -
' - signals or,\n' + ' - user defined attributes') commands,\n' + ' - signals or,\n' + ' - user defined attributes')
*/ */
/* /*
.def("__setattr__", +[](bp::object self, const std::string &name, bp::object value) { .def("__setattr__", +[](bp::object self, const std::string &name,
Entity& e = bp::extract<Entity&> (self); bp::object value) { Entity& e = bp::extract<Entity&> (self); if
if (e.hasSignal(name)) (e.hasSignal(name)) throw std::invalid_argument(name + " already
throw std::invalid_argument(name + " already designates a signal. " designates a signal. " "It is not advised to set a new attribute of the
"It is not advised to set a new attribute of the same name."); same name.");
// TODO How do you do that ? I am sure it is possible. // TODO How do you do that ? I am sure it is possible.
//object.__setattr__(self, name, value) //object.__setattr__(self, name, value)
}) })
...@@ -163,66 +190,85 @@ void exposeEntityBase() { ...@@ -163,66 +190,85 @@ void exposeEntityBase() {
/* TODO ? /* TODO ?
def boundNewCommand(self, cmdName): def boundNewCommand(self, cmdName):
""" """
At construction, all existing commands are bound directly in the class. At construction, all existing commands are bound directly in the
This method enables to bound new commands dynamically. These new bounds class. This method enables to bound new commands dynamically. These new
are not made with the class, but directly with the object instance. bounds are not made with the class, but directly with the object instance.
""" """
def boundAllNewCommands(self): def boundAllNewCommands(self):
""" """
For all commands that are not attribute of the object instance nor of the For all commands that are not attribute of the object instance nor of
class, a new attribute of the instance is created to bound the command. the class, a new attribute of the instance is created to bound the
command.
""" """
*/ */
// For backward compat // For backward compat
.add_static_property("entities", bp::make_function(&getEntityMap, reference_existing_object())); .add_static_property(
"entities",
bp::make_function(&getEntityMap, reference_existing_object()));
python::exposeEntity<PythonEntity, bp::bases<Entity>, 0>() python::exposeEntity<PythonEntity, bp::bases<Entity>, 0>()
.def("signalRegistration", &PythonEntity::signalRegistration) .def("signalRegistration", &PythonEntity::signalRegistration)
.def("signalDeregistration", &PythonEntity::signalDeregistration); .def("signalDeregistration", &PythonEntity::signalDeregistration);
python::exposeEntity<python::PythonSignalContainer, bp::bases<Entity>, 0>().def( python::exposeEntity<python::PythonSignalContainer, bp::bases<Entity>, 0>()
"rmSignal", &python::PythonSignalContainer::rmSignal, "Remove a signal", bp::arg("signal_name")); .def("rmSignal", &python::PythonSignalContainer::rmSignal,
"Remove a signal", bp::arg("signal_name"));
} }
void exposeCommand() { void exposeCommand() {
using dg::command::Command; using dg::command::Command;
bp::class_<Command, boost::noncopyable>("Command", bp::no_init) bp::class_<Command, boost::noncopyable>("Command", bp::no_init)
.def("__call__", bp::raw_function(dg::python::entity::executeCmd, 1), "execute the command") .def("__call__", bp::raw_function(dg::python::entity::executeCmd, 1),
"execute the command")
.add_property("__doc__", &Command::getDocstring); .add_property("__doc__", &Command::getDocstring);
} }
void exposeOldAPI() { void exposeOldAPI() {
bp::def("plug", dynamicgraph::python::plug, "plug an output signal into an input signal", bp::def("plug", dynamicgraph::python::plug,
"plug an output signal into an input signal",
(bp::arg("signalOut"), "signalIn")); (bp::arg("signalOut"), "signalIn"));
bp::def("enableTrace", dynamicgraph::python::enableTrace, "Enable or disable tracing debug info in a file"); bp::def("enableTrace", dynamicgraph::python::enableTrace,
"Enable or disable tracing debug info in a file");
// Signals // Signals
bp::def("create_signal_wrapper", dynamicgraph::python::signalBase::createSignalWrapper, reference_existing_object(), bp::def("create_signal_wrapper",
"create a SignalWrapper C++ object"); dynamicgraph::python::signalBase::createSignalWrapper,
reference_existing_object(), "create a SignalWrapper C++ object");
// Entity // Entity
bp::def("factory_get_entity_class_list", dynamicgraph::python::factory::getEntityClassList, bp::def("factory_get_entity_class_list",
dynamicgraph::python::factory::getEntityClassList,
"return the list of entity classes"); "return the list of entity classes");
bp::def("writeGraph", dynamicgraph::python::pool::writeGraph, "Write the graph of entities in a filename."); bp::def("writeGraph", dynamicgraph::python::pool::writeGraph,
bp::def("get_entity_list", dynamicgraph::python::pool::getEntityList, "return the list of instanciated entities"); "Write the graph of entities in a filename.");
bp::def("addLoggerFileOutputStream", dynamicgraph::python::debug::addLoggerFileOutputStream, bp::def("get_entity_list", dynamicgraph::python::pool::getEntityList,
"return the list of instanciated entities");
bp::def("addLoggerFileOutputStream",
dynamicgraph::python::debug::addLoggerFileOutputStream,
"add a output file stream to the logger by filename"); "add a output file stream to the logger by filename");
bp::def("addLoggerCoutOutputStream", dynamicgraph::python::debug::addLoggerCoutOutputStream, bp::def("addLoggerCoutOutputStream",
dynamicgraph::python::debug::addLoggerCoutOutputStream,
"add std::cout as output stream to the logger"); "add std::cout as output stream to the logger");
bp::def("closeLoggerFileOutputStream", dynamicgraph::python::debug::closeLoggerFileOutputStream, bp::def("closeLoggerFileOutputStream",
dynamicgraph::python::debug::closeLoggerFileOutputStream,
"close all the loggers file output streams."); "close all the loggers file output streams.");
bp::def("real_time_logger_destroy", dynamicgraph::python::debug::realTimeLoggerDestroy, bp::def("real_time_logger_destroy",
dynamicgraph::python::debug::realTimeLoggerDestroy,
"Destroy the real time logger."); "Destroy the real time logger.");
bp::def("real_time_logger_spin_once", dynamicgraph::python::debug::realTimeLoggerSpinOnce, bp::def("real_time_logger_spin_once",
dynamicgraph::python::debug::realTimeLoggerSpinOnce,
"Destroy the real time logger."); "Destroy the real time logger.");
bp::def("real_time_logger_instance", dynamicgraph::python::debug::realTimeLoggerInstance, bp::def("real_time_logger_instance",
dynamicgraph::python::debug::realTimeLoggerInstance,
"Starts the real time logger."); "Starts the real time logger.");
} }
void enableEigenPy() { void enableEigenPy() {
eigenpy::enableEigenPy(); eigenpy::enableEigenPy();
if (!eigenpy::register_symbolic_link_to_registered_type<Eigen::Quaterniond>()) eigenpy::exposeQuaternion(); if (!eigenpy::register_symbolic_link_to_registered_type<Eigen::Quaterniond>())
if (!eigenpy::register_symbolic_link_to_registered_type<Eigen::AngleAxisd>()) eigenpy::exposeAngleAxis(); eigenpy::exposeQuaternion();
if (!eigenpy::register_symbolic_link_to_registered_type<Eigen::AngleAxisd>())
eigenpy::exposeAngleAxis();
eigenpy::enableEigenPySpecific<Eigen::Matrix4d>(); eigenpy::enableEigenPySpecific<Eigen::Matrix4d>();
} }
...@@ -239,22 +285,33 @@ BOOST_PYTHON_MODULE(wrap) { ...@@ -239,22 +285,33 @@ BOOST_PYTHON_MODULE(wrap) {
typedef dg::PoolStorage::Entities MapOfEntities; typedef dg::PoolStorage::Entities MapOfEntities;
bp::class_<MapOfEntities>("MapOfEntities") bp::class_<MapOfEntities>("MapOfEntities")
.def("__len__", &MapOfEntities::size) .def("__len__", &MapOfEntities::size)
.def("keys", .def(
+[](const MapOfEntities& m) -> bp::tuple { "keys",
bp::list res; +[](const MapOfEntities& m) -> bp::tuple {
for (const auto& el : m) res.append(el.first); bp::list res;
return bp::tuple(res); for (const auto& el : m) res.append(el.first);
}) return bp::tuple(res);
.def("values", })
+[](const MapOfEntities& m) -> bp::tuple { .def(
bp::list res; "values",
for (const auto& el : m) res.append(bp::ptr(el.second)); +[](const MapOfEntities& m) -> bp::tuple {
return bp::tuple(res); bp::list res;
}) for (const auto& el : m) res.append(bp::ptr(el.second));
.def("__getitem__", static_cast<dg::Entity*& (MapOfEntities::*)(const std::string& k)>(&MapOfEntities::at), return bp::tuple(res);
})
.def("__getitem__",
static_cast<dg::Entity*& (MapOfEntities::*)(const std::string& k)>(
&MapOfEntities::at),
reference_existing_object()) reference_existing_object())
.def("__setitem__", +[](MapOfEntities& m, const std::string& n, dg::Entity* e) { m.emplace(n, e); }) .def(
"__setitem__", +[](MapOfEntities& m, const std::string& n,
dg::Entity* e) { m.emplace(n, e); })
.def("__iter__", bp::iterator<MapOfEntities>()) .def("__iter__", bp::iterator<MapOfEntities>())
.def("__contains__", +[](const MapOfEntities& m, const std::string& n) -> bool { return m.count(n); }); .def(
bp::to_python_converter<MapOfEntities::value_type, MapOfEntitiesPairToPythonConverter>(); "__contains__",
+[](const MapOfEntities& m, const std::string& n) -> bool {
return m.count(n);
});
bp::to_python_converter<MapOfEntities::value_type,
MapOfEntitiesPairToPythonConverter>();
} }
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS. // Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <iostream> #include <dynamic-graph/command.h>
#include <dynamic-graph/entity.h> #include <dynamic-graph/entity.h>
#include <dynamic-graph/factory.h> #include <dynamic-graph/factory.h>
#include <dynamic-graph/command.h>
#include <dynamic-graph/linear-algebra.h> #include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/pool.h> #include <dynamic-graph/pool.h>
#include <dynamic-graph/value.h> #include <dynamic-graph/value.h>
#include <iostream>
#include "dynamic-graph/python/convert-dg-to-py.hh" #include "dynamic-graph/python/convert-dg-to-py.hh"
#include "dynamic-graph/python/dynamic-graph-py.hh" #include "dynamic-graph/python/dynamic-graph-py.hh"
...@@ -38,7 +37,8 @@ namespace entity { ...@@ -38,7 +37,8 @@ namespace entity {
/// \param obj an Entity object /// \param obj an Entity object
void addCommands(bp::object obj) { void addCommands(bp::object obj) {
Entity& entity = bp::extract<Entity&>(obj); Entity& entity = bp::extract<Entity&>(obj);
for (const auto& el : entity.getNewStyleCommandMap()) obj.attr(el.first.c_str()) = bp::object(bp::ptr(el.second)); for (const auto& el : entity.getNewStyleCommandMap())
obj.attr(el.first.c_str()) = bp::object(bp::ptr(el.second));
} }
/// \param obj an Entity object /// \param obj an Entity object
...@@ -57,16 +57,20 @@ void addSignals(bp::object obj) { ...@@ -57,16 +57,20 @@ void addSignals(bp::object obj) {
Entity* create(const char* className, const char* instanceName) { Entity* create(const char* className, const char* instanceName) {
Entity* obj = NULL; Entity* obj = NULL;
/* Try to find if the corresponding object already exists. */ /* Try to find if the corresponding object already exists. */
if (dynamicgraph::PoolStorage::getInstance()->existEntity(instanceName, obj)) { if (dynamicgraph::PoolStorage::getInstance()->existEntity(instanceName,
obj)) {
if (obj->getClassName() != className) { if (obj->getClassName() != className) {
throw std::invalid_argument("Found an object named " + std::string(instanceName) + throw std::invalid_argument("Found an object named " +
std::string(instanceName) +
",\n" ",\n"
"but this object is of type " + "but this object is of type " +
std::string(obj->getClassName()) + " and not " + std::string(className)); std::string(obj->getClassName()) +
" and not " + std::string(className));
} }
} else /* If not, create a new object. */ } else /* If not, create a new object. */
{ {
obj = dynamicgraph::FactoryStorage::getInstance()->newEntity(std::string(className), std::string(instanceName)); obj = dynamicgraph::FactoryStorage::getInstance()->newEntity(
std::string(className), std::string(instanceName));
} }
return obj; return obj;
...@@ -79,7 +83,8 @@ bp::object executeCmd(bp::tuple args, bp::dict) { ...@@ -79,7 +83,8 @@ bp::object executeCmd(bp::tuple args, bp::dict) {
throw std::out_of_range("Wrong number of arguments"); throw std::out_of_range("Wrong number of arguments");
std::vector<Value> values; std::vector<Value> values;
values.reserve(command.valueTypes().size()); values.reserve(command.valueTypes().size());
for (int i = 1; i < bp::len(args); ++i) values.push_back(convert::toValue(args[i], command.valueTypes()[i - 1])); for (int i = 1; i < bp::len(args); ++i)
values.push_back(convert::toValue(args[i], command.valueTypes()[i - 1]));
command.setParameterValues(values); command.setParameterValues(values);
return convert::fromValue(command.execute()); return convert::fromValue(command.execute());
} }
......
...@@ -5,5 +5,5 @@ ...@@ -5,5 +5,5 @@
from __future__ import print_function from __future__ import print_function
# for backward compat # for backward compat
from .wrap import LoggerVerbosity as VerbosityLevel from .wrap import LoggerVerbosity as VerbosityLevel # noqa
from .wrap import Entity from .wrap import Entity # noqa
// 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;
......
// 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/dynamic-graph-py.hh" #include "dynamic-graph/python/dynamic-graph-py.hh"
...@@ -11,9 +12,13 @@ namespace python { ...@@ -11,9 +12,13 @@ namespace python {
namespace pool { namespace pool {
void writeGraph(const char* filename) { PoolStorage::getInstance()->writeGraph(filename); } void writeGraph(const char* filename) {
PoolStorage::getInstance()->writeGraph(filename);
}
const std::map<std::string, Entity*>* getEntityMap() { return &PoolStorage::getInstance()->getEntityMap(); } const std::map<std::string, Entity*>* getEntityMap() {
return &PoolStorage::getInstance()->getEntityMap();
}
/** /**
\brief Get list of entities \brief Get list of entities
...@@ -21,7 +26,8 @@ const std::map<std::string, Entity*>* getEntityMap() { return &PoolStorage::getI ...@@ -21,7 +26,8 @@ const std::map<std::string, Entity*>* getEntityMap() { return &PoolStorage::getI
bp::list getEntityList() { bp::list getEntityList() {
std::vector<std::string> entityNames; std::vector<std::string> entityNames;
bp::list res; bp::list res;
const PoolStorage::Entities& listOfEntities = PoolStorage::getInstance()->getEntityMap(); const PoolStorage::Entities& listOfEntities =
PoolStorage::getInstance()->getEntityMap();
for (const auto& el : listOfEntities) res.append(el.second->getName()); for (const auto& el : listOfEntities) res.append(el.second->getName());
return res; return res;
......
...@@ -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 <boost/python.hpp>
#include "dynamic-graph/python/signal.hh"
#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-time-dependent.h> #include <dynamic-graph/signal-time-dependent.h>
#include <dynamic-graph/linear-algebra.h> #include <dynamic-graph/signal.h>
#include <dynamic-graph/value.h> #include <dynamic-graph/value.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/signal-wrapper.hh" #include "dynamic-graph/python/signal-wrapper.hh"
#include "dynamic-graph/python/signal.hh"
using dynamicgraph::SignalBase; using dynamicgraph::SignalBase;
...@@ -43,52 +41,68 @@ template <typename Time> ...@@ -43,52 +41,68 @@ template <typename Time>
void exposeSignalBase(const char* name) { void exposeSignalBase(const char* name) {
typedef SignalBase<Time> S_t; typedef SignalBase<Time> S_t;
bp::class_<S_t, boost::noncopyable>(name, bp::no_init) 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>()), .add_property("time",
bp::make_function(
&S_t::getTime,
bp::return_value_policy<bp::copy_const_reference>()),
&S_t::setTime) &S_t::setTime)
.add_property("name", bp::make_function(&S_t::getName, bp::return_value_policy<bp::copy_const_reference>())) .add_property("name",
bp::make_function(
.def("getName", &S_t::getName, bp::return_value_policy<bp::copy_const_reference>()) &S_t::getName,
.def("getClassName", bp::return_value_policy<bp::copy_const_reference>()))
+[](const S_t& s) -> std::string {
std::string ret; .def("getName", &S_t::getName,
s.getClassName(ret); bp::return_value_policy<bp::copy_const_reference>())
return ret; .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("plug", &S_t::plug, "Plug the signal to another signal")
.def("unplug", &S_t::unplug, "Unplug the signal") .def("unplug", &S_t::unplug, "Unplug the signal")
.def("isPlugged", &S_t::isPlugged, "Whether the signal is plugged") .def("isPlugged", &S_t::isPlugged, "Whether the signal is plugged")
.def("getPlugged", &S_t::getPluged, bp::return_value_policy<bp::reference_existing_object>(), .def("getPlugged", &S_t::getPluged,
bp::return_value_policy<bp::reference_existing_object>(),
"To which signal the signal is plugged") "To which signal the signal is plugged")
.def("recompute", &S_t::recompute, "Recompute the signal at given time") .def("recompute", &S_t::recompute, "Recompute the signal at given time")
.def("__str__", .def(
+[](const S_t& s) -> std::string { "__str__",
std::ostringstream oss; +[](const S_t& s) -> std::string {
s.display(oss); std::ostringstream oss;
return oss.str(); s.display(oss);
}) return oss.str();
.def("displayDependencies", })
+[](const S_t& s, int time) -> std::string { .def(
std::ostringstream oss; "displayDependencies",
s.displayDependencies(oss, time); +[](const S_t& s, int time) -> std::string {
return oss.str(); std::ostringstream oss;
}, s.displayDependencies(oss, time);
"Print the signal dependencies in a string"); return oss.str();
},
"Print the signal dependencies in a string");
} }
template <> template <>
auto exposeSignal<MatrixHomogeneous, time_type>(const std::string& name) { auto exposeSignal<MatrixHomogeneous, time_type>(const std::string& name) {
typedef Signal<MatrixHomogeneous, time_type> S_t; 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>()); bp::class_<S_t, bp::bases<SignalBase<time_type> >, boost::noncopyable> obj(
obj.add_property("value", +[](const S_t& signal) -> Matrix4 { return signal.accessCopy().matrix(); }, name.c_str(), bp::init<std::string>());
+[](S_t& signal, const Matrix4& v) { obj.add_property(
// TODO it isn't hard to support pinocchio::SE3 type here. "value",
// However, this adds a dependency to pinocchio. +[](const S_t& signal) -> Matrix4 {
signal.setConstant(MatrixHomogeneous(v)); return signal.accessCopy().matrix();
}, },
"the signal value."); +[](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; return obj;
} }
...@@ -115,7 +129,8 @@ void exposeSignals() { ...@@ -115,7 +129,8 @@ void exposeSignals() {
namespace signalBase { namespace signalBase {
template <class T> template <class T>
SignalWrapper<T, int>* createSignalWrapperTpl(const char* name, bp::object 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;
...@@ -138,7 +153,8 @@ PythonSignalContainer* getPythonSignalContainer() { ...@@ -138,7 +153,8 @@ PythonSignalContainer* getPythonSignalContainer() {
/** /**
\brief Create an instance of SignalWrapper \brief Create an instance of SignalWrapper
*/ */
SignalBase<int>* createSignalWrapper(const char* name, const char* type, bp::object object) { SignalBase<int>* createSignalWrapper(const char* name, const char* type,
bp::object object) {
PythonSignalContainer* psc = getPythonSignalContainer(); PythonSignalContainer* psc = getPythonSignalContainer();
if (psc == NULL) return NULL; if (psc == NULL) return NULL;
......
// 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 {
void PythonSignalContainer::signalRegistration(const SignalArray<int>& signals) { 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) {
......
...@@ -4,28 +4,35 @@ ...@@ -4,28 +4,35 @@
from __future__ import print_function from __future__ import print_function
from .wrap import SignalBase, create_signal_wrapper as SignalWrapper
# I kept what follows for backward compatibility but I think it should be # I kept what follows for backward compatibility but I think it should be
# removed # removed
import re import re
from .wrap import SignalBase # noqa
from .wrap import create_signal_wrapper as SignalWrapper # noqa
def stringToTuple(vector): 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)
...@@ -35,10 +42,10 @@ def tupleToString(vector): ...@@ -35,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
...@@ -49,20 +56,30 @@ def stringToMatrix(string): ...@@ -49,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)
...@@ -74,19 +91,19 @@ def matrixToString(matrix): ...@@ -74,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
...@@ -100,18 +117,18 @@ def objectToString(obj): ...@@ -100,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)
......
...@@ -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/python/module.hh"
#include <dynamic-graph/tracer.h> #include <dynamic-graph/tracer.h>
#include "dynamic-graph/python/module.hh"
BOOST_PYTHON_MODULE(wrap) { BOOST_PYTHON_MODULE(wrap) {
using dynamicgraph::Tracer; using dynamicgraph::Tracer;
bp::import("dynamic_graph"); bp::import("dynamic_graph");
dynamicgraph::python::exposeEntity<Tracer>().def("addSignal", &Tracer::addSignalToTrace); dynamicgraph::python::exposeEntity<Tracer>().def("addSignal",
&Tracer::addSignalToTrace);
} }
#include "dynamic-graph/python/module.hh"
#include <dynamic-graph/tracer-real-time.h> #include <dynamic-graph/tracer-real-time.h>
#include "dynamic-graph/python/module.hh"
BOOST_PYTHON_MODULE(wrap) { BOOST_PYTHON_MODULE(wrap) {
using dynamicgraph::Tracer; using dynamicgraph::Tracer;
using dynamicgraph::TracerRealTime; using dynamicgraph::TracerRealTime;
......