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
1ff01145
Commit
1ff01145
authored
Feb 15, 2018
by
Joseph Mirabel
Committed by
Guilhem Saurel
Jul 30, 2018
Browse files
Add SignalWrapper which allows to bind a Python function to a signal.
parent
582b6658
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/CMakeLists.txt
View file @
1ff01145
...
...
@@ -73,6 +73,7 @@ ADD_LIBRARY(${PYTHON_MODULE}
factory-py.cc
pool-py.cc
signal-caster-py.cc
signal-wrapper.cc
)
# Remove prefix lib
...
...
src/dynamic-graph-py.cc
View file @
1ff01145
...
...
@@ -23,6 +23,7 @@
#include
<dynamic-graph/signal-base.h>
#include
"exception.hh"
#include
"signal-wrapper.hh"
namespace
dynamicgraph
{
namespace
python
{
...
...
@@ -30,6 +31,7 @@ namespace dynamicgraph {
// Declare functions defined in other source files
namespace
signalBase
{
extern
PyObject
*
create
(
PyObject
*
self
,
PyObject
*
args
);
extern
PyObject
*
createSignalWrapper
(
PyObject
*
self
,
PyObject
*
args
);
extern
PyObject
*
getTime
(
PyObject
*
self
,
PyObject
*
args
);
extern
PyObject
*
setTime
(
PyObject
*
self
,
PyObject
*
args
);
extern
PyObject
*
getName
(
PyObject
*
self
,
PyObject
*
args
);
...
...
@@ -151,6 +153,8 @@ static PyMethodDef dynamicGraphMethods[] = {
// 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
,
...
...
src/signal-base-py.cc
View file @
1ff01145
...
...
@@ -25,6 +25,7 @@
#include
"convert-dg-to-py.hh"
#include
"exception.hh"
#include
"signal-wrapper.hh"
using
dynamicgraph
::
SignalBase
;
...
...
@@ -56,6 +57,58 @@ namespace dynamicgraph {
return
PyCObject_FromVoidPtr
((
void
*
)
obj
,
destroy
);
}
template
<
class
T
>
void
*
createSignalWrapperTpl
(
const
char
*
name
,
PyObject
*
o
,
std
::
string
&
error
)
{
typedef
SignalWrapper
<
T
,
int
>
SignalWrapper_t
;
if
(
!
SignalWrapper_t
::
checkCallable
(
o
,
error
))
{
return
NULL
;
}
SignalWrapper_t
*
obj
=
new
SignalWrapper_t
(
name
,
o
);
return
(
void
*
)
obj
;
}
#define SIGNAL_WRAPPER_TYPE(IF, Enum, Type) \
IF (command::Value::typeName(command::Value::Enum) \
.compare(type) == 0) { \
obj = createSignalWrapperTpl<Type> (name, object, error); \
}
/**
\brief Create an instance of SignalWrapper
*/
PyObject
*
createSignalWrapper
(
PyObject
*
/*self*/
,
PyObject
*
args
)
{
char
*
name
=
NULL
;
char
*
type
=
NULL
;
PyObject
*
object
=
NULL
;
if
(
!
PyArg_ParseTuple
(
args
,
"ssO"
,
&
name
,
&
type
,
&
object
))
return
NULL
;
void
*
obj
=
NULL
;
std
::
string
error
;
SIGNAL_WRAPPER_TYPE
(
if
,
BOOL
,
bool
)
// SIGNAL_WRAPPER_TYPE(else if, UNSIGNED ,bool)
SIGNAL_WRAPPER_TYPE
(
else
if
,
INT
,
int
)
SIGNAL_WRAPPER_TYPE
(
else
if
,
FLOAT
,
float
)
SIGNAL_WRAPPER_TYPE
(
else
if
,
DOUBLE
,
double
)
// SIGNAL_WRAPPER_TYPE(else if, STRING ,bool)
SIGNAL_WRAPPER_TYPE
(
else
if
,
VECTOR
,
Vector
)
// SIGNAL_WRAPPER_TYPE(else if, MATRIX ,bool)
// SIGNAL_WRAPPER_TYPE(else if, MATRIX4D ,bool)
else
{
error
=
"Type not understood"
;
}
if
(
obj
==
NULL
)
{
PyErr_SetString
(
dgpyError
,
error
.
c_str
());
return
NULL
;
}
// Return the pointer
return
PyCObject_FromVoidPtr
(
obj
,
destroy
);
}
/**
\brief Destroy an instance of InvertedPendulum
*/
...
...
src/signal-wrapper.cc
0 → 100644
View file @
1ff01145
// Copyright (c) 2018, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of dynamic-graph-python.
// dynamic-graph-python is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// dynamic-graph-python is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph-python. If not, see <http://www.gnu.org/licenses/>.
#include
<Python.h>
#include
<signal-wrapper.hh>
namespace
dynamicgraph
{
namespace
python
{
namespace
signalWrapper
{
void
convert
(
PyObject
*
o
,
bool
&
v
)
{
v
=
(
o
==
Py_True
);
}
void
convert
(
PyObject
*
o
,
int
&
v
)
{
v
=
(
int
)
PyInt_AS_LONG
(
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
]);
}
}
template
<
class
T
,
class
Time
>
bool
SignalWrapper
<
T
,
Time
>::
checkCallable
(
PyObject
*
c
,
std
::
string
&
error
)
{
if
(
PyCallable_Check
(
c
)
==
0
)
{
PyObject
*
str
=
PyObject_Str
(
c
);
error
=
PyString_AsString
(
str
);
error
+=
" is not callable"
;
Py_DECREF
(
str
);
return
false
;
}
return
true
;
}
template
class
SignalWrapper
<
bool
,
int
>;
template
class
SignalWrapper
<
int
,
int
>;
template
class
SignalWrapper
<
float
,
int
>;
template
class
SignalWrapper
<
double
,
int
>;
template
class
SignalWrapper
<
Vector
,
int
>;
}
// namespace dynamicgraph
}
// namespace python
src/signal-wrapper.hh
0 → 100644
View file @
1ff01145
// Copyright (c) 2018, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of dynamic-graph-python.
// dynamic-graph-python is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// dynamic-graph-python is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph-python. If not, see <http://www.gnu.org/licenses/>.
#include
<Python.h>
#include
<dynamic-graph/linear-algebra.h>
#include
<dynamic-graph/signal.h>
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);
}
template
<
class
T
,
class
Time
>
class
SignalWrapper
:
public
Signal
<
T
,
Time
>
{
public:
typedef
Signal
<
T
,
Time
>
parent_t
;
static
bool
checkCallable
(
PyObject
*
c
,
std
::
string
&
error
);
SignalWrapper
(
std
::
string
name
,
PyObject
*
_callable
)
:
parent_t
(
name
)
,
callable
(
_callable
)
// , argsTuple (NULL)
// , argTime (NULL)
// , argValue (NULL)
{
typedef
boost
::
function2
<
T
&
,
T
&
,
Time
>
function_t
;
Py_INCREF
(
callable
);
function_t
f
=
boost
::
bind
(
&
SignalWrapper
::
call
,
this
,
_1
,
_2
);
this
->
setFunction
(
f
);
// argsTuple = PyTuple_New(1);
// argTime = Py
}
virtual
~
SignalWrapper
()
{
Py_DECREF
(
callable
);
// Py_DECREF(args);
};
private:
T
&
call
(
T
&
value
,
Time
t
)
{
char
format
[]
=
"i"
;
PyObject
*
obj
=
PyObject_CallFunction
(
callable
,
format
,
t
);
if
(
obj
==
NULL
)
std
::
cerr
<<
"Could not call callable"
<<
std
::
endl
;
else
{
signalWrapper
::
convert
(
obj
,
value
);
Py_DECREF
(
obj
);
}
return
value
;
}
PyObject
*
callable
;
// PyObject* argsTuple;
// PyObject* argTime;
// PyObject* argValue;
};
}
// namespace dynamicgraph
}
// namespace python
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment