Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stack Of Tasks
dynamic-graph-python
Commits
eb0b8503
Commit
eb0b8503
authored
Nov 09, 2020
by
Guilhem Saurel
Browse files
Merge branch 'master' into devel
parents
f77269a3
fa39add3
Pipeline
#11964
passed with stage
in 8 minutes and 17 seconds
Changes
32
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
eb0b8503
...
...
@@ -30,33 +30,38 @@ PROJECT(${PROJECT_NAME} ${PROJECT_ARGS})
FINDPYTHON
()
ADD_PROJECT_DEPENDENCY
(
dynamic-graph REQUIRED PKG_CONFIG_REQUIRES dynamic-graph
)
SET
(
BOOST_COMPONENTS filesystem system thread program_options unit_test_framework python
)
SEARCH_FOR_BOOST
()
ADD_PROJECT_DEPENDENCY
(
eigenpy REQUIRED PKG_CONFIG_REQUIRES eigenpy
)
SEARCH_FOR_BOOST_PYTHON
(
REQUIRED
)
IF
(
BUILD_TESTING
)
FIND_PACKAGE
(
Boost REQUIRED COMPONENTS unit_test_framework
)
ENDIF
(
BUILD_TESTING
)
# Main Library
SET
(
${
PROJECT_NAME
}
_HEADERS
include/
${
CUSTOM_HEADER_DIR
}
/api.hh
include/
${
CUSTOM_HEADER_DIR
}
/convert-dg-to-py.hh
include/
${
CUSTOM_HEADER_DIR
}
/dynamic-graph-py.hh
include/
${
CUSTOM_HEADER_DIR
}
/exception.hh
include/
${
CUSTOM_HEADER_DIR
}
/exception-python.hh
include/
${
CUSTOM_HEADER_DIR
}
/interpreter.hh
include/
${
CUSTOM_HEADER_DIR
}
/module.hh
include/
${
CUSTOM_HEADER_DIR
}
/python-compat.hh
include/
${
CUSTOM_HEADER_DIR
}
/signal.hh
include/
${
CUSTOM_HEADER_DIR
}
/signal-wrapper.hh
)
SET
(
${
PROJECT_NAME
}
_SOURCES
src/interpreter.cc
src/dynamic_graph/python-compat.cc
src/dynamic_graph/entity-py.cc
src/dynamic_graph/convert-dg-to-py.cc
)
ADD_LIBRARY
(
${
PROJECT_NAME
}
SHARED
${${
PROJECT_NAME
}
_SOURCES
}
${${
PROJECT_NAME
}
_HEADERS
}
)
TARGET_INCLUDE_DIRECTORIES
(
${
PROJECT_NAME
}
SYSTEM PUBLIC
${
PYTHON_INCLUDE_DIR
S
}
)
TARGET_INCLUDE_DIRECTORIES
(
${
PROJECT_NAME
}
SYSTEM PUBLIC
${
PYTHON_INCLUDE_DIR
}
)
TARGET_INCLUDE_DIRECTORIES
(
${
PROJECT_NAME
}
PUBLIC $<INSTALL_INTERFACE:include>
)
TARGET_LINK_LIBRARIES
(
${
PROJECT_NAME
}
${
Boost_LIBRARIES
}
${
PYTHON_LIBRARY
}
${
Boost_PYTHON_LIBRARIES
}
dynamic-graph::dynamic-graph
)
TARGET_LINK_LIBRARIES
(
${
PROJECT_NAME
}
PUBLIC
${
PYTHON_LIBRARY
}
dynamic-graph::dynamic-graph
)
TARGET_LINK_BOOST_PYTHON
(
${
PROJECT_NAME
}
PRIVATE
)
IF
(
SUFFIX_SO_VERSION
)
SET_TARGET_PROPERTIES
(
${
PROJECT_NAME
}
PROPERTIES SOVERSION
${
PROJECT_VERSION
}
)
...
...
@@ -67,7 +72,9 @@ TARGET_COMPILE_DEFINITIONS(${PROJECT_NAME} PRIVATE PYTHON_LIBRARY="${PYTHON_LIBR
INSTALL
(
TARGETS
${
PROJECT_NAME
}
EXPORT
${
TARGETS_EXPORT_NAME
}
DESTINATION lib
)
ADD_SUBDIRECTORY
(
src
)
ADD_SUBDIRECTORY
(
tests
)
IF
(
BUILD_TESTING
)
ADD_SUBDIRECTORY
(
tests
)
ENDIF
(
BUILD_TESTING
)
PKG_CONFIG_APPEND_LIBS
(
${
PROJECT_NAME
}
)
INSTALL
(
FILES package.xml DESTINATION share/
${
PROJECT_NAME
}
)
cmake
@
91f97c1c
Compare
fb4c22c3
...
91f97c1c
Subproject commit
fb4c22c319ec5320f9a85527eb1a4130954846f5
Subproject commit
91f97c1c31608f48d697a6b11037f13e878b9837
include/dynamic-graph/python/convert-dg-to-py.hh
View file @
eb0b8503
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include
<boost/python.hpp>
#include
<dynamic-graph/linear-algebra.h>
#include
<dynamic-graph/value.h>
#include
<dynamic-graph/python/exception-python.hh>
namespace
dynamicgraph
{
namespace
python
{
namespace
convert
{
command
::
Value
pythonToValue
(
PyObject
*
pyObject
,
const
command
::
Value
::
Type
&
valueType
);
PyObject
*
vectorToPython
(
const
Vector
&
vector
);
PyObject
*
matrixToPython
(
const
::
dynamicgraph
::
Matrix
&
matrix
);
PyObject
*
matrix4dToPython
(
const
Eigen
::
Matrix4d
&
matrix
);
PyObject
*
valueToPython
(
const
::
dynamicgraph
::
command
::
Value
&
value
);
command
::
Value
toValue
(
boost
::
python
::
object
o
,
const
command
::
Value
::
Type
&
type
);
boost
::
python
::
object
fromValue
(
const
command
::
Value
&
value
);
}
// namespace convert
}
// namespace python
...
...
include/dynamic-graph/python/dynamic-graph-py.hh
View file @
eb0b8503
...
...
@@ -4,189 +4,70 @@
#include
<iostream>
#include
<sstream>
#include
<boost/python.hpp>
#include
<dynamic-graph/debug.h>
#include
<dynamic-graph/exception-factory.h>
#include
<dynamic-graph/signal-base.h>
#include
"dynamic-graph/python/signal-wrapper.hh"
namespace
bp
=
boost
::
python
;
namespace
dynamicgraph
{
namespace
python
{
template
<
typename
Iterator
>
inline
bp
::
list
to_py_list
(
Iterator
begin
,
Iterator
end
)
{
typedef
typename
Iterator
::
value_type
T
;
bp
::
list
lst
;
std
::
for_each
(
begin
,
end
,
[
&
](
const
T
&
t
)
{
lst
.
append
(
t
);
});
return
lst
;
}
template
<
typename
Iterator
>
inline
bp
::
tuple
to_py_tuple
(
Iterator
begin
,
Iterator
end
)
{
return
bp
::
tuple
(
to_py_list
(
begin
,
end
));
}
template
<
typename
T
>
inline
std
::
vector
<
T
>
to_std_vector
(
const
bp
::
object
&
iterable
)
{
return
std
::
vector
<
T
>
(
bp
::
stl_input_iterator
<
T
>
(
iterable
),
bp
::
stl_input_iterator
<
T
>
());
}
void
exposeSignals
();
// Declare functions defined in other source files
namespace
signalBase
{
PyObject
*
create
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
createSignalWrapper
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getTime
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
setTime
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getName
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getClassName
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
display
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
displayDependencies
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getValue
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
setValue
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
recompute
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
unplug
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
isPlugged
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getPlugged
(
PyObject
*
self
,
PyObject
*
args
);
SignalBase
<
int
>*
createSignalWrapper
(
const
char
*
name
,
const
char
*
type
,
bp
::
object
object
);
}
// namespace signalBase
namespace
entity
{
PyObject
*
create
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
display
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
display
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getName
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getClassName
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
hasSignal
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getSignal
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
listSignals
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
executeCommand
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
listCommands
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getCommandDocstring
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getDocString
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
setLoggerVerbosityLevel
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getLoggerVerbosityLevel
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
setTimeSample
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getTimeSample
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
setStreamPrintPeriod
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getStreamPrintPeriod
(
PyObject
*
self
,
PyObject
*
args
);
/// \param obj an Entity object
void
addCommands
(
boost
::
python
::
object
obj
);
void
addSignals
(
boost
::
python
::
object
obj
);
Entity
*
create
(
const
char
*
type
,
const
char
*
name
);
bp
::
object
executeCmd
(
bp
::
tuple
args
,
bp
::
dict
);
}
// namespace entity
namespace
factory
{
PyObject
*
getEntityClassList
(
PyObject
*
self
,
PyObject
*
args
);
}
namespace
signalCaster
{
PyObject
*
getSignalTypeList
(
PyObject
*
self
,
PyObject
*
args
);
bp
::
tuple
getEntityClassList
();
}
namespace
pool
{
PyObject
*
writeGraph
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
getEntityList
(
PyObject
*
self
,
PyObject
*
args
);
void
writeGraph
(
const
char
*
filename
);
bp
::
list
getEntityList
();
const
std
::
map
<
std
::
string
,
Entity
*>*
getEntityMap
();
}
// namespace pool
namespace
debug
{
PyObject
*
addLoggerFileOutputStream
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
addLoggerCoutOutputStream
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
closeLoggerFileOutputStream
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
realTimeLoggerSpinOnce
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
realTimeLoggerDestroy
(
PyObject
*
self
,
PyObject
*
args
);
PyObject
*
realTimeLoggerInstance
(
PyObject
*
self
,
PyObject
*
args
);
void
addLoggerFileOutputStream
(
const
char
*
filename
);
void
addLoggerCoutOutputStream
();
void
closeLoggerFileOutputStream
();
void
realTimeLoggerSpinOnce
();
void
realTimeLoggerDestroy
();
void
realTimeLoggerInstance
();
}
// namespace debug
struct
module_state
{
PyObject
*
dgpyError
;
};
PyObject
*
plug
(
PyObject
*
/*self*/
,
PyObject
*
args
);
PyObject
*
enableTrace
(
PyObject
*
/*self*/
,
PyObject
*
args
);
PyObject
*
error_out
(
#if PY_MAJOR_VERSION >= 3
PyObject
*
m
,
PyObject
*
#else
PyObject
*
,
PyObject
*
#endif
);
/**
\brief List of python functions
*/
__attribute__
((
unused
))
static
PyMethodDef
dynamicGraphMethods
[]
=
{
{
"w_plug"
,
dynamicgraph
::
python
::
plug
,
METH_VARARGS
,
"plug an output signal into an input signal"
},
{
"enableTrace"
,
dynamicgraph
::
python
::
enableTrace
,
METH_VARARGS
,
"Enable or disable tracing debug info in a file"
},
// Signals
{
"create_signal_base"
,
dynamicgraph
::
python
::
signalBase
::
create
,
METH_VARARGS
,
"create a SignalBase C++ object"
},
{
"create_signal_wrapper"
,
dynamicgraph
::
python
::
signalBase
::
createSignalWrapper
,
METH_VARARGS
,
"create a SignalWrapper C++ object"
},
{
"signal_base_get_time"
,
dynamicgraph
::
python
::
signalBase
::
getTime
,
METH_VARARGS
,
"Get time of a SignalBase"
},
{
"signal_base_set_time"
,
dynamicgraph
::
python
::
signalBase
::
setTime
,
METH_VARARGS
,
"Set time of a SignalBase"
},
{
"signal_base_get_name"
,
dynamicgraph
::
python
::
signalBase
::
getName
,
METH_VARARGS
,
"Get the name of a signal"
},
{
"signal_base_get_class_name"
,
dynamicgraph
::
python
::
signalBase
::
getClassName
,
METH_VARARGS
,
"Get the class name of a signal"
},
{
"signal_base_display"
,
dynamicgraph
::
python
::
signalBase
::
display
,
METH_VARARGS
,
"Print the signal in a string"
},
{
"signal_base_display_dependencies"
,
dynamicgraph
::
python
::
signalBase
::
displayDependencies
,
METH_VARARGS
,
"Print the signal dependencies in a string"
},
{
"signal_base_get_value"
,
dynamicgraph
::
python
::
signalBase
::
getValue
,
METH_VARARGS
,
"Read the value of a signal"
},
{
"signal_base_set_value"
,
dynamicgraph
::
python
::
signalBase
::
setValue
,
METH_VARARGS
,
"Set the value of a signal"
},
{
"signal_base_recompute"
,
dynamicgraph
::
python
::
signalBase
::
recompute
,
METH_VARARGS
,
"Recompute the signal at given time"
},
{
"signal_base_unplug"
,
dynamicgraph
::
python
::
signalBase
::
unplug
,
METH_VARARGS
,
"Unplug the signal"
},
{
"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"
},
// Entity
{
"create_entity"
,
dynamicgraph
::
python
::
entity
::
create
,
METH_VARARGS
,
"create an Entity C++ object"
},
{
"display_entity"
,
dynamicgraph
::
python
::
entity
::
display
,
METH_VARARGS
,
"print an Entity C++ object"
},
{
"entity_get_name"
,
dynamicgraph
::
python
::
entity
::
getName
,
METH_VARARGS
,
"get the name of an Entity"
},
{
"entity_get_class_name"
,
dynamicgraph
::
python
::
entity
::
getClassName
,
METH_VARARGS
,
"get the class name of an Entity"
},
{
"entity_has_signal"
,
dynamicgraph
::
python
::
entity
::
hasSignal
,
METH_VARARGS
,
"return True if the entity has a signal with the given name"
},
{
"entity_get_signal"
,
dynamicgraph
::
python
::
entity
::
getSignal
,
METH_VARARGS
,
"get signal by name from an Entity"
},
{
"entity_list_signals"
,
dynamicgraph
::
python
::
entity
::
listSignals
,
METH_VARARGS
,
"Return the list of signals of an entity."
},
{
"entity_execute_command"
,
dynamicgraph
::
python
::
entity
::
executeCommand
,
METH_VARARGS
,
"execute a command"
},
{
"entity_list_commands"
,
dynamicgraph
::
python
::
entity
::
listCommands
,
METH_VARARGS
,
"list the commands of an entity"
},
{
"entity_get_command_docstring"
,
dynamicgraph
::
python
::
entity
::
getCommandDocstring
,
METH_VARARGS
,
"get the docstring of an entity command"
},
{
"entity_get_docstring"
,
dynamicgraph
::
python
::
entity
::
getDocString
,
METH_VARARGS
,
"get the doc string of an entity type"
},
{
"factory_get_entity_class_list"
,
dynamicgraph
::
python
::
factory
::
getEntityClassList
,
METH_VARARGS
,
"return the list of entity classes"
},
{
"signal_caster_get_type_list"
,
dynamicgraph
::
python
::
signalCaster
::
getSignalTypeList
,
METH_VARARGS
,
"return the list of signal type names"
},
{
"writeGraph"
,
dynamicgraph
::
python
::
pool
::
writeGraph
,
METH_VARARGS
,
"Write the graph of entities in a filename."
},
{
"get_entity_list"
,
dynamicgraph
::
python
::
pool
::
getEntityList
,
METH_VARARGS
,
"return the list of instanciated entities"
},
{
"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
,
"get the verbosity level of the entity"
},
{
"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."
},
{
"error_out"
,
(
PyCFunction
)
dynamicgraph
::
python
::
error_out
,
METH_NOARGS
,
NULL
},
{
NULL
,
NULL
,
0
,
NULL
}
/* Sentinel */
};
#if PY_MAJOR_VERSION >= 3
__attribute__
((
unused
))
static
struct
PyModuleDef
dynamicGraphModuleDef
=
{
PyModuleDef_HEAD_INIT
,
"wrap"
,
NULL
,
sizeof
(
struct
dynamicgraph
::
python
::
module_state
),
dynamicGraphMethods
,
NULL
,
NULL
,
NULL
,
NULL
};
#define GETSTATE(m) ((struct dynamicgraph::python::module_state*)PyModule_GetState(m))
#define DGPYERROR(m) GETSTATE(m)->dgpyError
#define INITERROR return NULL
#else
__attribute__
((
unused
))
static
struct
module_state
_state
;
#define GETSTATE(m) (&dynamicgraph::python::_state)
#define DGPYERROR(m) dynamicgraph::python::dgpyError
#define INITERROR return
#endif
}
// namespace python
}
// namespace dynamicgraph
...
...
include/dynamic-graph/python/exception-python.hh
deleted
100644 → 0
View file @
f77269a3
// -*- mode: c++ -*-
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
#ifndef DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
#define DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
#include
<dynamic-graph/fwd.hh>
#include
<dynamic-graph/exception-abstract.h>
#include
"dynamic-graph/python/python-compat.hh"
// Depending on whether one is building or using the
// library define DLLAPI to import or export.
#if defined(WIN32)
#if defined(wrap_EXPORTS)
#define WRAP_DLLAPI __declspec(dllexport)
#else
#define WRAP_DLLAPI __declspec(dllimport)
#endif
#else
#define WRAP_DLLAPI
#endif
namespace
dynamicgraph
{
namespace
python
{
/// \ingroup error
///
/// \brief Generic error class.
class
WRAP_DLLAPI
ExceptionPython
:
public
ExceptionAbstract
{
public:
enum
ErrorCodeEnum
{
GENERIC
,
VALUE_PARSING
,
VECTOR_PARSING
,
MATRIX_PARSING
,
CLASS_INCONSISTENT
};
static
const
std
::
string
EXCEPTION_NAME
;
explicit
ExceptionPython
(
const
ExceptionPython
::
ErrorCodeEnum
&
errcode
,
const
std
::
string
&
msg
=
""
);
ExceptionPython
(
const
ExceptionPython
::
ErrorCodeEnum
&
errcode
,
const
std
::
string
&
msg
,
const
char
*
format
,
...);
virtual
~
ExceptionPython
()
throw
()
{}
virtual
const
std
::
string
&
getExceptionName
()
const
{
return
ExceptionPython
::
EXCEPTION_NAME
;
}
};
}
// end of namespace python
}
// end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
include/dynamic-graph/python/exception.hh
deleted
100644 → 0
View file @
f77269a3
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#ifndef DYNAMIC_GRAPH_PYTHON_EXCEPTION
#define DYNAMIC_GRAPH_PYTHON_EXCEPTION
#include
"dynamic-graph/python/dynamic-graph-py.hh"
/// \brief Catch all exceptions which may be sent when C++ code is
/// called.
#define CATCH_ALL_EXCEPTIONS(m) \
catch (const std::exception& exc) { \
PyErr_SetString(DGPYERROR(m), exc.what()); \
return NULL; \
} \
catch (const char* s) { \
PyErr_SetString(DGPYERROR(m), s); \
return NULL; \
} \
catch (...) { \
PyErr_SetString(DGPYERROR(m), "Unknown exception"); \
return NULL; \
} \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION
include/dynamic-graph/python/module.hh
0 → 100644
View file @
eb0b8503
#ifndef DYNAMIC_GRAPH_PYTHON_MODULE_HH
#define DYNAMIC_GRAPH_PYTHON_MODULE_HH
#ifdef PINOCCHIO_WITH_URDFDOM
// If pinocchio is used, we have to include pinocchio header before boost mpl
#include
<pinocchio/fwd.hpp>
#endif
#include
<boost/python.hpp>
#include
<boost/mpl/for_each.hpp>
#include
<dynamic-graph/entity.h>
#include
<dynamic-graph/python/dynamic-graph-py.hh>
namespace
dynamicgraph
{
namespace
python
{
constexpr
int
AddSignals
=
1
;
constexpr
int
AddCommands
=
2
;
namespace
internal
{
template
<
typename
T
,
int
Options
=
AddCommands
|
AddSignals
>
bp
::
object
makeEntity1
(
const
char
*
name
)
{
Entity
*
ent
=
entity
::
create
(
T
::
CLASS_NAME
.
c_str
(),
name
);
assert
(
dynamic_cast
<
T
*>
(
ent
)
!=
NULL
);
bp
::
object
obj
(
bp
::
ptr
(
static_cast
<
T
*>
(
ent
)));
if
(
Options
&
AddCommands
)
entity
::
addCommands
(
obj
);
if
(
Options
&
AddSignals
)
entity
::
addSignals
(
obj
);
return
obj
;
}
template
<
typename
T
,
int
Options
=
AddCommands
|
AddSignals
>
bp
::
object
makeEntity2
()
{
return
makeEntity1
<
T
,
Options
>
(
""
);
}
}
// namespace internal
/// \tparam Options by default, all the signals and commands are added as
/// attribute to the Python object. This behaviour works fine for
/// entities that have static commands and signals.
/// If some commands or signals are added or removed dynamiccally, then
/// it is better to disable the default behaviour and handle it
/// specifically.
template
<
typename
T
,
typename
bases
=
boost
::
python
::
bases
<
dynamicgraph
::
Entity
>,
int
Options
=
AddCommands
|
AddSignals
>
inline
auto
exposeEntity
()
{
// std::string hiddenClassName ("_" + T::CLASS_NAME);
std
::
string
hiddenClassName
(
T
::
CLASS_NAME
);
namespace
bp
=
boost
::
python
;
bp
::
class_
<
T
,
bases
,
boost
::
noncopyable
>
obj
(
hiddenClassName
.
c_str
(),
bp
::
init
<
std
::
string
>
());
/* TODO at the moment, I couldn't easily find a way to define a Python constructor
* that would create the entity via the factory and then populate the
* python object with its commands.
* This is achieved with a factory function of the same name.
obj.def ("__init__", bp::raw_function(+[](bp::object args, bp::dict) {
if (bp::len(args) != 2)
throw std::length_error("Expected 2 arguments.");
bp::object self = args[0];
self.attr("__init__")(bp::extract<std::string>(args[1]));
Entity* ent = entity::create(T::CLASS_NAME.c_str(), name);
if (dynamic_cast<T*>(ent) == NULL)
std::cout << "foo" << std::endl;
assert(dynamic_cast<T*>(ent) != NULL);
self = bp::object(bp::ptr(static_cast<T*>(ent)));
//dynamicgraph::Entity& unused = bp::extract<dynamicgraph::Entity&>(self);
//entity::addCommands(self);
})
;
*/
bp
::
def
(
T
::
CLASS_NAME
.
c_str
(),
&
internal
::
makeEntity1
<
T
,
Options
>
);
bp
::
def
(
T
::
CLASS_NAME
.
c_str
(),
&
internal
::
makeEntity2
<
T
,
Options
>
);
if
(
!
(
Options
&
AddCommands
))
obj
.
def
(
"add_commands"
,
&
entity
::
addCommands
);
if
(
!
(
Options
&
AddSignals
))
obj
.
def
(
"add_signals"
,
&
entity
::
addSignals
);
return
obj
;
}
}
// namespace python
}
// namespace dynamicgraph
#endif // DYNAMIC_GRAPH_PYTHON_MODULE_HH
include/dynamic-graph/python/signal-wrapper.hh
View file @
eb0b8503
...
...
@@ -4,6 +4,8 @@
#ifndef DGPY_SIGNAL_WRAPPER
#define DGPY_SIGNAL_WRAPPER
#include
<boost/python.hpp>
#include
<dynamic-graph/linear-algebra.h>
#include
<dynamic-graph/signal.h>
#include
<dynamic-graph/entity.h>
...
...
@@ -11,22 +13,12 @@
namespace
dynamicgraph
{
namespace
python
{
namespace
signalWrapper
{
void
convert
(
PyObject
*
o
,
int
&
v
);
void
convert
(
PyObject
*
o
,
bool
&
v
);
void
convert
(
PyObject
*
o
,
float
&
v
);
void
convert
(
PyObject
*
o
,
double
&
v
);
// void convert (PyObject* o, std::string& v);
void
convert
(
PyObject
*
o
,
Vector
&
v
);
// void convert (PyObject* o, Eigen::MatrixXd& v);
// void convert (PyObject* o, Eigen::Matrix4d& v);
}
// namespace signalWrapper
class
PythonSignalContainer
:
public
Entity
{
DYNAMIC_GRAPH_ENTITY_DECL
();
public:
PythonSignalContainer
(
const
std
::
string
&
name
)
;
using
Entity
::
Entity
;
void
signalRegistration
(
const
SignalArray
<
int
>&
signals
);
...
...
@@ -37,17 +29,17 @@ template <class T, class Time>
class
SignalWrapper
:
public
Signal
<
T
,
Time
>
{
public:
typedef
Signal
<
T
,
Time
>
parent_t
;
typedef
boost
::
python
::
object
pyobject
;
static
bool
checkCallable
(
PyO
bject
*
c
,
std
::
string
&
error
);
static
bool
checkCallable
(
pyo
bject
c
,
std
::
string
&
error
);
SignalWrapper
(
std
::
string
name
,
PyO
bject
*
_
callable
)
:
parent_t
(
name
),
callable
(
_
callable
)
{
SignalWrapper
(
std
::
string
name
,
pyo
bject
callable
)
:
parent_t
(
name
),
callable
(
callable
)
{
typedef
boost
::
function2
<
T
&
,
T
&
,
Time
>
function_t
;
Py_INCREF
(
callable
);
function_t
f
=
boost
::
bind
(
&
SignalWrapper
::
call
,
this
,
_1
,
_2
);
this
->
setFunction
(
f
);
}
virtual
~
SignalWrapper
()
{
Py_DECREF
(
callable
);
};
virtual
~
SignalWrapper
()
{
};
private:
T
&
call
(
T
&
value
,
Time
t
)
{
...
...
@@ -56,18 +48,12 @@ class SignalWrapper : public Signal<T, Time> {
if
(
PyGILState_GetThisThreadState
()
==
NULL
)
{
dgDEBUG
(
10
)
<<
"python thread not initialized"
<<
std
::
endl
;
}
char
format
[]
=
"i"
;
PyObject
*
obj
=
PyObject_CallFunction
(
callable
,
format
,
t
);
if
(
obj
==
NULL
)
{
dgERROR
<<
"Could not call callable"
<<
std
::
endl
;
}
else
{
signalWrapper
::
convert
(
obj
,
value
);
Py_DECREF
(
obj
);
}
pyobject
obj
=
callable
(
t
);
value
=
boost
::
python
::
extract
<
T
>
(
obj
);
PyGILState_Release
(
gstate
);
return
value
;
}
PyO
bject
*
callable
;
pyo
bject
callable
;
};
}
// namespace python
...
...
include/dynamic-graph/python/signal.hh
0 → 100644
View file @
eb0b8503
// Copyright 2020, Joseph Mirabel, LAAS-CNRS.
#include
<sstream>
#include
<boost/python.hpp>
#include
<dynamic-graph/signal-base.h>
#include
<dynamic-graph/signal-ptr.h>
#include
<dynamic-graph/signal-time-dependent.h>
#include
<dynamic-graph/signal.h>
#include
"dynamic-graph/python/signal-wrapper.hh"
namespace
dynamicgraph
{
namespace
python
{
template
<
typename
T
,
typename
Time
>
auto
exposeSignal
(
const
std
::
string
&
name
)
{
namespace
bp
=
boost
::
python
;
typedef
Signal
<
T
,
Time
>
S_t
;
bp
::
class_
<
S_t
,
bp
::
bases
<
SignalBase
<
Time
>
>
,
boost
::
noncopyable
>
obj
(
name
.
c_str
(),
bp
::
init
<
std
::
string
>
());
obj
.
add_property
(
"value"
,
bp
::
make_function
(
&
S_t
::
accessCopy
,
bp
::
return_value_policy
<
bp
::
copy_const_reference
>
()),
&
S_t
::
setConstant
,
// TODO check the setter
"the signal value.
\n
"
"warning: for Eigen objects, sig.value[0] = 1. may not work)."
);
return
obj
;
}
template
<
typename
T
,
typename
Time
&g