6 #include <dynamic-graph/factory.h> 
    8 #include <sot/core/debug.hh> 
    9 #include <sot/core/stop-watch.hh> 
   16 namespace dg = ::dynamicgraph;
 
   18 using namespace dg::command;
 
   20 using namespace Eigen;
 
   22 #define PROFILE_SE3_POSITION_DESIRED_COMPUTATION "SE3TrajGen: traj computation" 
   30                                    "SE3TrajectoryGenerator");
 
   37       CONSTRUCT_SIGNAL_IN(initial_value, 
dynamicgraph::Vector),
 
   39       CONSTRUCT_SIGNAL_IN(trigger, bool),
 
   41       CONSTRUCT_SIGNAL_OUT(ddx, 
dynamicgraph::Vector, m_xSOUT),
 
   42       m_initSucceeded(false),
 
   48       m_splineReady(false) {
 
   49   BIND_SIGNAL_TO_FUNCTION(x, OUT, dynamicgraph::Vector);
 
   51   Entity::signalRegistration(m_xSOUT << m_dxSOUT << m_ddxSOUT
 
   52                                      << m_initial_valueSIN << m_triggerSIN);
 
   55   addCommand(
"init", makeCommandVoid1(
 
   57                          docCommandVoid1(
"Initialize the entity.",
 
   58                                          "Time period in seconds (double)")));
 
   64           docCommandVoid1(
"Get the current value of the specified index.",
 
   67   addCommand(
"playTrajectoryFile",
 
   71                      "Play the trajectory read from the specified text file.",
 
   72                      "(string) File name, path included")));
 
   76                        docCommandVoid3(
"Load serialized spline from file",
 
   78                                        "(double) time to initial conf",
 
   79                                        "(Matrix) orientation of the point")));
 
   85           docCommandVoid3(
"Start an infinite sinusoid motion.",
 
   86                           "(int)    index", 
"(double) final value",
 
   87                           "(double) time to reach the final value in sec")));
 
   93           docCommandVoid4(
"Start an infinite triangle wave.", 
"(int)    index",
 
   94                           "(double) final values",
 
   95                           "(double) time to reach the final value in sec",
 
   96                           "(double) time to accelerate in sec")));
 
  102           docCommandVoid3(
"Start an infinite trajectory with piece-wise " 
  103                           "constant acceleration.",
 
  104                           "(int)    index", 
"(double) final values",
 
  105                           "(double) time to reach the final value in sec")));
 
  107   addCommand(
"startLinChirp",
 
  110                  docCommandVoid5(
"Start a linear-chirp motion.",
 
  111                                  "(int)    index", 
"(double) final values",
 
  112                                  "(double) initial frequency [Hz]",
 
  113                                  "(double) final frequency [Hz]",
 
  114                                  "(double) trajectory time [sec]")));
 
  115   addCommand(
"move", makeCommandVoid3(
 
  118                              "Move component corresponding to index to the " 
  119                              "specified value with a minimum jerk trajectory.",
 
  120                              "(int)    index", 
"(double) final values",
 
  121                              "(double) time to reach the final value in sec")));
 
  126           docCommandVoid1(
"Stop the motion of the specified index, or of all " 
  127                           "components of the vector if index is equal to -1.",
 
  132   if (dt <= 0.0) 
return SEND_MSG(
"Timestep must be positive", MSG_TYPE_ERROR);
 
  143   for (
unsigned int i = 0; i < 
m_np; i++) {
 
  153   m_splineTrajGen = 
new parametriccurves::Spline<double, Eigen::Dynamic>();
 
  163   if (!m_initSucceeded) {
 
  164     SEND_WARNING_STREAM_MSG(
 
  165         "Cannot compute signal positionDes before initialization!");
 
  171     if (s.size() != m_np) s.resize(m_np);
 
  175       const dynamicgraph::Vector& initial_value = m_initial_valueSIN(iter);
 
  176       if (initial_value.size() != m_np) {
 
  177         SEND_ERROR_STREAM_MSG(
 
  178             "Unexpected size of input signal initial_value: " +
 
  179             toString(initial_value.size()));
 
  183       for (
unsigned int i = 0; i < m_np; i++)
 
  184         m_currentTrajGen[i]->set_initial_point(initial_value(i));
 
  186     } 
else if (iter == 
static_cast<int>(m_iterLast)) {
 
  187       if (m_triggerSIN(iter) == 
true && m_splineReady) startSpline();
 
  188       if (m_status[0] == TG_TEXT_FILE) {
 
  189         for (
unsigned int i = 0; i < m_np; i++)
 
  190           s(i) = m_textFileTrajGen->getPos()[i];
 
  191       } 
else if (m_status[0] == TG_SPLINE) {
 
  192         const Eigen::Vector3d& t = (*m_splineTrajGen)(m_t);
 
  194         s.segment<3>(3) = m_splineRotation.row(0);
 
  195         s.segment<3>(6) = m_splineRotation.row(1);
 
  196         s.segment<3>(9) = m_splineRotation.row(2);
 
  198         for (
unsigned int i = 0; i < m_np; i++)
 
  199           s(i) = m_currentTrajGen[i]->getPos()(0);
 
  204     if (m_triggerSIN(iter) == 
true && m_splineReady) startSpline();
 
  205     if (m_status[0] == TG_TEXT_FILE) {
 
  206       const VectorXd& xRef = m_textFileTrajGen->compute_next_point();
 
  207       for (
unsigned int i = 0; i < m_np; i++) {
 
  209         if (m_textFileTrajGen->isTrajectoryEnded()) {
 
  210           m_noTrajGen[i]->set_initial_point(s(i));
 
  211           m_status[i] = TG_STOP;
 
  214       if (m_textFileTrajGen->isTrajectoryEnded())
 
  215         SEND_MSG(
"Text file trajectory ended.", MSG_TYPE_INFO);
 
  216     } 
else if (m_status[0] == TG_SPLINE) {
 
  218       if (!m_splineTrajGen->checkRange(m_t)) {
 
  219         const Eigen::Vector3d& t = (*m_splineTrajGen)(m_splineTrajGen->tmax());
 
  221         s.segment<3>(3) = m_splineRotation.row(0);
 
  222         s.segment<3>(6) = m_splineRotation.row(1);
 
  223         s.segment<3>(9) = m_splineRotation.row(2);
 
  224         for (
unsigned int i = 0; i < m_np; i++) {
 
  225           m_noTrajGen[i]->set_initial_point(s(i));
 
  226           m_status[i] = TG_STOP;
 
  228         m_splineReady = 
false;
 
  229         SEND_MSG(
"Spline trajectory ended. Remember to turn off the trigger.",
 
  233         const Eigen::Vector3d& t = (*m_splineTrajGen)(m_t);
 
  235         s.segment<3>(3) = m_splineRotation.row(0);
 
  236         s.segment<3>(6) = m_splineRotation.row(1);
 
  237         s.segment<3>(9) = m_splineRotation.row(2);
 
  240       for (
unsigned int i = 0; i < m_np; i++) {
 
  241         s(i) = m_currentTrajGen[i]->compute_next_point()(0);
 
  242         if (m_currentTrajGen[i]->isTrajectoryEnded()) {
 
  243           m_currentTrajGen[i] = m_noTrajGen[i];
 
  244           m_noTrajGen[i]->set_initial_point(s(i));
 
  245           m_status[i] = TG_STOP;
 
  246           SEND_MSG(
"Trajectory of index " + toString(i) + 
" ended.",
 
  258   if (!m_initSucceeded) {
 
  259     std::ostringstream oss(
 
  260         "Cannot compute signal positionDes before initialization! iter:");
 
  262     SEND_WARNING_STREAM_MSG(oss.str());
 
  266   if (s.size() != m_nv) s.resize(m_nv);
 
  267   if (m_status[0] == TG_TEXT_FILE) {
 
  268     for (
unsigned int i = 0; i < m_nv; i++)
 
  269       s(i) = m_textFileTrajGen->getVel()[i];
 
  270   } 
else if (m_status[0] == TG_SPLINE) {
 
  271     const Eigen::Vector3d& t = m_splineTrajGen->derivate(m_t, 1);
 
  273     s.segment<3>(3).setZero();
 
  275     for (
unsigned int i = 0; i < m_nv; i++)
 
  276       s(i) = m_currentTrajGen[i]->getVel()(0);
 
  282   if (!m_initSucceeded) {
 
  283     std::ostringstream oss(
 
  284         "Cannot compute signal positionDes before initialization! iter:");
 
  286     SEND_WARNING_STREAM_MSG(oss.str());
 
  290   if (s.size() != m_nv) s.resize(m_nv);
 
  292   if (m_status[0] == TG_TEXT_FILE) {
 
  293     for (
unsigned int i = 0; i < m_nv; i++)
 
  294       s(i) = m_textFileTrajGen->getAcc()[i];
 
  295   } 
else if (m_status[0] == TG_SPLINE) {
 
  296     const Eigen::Vector3d& t = m_splineTrajGen->derivate(m_t, 2);
 
  298     s.segment<3>(3).setZero();
 
  300     for (
unsigned int i = 0; i < m_nv; i++)
 
  301       s(i) = m_currentTrajGen[i]->getAcc()(0);
 
  311   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  312     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  314   SEND_MSG(
"Current value of component " + toString(
id) + 
" is " +
 
  321     return SEND_MSG(
"Cannot start sinusoid before initialization!",
 
  324   for (
unsigned int i = 0; i < 
m_np; i++)
 
  326       return SEND_MSG(
"You cannot control component " + toString(i) +
 
  327                           " because it is already controlled.",
 
  331     return SEND_MSG(
"Error while loading text file " + fileName,
 
  336   bool needToMoveToInitConf = 
false;
 
  338   for (
unsigned int i = 0; i < 
m_np; i++)
 
  340       needToMoveToInitConf = 
true;
 
  341       SEND_MSG(
"Component " + toString(i) +
 
  342                    " is too far from initial configuration so first i will " 
  348   if (needToMoveToInitConf) {
 
  349     for (
unsigned int i = 0; i < 
m_np; i++) {
 
  359   for (
unsigned int i = 0; i < 
m_np; i++) {
 
  365                                        const double& timeToInitConf,
 
  366                                        const Eigen::MatrixXd& init_rotation) {
 
  368     return SEND_MSG(
"Cannot start sinusoid before initialization!",
 
  371   for (
unsigned int i = 0; i < 
m_np; i++)
 
  373       return SEND_MSG(
"You cannot control component " + toString(i) +
 
  374                           " because it is already controlled.",
 
  378     return SEND_MSG(
"Error while loading text file " + fileName,
 
  383   bool needToMoveToInitConf = 
false;
 
  386   if (timeToInitConf < 0) {
 
  387     SEND_MSG(
"Spline Ready. Set trigger to true to start playing",
 
  392   const VectorXd& t = (*m_splineTrajGen)(0.0);
 
  399   for (
unsigned int i = 0; i < 
m_np; i++)
 
  401       needToMoveToInitConf = 
true;
 
  402       SEND_MSG(
"Component " + toString(i) +
 
  403                    " is too far from initial configuration so first i will " 
  409   if (needToMoveToInitConf) {
 
  410     for (
unsigned int i = 0; i < 
m_np; i++) {
 
  420   SEND_MSG(
"Spline Ready. Set trigger to true to start playing", MSG_TYPE_INFO);
 
  426   for (
unsigned int i = 0; i < 
m_np; i++) {
 
  432                                            const double& time) {
 
  434     return SEND_MSG(
"Cannot start sinusoid before initialization!",
 
  437   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  438     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  441     return SEND_MSG(
"Trajectory time must be a positive number",
 
  445         "You cannot move the specified component because it is already " 
  451       "Set initial point of sinusoid to " + toString(
m_sinTrajGen[i]->getPos()),
 
  461                                            const double& Tacc) {
 
  463     return SEND_MSG(
"Cannot start triangle before initialization!",
 
  465   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  466     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  470         "You cannot move the specified component because it is already " 
  475   SEND_MSG(
"Set initial point of triangular trajectory to " +
 
  481     return SEND_MSG(
"Trajectory time cannot be negative.", MSG_TYPE_ERROR);
 
  485         "Acceleration time cannot be negative or larger than half the " 
  494                                            const double& time) {
 
  497         "Cannot start constant-acceleration trajectory before initialization!",
 
  499   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  500     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  503     return SEND_MSG(
"Trajectory time must be a positive number",
 
  507         "You cannot move the specified component because it is already " 
  512   SEND_MSG(
"Set initial point of const-acc trajectory to " +
 
  522                                               const double& xFinal,
 
  525                                               const double& time) {
 
  527     return SEND_MSG(
"Cannot start linear chirp before initialization!",
 
  529   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  530     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  533     return SEND_MSG(
"Trajectory time must be a positive number",
 
  537         "You cannot move the specified component because it is already " 
  542         "f0 " + toString(f0) + 
" cannot to be more than f1 " + toString(f1),
 
  545     return SEND_MSG(
"Frequency has to be positive " + toString(f0),
 
  549     return SEND_MSG(
"Error while setting initial point " +
 
  553     return SEND_MSG(
"Error while setting final point " + toString(xFinal),
 
  556     return SEND_MSG(
"Error while setting trajectory time " + toString(time),
 
  559     return SEND_MSG(
"Error while setting initial frequency " + toString(f0),
 
  562     return SEND_MSG(
"Error while setting final frequency " + toString(f1),
 
  569                                   const double& time) {
 
  571     return SEND_MSG(
"Cannot move value before initialization!", MSG_TYPE_ERROR);
 
  573   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  574     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  576     return SEND_MSG(
"Trajectory time must be a positive number",
 
  580         "You cannot move the specified component because it is already " 
  593     return SEND_MSG(
"Cannot stop value before initialization!", MSG_TYPE_ERROR);
 
  597     for (
unsigned int i = 0; i < 
m_np; i++) {
 
  605   if (id < 0 || id >= 
static_cast<int>(
m_np))
 
  606     return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
 
  621   os << 
"SE3TrajectoryGenerator " << getName();
 
  623     getProfiler().report_all(3, os);
 
  624   } 
catch (ExceptionSignal e) {
 
virtual const Eigen::VectorXd & get_initial_point()
 
void move(const int &id, const double &xFinal, const double &time)
 
Eigen::Matrix3d m_splineRotation
 
std::vector< SinusoidTrajectoryGenerator * > m_sinTrajGen
 
double m_t
last iter index
 
void setSpline(const std::string &filename, const double &timeToInitConf, const Eigen::MatrixXd &init_rotation)
 
TextFileTrajectoryGenerator * m_textFileTrajGen
 
void init(const double &dt)
 
std::vector< LinearChirpTrajectoryGenerator * > m_linChirpTrajGen
 
double m_dt
true if it is the first iteration, false otherwise
 
std::vector< ConstantAccelerationTrajectoryGenerator * > m_constAccTrajGen
 
void startTriangle(const int &id, const double &xFinal, const double &time, const double &Tacc)
 
virtual void display(std::ostream &os) const
 
parametriccurves::Spline< double, Eigen::Dynamic > * m_splineTrajGen
 
void startLinearChirp(const int &id, const double &xFinal, const double &f0, const double &f1, const double &time)
 
void startConstAcc(const int &id, const double &xFinal, const double &time)
 
void startSinusoid(const int &id, const double &xFinal, const double &time)
 
std::vector< TG_Status > m_status
 
bool m_firstIter
true if the entity has been successfully initialized
 
std::vector< TriangleTrajectoryGenerator * > m_triangleTrajGen
 
std::vector< NoTrajectoryGenerator * > m_noTrajGen
 
std::vector< AbstractTrajectoryGenerator * > m_currentTrajGen
status of the component
 
void getValue(const int &id)
 
std::vector< MinimumJerkTrajectoryGenerator * > m_minJerkTrajGen
 
unsigned int m_np
control loop time period
 
SE3TrajectoryGenerator(const std::string &name)
 
void playTrajectoryFile(const std::string &fileName)
 
virtual bool loadTextFile(const std::string &fileName)
 
DEFINE_SIGNAL_OUT_FUNCTION(u, dynamicgraph::Vector)
 
AdmittanceController EntityClassName
 
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(AdmittanceController, "AdmittanceController")
 
#define PROFILE_SE3_POSITION_DESIRED_COMPUTATION