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
  • cberge/dynamic-graph
  • ostasse/dynamic-graph
  • gsaurel/dynamic-graph
  • stack-of-tasks/dynamic-graph
4 results
Show changes
Showing
with 1792 additions and 1440 deletions
......@@ -2,262 +2,213 @@
// 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_DEBUG_HH
# define DYNAMIC_GRAPH_DEBUG_HH
# include <cstdio>
# include <cstdarg>
# include <iostream>
# include <fstream>
# include <sstream>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/dynamic-graph-api.h>
# ifndef VP_DEBUG_MODE
# define VP_DEBUG_MODE 0
# endif //! VP_DEBUG_MODE
# ifndef VP_TEMPLATE_DEBUG_MODE
# define VP_TEMPLATE_DEBUG_MODE 0
# endif //! VP_TEMPLATE_DEBUG_MODE
#define DG_COMMON_TRACES \
do { \
va_list arg; \
va_start (arg, format); \
vsnprintf (charbuffer, SIZE, format, arg); \
va_end (arg); \
outputbuffer << tmpbuffer.str () << charbuffer << std::endl; \
} while(0)
namespace dynamicgraph
{
/// \ingroup debug
///
/// \brief Logging class.
///
/// This class should never be used directly, please use the
/// debugging macro instead.
class DYNAMIC_GRAPH_DLLAPI DebugTrace
{
public:
static const int SIZE = 512;
std::stringstream tmpbuffer;
std::ostream& outputbuffer;
char charbuffer[SIZE+1];
int traceLevel;
int traceLevelTemplate;
DebugTrace (std::ostream& os)
: outputbuffer (os)
{}
inline void trace (const int level, const char* format, ...)
{
if (level <= traceLevel)
DG_COMMON_TRACES; tmpbuffer.str("");
}
inline void trace (const char* format, ...)
{
DG_COMMON_TRACES;
#define DYNAMIC_GRAPH_DEBUG_HH
#include <dynamic-graph/dynamic-graph-api.h>
#include <cstdarg>
#include <cstdio>
#include <dynamic-graph/fwd.hh>
#include <fstream>
#include <sstream>
#ifndef VP_DEBUG_MODE
#define VP_DEBUG_MODE 0
#endif //! VP_DEBUG_MODE
#ifndef VP_TEMPLATE_DEBUG_MODE
#define VP_TEMPLATE_DEBUG_MODE 0
#endif //! VP_TEMPLATE_DEBUG_MODE
#define DG_COMMON_TRACES \
do { \
va_list arg; \
va_start(arg, format); \
vsnprintf(charbuffer, SIZE, format, arg); \
va_end(arg); \
outputbuffer << tmpbuffer.str() << charbuffer << std::endl; \
} while (0)
namespace dynamicgraph {
/// \ingroup debug
///
/// \brief Logging class.
///
/// This class should never be used directly, please use the
/// debugging macro instead.
class DYNAMIC_GRAPH_DLLAPI DebugTrace {
public:
static const int SIZE = 512;
std::stringstream tmpbuffer;
std::ostream &outputbuffer;
char charbuffer[SIZE + 1];
int traceLevel;
int traceLevelTemplate;
DebugTrace(std::ostream &os) : outputbuffer(os) {}
inline void trace(const int level, const char *format, ...) {
if (level <= traceLevel) DG_COMMON_TRACES;
tmpbuffer.str("");
}
inline void trace(const char *format, ...) {
DG_COMMON_TRACES;
tmpbuffer.str("");
}
inline void trace(const int level = -1) {
if (level <= traceLevel) {
outputbuffer << tmpbuffer.str();
tmpbuffer.str("");
}
}
inline void trace (const int level=-1)
{
if (level <= traceLevel)
outputbuffer << tmpbuffer.str (); tmpbuffer.str("");
}
inline void traceTemplate(const int level, const char *format, ...) {
if (level <= traceLevelTemplate) DG_COMMON_TRACES;
tmpbuffer.str("");
}
inline void traceTemplate (const int level, const char* format, ...)
{
if (level <= traceLevelTemplate)
DG_COMMON_TRACES;
tmpbuffer.str("");
}
inline void traceTemplate (const char* format, ...)
{
DG_COMMON_TRACES;
tmpbuffer.str("");
}
inline void traceTemplate(const char *format, ...) {
DG_COMMON_TRACES;
tmpbuffer.str("");
}
inline DebugTrace& pre (const std::ostream&)
{
return *this;
}
inline DebugTrace &pre(const std::ostream &) { return *this; }
inline DebugTrace& pre (const std::ostream&, int level)
{
traceLevel = level;
return *this;
}
inline DebugTrace &pre(const std::ostream &, int level) {
traceLevel = level;
return *this;
}
static const char* DEBUG_FILENAME_DEFAULT;
static void openFile (const char* filename = DEBUG_FILENAME_DEFAULT);
static void closeFile( const char* filename = DEBUG_FILENAME_DEFAULT);
};
static const char *DEBUG_FILENAME_DEFAULT;
static void openFile(const char *filename = DEBUG_FILENAME_DEFAULT);
static void closeFile(const char *filename = DEBUG_FILENAME_DEFAULT);
};
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgDEBUGFLOW;
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW;
} // end of namespace dynamicgraph
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgDEBUGFLOW;
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW;
} // end of namespace dynamicgraph
# ifdef VP_DEBUG
#ifdef VP_DEBUG
# define dgPREDEBUG \
__FILE__ << ": " <<__FUNCTION__ << "(#" << __LINE__ << ") :"
# define dgPREERROR \
"\t!! "<<__FILE__ << ": " <<__FUNCTION__ << "(#" << __LINE__ << ") :"
#define dgPREDEBUG __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :"
#define dgPREERROR \
"\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :"
# define dgDEBUG(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good ())) \
; \
else \
#define dgDEBUG(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
dgDEBUGFLOW.outputbuffer << dgPREDEBUG
# define dgDEBUGMUTE(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good ())) \
; \
else \
#define dgDEBUGMUTE(level) \
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
dgDEBUGFLOW.outputbuffer
# define dgERROR \
if (!dgDEBUGFLOW.outputbuffer.good ()) \
; \
else \
#define dgERROR \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgERRORFLOW.outputbuffer << dgPREERROR
# define dgDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good ()) \
; \
else \
dgDEBUGFLOW.pre (dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_DEBUG_MODE).trace
#define dgDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgDEBUGFLOW.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_DEBUG_MODE).trace
# define dgERRORF \
if (!dgDEBUGFLOW.outputbuffer.good ()) \
; \
else \
dgERRORFLOW.pre (dgERRORFLOW.tmpbuffer << dgPREERROR).trace
#define dgERRORF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgERRORFLOW.pre(dgERRORFLOW.tmpbuffer << dgPREERROR).trace
// TEMPLATE
# define dgTDEBUG(level) \
if ((level > VP_TEMPLATE_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good ())) \
; \
else \
#define dgTDEBUG(level) \
if ((level > VP_TEMPLATE_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \
; \
else \
dgDEBUGFLOW.outputbuffer << dgPREDEBUG
# define dgTDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good ()) \
; \
else \
dgDEBUGFLOW.pre \
(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE).trace
#define dgTDEBUGF \
if (!dgDEBUGFLOW.outputbuffer.good()) \
; \
else \
dgDEBUGFLOW \
.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE) \
.trace
inline bool dgDEBUG_ENABLE (const int & level)
{
return level<=VP_DEBUG_MODE;
}
inline bool dgDEBUG_ENABLE(const int &level) { return level <= VP_DEBUG_MODE; }
inline bool dgTDEBUG_ENABLE (const int & level)
{
return level<=VP_TEMPLATE_DEBUG_MODE;
inline bool dgTDEBUG_ENABLE(const int &level) {
return level <= VP_TEMPLATE_DEBUG_MODE;
}
# else // VP_DEBUG
#else // VP_DEBUG
# define dgPREERROR \
"\t!! "<<__FILE__ << ": " <<__FUNCTION__ << "(#" << __LINE__ << ") :"
#define dgPREERROR \
"\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :"
# define dgDEBUG(level) \
if (1) \
; \
else \
std::cout
#define dgDEBUG(level) \
if (1) \
; \
else \
::dynamicgraph::__null_stream()
# define dgDEBUGMUTE (level) \
if (1) \
; \
else \
std::cout
#define dgDEBUGMUTE \
(level) if (1); \
else ::dynamicgraph::__null_stream()
# define dgERROR \
dgERRORFLOW.outputbuffer << dgPREERROR
#define dgERROR dgERRORFLOW.outputbuffer << dgPREERROR
inline void dgDEBUGF (const int, const char*, ...)
{
return;
}
inline void dgDEBUGF(const int, const char *, ...) { return; }
inline void dgDEBUGF (const char*, ...)
{
return;
}
inline void dgDEBUGF(const char *, ...) { return; }
inline void dgERRORF (const int, const char*, ...)
{
return;
}
inline void dgERRORF(const int, const char *, ...) { return; }
inline void dgERRORF(const char *, ...) { return; }
inline void dgERRORF (const char*, ...)
{
return;
namespace dynamicgraph {
inline std::ostream &__null_stream() {
// This function should never be called. With -O3,
// it should not appear in the generated binary.
static std::ostream os(NULL);
return os;
}
} // namespace dynamicgraph
// TEMPLATE
# define dgTDEBUG(level) \
if (1) \
; \
else \
std::cout
inline void dgTDEBUGF (const int, const char*, ...)
{
return;
}
#define dgTDEBUG(level) \
if (1) \
; \
else \
::dynamicgraph::__null_stream()
inline void dgTDEBUGF (const char*, ...)
{
return;
}
inline void dgTDEBUGF(const int, const char *, ...) { return; }
# define dgDEBUG_ENABLE(level) false
# define dgTDEBUG_ENABLE(level) false
inline void dgTDEBUGF(const char *, ...) { return; }
# endif //! VP_DEBUG
#define dgDEBUG_ENABLE(level) false
#define dgTDEBUG_ENABLE(level) false
# define dgDEBUGIN(level) \
dgDEBUG(level) << "# In {" << std::endl
#endif //! VP_DEBUG
# define dgDEBUGOUT(level) \
dgDEBUG(level) << "# Out }" << std::endl
#define dgDEBUGIN(level) dgDEBUG(level) << "# In {" << std::endl
# define dgDEBUGINOUT(level) \
dgDEBUG(level) << "# In/Out { }" << std::endl
#define dgDEBUGOUT(level) dgDEBUG(level) << "# Out }" << std::endl
#define dgDEBUGINOUT(level) dgDEBUG(level) << "# In/Out { }" << std::endl
# define dgTDEBUGIN(level) \
dgTDEBUG(level) << "# In {" << std::endl
#define dgTDEBUGIN(level) dgTDEBUG(level) << "# In {" << std::endl
# define dgTDEBUGOUT(level) \
dgTDEBUG(level) << "# Out }" << std::endl
#define dgTDEBUGOUT(level) dgTDEBUG(level) << "# Out }" << std::endl
# define dgTDEBUGINOUT(level) \
dgTDEBUG(level) << "# In/Out { }" << std::endl
#define dgTDEBUGINOUT(level) dgTDEBUG(level) << "# In/Out { }" << std::endl
#endif //! DYNAMIC_GRAPH_DEBUG_HH
#endif //! DYNAMIC_GRAPH_DEBUG_HH
......@@ -2,20 +2,8 @@
// 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_API_H
# define DYNAMIC_GRAPH_API_H
# include <dynamic-graph/config.hh>
#endif //! DYNAMIC_GRAPH_API_H
#define DYNAMIC_GRAPH_API_H
#include <dynamic-graph/config.hh>
#endif //! DYNAMIC_GRAPH_API_H
......@@ -3,158 +3,164 @@
//
// Author: Rohan Budhiraja
//
// 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 Lesser General 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_EIGEN_IO_H
#define DYNAMIC_GRAPH_EIGEN_IO_H
#include <iostream>
#include <boost/format.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <dynamic-graph/exception-signal.h>
#include <dynamic-graph/linear-algebra.h>
#include <Eigen/Geometry>
#include <boost/format.hpp>
#include <boost/numeric/conversion/cast.hpp>
using dynamicgraph::ExceptionSignal;
//TODO: Eigen 3.3 onwards has a global Eigen::Index definition.
//If Eigen version is updated, use Eigen::Index instead of this macro.
// TODO: Eigen 3.3 onwards has a global Eigen::Index definition.
// If Eigen version is updated, use Eigen::Index instead of this macro.
/* \brief Eigen Vector input from istream
*
* Input Vector format: [N](val1,val2,val3,...,valN)
* e.g. [5](1,23,32.2,12.12,32)
*/
/* \brief Eigen Vector input from istream
*
* Input Vector format: [N](val1,val2,val3,...,valN)
* e.g. [5](1,23,32.2,12.12,32)
*/
namespace Eigen {
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE eigen_index;
inline std::istringstream& operator >> (std::istringstream &iss,
dynamicgraph::Vector &inst) {
unsigned int _size;
double _dbl_val;
char _ch;
boost::format fmt ("Failed to enter %s as vector. Reenter as [N](val1,val2,val3,...,valN)");
fmt %iss.str();
if(iss>> _ch && _ch != '['){
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE eigen_index;
inline std::istringstream &operator>>(std::istringstream &iss,
dynamicgraph::Vector &inst) {
unsigned int _size;
double _dbl_val;
char _ch;
boost::format fmt(
"Failed to enter %s as vector."
" Reenter as [N](val1,val2,val3,...,valN)");
fmt % iss.str();
if (iss >> _ch && _ch != '[') {
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
} else {
if (iss >> _size && !iss.fail()) {
inst.resize(_size);
} else
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
if (iss >> _ch && _ch != ']')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
else {
if(iss >> _size && !iss.fail()){
inst.resize(_size);
}
else
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
if(iss >> _ch && _ch != ']')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
if (iss >> _ch && _ch != '(')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
else {
if(iss>> _ch && _ch != '(')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
else {
for (unsigned int i=0;i<_size; i++){
iss >> _dbl_val;
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
inst(i) = _dbl_val;
}
if(iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
for (unsigned int i = 0; i < _size; i++) {
iss >> _dbl_val;
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
inst(i) = _dbl_val;
}
if (iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
}
return iss;
}
return iss;
}
/* \brief Eigen Matrix input from istream
*
* Matrix format: [M,N]((val11,val12,val13,...,val1N),...,(valM1,valM2,...,valMN))
* e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2))
*/
template<typename Derived>
inline std::istringstream& operator >> (std::istringstream &iss,
DenseBase<Derived> &inst) {
unsigned int _colsize;
unsigned int _rowsize;
double _dbl_val;
char _ch;
boost::format fmt ("Failed to enter %s as vector. Reenter as [N](val1,val2,val3,...,valN)");
fmt %iss.str();
if(iss>> _ch && _ch != '['){
/* \brief Eigen Matrix input from istream
*
* Matrix format: [M,N]((val11,val12,val13,...,val1N),...,
* (valM1,valM2,...,valMN))
* e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2))
*/
template <typename Derived>
inline std::istringstream &operator>>(std::istringstream &iss,
DenseBase<Derived> &inst) {
unsigned int _colsize;
unsigned int _rowsize;
double _dbl_val;
char _ch;
boost::format fmt(
"Failed to enter %s as matrix. Reenter as "
"((val11,val12,val13,...,val1N),"
"...,(valM1,valM2,...,valMN))");
MatrixXd _tmp_matrix;
fmt % iss.str();
if (iss >> _ch && _ch != '[') {
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
} else {
iss >> _rowsize;
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
iss >> _colsize;
if (iss.fail())
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
else {
iss >>_rowsize;
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
iss >> _colsize;
if (iss.fail())
throw ExceptionSignal(ExceptionSignal::GENERIC,fmt.str());
_tmp_matrix.resize(_rowsize, _colsize);
if (iss >> _ch && _ch != ']')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
else {
inst.resize(_rowsize,_colsize);
if(iss >> _ch && _ch != ']')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
else {
if(iss>> _ch && _ch != '(')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
else {
for (unsigned int j=0;j<_rowsize; j++){
if(iss>> _ch && _ch != '(')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
for (unsigned int i=0;i<_colsize; i++){
iss >> _dbl_val;
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
inst(j,i) = _dbl_val;
}
if(iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
if (iss.peek() == ',' || iss.peek() == ' ')
iss.ignore();
}
if(iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
}
if (iss >> _ch && _ch != '(')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
else {
for (unsigned int j = 0; j < _rowsize; j++) {
if (iss >> _ch && _ch != '(')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
for (unsigned int i = 0; i < _colsize; i++) {
iss >> _dbl_val;
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
_tmp_matrix(j, i) = _dbl_val;
}
if (iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
if (iss.peek() == ',' || iss.peek() == ' ') iss.ignore();
}
if (iss >> _ch && _ch != ')')
throw ExceptionSignal(ExceptionSignal::GENERIC, fmt.str());
}
}
}
return iss;
}
inst = _tmp_matrix;
return iss;
}
inline std::istringstream &operator>>(std::istringstream &iss,
Transform<double, 3, Affine> &inst) {
MatrixXd M;
iss >> M;
inst.matrix() = M;
return iss;
}
/* \brief Eigen Homogeneous Matrix output
*
* Matrix format: [M,N]((val11,val12,val13,...,val1N),...,
* (valM1,valM2,...,valMN))
* e.g. [2,5]((1 23 32.2 12.12 32),(2 32 23 92.01 19.2))
*/
inline std::ostream &operator<<(std::ostream &os,
Transform<double, 3, Affine> MH) {
IOFormat boostFmt(StreamPrecision, DontAlignCols, ",", ",", "(", ")", "(",
")");
os << "[4,4]" << MH.matrix().format(boostFmt);
return os;
}
inline std::ostream &operator<<(std::ostream &os, AngleAxisd quat) {
VectorXd v(4);
v(0) = quat.angle();
v.tail<3>() = quat.axis();
os << v;
return os;
}
inline std::istringstream& operator >> (std::istringstream &iss,
Transform<double,3,Affine> &inst) {
Matrix4d M; iss >> M; inst = M; return iss; }
inline std::ostream& operator << (std::ostream &os,
Transform<double,3,Affine> MH) {
os << MH.matrix(); return os; }
inline std::ostream& operator << (std::ostream &os,
AngleAxisd quat) {
Vector4d v; v(0) = quat.angle(); v.tail<3>() = quat.axis();
os << v; return os; }
inline std::istringstream& operator >> (std::istringstream &iss,
AngleAxisd &inst) {
Vector4d v; iss >>v;
inst.angle() = v(0); inst.axis() = v.tail<3>();
return iss; }
inline std::istringstream &operator>>(std::istringstream &iss,
AngleAxisd &inst) {
VectorXd v(4);
iss >> v;
inst.angle() = v(0);
inst.axis() = v.tail<3>();
return iss;
}
} // namespace Eigen
#endif //DYNAMIC_GRAPH_EIGEN_IO_H
#endif // DYNAMIC_GRAPH_EIGEN_IO_H
/*
* Copyright 2011, Nicolas Mansard, LAAS-CNRS
*
* This file is part of sot-core.
* sot-core 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.
* sot-core 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 Lesser General Public License for more details. You should
* have received a copy of the GNU Lesser General Public License along
* with sot-core. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __sot_core_entity_helper_H__
#define __sot_core_entity_helper_H__
namespace dynamicgraph {
namespace dynamicgraph
{
template <typename Ent>
struct EntityHelper {
typedef Ent EntityClassName;
// static const std::string CLASS_NAME; TO BE ADDED IN DG DIRECTLY
};
template< typename Ent >
struct EntityHelper
{
typedef Ent EntityClassName;
//static const std::string CLASS_NAME; TO BE ADDED IN DG DIRECTLY
};
} // namespace dynamicgraph
} // namespace dynamicgraph
#endif // __sot_core_entity_helper_H__
#endif // __sot_core_entity_helper_H__
......@@ -2,33 +2,21 @@
// 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_ENTITY_H
# define DYNAMIC_GRAPH_ENTITY_H
# include <iosfwd>
# include <map>
# include <sstream>
# include <string>
# include <boost/noncopyable.hpp>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/dynamic-graph-api.h>
# include <dynamic-graph/exception-factory.h>
# include <dynamic-graph/signal-array.h>
# include <dynamic-graph/signal-base.h>
#define DYNAMIC_GRAPH_ENTITY_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/logger.h>
#include <dynamic-graph/signal-array.h>
#include <dynamic-graph/signal-base.h>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/fwd.hh>
#include <iosfwd>
#include <map>
#include <sstream>
#include <string>
/// \brief Helper macro for entity declaration.
///
......@@ -47,87 +35,150 @@
/// Caution: you *MUST* call DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN in the
/// associated source file to ensure that the attributes generated by
/// this macro are correctly initialized.
# define DYNAMIC_GRAPH_ENTITY_DECL() \
public: \
virtual const std::string& getClassName () const \
{ \
return CLASS_NAME; \
} \
#define DYNAMIC_GRAPH_ENTITY_DECL() \
public: \
virtual const std::string &getClassName() const { return CLASS_NAME; } \
static const std::string CLASS_NAME
namespace dynamicgraph
{
/// \ingroup dgraph
///
/// \brief This class represents an entity, i.e. a generic
/// computational unit that provides input and output signals.
///
/// These signals link the entities together to form a complete
/// computation graph. To declare a new entity, please see the
/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in factory.h. A
/// command-line interface provided by the entity can be used by a
/// sot shell to call methods from entities and display the result
/// of their execution. Classes that derive from Entity can
/// customize the command-line by overriding commandLine ().
class DYNAMIC_GRAPH_DLLAPI Entity : private boost::noncopyable
{
public:
typedef std::map< std::string,SignalBase<int>* > SignalMap;
typedef std::map<const std::string, command::Command*> CommandMap_t;
explicit Entity (const std::string& name);
virtual ~Entity ();
const std::string& getName () const
{
return name;
}
virtual const std::string& getClassName () const = 0;
virtual std::string getDocString () const;
bool hasSignal( const std::string & signame ) const;
SignalBase<int>& getSignal (const std::string& signalName);
const SignalBase<int>& getSignal (const std::string& signalName) const;
std::ostream& displaySignalList(std::ostream& os) const;
virtual std::ostream& writeGraph (std::ostream& os) const;
virtual std::ostream& writeCompletionList (std::ostream& os) const;
virtual void display (std::ostream& os) const;
virtual void commandLine (const std::string& cmdLine,
std::istringstream& cmdArgs,
std::ostream& os);
virtual SignalBase<int>* test ()
{
return 0;
}
virtual void test2 (SignalBase<int>*)
{
return ;
}
const std::string& getCommandList () const;
CommandMap_t getNewStyleCommandMap();
command::Command* getNewStyleCommand( const std::string& cmdName );
SignalMap getSignalMap() const;
protected:
void addCommand(const std::string& name,command::Command* command);
void entityRegistration ();
void entityDeregistration ();
void signalRegistration (const SignalArray<int>& signals);
void signalDeregistration (const std::string& name);
std::string name;
SignalMap signalMap;
CommandMap_t commandMap;
};
DYNAMIC_GRAPH_DLLAPI std::ostream&
operator<< (std::ostream& os, const dynamicgraph::Entity& ent);
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_ENTITY_H
namespace dynamicgraph {
/// \ingroup dgraph
///
/// \brief This class represents an entity, i.e. a generic
/// computational unit that provides input and output signals.
///
/// These signals link the entities together to form a complete
/// computation graph. To declare a new entity, please see the
/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in factory.h.
class DYNAMIC_GRAPH_DLLAPI Entity : private boost::noncopyable {
public:
typedef std::map<std::string, SignalBase<int> *> SignalMap;
typedef std::map<const std::string, command::Command *> CommandMap_t;
explicit Entity(const std::string &name);
virtual ~Entity();
const std::string &getName() const { return name; }
virtual const std::string &getClassName() const {
static std::string ret("Entity");
return ret;
}
/** \brief Returns the Entity documentation
\return The documentation is provided as std::string object.
*/
virtual std::string getDocString() const;
/** \brief Test if a signal of name signame is present.
\return True if the signal is present, False otherwise
*/
bool hasSignal(const std::string &signame) const;
/** \brief Provides a reference to the signal named signalName.
\param signalName: Name of the signal
\return A reference to the signal with a temporal dependency.
*/
SignalBase<int> &getSignal(const std::string &signalName);
/** \brief Provides a const reference to the signal named signalName.
\param signalName: Name of the signal
\return A const reference to the signal with a temporal dependency.
*/
const SignalBase<int> &getSignal(const std::string &signalName) const;
/** \brief Display the list of signals of this entity in output stream os.
\param os: the output stream where to display the list of signals.
\returns The output stream given in parameter.
*/
std::ostream &displaySignalList(std::ostream &os) const;
/** \brief This method is used to write down in os the edges of the graph
by calling the signals writeGraph method.
\param os: The output stream where to write the informations.
\return os: The output stream.
*/
virtual std::ostream &writeGraph(std::ostream &os) const;
/** \brief This method is used write in the output stream os the
signals names and the commands of the entity.
\param os: The output stream where to write the list of objects
related to the entity.
*/
virtual std::ostream &writeCompletionList(std::ostream &os) const;
/** \brief Display information on the entity inside the output stream os.
*/
virtual void display(std::ostream &os) const;
virtual SignalBase<int> *test() { return 0; }
virtual void test2(SignalBase<int> *) { return; }
const std::string &getCommandList() const;
/** \brief Provides the std::map where all the commands are registered
\returns A map of pointers towards Command objects
*/
CommandMap_t getNewStyleCommandMap();
/** \brief Provides the pointer towards the Command object cmdName.
\param cmdName: Name of the command
*/
command::Command *getNewStyleCommand(const std::string &cmdName);
/** \brief Provides a map of all the signals.
\returns A copy of the map with all the pointers towards
the entity signals.
*/
SignalMap getSignalMap() const;
/// \name Logger related methods
/// \{
Logger &logger() { return logger_; };
Logger const &logger() const { return logger_; };
/// \brief Send messages \c msg with level \c t.
/// Add string file and line to message.
void sendMsg(const std::string &msg, MsgType t = MSG_TYPE_INFO,
const std::string &lineId = "");
/// \brief Specify the verbosity level of the logger.
void setLoggerVerbosityLevel(LoggerVerbosity lv) { logger_.setVerbosity(lv); }
/// \brief Get the logger's verbosity level.
LoggerVerbosity getLoggerVerbosityLevel() { return logger_.getVerbosity(); }
/// \brief Set the time sample.
bool setTimeSample(double t) { return logger_.setTimeSample(t); }
/// \brief Get the time sample.
double getTimeSample() { return logger_.getTimeSample(); }
/// \brief Set the period of the stream period
bool setStreamPrintPeriod(double t) {
return logger_.setStreamPrintPeriod(t);
}
/// \brief Get the period of the stream period
double getStreamPrintPeriod() { return logger_.getStreamPrintPeriod(); }
/// \}
protected:
void addCommand(const std::string &name, command::Command *command);
void entityRegistration();
void entityDeregistration();
void signalRegistration(const SignalArray<int> &signals);
void signalDeregistration(const std::string &name);
std::string name;
SignalMap signalMap;
CommandMap_t commandMap;
Logger logger_;
};
DYNAMIC_GRAPH_DLLAPI std::ostream &operator<<(std::ostream &os,
const dynamicgraph::Entity &ent);
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_ENTITY_H
......@@ -2,169 +2,136 @@
// 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_EXCEPTION_ABSTRACT_H
# define DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
# include <iostream>
# include <string>
#define DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
#include <dynamic-graph/dynamic-graph-api.h>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/fwd.hh>
#include <string>
// Uncomment this macros to have lines parameter on the throw display
// #define DYNAMIC-GRAPH_EXCEPTION_PASSING_PARAM
# define DG_RETHROW \
(const ::dynamicgraph::ExceptionAbstract& err) \
{ \
throw err; \
#define DG_RETHROW \
(const ::dynamicgraph::ExceptionAbstract &err) { throw err; }
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
#define DG_THROW \
throw ::dynamicgraph::ExceptionAbstract::Param(__LINE__, __FUNCTION__, \
__FILE__) +
#else
#define DG_THROW throw
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Abstract root class for all dynamic-graph exceptions.
class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception {
public:
/// \ingroup error
///
/// \brief Class owned by exceptions to store error locations.
class Param {
public:
static const int BUFFER_SIZE = 80;
Param(const int &_line, const char *_function, const char *_file);
Param()
: functionPTR(),
function(),
line(),
filePTR(),
file(),
pointersSet(false),
set(false) {}
Param &initCopy(const Param &p);
const char *functionPTR;
char function[BUFFER_SIZE];
int line;
const char *filePTR;
char file[BUFFER_SIZE];
bool pointersSet;
bool set;
};
/// \brief Categories error code.
///
/// Each value matches categories used by a subclass of
/// ExceptionAbstract.
///
/// This is the programmer responsibility to make sure there is
/// enough room between two categories error code.
enum ExceptionEnum {
ABSTRACT = 0,
SIGNAL = 100,
FACTORY = 200,
TRACES = 300,
TOOLS = 700
};
static const std::string EXCEPTION_NAME;
explicit ExceptionAbstract(const int &code, const std::string &msg = "");
virtual ~ExceptionAbstract() throw() {}
virtual const std::string &getExceptionName() const { return EXCEPTION_NAME; }
/// \brief Access to the error code.
int getCode() const;
/// \brief Reference access to the error message (can be empty).
const std::string &getStringMessage() const;
/// \brief Access to the pointer on the array of \e char related
/// to the error string.
///
/// Cannot be \e NULL.
const char *getMessage() const;
virtual const char *what() const throw() {
return getStringMessage().c_str();
}
# ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
# define DG_THROW \
throw ::dynamicgraph::ExceptionAbstract::Param \
(__LINE__, __FUNCTION__, __FILE__) +
# else
# define DG_THROW \
throw
# endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
/// \brief Print the error structure.
DYNAMIC_GRAPH_DLLAPI friend std::ostream &operator<<(
std::ostream &os, const ExceptionAbstract &err);
protected:
/// \brief Error code.
/// \sa ErrorCodeEnum
int code;
namespace dynamicgraph
{
/// \ingroup error
/// \brief Error message (can be empty).
std::string message;
#ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
/// \brief Optional mutable attribute to store exception location.
///
/// \brief Abstract root class for all dynamic-graph exceptions.
class DYNAMIC_GRAPH_DLLAPI ExceptionAbstract : public std::exception
{
public:
/// \ingroup error
///
/// \brief Class owned by exceptions to store error locations.
class Param
{
public:
static const int BUFFER_SIZE = 80;
Param (const int& _line, const char* _function, const char* _file);
Param ()
: functionPTR (),
function (),
line (),
filePTR (),
file (),
pointersSet (false),
set (false)
{}
Param& initCopy (const Param& p);
const char* functionPTR;
char function[BUFFER_SIZE];
int line;
const char* filePTR;
char file[BUFFER_SIZE];
bool pointersSet;
bool set;
};
/// \brief Categories error code.
///
/// Each value matches categories used by a subclass of
/// ExceptionAbstract.
///
/// This is the programmer responsibility to make sure there is
/// enough room between two categories error code.
enum ExceptionEnum
{
ABSTRACT = 0,
SIGNAL = 100,
FACTORY = 200,
TRACES = 300,
TOOLS = 700
};
static const std::string EXCEPTION_NAME;
explicit ExceptionAbstract (const int& code, const std::string& msg = "");
virtual ~ExceptionAbstract () throw ()
{}
virtual const std::string& getExceptionName () const
{
return EXCEPTION_NAME;
}
/// \brief Access to the error code.
int getCode () const;
/// \brief Reference access to the error message (can be empty).
const std::string& getStringMessage () const;
/// \brief Access to the pointer on the array of \e char related
/// to the error string.
///
/// Cannot be \e NULL.
const char* getMessage () const;
virtual const char* what () const throw ()
{
return getStringMessage ().c_str ();
}
/// \brief Print the error structure.
DYNAMIC_GRAPH_DLLAPI friend std::ostream&
operator << (std::ostream & os, const ExceptionAbstract & err);
protected:
/// \brief Error code.
/// \sa ErrorCodeEnum
int code;
/// \brief Error message (can be empty).
std::string message;
# ifdef DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
/// \brief Optional mutable attribute to store exception location.
///
/// Only present if DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
/// preprocessor symbol exists.
mutable Param p;
template<class Exc>
friend const Exc&
operator+ (const ExceptionAbstract::Param& p, const Exc& e)
{
e.p.initCopy(p);
return e;
}
template<class Exc>
friend Exc&
operator+ (const ExceptionAbstract::Param& p, Exc& e)
{
e.p.initCopy (p);
return e;
}
# endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
private:
/// \brief Forbid the empty constructor (private).
ExceptionAbstract ();
};
} // end of namespace dynamicgraph
/// Only present if DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
/// preprocessor symbol exists.
mutable Param p;
template <class Exc>
friend const Exc &operator+(const ExceptionAbstract::Param &p, const Exc &e) {
e.p.initCopy(p);
return e;
}
template <class Exc>
friend Exc &operator+(const ExceptionAbstract::Param &p, Exc &e) {
e.p.initCopy(p);
return e;
}
#endif // DYNAMICGRAPH_EXCEPTION_PASSING_PARAM
private:
/// \brief Forbid the empty constructor (private).
ExceptionAbstract();
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_ABSTRACT_H
......@@ -2,65 +2,48 @@
// 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_EXCEPTION_FACTORY_H
# define DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
# include <string>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/dynamic-graph-api.h>
# include <dynamic-graph/exception-abstract.h>
namespace dynamicgraph
{
/// \ingroup error
///
/// \brief Generic error class.
class DYNAMIC_GRAPH_DLLAPI ExceptionFactory : public ExceptionAbstract
{
public:
enum ErrorCodeEnum
{
GENERIC = ExceptionAbstract::FACTORY
,UNREFERED_OBJECT
,UNREFERED_SIGNAL
,UNREFERED_FUNCTION
,DYNAMIC_LOADING
,SIGNAL_CONFLICT
,FUNCTION_CONFLICT
,OBJECT_CONFLICT
,SYNTAX_ERROR
,READ_FILE
};
#define DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/fwd.hh>
#include <string>
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Generic error class.
class DYNAMIC_GRAPH_DLLAPI ExceptionFactory : public ExceptionAbstract {
public:
enum ErrorCodeEnum {
GENERIC = ExceptionAbstract::FACTORY,
UNREFERED_OBJECT,
UNREFERED_SIGNAL,
UNREFERED_FUNCTION,
DYNAMIC_LOADING,
SIGNAL_CONFLICT,
FUNCTION_CONFLICT,
OBJECT_CONFLICT,
SYNTAX_ERROR,
READ_FILE
};
static const std::string EXCEPTION_NAME;
static const std::string EXCEPTION_NAME;
explicit ExceptionFactory (const ExceptionFactory::ErrorCodeEnum& errcode,
const std::string & msg = "");
explicit ExceptionFactory(const ExceptionFactory::ErrorCodeEnum &errcode,
const std::string &msg = "");
ExceptionFactory (const ExceptionFactory::ErrorCodeEnum& errcode,
const std::string& msg, const char* format, ...);
ExceptionFactory(const ExceptionFactory::ErrorCodeEnum &errcode,
const std::string &msg, const char *format, ...);
virtual ~ExceptionFactory () throw ()
{}
virtual ~ExceptionFactory() throw() {}
virtual const std::string& getExceptionName () const
{
return ExceptionFactory::EXCEPTION_NAME;
}
};
} // end of namespace dynamicgraph
virtual const std::string &getExceptionName() const {
return ExceptionFactory::EXCEPTION_NAME;
}
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_FACTORY_H
......@@ -2,62 +2,43 @@
// 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_EXCEPTION_SIGNAL_H
# define DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/dynamic-graph-api.h>
# include <dynamic-graph/exception-abstract.h>
namespace dynamicgraph
{
/// \ingroup error
///
/// \brief Exceptions raised when an error related to signals
/// happen.
class DYNAMIC_GRAPH_DLLAPI ExceptionSignal : public ExceptionAbstract
{
public:
enum ErrorCodeEnum
{
GENERIC = ExceptionAbstract::SIGNAL
,READWRITE_LOCK
,COPY_NOT_INITIALIZED
,NOT_INITIALIZED
,PLUG_IMPOSSIBLE
,SET_IMPOSSIBLE
,BAD_CAST
};
static const std::string EXCEPTION_NAME;
explicit ExceptionSignal (const ExceptionSignal::ErrorCodeEnum& errcode,
const std::string & msg = "" );
ExceptionSignal (const ExceptionSignal::ErrorCodeEnum& errcode,
const std::string & msg, const char* format, ...);
virtual ~ExceptionSignal () throw ()
{}
virtual const std::string& getExceptionName () const
{
return EXCEPTION_NAME;
}
#define DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/fwd.hh>
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Exceptions raised when an error related to signals
/// happen.
class DYNAMIC_GRAPH_DLLAPI ExceptionSignal : public ExceptionAbstract {
public:
enum ErrorCodeEnum {
GENERIC = ExceptionAbstract::SIGNAL,
READWRITE_LOCK,
COPY_NOT_INITIALIZED,
NOT_INITIALIZED,
PLUG_IMPOSSIBLE,
SET_IMPOSSIBLE,
BAD_CAST
};
} // end of namespace dynamicgraph
static const std::string EXCEPTION_NAME;
explicit ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
const std::string &msg = "");
ExceptionSignal(const ExceptionSignal::ErrorCodeEnum &errcode,
const std::string &msg, const char *format, ...);
virtual ~ExceptionSignal() throw() {}
virtual const std::string &getExceptionName() const { return EXCEPTION_NAME; }
};
} // end of namespace dynamicgraph
#endif //!DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_SIGNAL_H
......@@ -2,55 +2,33 @@
// 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_EXCEPTION_TRACES_H
# define DYNAMIC_GRAPH_EXCEPTION_TRACES_H
# include <string>
#define DYNAMIC_GRAPH_EXCEPTION_TRACES_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-abstract.h>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/dynamic-graph-api.h>
# include <dynamic-graph/exception-abstract.h>
#include <dynamic-graph/fwd.hh>
#include <string>
namespace dynamicgraph
{
/// \ingroup error
///
/// \brief Exceptions raised when an error related to traces happen.
class DYNAMIC_GRAPH_DLLAPI ExceptionTraces : public ExceptionAbstract
{
public:
enum ErrorCodeEnum
{
GENERIC = ExceptionAbstract::TRACES
,NOT_OPEN
};
namespace dynamicgraph {
/// \ingroup error
///
/// \brief Exceptions raised when an error related to traces happen.
class DYNAMIC_GRAPH_DLLAPI ExceptionTraces : public ExceptionAbstract {
public:
enum ErrorCodeEnum { GENERIC = ExceptionAbstract::TRACES, NOT_OPEN };
static const std::string EXCEPTION_NAME;
static const std::string EXCEPTION_NAME;
explicit ExceptionTraces (const ExceptionTraces::ErrorCodeEnum& errcode,
const std::string & msg = "");
ExceptionTraces (const ExceptionTraces::ErrorCodeEnum& errcode,
const std::string& msg, const char* format, ...);
virtual ~ExceptionTraces () throw ()
{}
explicit ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
const std::string &msg = "");
ExceptionTraces(const ExceptionTraces::ErrorCodeEnum &errcode,
const std::string &msg, const char *format, ...);
virtual ~ExceptionTraces() throw() {}
virtual const std::string& getExceptionName () const
{
return EXCEPTION_NAME;
}
};
} // end of namespace dynamicgraph.
virtual const std::string &getExceptionName() const { return EXCEPTION_NAME; }
};
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_EXCEPTION_TRACES_H
#endif //! DYNAMIC_GRAPH_EXCEPTION_TRACES_H
......@@ -2,30 +2,17 @@
// 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_FACTORY_HH
# define DYNAMIC_GRAPH_FACTORY_HH
# include <map>
# include <string>
# include <vector>
# include <boost/noncopyable.hpp>
#define DYNAMIC_GRAPH_FACTORY_HH
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/exception-factory.h>
# include <dynamic-graph/dynamic-graph-api.h>
#include <boost/noncopyable.hpp>
#include <dynamic-graph/fwd.hh>
#include <map>
#include <string>
#include <vector>
/// \ingroup dgraph
///
......@@ -36,197 +23,180 @@
/// \param CLASSNAME the name of the Entity to be registered (this must
/// be a std::string or a type implicitly castable into a std::string
/// such as classic C string delimited by double quotes).
# define DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CLASSTYPE, CLASSNAME) \
const std::string CLASSTYPE::CLASS_NAME = CLASSNAME; \
extern "C" { \
::dynamicgraph::Entity* \
EntityMaker_##CLASSTYPE(const std::string& objname) \
{ \
return new CLASSTYPE (objname); \
} \
::dynamicgraph::EntityRegisterer \
reg_##CLASSTYPE (CLASSNAME, \
&EntityMaker_##CLASSTYPE); \
} \
#define DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(CLASSTYPE, CLASSNAME) \
const std::string CLASSTYPE::CLASS_NAME = CLASSNAME; \
extern "C" { \
::dynamicgraph::Entity *EntityMaker_##CLASSTYPE( \
const std::string &objname) { \
return new CLASSTYPE(objname); \
} \
::dynamicgraph::EntityRegisterer reg_##CLASSTYPE(CLASSNAME, \
&EntityMaker_##CLASSTYPE); \
} \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
namespace dynamicgraph {
/// \ingroup dgraph
///
/// \brief Provides a way to create Entity objects from their class
/// name.
///
/// The dynamic graph frameworks relies on entities (see Entity)
/// which defines atomic processing units. This class provides a
/// robust way to enumerate and instantiate these entities.
/// Each entity has a name (its type name) and can be instantiated.
/// Each instance also has a name.
///
/// For instance one can define a C++ class called MyEntity which
/// inherits from dynamicgraph::Entity. This type can be registered
/// into the factory to teach the framework that:
/// - this entity exists
/// - this entity can be instantiated (and how to instantiate it).
///
/// To achieve this, one must pass an entity name and a function pointer.
///
/// The entity name will identify the class <b>at run-time</b>
/// (be careful: this may not be equivalent to the C++ class name
/// even if it is recommended to do so).
///
/// The function pointer must point on a function taking a string as
/// input and returning an instance of the Entity (the concrete
/// subclass, not directly the upper Entity class).
///
/// The instances returned by this function <b>must</b> be
/// dynamically allocated and the caller <b>must</b> get the
/// ownership of the instance (i.e. it will free it when required).
///
/// To finish, please note that the instance name indicates to the
/// entity how the instance itself is called at run-time. This name
/// does not need to be unique and no check is done on it. It is
/// the caller responsibility to make sure that the instance name is
/// appropriate and to check for uniqueness if required.
///
///
/// This class is a singleton. The rationale is that each
/// unique name must identify a unique Entity. The use of a single
/// instance of this class enforces this behavior, instantiating one
/// yourself would break this property.
class DYNAMIC_GRAPH_DLLAPI FactoryStorage : private boost::noncopyable {
public:
/// \brief Function pointer providing an entity instance from its
/// name.
typedef Entity *(*EntityConstructor_ptr)(const std::string &);
~FactoryStorage();
/// \brief Get pointer to unique object of the class
static FactoryStorage *getInstance();
namespace dynamicgraph
{
/// \ingroup dgraph
/// \brief Destroy the unique instance of the class
static void destroy();
/// \brief Add a new entity to the factory.
///
/// \brief Provides a way to create Entity objects from their class
/// name.
/// It is not allowed to have several entities using the same
/// name. If this is the case, an ExceptionFactory exception will
/// be raised with the code OBJECT_CONFLICT.
///
/// If the function pointer is null, an ExceptionFactory exception
/// will be raised with the code OBJECT_CONFLICT.
///
/// \param entname the name used to subscribe the entity.
/// \param ent pointer to a function allocating an entity from an
/// instance name.
void registerEntity(const std::string &entname, EntityConstructor_ptr ent);
/// \brief Delete an entity from the factory.
///
/// If the provided entity name does not exist in the factory,
/// an ExceptionFactory exception will be raised with the code
/// OBJECT_CONFLICT.
///
/// The dynamic graph frameworks relies on entities (see Entity)
/// which defines atomic processing units. This class provides a
/// robust way to enumerate and instantiate these entities.
/// Each entity has a name (its type name) and can be instantiated.
/// Each instance also has a name.
/// \param entname the entity name (as passed to registerEntity before)
void deregisterEntity(const std::string &entname);
/// \brief Instantiate (and allocate) an entity.
///
/// For instance one can define a C++ class called MyEntity which
/// inherits from dynamicgraph::Entity. This type can be registered
/// into the factory to teach the framework that:
/// - this entity exists
/// - this entity can be instantiated (and how to instantiate it).
/// An instance called objname of the entity which type is classname
/// will be allocated by this method.
///
/// To achieve this, one must pass an entity name and a function pointer.
/// It is <b>the caller</b> responsibility to free the
/// returned object.
///
/// The entity name will identify the class <b>at run-time</b>
/// (be careful: this may not be equivalent to the C++ class name
/// even if it is recommended to do so).
/// If the class name does not exist, an ExceptionFactory
/// exception will be raised with the code UNREFERED_OBJECT.
///
/// The function pointer must point on a function taking a string as
/// input and returning an instance of the Entity (the concrete
/// subclass, not directly the upper Entity class).
/// The instance name (objname) is passed to the Entity
/// constructor and it is the caller responsibility to avoid
/// instance name conflicts if necessary.
///
/// The instances returned by this function <b>must</b> be
/// dynamically allocated and the caller <b>must</b> get the
/// ownership of the instance (i.e. it will free it when required).
/// \param classname the name of the Entity type
/// \param objname the instance name
/// \return Dynamically allocated instance of classname.
Entity *newEntity(const std::string &classname,
const std::string &objname) const;
/// \brief Check if an Entity associated with a particular name
/// has already been registered.
///
/// To finish, please note that the instance name indicates to the
/// entity how the instance itself is called at run-time. This name
/// does not need to be unique and no check is done on it. It is
/// the caller responsibility to make sure that the instance name is
/// appropriate and to check for uniqueness if required.
/// \param name entity name
/// \return Do the entity exist?
bool existEntity(const std::string &name) const;
/// \brief List the available entities.
///
/// Available entities are appended to the method argument.
///
/// This class is a singleton. The rationale is that each
/// unique name must identify a unique Entity. The use of a single
/// instance of this class enforces this behavior, instantiating one
/// yourself would break this property.
class DYNAMIC_GRAPH_DLLAPI FactoryStorage : private boost::noncopyable
{
public:
/// \brief Function pointer providing an entity instance from its
/// name.
typedef Entity* (*EntityConstructor_ptr) (const std::string&);
~FactoryStorage ();
/// \brief Get pointer to unique object of the class
static FactoryStorage* getInstance();
/// \brief Destroy the unique instance of the class
static void destroy();
/// \brief Add a new entity to the factory.
///
/// It is not allowed to have several entities using the same
/// name. If this is the case, an ExceptionFactory exception will
/// be raised with the code OBJECT_CONFLICT.
///
/// If the function pointer is null, an ExceptionFactory exception
/// will be raised with the code OBJECT_CONFLICT.
///
/// \param entname the name used to subscribe the entity.
/// \param ent pointer to a function allocating an entity from an
/// instance name.
void registerEntity (const std::string& entname,
EntityConstructor_ptr ent);
/// \brief Delete an entity from the factory.
///
/// If the provided entity name does not exist in the factory,
/// an ExceptionFactory exception will be raised with the code
/// OBJECT_CONFLICT.
///
/// \param entname the entity name (as passed to registerEntity before)
void deregisterEntity (const std::string& entname);
/// \brief Instantiate (and allocate) an entity.
///
/// An instance called objname of the entity which type is classname
/// will be allocated by this method.
///
/// It is <b>the caller</b> responsibility to free the
/// returned object.
///
/// If the class name does not exist, an ExceptionFactory
/// exception will be raised with the code UNREFERED_OBJECT.
///
/// The instance name (objname) is passed to the Entity
/// constructor and it is the caller responsibility to avoid
/// instance name conflicts if necessary.
///
/// \param classname the name of the Entity type
/// \param objname the instance name
/// \return Dynamically allocated instance of classname.
Entity* newEntity (const std::string& classname,
const std::string& objname) const;
/// \brief Check if an Entity associated with a particular name
/// has already been registered.
///
/// \param name entity name
/// \return Do the entity exist?
bool existEntity (const std::string& name) const;
/// \brief List the available entities.
///
/// Available entities are appended to the method argument.
///
/// \param list Available entities will be appended to list.
void listEntities (std::vector <std::string>& list) const;
/// \brief Define FactoryStorage commands.
///
/// Define two equivalent commands:
/// - list
/// - listEntities
/// listing the available entities.
void commandLine (const std::string& cmdLine,
std::istringstream& cmdArgs,
std::ostream& os);
private:
/// \brief Constructor the factory.
///
/// After the initialization, no entities will be available.
/// registerEntity has to be used to add new entities to the
/// object.
explicit FactoryStorage ();
/// \brief Entity map type.
///
/// This maps entity names to functions pointers which can be
/// used to instantiate an Entity.
typedef std::map<std::string, EntityConstructor_ptr> EntityMap;
/// \brief The entity map storing information about how to
/// instantiate an Entity.
EntityMap entityMap;
/// \pointer to the unique object of the class
static FactoryStorage* instance_;
};
/// \ingroup dgraph
/// \param list Available entities will be appended to list.
void listEntities(std::vector<std::string> &list) const;
private:
/// \brief Constructor the factory.
///
/// \brief This class automatically register an Entity to the
/// global factory at initialization and unregister it during
/// instance destruction.
/// After the initialization, no entities will be available.
/// registerEntity has to be used to add new entities to the
/// object.
explicit FactoryStorage();
/// \brief Entity map type.
///
/// This class is mainly used by the
/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro and is of little interest
/// by itself.
class DYNAMIC_GRAPH_DLLAPI EntityRegisterer : private boost::noncopyable
{
public:
/// \brief Register entity to the global factory.
explicit EntityRegisterer (const std::string& entityClassName,
FactoryStorage::EntityConstructor_ptr maker);
/// \brief Unregister entity to the global factory.
~EntityRegisterer ();
private:
/// \brief Name of the entity registered when the instance has
/// been initialized.
const std::string entityName;
};
/// This maps entity names to functions pointers which can be
/// used to instantiate an Entity.
typedef std::map<std::string, EntityConstructor_ptr> EntityMap;
/// \brief The entity map storing information about how to
/// instantiate an Entity.
EntityMap entityMap;
/// \pointer to the unique object of the class
static FactoryStorage *instance_;
};
/// \ingroup dgraph
///
/// \brief This class automatically register an Entity to the
/// global factory at initialization and unregister it during
/// instance destruction.
///
/// This class is mainly used by the
/// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro and is of little interest
/// by itself.
class DYNAMIC_GRAPH_DLLAPI EntityRegisterer : private boost::noncopyable {
public:
/// \brief Register entity to the global factory.
explicit EntityRegisterer(const std::string &entityClassName,
FactoryStorage::EntityConstructor_ptr maker);
/// \brief Unregister entity to the global factory.
~EntityRegisterer();
private:
/// \brief Name of the entity registered when the instance has
/// been initialized.
const std::string entityName;
};
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_FACTORY_HH
#endif //! DYNAMIC_GRAPH_FACTORY_HH
// LocalWords: unregister
// Copyright 2010, Thomas Moulard, JRL, CNRS/AIST
// Copyright 2010-2019, CNRS, JRL, AIST, LAAS
// Thomas Moulard, Olivier Stasse
//
// 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_FWD_HH
# define DYNAMIC_GRAPH_FWD_HH
namespace dynamicgraph
{
class Contiifstream;
class DebugTrace;
class PluginRefMap;
class Entity;
class EntityRegisterer;
class ExceptionAbstract;
class ExceptionFactory;
class ExceptionSignal;
class ExceptionTraces;
class FactoryStorage;
class Interpreter;
class InterpreterHelper;
class OutStringStream;
class PluginLoader;
class PoolStorage;
class ShellFunctionRegisterer;
class SignalCaster;
class SignalCastRegisterer;
class Tracer;
class TracerRealTime;
template <typename T>
class DefaultCastRegisterer;
template <typename T, typename Time>
class Signal;
template <typename Time>
class SignalArray;
template <typename Time>
class SignalArray_const;
template <typename Time>
class SignalBase;
template <typename T, typename Time>
class SignalPtr;
template <typename T, typename Time>
class SignalTimeDependent;
template <typename Time>
class TimeDependency;
namespace command
{
class Command;
} // end of namespace command.
} // end of namespace dynamicgraph.
class ShellFunctions;
class ShellProcedure;
#endif //! DYNAMIC_GRAPH_FWD_HH
#define DYNAMIC_GRAPH_FWD_HH
#include <boost/smart_ptr.hpp>
namespace dynamicgraph {
// to be replace by std:: when we switch to C++11 and later
using boost::const_pointer_cast;
using boost::dynamic_pointer_cast;
using boost::make_shared;
using boost::shared_ptr;
using boost::static_pointer_cast;
using boost::weak_ptr;
class DebugTrace;
class PluginRefMap;
class Entity;
class EntityRegisterer;
class ExceptionAbstract;
class ExceptionFactory;
class ExceptionSignal;
class ExceptionTraces;
class FactoryStorage;
class Interpreter;
typedef shared_ptr<Interpreter> InterpreterShPtr_t;
class InterpreterHelper;
class Logger;
class OutStringStream;
class PluginLoader;
class PoolStorage;
class Tracer;
class TracerRealTime;
template <typename T, typename Time>
class Signal;
template <typename Time>
class SignalArray;
template <typename Time>
class SignalArray_const;
template <typename Time>
class SignalBase;
template <typename T, typename Time>
class SignalPtr;
template <typename T, typename Time>
class SignalTimeDependent;
template <typename Time>
class TimeDependency;
namespace command {
class Command;
} // end of namespace command.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_FWD_HH
/* -*- c++ -*-
*
* Copyright 2010,
* François Bleibel,
* Olivier Stasse,
*
* 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 Lesser General 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 DG_FACTORY_COMMAND_IMPORT_DEFAULT_PATHS_H
# define DG_FACTORY_COMMAND_IMPORT_DEFAULT_PATHS_H
/// Default script path as known by CMake at configure time.
# define DG_IMPORT_DEFAULT_PATHS "@DG_IMPORT_DEFAULT_PATHS@"
#endif //! SOT_FACTORY_COMMAND_IMPORT_DEFAULT_PATHS_H
......@@ -3,26 +3,15 @@
//
// Author: Florent Lamiraux
//
// 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 Lesser General 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_LINEAR_ALGEBRA_H
#define DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
#include <Eigen/Core>
#include <Eigen/Geometry>
namespace dynamicgraph {
typedef Eigen::MatrixXd Matrix;
typedef Eigen::VectorXd Vector;
}
typedef Eigen::MatrixXd Matrix;
typedef Eigen::VectorXd Vector;
} // namespace dynamicgraph
#endif //DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
#endif // DYNAMIC_GRAPH_LINEAR_ALGEBRA_H
/*
* Copyright 2015, 2019
* LAAS-CNRS
* Andrea Del Prete, François Bailly, Olivier Stasse
*
*/
#ifndef __dynamic_graph_logger_H__
#define __dynamic_graph_logger_H__
/* --------------------------------------------------------------------- */
/* --- API ------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
#if defined(WIN32)
#if defined(logger_EXPORTS)
#define LOGGER_EXPORT __declspec(dllexport)
#else
#define LOGGER_EXPORT __declspec(dllimport)
#endif
#else
#define LOGGER_EXPORT
#endif
namespace dynamicgraph {
/** Enum representing the different kind of messages.
*/
enum MsgType {
MSG_TYPE_TYPE_BITS = 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3, // 15
MSG_TYPE_STREAM_BIT = 1 << 4, // 16
MSG_TYPE_DEBUG = 1 << 3, // 1
MSG_TYPE_INFO = 1 << 2, // 2
MSG_TYPE_WARNING = 1 << 1, // 4
MSG_TYPE_ERROR = 1 << 0, // 8
MSG_TYPE_DEBUG_STREAM = MSG_TYPE_DEBUG | MSG_TYPE_STREAM_BIT, // 17
MSG_TYPE_INFO_STREAM = MSG_TYPE_INFO | MSG_TYPE_STREAM_BIT, // 18
MSG_TYPE_WARNING_STREAM = MSG_TYPE_WARNING | MSG_TYPE_STREAM_BIT, // 20
MSG_TYPE_ERROR_STREAM = MSG_TYPE_ERROR | MSG_TYPE_STREAM_BIT // 24
};
} // namespace dynamicgraph
/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */
#include <map>
/// \todo These 3 headers should be removed.
#include <dynamic-graph/linear-algebra.h>
#include <dynamic-graph/real-time-logger-def.h>
#include <boost/assign.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <dynamic-graph/deprecated.hh>
#include <fstream>
#include <iomanip> // std::setprecision
#include <sstream>
namespace dynamicgraph {
//#define LOGGER_VERBOSITY_INFO_WARNING_ERROR
#define LOGGER_VERBOSITY_ALL
#define SEND_MSG(msg, type) \
sendMsg(msg, type, __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__))
#define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_DEBUG_STREAM)
#define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO_STREAM)
#define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM)
#define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM)
#define _DYNAMIC_GRAPH_ENTITY_MSG(entity, type) \
(entity).logger().stream(type, __FILE__ BOOST_PP_STRINGIZE(__LINE__))
#define DYNAMIC_GRAPH_ENTITY_DEBUG(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG)
#define DYNAMIC_GRAPH_ENTITY_INFO(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO)
#define DYNAMIC_GRAPH_ENTITY_WARNING(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING)
#define DYNAMIC_GRAPH_ENTITY_ERROR(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR)
#define DYNAMIC_GRAPH_ENTITY_DEBUG_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG_STREAM)
#define DYNAMIC_GRAPH_ENTITY_INFO_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO_STREAM)
#define DYNAMIC_GRAPH_ENTITY_WARNING_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING_STREAM)
#define DYNAMIC_GRAPH_ENTITY_ERROR_STREAM(entity) \
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR_STREAM)
template <typename T>
std::string toString(const T &v, const int precision = 3,
const int width = -1) {
std::stringstream ss;
if (width > precision)
ss << std::fixed << std::setw(width) << std::setprecision(precision) << v;
else
ss << std::fixed << std::setprecision(precision) << v;
return ss.str();
}
template <typename T>
std::string toString(const std::vector<T> &v, const int precision = 3,
const int width = -1, const std::string separator = ", ") {
std::stringstream ss;
if (width > precision) {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[i] << separator;
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[v.size() - 1];
} else {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setprecision(precision) << v[i] << separator;
ss << std::fixed << std::setprecision(precision) << v[v.size() - 1];
}
return ss.str();
}
template <typename T>
std::string toString(const Eigen::MatrixBase<T> &v, const int precision = 3,
const int width = -1, const std::string separator = ", ") {
std::stringstream ss;
if (width > precision) {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[i] << separator;
ss << std::fixed << std::setw(width) << std::setprecision(precision)
<< v[v.size() - 1];
} else {
for (unsigned int i = 0; i < v.size() - 1; i++)
ss << std::fixed << std::setprecision(precision) << v[i] << separator;
ss << std::setprecision(precision) << v[v.size() - 1];
}
return ss.str();
}
enum LoggerVerbosity {
VERBOSITY_ALL = MSG_TYPE_DEBUG,
VERBOSITY_INFO_WARNING_ERROR = MSG_TYPE_INFO,
VERBOSITY_WARNING_ERROR = MSG_TYPE_WARNING,
VERBOSITY_ERROR = MSG_TYPE_ERROR,
VERBOSITY_NONE = 0
};
/// \ingroup debug
///
/// \brief Class for logging messages
///
/// It is intended to be used like this:
/// \code
/// #define ENABLE_RT_LOG
/// #include <dynamic-graph/real-time-logger.h>
///
/// // Somewhere in the main function of your executable
/// int main (int argc, char** argv) {
/// std::ofstream of;
/// of.open("/tmp/dg-LOGS.txt",std::ofstream::out|std::ofstream::app);
/// dgADD_OSTREAM_TO_RTLOG (of);
/// }
///
/// // Somewhere in your library
/// dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel =
/// VERBOSITY_WARNING_ERROR;
/// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel);
/// ...
/// // using macros
/// DYNAMIC_GRAPH_ENTITY_WARNING(entity) << "your message\n";
///
/// // or the equivalent code without macros:
/// // Please use '\n' instead of std::endl and flushing will have no effect
/// entity.logger.stream(dynamicgraph::MSG_TYPE_WARNING,
/// __FILE__ BOOST_PP_STRINGIZE(__LINE__))
/// << your message << '\n';
///
/// \endcode
///
/// \todo remove m_timeSample and streamPrintPeriod to rather use a simple
/// integer counting the number of calls. This will achieve exactly the
/// same behaviour without rouding numerical errors.
class Logger {
public:
/** Constructor */
Logger(double timeSample = 0.001, double streamPrintPeriod = 1.0);
/** Destructor */
~Logger();
/** Method to be called at every control iteration
* to decrement the internal Logger's counter. */
void countdown();
/** Get an output stream independently of the debug level.
*/
RTLoggerStream stream() {
return ::dynamicgraph::RealTimeLogger::instance().front();
}
/** Print the specified message on standard output if the verbosity level
* allows it. The lineId is used to identify the point where sendMsg is
* called so that streaming messages are printed only every streamPrintPeriod
* iterations.
* \param type specifies the verbosity level, for instance MSG_TYPE_DEBUG
* \param lineId typically __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__)
*/
RTLoggerStream stream(MsgType type, const std::string &lineId = "") {
RealTimeLogger &rtlogger = ::dynamicgraph::RealTimeLogger::instance();
if (acceptMsg(type, lineId)) return rtlogger.front();
return rtlogger.emptyStream();
}
/** \deprecated instead, use
* \code
* stream(type, lineId) << msg << '\n';
* \endcode
*/
[[deprecated("use stream(type, lineId) << msg")]] void sendMsg(
std::string msg, MsgType type, const std::string &lineId = "");
/** \deprecated instead, use
* \code
* stream(type, lineId) << msg << '\n';
* \endcode
*/
[[deprecated("use stream(type, lineId) << msg")]] void sendMsg(
std::string msg, MsgType type, const std::string &file, int line);
/** Set the sampling time at which the method countdown()
* is going to be called. */
bool setTimeSample(double t);
/** Get the sampling time at which the method countdown()
* is going to be called. */
double getTimeSample();
/** Set the time period for printing of streaming messages. */
bool setStreamPrintPeriod(double s);
/** Get the time period for printing of streaming messages. */
double getStreamPrintPeriod();
/** Set the verbosity level of the logger. */
void setVerbosity(LoggerVerbosity lv);
/** Get the verbosity level of the logger. */
LoggerVerbosity getVerbosity();
protected:
LoggerVerbosity m_lv; /// verbosity of the logger
double m_timeSample;
/// specify the period of call of the countdown method
double m_streamPrintPeriod; /// specify the time period of the stream prints
double m_printCountdown;
/// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff
typedef std::map<std::string, double> StreamCounterMap_t;
/** Pointer to the dynamic structure which holds
the collection of streaming messages */
StreamCounterMap_t m_stream_msg_counters;
inline bool isStreamMsg(MsgType m) { return (m & MSG_TYPE_STREAM_BIT); }
/** Check whether a message of type \p m and from \p c lineId should be
* accepted. \note If \p m is a stream type, the internal counter associated
* to \p lineId is updated.
*/
bool acceptMsg(MsgType m, const std::string &lineId) {
// If more verbose than the current verbosity level
if ((m & MSG_TYPE_TYPE_BITS) > m_lv) return false;
// if print is allowed by current verbosity level
if (isStreamMsg(m)) return checkStreamPeriod(lineId);
return true;
}
/** Check whether a message from \c lineId should be accepted.
* \note The internal counter associated to \c lineId is updated.
*/
bool checkStreamPeriod(const std::string &lineId);
};
} // namespace dynamicgraph
#endif // #ifndef __sot_torque_control_logger_H__
// Copyright 2010, Thomas Moulard, 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_NULL_PTR_HH
# define DYNAMIC_GRAPH_NULL_PTR_HH
namespace dynamicgraph
{
const class
{
public:
template<class T>
operator T*() const
{
return 0;
}
template<class C, class T>
operator T C::*() const
{
return 0;
}
private:
void operator&() const;
} nullptr = {};
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_NULL_PTR_HH
......@@ -2,144 +2,117 @@
// 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_POOL_H
# define DYNAMIC_GRAPH_POOL_H
# include <map>
# include <string>
# include <sstream>
#define DYNAMIC_GRAPH_POOL_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/exception-factory.h>
#include <dynamic-graph/signal-base.h>
#include <dynamic-graph/fwd.hh>
#include <map>
#include <sstream>
#include <string>
namespace dynamicgraph {
/*! @ingroup dgraph
\brief Singleton that keeps track of all the entities.
This class gives access to and remembers all the entities created
during its life.
This class provides the necessary operations to register, unregister each
instance of thoses classes.
As tasks and features derived from Entities, they should be registered
as such.
\note From the code it is not very clear why we should not unregister
from the tasks and the features...
*/
class DYNAMIC_GRAPH_DLLAPI PoolStorage {
public:
/*! \name Define types to simplify the writing
@{
*/
/*! \brief Sorted set of entities with unique key (name). */
typedef std::map<std::string, Entity *> Entities;
/// \brief Get unique instance of the class.
static PoolStorage *getInstance();
/// \brief Destroy the unique instance of the class
static void destroy();
# include <dynamic-graph/fwd.hh>
# include <dynamic-graph/exception-factory.h>
# include <dynamic-graph/signal-base.h>
# include <dynamic-graph/dynamic-graph-api.h>
/*! @} */
/*! \brief Default destructor */
~PoolStorage();
/*! \name Method related to the handling of entities.
@{
*/
/*! \brief Register an entity.
\par[in] entname: The name of the entity,
\par[in] ent: Pointer towards the entity.
*/
void registerEntity(const std::string &entname, Entity *ent);
namespace dynamicgraph
{
/*! @ingroup dgraph
\brief Singleton that keeps track of all the entities.
/*! \brief Unregister an entity.
\par[in] entname: The name of the entity,
*/
void deregisterEntity(const std::string &entname);
This class gives access to and remembers all the entities created
during its life.
/*! \brief Unregister an entity.
\par[in] entity: iterator in the map,
*/
void deregisterEntity(const Entities::iterator &entity);
/*! \brief Get an entity.
\par[in] entname: The name of the entity,
\return Pointer towards the entity.
*/
Entity &getEntity(const std::string &name);
This class provides the necessary operations to register, unregister each
instance of thoses classes.
As tasks and features derived from Entities, they should be registered
as such.
/// Const access to entity map
const Entities &getEntityMap() const;
\note From the code it is not very clear why we should not unregister
from the tasks and the features...
/*! \brief Test if the entity exists. */
bool existEntity(const std::string &name);
/*! \brief Test if the entity exists. If it does, return a pointer on it. */
bool existEntity(const std::string &name, Entity *&ptr);
/*! \brief Disallocate an entity.
\par[in] entname: The name of the entity,
*/
class DYNAMIC_GRAPH_DLLAPI PoolStorage
{
public:
/*! \name Define types to simplify the writing
@{
*/
/*! \brief Sorted set of entities with unique key (name). */
typedef std::map< std::string,Entity* > Entities;
/// \brief Get unique instance of the class.
static PoolStorage *getInstance();
/// \brief Destroy the unique instance of the class
static void destroy();
/*! @} */
/*! \brief Default destructor */
~PoolStorage ();
/*! \name Method related to the handling of entities.
@{
*/
/*! \brief Register an entity.
\par[in] entname: The name of the entity,
\par[in] ent: Pointer towards the entity.
*/
void registerEntity (const std::string& entname, Entity* ent);
/*! \brief Unregister an entity.
\par[in] entname: The name of the entity,
*/
void deregisterEntity (const std::string& entname);
/*! \brief Unregister an entity.
\par[in] entity: iterator in the map,
*/
void deregisterEntity( const Entities::iterator& entity );
/*! \brief Get an entity.
\par[in] entname: The name of the entity,
\return Pointer towards the entity.
*/
Entity& getEntity (const std::string& name);
/// Const access to entity map
const Entities& getEntityMap () const;
/*! \brief Test if the entity exists. */
bool existEntity (const std::string& name);
/*! \brief Test if the entity exists. If it does, return a pointer on it. */
bool existEntity (const std::string& name, Entity*& ptr);
/*! \brief Disallocate an entity.
\par[in] entname: The name of the entity,
*/
void clearPlugin (const std::string& name);
/*! @} */
///
/// \brief Get a signal by name
///
/// \param sigpath stream containing a string of the form "entity.signal"
SignalBase<int>& getSignal( std::istringstream& sigpath );
/*! \brief This method looks for the object named objectName,
and ask to provide the function functionName with the arguments cmdArg.
If the method of the object displays some information this will
be done on os.
The commands specific to the \b PoolStorage singleton are:
\li \b list : List all the entities registered in the pool
*/
void commandLine (const std::string& objectName,
const std::string& functionName,
std::istringstream& cmdArg,
std::ostream& os);
/*! \brief This method write a graph description on the file named
FileName. */
void writeGraph (const std::string& aFileName);
void writeCompletionList (std::ostream& os);
protected:
/*! \name Fields of the class to manage the three entities.
Also the name is singular, those are true sets.
@{
*/
/*! \brief Set of basic objects of the SoT */
Entities entityMap;
private:
PoolStorage () {}
static PoolStorage* instance_;
};
inline PoolStorage& g_pool() { return *PoolStorage::getInstance(); }
void clearPlugin(const std::string &name);
/*! @} */
///
/// \brief Get a signal by name
///
/// \param sigpath stream containing a string of the form "entity.signal"
SignalBase<int> &getSignal(std::istringstream &sigpath);
/*! \brief This method write a graph description on the file named
FileName. */
void writeGraph(const std::string &aFileName);
void writeCompletionList(std::ostream &os);
protected:
/*! \name Fields of the class to manage the three entities.
Also the name is singular, those are true sets.
@{
*/
/*! \brief Set of basic objects of the SoT */
Entities entityMap;
private:
PoolStorage() {}
static PoolStorage *instance_;
};
inline PoolStorage &g_pool() { return *PoolStorage::getInstance(); }
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_POOL_H
#endif //! DYNAMIC_GRAPH_POOL_H
/* Copyright LAAS, CNRS
* Author: O. Stasse, 2019
* See LICENSE file in the root directory of this repository.
*/
#ifndef DYNAMIC_GRAPH_PROCESS_LIST_H_
#define DYNAMIC_GRAPH_PROCESS_LIST_H_
#include <dynamic-graph/dynamic-graph-api.h>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <dynamic-graph/fwd.hh>
namespace dynamicgraph {
namespace CPU {
class DYNAMIC_GRAPH_DLLAPI ProcessData {};
class DYNAMIC_GRAPH_DLLAPI ProcessList {
public:
ProcessList();
};
/// This class gather information on a specific CPU.
///
class DYNAMIC_GRAPH_DLLAPI CPUData {
public:
CPUData();
int cpu_id_;
inline unsigned long long int computePeriod(unsigned long long int &a,
unsigned long long int &b) {
return (a > b) ? a - b : 0;
}
/// \brief Various classes of time spend by the CPU
/// @{
/// Total time
unsigned long long int total_time_;
/// Time spend in user mode
unsigned long long int user_mode_time_;
/// Time spend in user mode with low priority (nice mode)
unsigned long long int nice_time_;
/// Time spend in system mode
unsigned long long int system_time_;
/// Time spend in system mode
unsigned long long int system_all_time_;
/// Time spend in doing nothing.
unsigned long long int idle_time_;
/// Time spend in doing nothing.
unsigned long long int idle_all_time_;
/// Time spend in waiting an input/output to complete.
unsigned long long int iowait_time_;
/// Time spend in servicing hardware interrupts.
unsigned long long int irq_time_;
/// Time spend in servicing software interrupts.
unsigned long long int softirq_time_;
/// Time spend in other operating systems in a virtualized environments
/// Never doing this for control !
unsigned long long int steal_time_;
/// Time spend running a virtual CPU for guest operating systems
/// under the control of the Linux kernel
unsigned long long int guest_time_;
/// Time spent running a niced guest
/// (virtual CPU for guest operating systems under the
/// control of the Linux kernel)
unsigned long long int guest_nice_time_;
/// @}
/// \brief Various classes of time spend by the CPU by period
/// @{
/// Total time
unsigned long long int total_period_;
/// Time spend in user mode
unsigned long long int user_mode_period_;
/// Time spend in user mode with low priority (nice mode)
unsigned long long int nice_period_;
/// Time spend in system mode
unsigned long long int system_period_;
/// Time spend in all system mode
unsigned long long int system_all_period_;
/// Time spend in doing nothing.
unsigned long long int idle_period_;
/// Time spend in doing nothing.
unsigned long long int idle_all_period_;
/// Time spend in waiting an input/output to complete.
unsigned long long int iowait_period_;
/// Time spend in servicing hardware interrupts.
unsigned long long int irq_period_;
/// Time spend in servicing software interrupts.
unsigned long long int softirq_period_;
/// Time spend in other operating systems in a virtualized environments
/// Never doing this for control !
unsigned long long int steal_period_;
/// Time spend running a virtual CPU for guest operating systems
/// under the control of the Linux kernel
unsigned long long int guest_period_;
/// @}
double percent_;
void ProcessLine(std::istringstream &aCPULine);
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar &version;
ar &total_time_;
ar &user_mode_time_;
ar &nice_time_;
ar &system_time_;
ar &system_all_time_;
ar &idle_time_;
ar &idle_all_time_;
ar &iowait_time_;
ar &irq_time_;
ar &softirq_time_;
ar &steal_time_;
ar &guest_time_;
ar &guest_nice_time_;
ar &percent_;
}
};
/// This class gathers information on a computer.
/// This includes a list of CPU
class DYNAMIC_GRAPH_DLLAPI System {
private:
bool init_;
public:
System();
/// Read /proc/state file to extract CPU count.
void init();
/// Update CPU data information from /proc/stat
void readProcStat();
/// Friend class for serialization.
friend class boost::serialization::access;
/// Number of CPU.
unsigned int cpuNb_;
void ProcessCPULine(unsigned int cpunb, std::istringstream &aCPULine);
/// \brief Vector of CPU informations.
std::vector<CPUData> vCPUData_;
/// \brief Global CPU information.
CPUData gCPUData_;
template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar &version;
ar &cpuNb_;
ar &gCPUData_;
ar &vCPUData_;
}
};
} // namespace CPU
} // namespace dynamicgraph
#endif /* DYNAMIC_GRAPH_PROCESS_LIST_H_ */
// -*- mode: c++ -*-
// Copyright 2018, Joseph Mirabel LAAS-CNRS
//
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
#define DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <dynamic-graph/config.hh>
#include <sstream>
#include <vector>
namespace dynamicgraph {
/// \ingroup debug
///
/// \brief Stream for the real-time logger.
///
/// You should inherit from this class in order to redirect the logs where you
/// want.
/// \sa LoggerIOStream
class LoggerStream {
public:
virtual void write(const char *c) = 0;
};
/// Write to an ostream object.
///
/// The easieast is to use the macro dgADD_OSTREAM_TO_RTLOG(ostr) where
/// `ostr` can be `std::cout` or an std::ofstream...
class LoggerIOStream : public LoggerStream {
public:
LoggerIOStream(std::ostream &os) : os_(os) {}
virtual ~LoggerIOStream() {}
virtual void write(const char *c) { os_ << c; }
private:
std::ostream &os_;
};
typedef boost::shared_ptr<LoggerStream> LoggerStreamPtr_t;
class RealTimeLogger;
/// \cond DEVEL
/// \brief write entries to intenal buffer.
///
/// The entry starts when an instance is created and ends when is is deleted.
/// This class is only used by RealTimeLogger.
class RTLoggerStream {
public:
inline RTLoggerStream(RealTimeLogger *logger, std::ostream &os)
: ok_(logger != NULL), logger_(logger), os_(os) {}
template <typename T>
inline RTLoggerStream &operator<<(T t) {
if (ok_) os_ << t;
return *this;
}
inline RTLoggerStream &operator<<(std::ostream &(*pf)(std::ostream &)) {
if (ok_) os_ << pf;
return *this;
}
inline ~RTLoggerStream();
inline bool isNull() { return !ok_; }
private:
const bool ok_;
RealTimeLogger *logger_;
std::ostream &os_;
};
/// \endcond DEVEL
/// \ingroup debug
///
/// \brief Main class of the real-time logger.
///
/// It is intended to be used like this:
/// \code
/// #define ENABLE_RT_LOG
/// #include <dynamic-graph/real-time-logger.h>
///
/// // Somewhere in the main function of your executable
/// int main (int argc, char** argv) {
/// dgADD_OSTREAM_TO_RTLOG (std::cout);
/// }
///
/// // Somewhere in your library
/// dgRTLOG() << "your message. Prefer to use \n than std::endl."
/// \endcode
///
/// \note Thread safety. This class expects to have:
/// - only one reader: the one who take the log entries and write them
/// somewhere.
/// - one writer at a time. Writing to the logs is **never** a blocking
/// operation. If the resource is busy, the log entry is discarded.
class DYNAMIC_GRAPH_DLLAPI RealTimeLogger {
public:
static RealTimeLogger &instance();
static void destroy();
/// \todo add an argument to preallocate the internal string
/// to a given size.
RealTimeLogger(const std::size_t &bufferSize);
inline void clearOutputStreams() { outputs_.clear(); }
inline void addOutputStream(const LoggerStreamPtr_t &os) {
outputs_.push_back(os);
}
/// Write next message to output.
/// It does nothing if the buffer is empty.
/// \return true if it wrote something
bool spinOnce();
/// Return an object onto which a real-time thread can write.
/// The message is considered finished when the object is destroyed.
RTLoggerStream front();
/// Return an empty stream object.
RTLoggerStream emptyStream() { return RTLoggerStream(NULL, oss_); }
inline void frontReady() {
backIdx_ = (backIdx_ + 1) % buffer_.size();
wmutex.unlock();
}
inline bool empty() const { return frontIdx_ == backIdx_; }
inline bool full() const {
return ((backIdx_ + 1) % buffer_.size()) == frontIdx_;
}
inline std::size_t size() const {
if (frontIdx_ <= backIdx_)
return backIdx_ - frontIdx_;
else
return backIdx_ + buffer_.size() - frontIdx_;
}
inline std::size_t getBufferSize() { return buffer_.size(); }
~RealTimeLogger();
private:
struct Data {
std::stringbuf buf;
};
std::vector<LoggerStreamPtr_t> outputs_;
std::vector<Data *> buffer_;
/// Index of the next value to be read.
std::size_t frontIdx_;
/// Index of the slot where to write next value
/// (does not contain valid data).
std::size_t backIdx_;
std::ostream oss_;
/// The writer mutex.
boost::mutex wmutex;
std::size_t nbDiscarded_;
struct thread;
static RealTimeLogger *instance_;
static thread *thread_;
};
RTLoggerStream::~RTLoggerStream() {
if (ok_) {
os_ << std::ends;
logger_->frontReady();
}
}
} // end of namespace dynamicgraph
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_DEF_H
// -*- mode: c++ -*-
// Copyright 2018, Joseph Mirabel LAAS-CNRS
//
#ifndef DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#define DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
#ifdef ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) \
::dynamicgraph::RealTimeLogger::instance().addOutputStream( \
::dynamicgraph::LoggerStreamPtr_t( \
new ::dynamicgraph::LoggerIOStream(ostr)))
#define dgRTLOG() ::dynamicgraph::RealTimeLogger::instance().front()
#else // ENABLE_RT_LOG
#define dgADD_OSTREAM_TO_RTLOG(ostr) struct __end_with_semicolon
#define dgRTLOG() \
if (1) \
; \
else \
__null_stream()
#endif
#include <dynamic-graph/real-time-logger-def.h>
#endif //! DYNAMIC_GRAPH_LOGGER_REAL_TIME_H
......@@ -2,202 +2,153 @@
// 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_SIGNAL_ARRAY_H
# define DYNAMIC_GRAPH_SIGNAL_ARRAY_H
# include <dynamic-graph/signal-base.h>
# include <dynamic-graph/dynamic-graph-api.h>
# include <vector>
#define DYNAMIC_GRAPH_SIGNAL_ARRAY_H
#include <dynamic-graph/dynamic-graph-api.h>
#include <dynamic-graph/signal-base.h>
#include <stdio.h>
namespace dynamicgraph
{
/// \ingroup dgraph
///
/// \brief TODO
template<class Time>
class SignalArray_const
{
public:
static const int DEFAULT_SIZE = 20;
protected:
std::vector< const SignalBase<Time>* > const_array;
unsigned int size,rank;
public:
SignalArray_const<Time> (const unsigned int& sizeARG = DEFAULT_SIZE)
: const_array (sizeARG),
size (sizeARG),
rank (0)
{}
SignalArray_const<Time> (const SignalBase<Time>& sig)
: const_array (DEFAULT_SIZE),
size (DEFAULT_SIZE),
rank (0)
{
addElmt(&sig);
}
SignalArray_const<Time> (const SignalArray<Time>& siga)
: const_array (siga.getSize()),
size (siga.getSize ()),
rank (siga.getSize ())
{
for (unsigned int i = 0; i < rank; ++i)
const_array[i] = &siga[i];
}
SignalArray_const<Time> (const SignalArray_const<Time>& siga)
: const_array(siga.getSize ()),
size(siga.getSize ()),
rank(siga.getSize ())
{
for (unsigned int i = 0; i < rank; ++i)
const_array[i] = &siga[i];
}
#include <vector>
virtual ~SignalArray_const<Time> (){}
namespace dynamicgraph {
protected:
/// \ingroup dgraph
///
/// \brief TODO
template <class Time>
class SignalArray_const {
public:
static const int DEFAULT_SIZE = 20;
void addElmt (const SignalBase<Time>* el)
{
if (rank >= size)
{
size += DEFAULT_SIZE;
const_array.resize(size);
}
const_array[rank++] = el;
}
protected:
std::vector<const SignalBase<Time> *> const_array;
unsigned int size, rank;
public:
virtual SignalArray_const<Time>& operator<< (const SignalBase<Time>& sig)
{
addElmt (&sig);
return *this;
}
public:
virtual const SignalBase<Time>& operator[] (const unsigned int& idx) const
{
return *const_array[idx];
}
virtual unsigned int getSize () const
{
return rank;
}
};
public:
SignalArray_const<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: const_array(sizeARG), size(sizeARG), rank(0) {}
SignalArray_const<Time>(const SignalBase<Time> &sig)
: const_array(DEFAULT_SIZE), size(DEFAULT_SIZE), rank(0) {
addElmt(&sig);
}
template<class Time>
SignalArray_const<Time> operator<< (const SignalBase<Time>& sig1,
const SignalBase<Time>& sig2)
{
SignalArray_const<Time> res(sig1);
res<<sig2;
return res;
SignalArray_const<Time>(const SignalArray<Time> &siga)
: const_array(siga.getSize()),
size(siga.getSize()),
rank(siga.getSize()) {
for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i];
}
/// \ingroup dgraph
///
/// \brief TODO
template<class Time>
class SignalArray : public SignalArray_const<Time>
{
public:
using SignalArray_const<Time>::DEFAULT_SIZE;
using SignalArray_const<Time>::size;
using SignalArray_const<Time>::rank;
protected:
mutable std::vector< SignalBase<Time>* > array;
public:
SignalArray<Time> (const unsigned int& sizeARG = DEFAULT_SIZE)
: SignalArray_const<Time> (0),
array(sizeARG)
{
size=sizeARG;
}
SignalArray_const<Time>(const SignalArray_const<Time> &siga)
: const_array(siga.getSize()),
size(siga.getSize()),
rank(siga.getSize()) {
for (unsigned int i = 0; i < rank; ++i) const_array[i] = &siga[i];
}
SignalArray<Time> (SignalBase<Time>& sig)
: SignalArray_const<Time> (0),
array(DEFAULT_SIZE)
{
size=DEFAULT_SIZE;
addElmt(&sig);
}
virtual ~SignalArray_const<Time>() {}
SignalArray<Time> (const SignalArray<Time>& siga)
: SignalArray_const<Time> (siga.getSize()),
array (siga.getSize())
{
rank = siga.getSize ();
for (unsigned int i = 0; i < rank; ++i)
array[i]=&siga[i];
protected:
void addElmt(const SignalBase<Time> *el) {
if (rank >= size) {
size += DEFAULT_SIZE;
const_array.resize(size);
}
const_array[rank++] = el;
}
virtual ~SignalArray<Time> (){}
public:
virtual SignalArray_const<Time> &operator<<(const SignalBase<Time> &sig) {
addElmt(&sig);
return *this;
}
protected:
public:
virtual const SignalBase<Time> &operator[](const unsigned int &idx) const {
return *const_array[idx];
}
virtual unsigned int getSize() const { return rank; }
};
template <class Time>
SignalArray_const<Time> operator<<(const SignalBase<Time> &sig1,
const SignalBase<Time> &sig2) {
SignalArray_const<Time> res(sig1);
res << sig2;
return res;
}
/// \ingroup dgraph
///
/// \brief TODO
template <class Time>
class SignalArray : public SignalArray_const<Time> {
public:
using SignalArray_const<Time>::DEFAULT_SIZE;
using SignalArray_const<Time>::size;
using SignalArray_const<Time>::rank;
protected:
mutable std::vector<SignalBase<Time> *> array;
public:
SignalArray<Time>(const unsigned int &sizeARG = DEFAULT_SIZE)
: SignalArray_const<Time>(0), array(sizeARG) {
size = sizeARG;
}
void addElmt (SignalBase<Time>* el)
{
if (rank >= size)
{
size += DEFAULT_SIZE;
array.resize(size);
}
array[rank++] = el;
}
SignalArray<Time>(SignalBase<Time> &sig)
: SignalArray_const<Time>(0), array(DEFAULT_SIZE) {
size = DEFAULT_SIZE;
addElmt(&sig);
}
public:
virtual SignalArray<Time>& operator<< (SignalBase<Time>& sig)
{
addElmt(&sig);
return *this;
}
SignalArray<Time>(const SignalArray<Time> &siga)
: SignalArray_const<Time>(siga.getSize()), array(siga.getSize()) {
rank = siga.getSize();
for (unsigned int i = 0; i < rank; ++i) array[i] = &siga[i];
}
virtual SignalArray_const<Time>
operator<< (const SignalBase<Time>& sig) const
{
SignalArray_const<Time> res (*this);
res << sig;
return res;
}
virtual ~SignalArray<Time>() {}
virtual SignalBase<Time>& operator[] (const unsigned int& idx) const
{
return *array[idx];
protected:
void addElmt(SignalBase<Time> *el) {
if (rank >= size) {
size += DEFAULT_SIZE;
array.resize(size);
}
};
array[rank++] = el;
}
public:
virtual SignalArray<Time> &operator<<(SignalBase<Time> &sig) {
addElmt(&sig);
return *this;
}
template<class Time>
SignalArray<Time> operator<< (SignalBase<Time>& sig1,
SignalBase<Time>& sig2)
{
SignalArray<Time> res (sig1);
res << sig2;
virtual SignalArray_const<Time> operator<<(
const SignalBase<Time> &sig) const {
SignalArray_const<Time> res(*this);
res << sig;
return res;
}
DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL;
virtual SignalBase<Time> &operator[](const unsigned int &idx) const {
return *array[idx];
}
};
template <class Time>
SignalArray<Time> operator<<(SignalBase<Time> &sig1, SignalBase<Time> &sig2) {
SignalArray<Time> res(sig1);
res << sig2;
return res;
}
DYNAMIC_GRAPH_DLLAPI extern SignalArray<int> sotNOSIGNAL;
} // end of namespace dynamicgraph.
} // end of namespace dynamicgraph.
#endif //! DYNAMIC_GRAPH_SIGNAL_ARRAY_H
#endif //! DYNAMIC_GRAPH_SIGNAL_ARRAY_H