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 457 additions and 977 deletions
# -*- coding: utf-8 -*-
#
# @PROJECT_NAME@ documentation build configuration file, created by
# sphinx-quickstart on Mon Nov 22 16:45:27 2010.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path = [os.path.abspath('@CMAKE_BINARY_DIR@/src')]+sys.path
sys.path = [os.path.abspath('@CMAKE_SOURCE_DIR@/src')]+sys.path
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.pngmath']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'@PROJECT_NAME@'
copyright = u'2010, Florent Lamiraux'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = []
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = '@PROJECT_NAME@doc'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', '@PROJECT_NAME@.tex', u'@PROJECT_NAME@ Documentation',
u'Florent Lamiraux', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}
.. dynamic-graph-python documentation master file, created by
sphinx-quickstart on Mon Nov 22 16:45:27 2010.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to dynamic-graph-python's documentation!
================================================
.. toctree::
:maxdepth: 2
Python module dynamic_graph implements bindings for dynamic-graph_ library. To each main C++ class is associated a Python class. Main classes are listed below.
Entity
------
maps dynamicgraph::Entity_ C++ class.
.. autoclass:: dynamic_graph.entity.Entity
:members:
SignalBase
----------
maps dynamicgraph::SignalBase_ C++ class.
.. autoclass:: dynamic_graph.signal_base.SignalBase
:members:
Other funtions of the module
----------------------------
.. automodule:: dynamic_graph
:members:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. _dynamic-graph: file://@DYNAMIC_GRAPH_DOXYGENDOCDIR@/index.html
.. _Entity: file://@DYNAMIC_GRAPH_DOXYGENDOCDIR@/classdynamicgraph_1_1_entity.html
.. _SignalBase: file://@DYNAMIC_GRAPH_DOXYGENDOCDIR@/classdynamicgraph_1_1_signal_base.html
# Copyright 2010, 2011, Florent Lamiraux, CNRS
#
# This file is part of dynamic-graph-python.
# dynamic-graph-python is free software: you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# dynamic-graph-python is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Lesser Public License for more details. You should have
# received a copy of the GNU Lesser General Public License along with
# dynamic-graph-python. If not, see <http://www.gnu.org/licenses/>.
// -*- mode: c++ -*- // -*- mode: c++ -*-
// Copyright 2011, Florent Lamiraux, CNRS. // Copyright 2011, Florent Lamiraux, CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph 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 is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#ifndef DYNAMIC_GRAPH_PYTHON_API_HH #ifndef DYNAMIC_GRAPH_PYTHON_API_HH
# define DYNAMIC_GRAPH_PYTHON_API_HH #define DYNAMIC_GRAPH_PYTHON_API_HH
# include <dynamic-graph/python/config.hh> #include <dynamic-graph/python/config.hh>
#endif //DYNAMIC_GRAPH_PYTHON_API_HH #endif // DYNAMIC_GRAPH_PYTHON_API_HH
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/value.h>
#include <boost/python.hpp>
namespace dynamicgraph {
namespace python {
namespace convert {
command::Value toValue(boost::python::object o,
const command::Value::Type& type);
boost::python::object fromValue(const command::Value& value);
} // namespace convert
} // namespace python
} // namespace dynamicgraph
#ifndef DYNAMIC_GRAPH_PY
#define DYNAMIC_GRAPH_PY
#include <dynamic-graph/debug.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/signal-base.h>
#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <iostream>
#include <sstream>
#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 {
SignalBase<int>* createSignalWrapper(const char* name, const char* type,
bp::object object);
} // namespace signalBase
namespace entity {
/// \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 {
bp::tuple getEntityClassList();
}
namespace pool {
void writeGraph(const char* filename);
bp::list getEntityList();
const std::map<std::string, Entity*>* getEntityMap();
} // namespace pool
namespace debug {
void addLoggerFileOutputStream(const char* filename);
void addLoggerCoutOutputStream();
void closeLoggerFileOutputStream();
void realTimeLoggerSpinOnce();
void realTimeLoggerDestroy();
void realTimeLoggerInstance();
} // namespace debug
} // namespace python
} // namespace dynamicgraph
#endif
// -*- mode: c++ -*-
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph 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 is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#ifndef DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
# define DYNAMIC_GRAPH_PYTHON_EXCEPTION_PYTHON_H
# include <string>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/exception-abstract.h>
// 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
/*
* Copyright CNRS 2021
*
* Author: Florent Lamiraux
*
* This file is part of sot-core.
*/
#ifndef DYNAMIC_GRAPH_PYTHON_FWD_HH
#define DYNAMIC_GRAPH_PYTHON_FWD_HH
#include <dynamic-graph/fwd.hh>
namespace dynamicgraph {
namespace python {
class Interpreter;
typedef shared_ptr<Interpreter> InterpreterPtr_t;
} // namespace python
} // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_PYTHON_FWD_HH
// -*- mode: c++ -*- // -*- mode: c++ -*-
// Copyright 2011, Florent Lamiraux, CNRS. // Copyright 2011, Florent Lamiraux, CNRS.
//
// This file is part of dynamic-graph-python. #ifndef DYNAMIC_GRAPH_PYTHON_INTERPRETER_H
// dynamic-graph is free software: you can redistribute it and/or #define DYNAMIC_GRAPH_PYTHON_INTERPRETER_H
// 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 is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#undef _POSIX_C_SOURCE #undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE #undef _XOPEN_SOURCE
#include <Python.h> #include <dynamic-graph/python/fwd.hh>
#include <string>
#include "dynamic-graph/python/api.hh"
#include "dynamic-graph/python/deprecated.hh"
#ifndef DYNAMIC_GRAPH_PYTHON_INTERPRETER_H
# define DYNAMIC_GRAPH_PYTHON_INTERPRETER_H
#include "dynamic-graph/python/api.hh" #include "dynamic-graph/python/api.hh"
#include "dynamic-graph/python/python-compat.hh"
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
/// ///
/// This class implements a basis python interpreter. /// This class implements a basis python interpreter.
/// ///
/// String sent to method python are interpreted by an onboard python /// String sent to method python are interpreted by an onboard python
/// interpreter. /// interpreter.
class DYNAMIC_GRAPH_PYTHON_DLLAPI Interpreter class DYNAMIC_GRAPH_PYTHON_DLLAPI Interpreter {
{ public:
public: Interpreter();
Interpreter(); ~Interpreter();
~Interpreter(); /// \brief Method to start python interperter.
/// \brief Method to start python interperter. /// \param command string to execute
/// \param command string to execute /// Method deprecated, you *SHOULD* handle error messages.
/// Method deprecated, you *SHOULD* handle error messages. [[deprecated("you *SHOULD* handle error messages")]] std::string python(
DYNAMIC_GRAPH_PYTHON_DEPRECATED std::string python( const std::string& command ); const std::string& command);
/// \brief Method to start python interperter. /// \brief Method to start python interperter.
/// \param command string to execute, result, stdout, stderr strings /// \param command string to execute, result, stdout, stderr strings
void python( const std::string& command , std::string& result, void python(const std::string& command, std::string& result, std::string& out,
std::string& out, std::string& err); std::string& err);
/// \brief Method to exectue a python script. /// \brief Method to exectue a python script.
/// \param filename the filename /// \param filename the filename
void runPythonFile( std::string filename ); void runPythonFile(std::string filename);
void runPythonFile( std::string filename, std::string& err); void runPythonFile(std::string filename, std::string& err);
void runMain( void ); void runMain(void);
/// \brief Process input stream to send relevant blocks to python /// \brief Process input stream to send relevant blocks to python
/// \param stream input stream /// \param stream input stream
std::string processStream(std::istream& stream, std::ostream& os); std::string processStream(std::istream& stream, std::ostream& os);
/// \brief Return a pointer to the dictionary of global variables /// \brief Return a pointer to the dictionary of global variables
PyObject* globals(); PyObject* globals();
private: private:
/// Pointer to the dictionary of global variables /// The Python thread state
PyObject* globals_; PyThreadState* _pyState;
/// Pointer to the dictionary of local variables /// Pointer to the dictionary of global variables
PyObject* locals_; PyObject* globals_;
PyObject* mainmod_; /// Pointer to the dictionary of local variables
PyObject* traceback_format_exception_; PyObject* locals_;
}; PyObject* mainmod_;
} // namespace python };
} // namespace dynamicgraph } // namespace python
#endif // DYNAMIC_GRAPH_PYTHON_INTERPRETER_H } // namespace dynamicgraph
#endif // DYNAMIC_GRAPH_PYTHON_INTERPRETER_H
#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 <dynamic-graph/entity.h>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/python.hpp>
#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
#ifndef DGPY_PYTHON_COMPAT_H
#define DGPY_PYTHON_COMPAT_H
#include <string>
#define PY_SSIZE_T_CLEAN
#include <Python.h>
// Get any PyObject and get its str() representation as an std::string
std::string obj_to_str(PyObject* o);
#endif
// Copyright (c) 2018, Joseph Mirabel
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
#ifndef DGPY_SIGNAL_WRAPPER
#define DGPY_SIGNAL_WRAPPER
#include <dynamic-graph/entity.h>
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/signal.h>
#include <boost/bind.hpp>
#include <boost/python.hpp>
#include "dynamic-graph/python/python-compat.hh"
namespace dynamicgraph {
namespace python {
class PythonSignalContainer : public Entity {
DYNAMIC_GRAPH_ENTITY_DECL();
public:
using Entity::Entity;
void signalRegistration(const SignalArray<int>& signals);
void rmSignal(const std::string& name);
};
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(pyobject c, std::string& error);
SignalWrapper(std::string name, pyobject callable)
: parent_t(name), callable(callable) {
typedef boost::function2<T&, T&, Time> function_t;
function_t f = boost::bind(&SignalWrapper::call, this, _1, _2);
this->setFunction(f);
}
virtual ~SignalWrapper(){};
private:
T& call(T& value, Time t) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
if (PyGILState_GetThisThreadState() == NULL) {
dgDEBUG(10) << "python thread not initialized" << std::endl;
}
pyobject obj = callable(t);
value = boost::python::extract<T>(obj);
PyGILState_Release(gstate);
return value;
}
pyobject callable;
};
} // namespace python
} // namespace dynamicgraph
#endif
// Copyright 2020, Joseph Mirabel, LAAS-CNRS.
#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 <boost/python.hpp>
#include <sstream>
#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>
auto exposeSignalWrapper(const std::string& name) {
namespace bp = boost::python;
typedef SignalWrapper<T, Time> S_t;
bp::class_<S_t, bp::bases<Signal<T, Time> >, boost::noncopyable> obj(
name.c_str(), bp::no_init);
return obj;
}
template <typename T, typename Time>
auto exposeSignalPtr(const std::string& name) {
namespace bp = boost::python;
typedef SignalPtr<T, Time> S_t;
bp::class_<S_t, bp::bases<Signal<T, Time> >, boost::noncopyable> obj(
name.c_str(), bp::no_init);
return obj;
}
template <typename T, typename Time>
auto exposeSignalTimeDependent(const std::string& name) {
namespace bp = boost::python;
typedef SignalTimeDependent<T, Time> S_t;
bp::class_<S_t, bp::bases<Signal<T, Time> >, boost::noncopyable> obj(
name.c_str(), bp::no_init);
return obj;
}
template <typename T, typename Time>
void exposeSignalsOfType(const std::string& name) {
exposeSignal<T, Time>("Signal" + name);
exposeSignalPtr<T, Time>("SignalPtr" + name);
exposeSignalWrapper<T, Time>("SignalWrapper" + name);
exposeSignalTimeDependent<T, Time>("SignalTimeDependent" + name);
}
} // namespace python
} // namespace dynamicgraph
<?xml version="1.0"?>
<package format="3">
<name>dynamic-graph-python</name>
<version>4.0.11</version>
<description>Dynamic graph library Python bindings</description>
<maintainer email="guilhem.saurel@laas.fr">Guilhem Saurel</maintainer>
<author>Nicolas Mansard</author>
<author>Olivier Stasse</author>
<license>BSD</license>
<url type="website">https://github.com/stack-of-tasks/dynamic-graph-python</url>
<build_depend>git</build_depend>
<build_depend>doxygen</build_depend>
<!-- The following tag is recommended by REP-136 -->
<exec_depend condition="$ROS_VERSION == 1">catkin</exec_depend>
<depend condition="$ROS_PYTHON_VERSION == 2">python</depend>
<depend condition="$ROS_PYTHON_VERSION == 3">python3</depend>
<depend condition="$ROS_PYTHON_VERSION == 2">python-numpy</depend>
<depend condition="$ROS_PYTHON_VERSION == 3">python3-numpy</depend>
<depend>eigen</depend>
<depend>boost</depend>
<depend>eigenpy</depend>
<depend>dynamic-graph</depend>
<buildtool_depend>cmake</buildtool_depend>
<export>
<build_type>cmake</build_type>
</export>
</package>
[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
# Copyright 2010, 2011, Florent Lamiraux, Thomas Moulard, JRL, CNRS/AIST # Python bindings
#
# 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/>.
# add_subdirectory(dynamic_graph)
# Python
#
set(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
INCLUDE(../cmake/python.cmake)
FINDPYTHON()
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) set(PYTHON_SOURCES __init__.py attrpath.py entity.py signal_base.py
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS} ${PYTHON_LIBRARY_DIRS}) script_shortcuts.py tools.py)
INCLUDE(../cmake/python.cmake) foreach(source ${PYTHON_SOURCES})
# python_install_on_site(dynamic_graph ${source})
# endforeach(source)
# Python interpreter
#
#
SET(LIBRARY_NAME ${PROJECT_NAME})
ADD_LIBRARY(${LIBRARY_NAME}
SHARED
interpreter.cc)
TARGET_LINK_LIBRARIES(${LIBRARY_NAME}
${PYTHON_LIBRARY})
IF(UNIX)
TARGET_LINK_LIBRARIES(${LIBRARY_NAME} ${Boost_LIBRARIES})
ENDIF(UNIX)
SET_TARGET_PROPERTIES(${LIBRARY_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION})
PKG_CONFIG_USE_DEPENDENCY(${LIBRARY_NAME} dynamic-graph)
INSTALL(TARGETS ${LIBRARY_NAME}
DESTINATION ${CMAKE_INSTALL_LIBDIR})
SET(EXECUTABLE_NAME dg-python)
ADD_EXECUTABLE(${EXECUTABLE_NAME} dg-python.cc)
TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME}
${LIBRARY_NAME}
)
INSTALL(TARGETS dg-python DESTINATION ${CMAKE_INSTALL_BINDIR})
#
#
# Python bindings
#
#
SET(PYTHON_MODULE wrap)
ADD_LIBRARY(${PYTHON_MODULE}
MODULE
exception-python.cc
convert-dg-to-py.cc
dynamic-graph-py.cc
signal-base-py.cc
entity-py.cc
factory-py.cc
pool-py.cc
signal-caster-py.cc
)
# Remove prefix lib
SET_TARGET_PROPERTIES(${PYTHON_MODULE}
PROPERTIES PREFIX "")
PKG_CONFIG_USE_DEPENDENCY(${PYTHON_MODULE} dynamic-graph)
TARGET_LINK_LIBRARIES(${PYTHON_MODULE} ${PYTHON_LIBRARY})
CONFIG_FILES(link-to-python.hh)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}
${CMAKE_CURRENT_BINARY_DIR})
#
# Installation
#
SET(PYTHON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/dynamic_graph)
INSTALL(TARGETS ${PYTHON_MODULE}
DESTINATION
${PYTHON_INSTALL_DIR})
SET (PYTHON_SOURCES
__init__.py
attrpath.py
entity.py
signal_base.py
matlab.py
script_shortcuts.py
tools.py
)
FOREACH (SOURCE ${PYTHON_SOURCES})
PYTHON_INSTALL_ON_SITE(dynamic_graph ${SOURCE} )
ENDFOREACH (SOURCE)
# --- ADD the wrap on the dg modules # --- ADD the wrap on the dg modules
# Tracer plugin link_directories(${DYNAMIC_GRAPH_PLUGINDIR})
IF(WIN32) dynamic_graph_python_module(
SET(TRACER_PLUGIN ${DYNAMIC_GRAPH_PLUGINDIR}/tracer${CMAKE_STATIC_LIBRARY_SUFFIX}) "tracer" dynamic-graph::tracer tracer-wrap SOURCE_PYTHON_MODULE
ELSE(WIN32) ${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer/wrap.cc)
SET(TRACER_PLUGIN ${DYNAMIC_GRAPH_PLUGINDIR}/tracer${CMAKE_SHARED_LIBRARY_SUFFIX}) dynamic_graph_python_module(
ENDIF(WIN32) "tracer_real_time" dynamic-graph::tracer-real-time tracer_real_time-wrap
DYNAMIC_GRAPH_PYTHON_MODULE("tracer" ${TRACER_PLUGIN} tracer-wrap) SOURCE_PYTHON_MODULE
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_graph/tracer_real_time/wrap.cc)
# TracerRealTime plugin
IF(WIN32)
SET(TRACERREALTIME_PLUGIN ${DYNAMIC_GRAPH_PLUGINDIR}/tracer-real-time${CMAKE_STATIC_LIBRARY_SUFFIX})
ELSE(WIN32)
SET(TRACERREALTIME_PLUGIN ${DYNAMIC_GRAPH_PLUGINDIR}/tracer-real-time${CMAKE_SHARED_LIBRARY_SUFFIX})
ENDIF(WIN32)
DYNAMIC_GRAPH_PYTHON_MODULE("tracer_real_time" ${TRACERREALTIME_PLUGIN} tracer_real_time-wrap)
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph-python is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// dynamic-graph-python is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Lesser Public License for more details. You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include "../src/convert-dg-to-py.hh"
#include <iostream>
#include <sstream>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/signal.h>
#include <dynamic-graph/signal-caster.h>
namespace dynamicgraph {
using ::dynamicgraph::SignalBase;
namespace python {
namespace convert {
void fillMatrixRow(Matrix& m, unsigned iRow, PyObject* tuple)
{
if (PyTuple_Size(tuple) != (int)m.nbCols()) {
throw ExceptionPython(ExceptionPython::MATRIX_PARSING,
"lines of matrix have different sizes.");
}
for (unsigned int iCol=0; iCol < m.nbCols(); iCol++) {
PyObject* pyDouble = PyTuple_GetItem(tuple, iCol);
if (PyFloat_Check(pyDouble))
m(iRow, iCol) = PyFloat_AsDouble(pyDouble);
else if(PyInt_Check(pyDouble))
m(iRow, iCol) = (int)PyInt_AS_LONG(pyDouble)+0.0;
else
throw ExceptionPython(ExceptionPython::MATRIX_PARSING,
"element of matrix should be "
"a floating point number.");
}
}
command::Value pythonToValue(PyObject* pyObject,
const command::Value::Type& valueType)
{
using command::Value;
bool bvalue;
unsigned uvalue;
int ivalue;
float fvalue;
double dvalue;
std::string svalue;
Vector v;
Matrix m;
Py_ssize_t nCols;
Py_ssize_t size;
PyObject* row;
Py_ssize_t nRows;
switch (valueType) {
case (Value::BOOL) :
if (!PyBool_Check(pyObject)) {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"bool");
}
bvalue = PyObject_IsTrue(pyObject);
return Value(bvalue);
break;
case (Value::UNSIGNED) :
if (!PyInt_Check(pyObject)) {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"unsigned int");
}
uvalue = (unsigned int)PyInt_AsUnsignedLongMask(pyObject);
return Value(uvalue);
break;
case (Value::INT) :
if (!PyInt_Check(pyObject)) {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"int");
}
ivalue = (int)PyInt_AS_LONG(pyObject);
return Value(ivalue);
break;
case (Value::FLOAT) :
if (PyFloat_Check(pyObject)) {
fvalue = (float)PyFloat_AsDouble(pyObject);
return Value(fvalue);
} else if (PyInt_Check(pyObject)) {
fvalue = (float)PyInt_AS_LONG(pyObject);
return Value(fvalue);
} else {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"float");
}
break;
case (Value::DOUBLE) :
if (PyFloat_Check(pyObject)) {
dvalue = PyFloat_AsDouble(pyObject);
return Value(dvalue);
} else if (PyInt_Check(pyObject)) {
dvalue = (double)PyInt_AS_LONG(pyObject);
return Value(dvalue);
} else {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"double");
}
break;
case (Value::STRING) :
if (!PyString_Check(pyObject)) {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"string");
}
svalue = PyString_AsString(pyObject);
return Value(svalue);
break;
case (Value::VECTOR) :
// Check that argument is a tuple
if (!PyTuple_Check(pyObject)) {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"vector");
}
size = PyTuple_Size(pyObject);
v.resize(size);
for (Py_ssize_t i=0; i<size; i++) {
PyObject* pyDouble = PyTuple_GetItem(pyObject, i);
if (PyFloat_Check(pyDouble))
v(i) = PyFloat_AsDouble(pyDouble);
else if(PyInt_Check(pyDouble))
v(i) = (int)PyInt_AS_LONG(pyDouble)+0.0;
else
throw ExceptionPython(ExceptionPython::VECTOR_PARSING,
"element of vector should be a floating "
"point number.");
}
return Value(v);
break;
case (Value::MATRIX) :
// Check that argument is a tuple
if (!PyTuple_Check(pyObject)) {
throw ExceptionPython(ExceptionPython::VALUE_PARSING,
"matrix");
}
nRows = PyTuple_Size(pyObject);
if (nRows == 0) {
return Value(Matrix());
}
row = PyTuple_GetItem(pyObject, 0);
if (!PyTuple_Check(row)) {
throw ExceptionPython(ExceptionPython::MATRIX_PARSING,
"matrix");
}
nCols = PyTuple_Size(row);
m.resize((unsigned int)nRows, (unsigned int)nCols);
fillMatrixRow(m, 0, row);
for (Py_ssize_t iRow=1; iRow<nRows; iRow++) {
row = PyTuple_GetItem(pyObject, iRow);
if (!PyTuple_Check(row)) {
throw ExceptionPython(ExceptionPython::MATRIX_PARSING,
"matrix");
}
fillMatrixRow(m, static_cast<unsigned> (iRow), row);
}
return Value(m);
break;
default:
std::cerr << "Only int, double and string are supported."
<< std::endl;
}
return Value();
}
PyObject* vectorToPython(const Vector& vector)
{
PyObject* tuple = PyTuple_New(vector.size());
for (unsigned int index = 0; index < vector.size(); index++) {
PyObject* pyDouble = PyFloat_FromDouble(vector(index));
PyTuple_SET_ITEM(tuple, index, pyDouble);
}
return tuple;
}
PyObject* matrixToPython(const Matrix& matrix)
{
PyObject* tuple = PyTuple_New(matrix.nbRows());
for (unsigned int iRow = 0; iRow < matrix.nbRows(); iRow++) {
PyObject* row = PyTuple_New(matrix.nbCols());
for (unsigned iCol=0; iCol < matrix.nbCols(); iCol++) {
PyObject* pyDouble = PyFloat_FromDouble(matrix(iRow, iCol));
PyTuple_SET_ITEM(row, iCol, pyDouble);
}
PyTuple_SET_ITEM(tuple, iRow, row);
}
return tuple;
}
PyObject* valueToPython(const command::Value& value)
{
using command::Value;
bool boolValue;
unsigned unsignedValue;
int intValue;
float floatValue;
double doubleValue;
std::string stringValue;
Vector vectorValue;
Matrix matrixValue;
switch(value.type()) {
case (Value::BOOL) :
boolValue = value.value();
if (boolValue) {
return PyBool_FromLong(1);
}
return PyBool_FromLong(0);
case (Value::UNSIGNED) :
unsignedValue = value.value();
return Py_BuildValue("I", unsignedValue);
case (Value::INT) :
intValue = value.value();
return Py_BuildValue("i", intValue);
case (Value::FLOAT) :
floatValue = value.value();
return Py_BuildValue("f", floatValue);
case (Value::DOUBLE) :
doubleValue = value.value();
return Py_BuildValue("d", doubleValue);
case (Value::STRING) :
stringValue = (std::string) value.value();
return Py_BuildValue("s", stringValue.c_str());
case (Value::VECTOR) :
vectorValue = value.value();
return vectorToPython(vectorValue);
case (Value::MATRIX) :
matrixValue = value.value();
return matrixToPython(matrixValue);
default:
return Py_BuildValue("");
}
return Py_BuildValue("");
}
} // namespace dynamicgraph
} // namespace python
} // namespace convert
// Copyright 2010, Florent Lamiraux, Thomas Moulard, LAAS-CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph-python is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// dynamic-graph-python is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Lesser Public License for more details. You should
// have received a copy of the GNU Lesser General Public License along
// with dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <Python.h>
#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* valueToPython(const ::dynamicgraph::command::Value& value);
} // namespace dynamicgraph
} // namespace python
}
// Copyright 2011, Florent Lamiraux CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph 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 is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
#include <dynamic-graph/debug.h>
#include "dynamic-graph/python/interpreter.hh"
using namespace dynamicgraph;
// Factorize exception catching code.
#define CATCH_EXCEPTIONS() \
catch (std::exception& e) \
{ \
std::cout \
<< errorPrefix \
<< e.what () << std::endl; \
} \
catch (const char* str) \
{ \
std::cout << errorPrefix \
<< "Unknown exception " << str << std::endl; \
} \
catch (...) \
{ \
dgDEBUG(5) << errorPrefix << " Unknown exception " << std::endl; \
} \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
struct Options
{
/// \brief Prologue path (a prologue is a script implicitly
/// evaluated at start-up).
};
int main (int argc, char** argv)
{
dgDEBUGIN(15);
dgDEBUG(5) << " Loading..." << std::endl;
// Parse options.
std::vector<std::string> inputs;
namespace po = boost::program_options;
po::options_description desc ("Allowed options");
desc.add_options ()
("input,i",
po::value<std::vector<std::string> >(&inputs),
"file(s) evaluated at start-up")
("help,h", "produce help message")
;
po::positional_options_description p;
p.add("input", -1);
po::variables_map vm;
try
{
po::store(po::command_line_parser(argc, argv).
options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count ("help"))
{
std::cout << "Usage: " << argv[0] << " [options]" << std::endl
<< desc << std::endl
<< "Report bugs to <hpp@laas.fr>" << std::endl;
return 1;
}
}
catch (po::error& error)
{
std::cerr << "Error while parsing argument: "
<< error.what () << std::endl;
return 1;
}
std::list<std::string> inputList (inputs.begin (),
inputs.end ());
// Load all input files.
dynamicgraph::python::Interpreter interpreter;
BOOST_FOREACH (const std::string& pathStr, inputList)
{
boost::filesystem::path path (pathStr);
std::stringstream ss;
#if BOOST_FILESYSTEM_VERSION == 2
ss << "!! In file <" << path.file_string () << "> : ";
#else
ss << "!! In file <" << path.string () << "> : ";
#endif
std::string errorPrefix = ss.str ();
try
{
#if BOOST_FILESYSTEM_VERSION == 2
interpreter.runPythonFile (path.file_string ());
#else
interpreter.runPythonFile (path.string ());
#endif
}
CATCH_EXCEPTIONS ();
return 0;
}
std::string errorPrefix = "";
std::string command;
while(1) {
command = interpreter.processStream(std::cin, std::cout);
if (command != "\n") {
std::string result, out, err;
interpreter.python(command, result, out, err);
if (out != "") {
std::cout << out << std::endl;
}
if (err != "") {
std::cout << err << std::endl;
}
if (result != "None") {
std::cout << result << std::endl;
}
}
if (std::cin.eof ())
break;
}
std::cout << std::endl;
return 0;
}