New entity types are defined by
The interface is defined in file include/dynamic-graph/tutorial/inverted-pendulum.hh
.
First, we include
#include <dynamic-graph/entity.h> #include <dynamic-graph/signal-ptr.h> #include <dynamic-graph/linear-algebra.h>
Then in namespace dynamicgraph::tutorial
we define class InvertedPendulum
namespace dynamicgraph { namespace tutorial { class InvertedPendulum : public Entity {
with a constructor taking a name as an input
InvertedPendulum(const std::string& inName);
For the internal machinery, each entity can provide the name of the class it belongs to:
virtual const std::string& getClassName (void) const { return CLASS_NAME; }
Class InvertedPendulum represents a dynamical system. The following method integrates the equation of motion over a time step
void incr(double inTimeStep);
Setters and getters will enable us later to control parameters through commands.
void setCartMass (const double& inMass) { cartMass_ = inMass; } double getCartMass () const { return cartMass_; } void setPendulumMass (const double& inMass) { pendulumMass_ = inMass; } double getPendulumMass () const { return pendulumMass_; } void setPendulumLength (const double& inLength) { pendulumLength_ = inLength; } double getPendulumLength () const { return pendulumLength_; }
The name of the class is stored as a static member
static const std::string CLASS_NAME;
In the private part of the class, we store signals
SignalPtr< double, int > forceSIN; Signal< Vector, int> stateSOUT;
and parameters
double cartMass_; double pendulumMass_; double pendulumLength_; double viscosity_;
The implementation is written in file src/inverted-pendulum.cc
.
First, we include headers defining
#include <dynamic-graph/factory.h> #include <dynamic-graph/command-setter.h> #include <dynamic-graph/command-getter.h> #include "dynamic-graph/tutorial/inverted-pendulum.hh" #include "command-increment.hh"
The second step consists in
using a macro defined in dynamic-graph/factory.h
:
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(InvertedPendulum, "InvertedPendulum");
Then we define the class constructor
InvertedPendulum::InvertedPendulum(const std::string& inName) : Entity(inName), forceSIN(NULL, "InvertedPendulum("+inName+")::input(vector)::force"), stateSOUT("InvertedPendulum("+inName+")::output(vector)::state"), cartMass_(1.0), pendulumMass_(1.0), pendulumLength_(1.0), viscosity_(0.1)
We register signals into an associative array stored into Entity class
signalRegistration (forceSIN); signalRegistration (stateSOUT);
We set input and output signal as constant with a given value
Vector state = boost::numeric::ublas::zero_vector<double>(4); double input = 0.; stateSOUT.setConstant(state); forceSIN.setConstant(input);
The following lines of code define and register commands into the entity. A command is created by calling a constructor with
std::string docstring; // Incr docstring = "\n" " Integrate dynamics for time step provided as input\n" "\n" " take one floating point number as input\n" "\n"; addCommand(std::string("incr"), new command::Increment(*this, docstring));
In this example, command::Increment is a command specific to our class InvertedPendulum. This new command is explained in page Creating a new command.
Setter and getter commands are available through classes templated by the type of entity using the command and the type of the parameter. Be aware that only a prespecified set of types are supported for commands, see class dynamicgraph::command::Value.
docstring = "\n" " Set cart mass\n" "\n"; addCommand(std::string("setCartMass"), new ::dynamicgraph::command::Setter<InvertedPendulum, double> (*this, &InvertedPendulum::setCartMass, docstring)); docstring = "\n" " Get cart mass\n" "\n"; addCommand(std::string("getCartMass"), new ::dynamicgraph::command::Getter<InvertedPendulum, double> (*this, &InvertedPendulum::getCartMass, docstring));
Signals are templated by the type of data they convey. In this example, we hae defined our own class of vectors InvertedPendulum::Vector. In order to be able to create signals with this type, we need to register the new type: