19 #include <dynamic-graph/factory.h>
21 #include <sot/core/debug.hh>
22 #include <sot/core/stop-watch.hh>
28 namespace talos_balance {
31 using namespace dynamicgraph::command;
33 using namespace Eigen;
35 #define PROFILE_ND_POSITION_DESIRED_COMPUTATION "NdTrajGen: traj computation"
36 #define DOUBLE_INF std::numeric_limits<double>::max()
43 "NdTrajectoryGenerator");
51 CONSTRUCT_SIGNAL_IN(trigger, bool),
55 m_initSucceeded(false),
60 m_splineReady(false) {
63 Entity::signalRegistration(m_xSOUT << m_dxSOUT << m_ddxSOUT
64 << m_initial_valueSIN << m_triggerSIN);
70 docCommandVoid2(
"Initialize the entity.",
71 "Time period in seconds (double)",
72 "size of output vector signal (int)")));
78 docCommandVoid1(
"Get the current value of the specified index.",
81 addCommand(
"playTrajectoryFile",
85 "Play the trajectory read from the specified text file.",
86 "(string) File name, path included")));
92 docCommandVoid3(
"Start an infinite sinusoid motion.",
93 "(int) index",
"(double) final value",
94 "(double) time to reach the final value in sec")));
99 docCommandVoid2(
"Load serialized spline from file",
101 "(double) time to initial conf")));
118 docCommandVoid3(
"Start an infinite trajectory with piece-wise "
119 "constant acceleration.",
120 "(int) index",
"(double) final values",
121 "(double) time to reach the final value in sec")));
123 addCommand(
"startLinChirp",
126 docCommandVoid5(
"Start a linear-chirp motion.",
127 "(int) index",
"(double) final values",
128 "(double) initial frequency [Hz]",
129 "(double) final frequency [Hz]",
130 "(double) trajectory time [sec]")));
131 addCommand(
"move", makeCommandVoid3(
134 "Move component corresponding to index to the "
135 "specified value with a minimum jerk trajectory.",
136 "(int) index",
"(double) final values",
137 "(double) time to reach the final value in sec")));
141 docCommandVoid2(
"Instantaneously set component corresponding "
142 "to index to the specified value.",
143 "(int) index",
"(double) desired value")));
148 docCommandVoid1(
"Stop the motion of the specified index, or of all "
149 "components of the vector if index is equal to -1.",
154 if (
dt <= 0.0)
return SEND_MSG(
"Timestep must be positive", MSG_TYPE_ERROR);
155 if (n < 1)
return SEND_MSG(
"n must be at least 1", MSG_TYPE_ERROR);
167 for (
unsigned i = 0; i <
m_n; i++) {
169 m_sinTrajGen[i] =
new parametriccurves::InfiniteSinusoid<double, 1>(5.0);
173 new parametriccurves::InfiniteConstAcc<double, 1>(5.0);
175 m_noTrajGen[i] =
new parametriccurves::Constant<double, 1>(5.0);
183 m_splineTrajGen =
new parametriccurves::Spline<double, Eigen::Dynamic>();
185 new parametriccurves::TextFile<double, Eigen::Dynamic>(
dt, n);
187 NdTrajectoryGenerator::setLoggerVerbosityLevel(
188 dynamicgraph::LoggerVerbosity::VERBOSITY_ALL);
197 if (!m_initSucceeded) {
198 SEND_WARNING_STREAM_MSG(
199 "Cannot compute signal positionDes before initialization!");
205 if (s.size() != m_n) s.resize(m_n);
210 if (initial_value.size() != m_n) {
211 SEND_MSG(
"Unexpected size of input signal initial_value: " +
212 toString(initial_value.size()),
217 for (
unsigned int i = 0; i < m_n; i++)
218 m_currentTrajGen[i]->setInitialPoint(initial_value(i));
220 }
else if (iter ==
static_cast<int>(m_iterLast)) {
221 if (m_triggerSIN(iter) ==
true && m_splineReady) startSpline();
222 if (m_status[0] == JTG_TEXT_FILE) {
223 s = (*m_textFileTrajGen)(m_t);
224 }
else if (m_status[0] == JTG_SPLINE) {
225 s = (*m_splineTrajGen)(m_t);
227 for (
unsigned int i = 0; i < m_n; i++)
228 s(i) = (*m_currentTrajGen[i])(m_t)[0];
234 const bool& isTriggered = m_triggerSIN(iter);
236 if (isTriggered || m_status[0] != JTG_TEXT_FILE) m_t += m_dt;
238 if (isTriggered && m_splineReady) startSpline();
240 if (m_status[0] == JTG_TEXT_FILE) {
242 for (
unsigned int i = 0; i < m_n; i++) {
243 s(i) = (*m_noTrajGen[i])(m_t)[0];
245 }
else if (!m_textFileTrajGen->checkRange(m_t)) {
246 s = (*m_textFileTrajGen)(m_textFileTrajGen->tmax() -
248 for (
unsigned int i = 0; i < m_n; i++) {
249 m_noTrajGen[i]->setInitialPoint(s(i));
250 m_status[i] = JTG_STOP;
252 SEND_MSG(
"Text file trajectory ended.", MSG_TYPE_INFO);
255 s = (*m_textFileTrajGen)(m_t);
256 }
else if (m_status[0] == JTG_SPLINE) {
257 if (!m_splineTrajGen->checkRange(m_t)) {
258 s = (*m_splineTrajGen)(m_splineTrajGen->tmax());
259 for (
unsigned int i = 0; i < m_n; i++) {
260 m_noTrajGen[i]->setInitialPoint(s(i));
261 m_status[i] = JTG_STOP;
263 m_splineReady =
false;
264 SEND_MSG(
"Spline trajectory ended. Remember to turn off the trigger.",
268 s = (*m_splineTrajGen)(m_t);
270 for (
unsigned int i = 0; i < m_n; i++) {
271 if (!m_currentTrajGen[i]->checkRange(m_t)) {
272 s(i) = (*m_currentTrajGen[i])(m_currentTrajGen[i]->tmax())[0];
273 m_currentTrajGen[i] = m_noTrajGen[i];
274 m_noTrajGen[i]->setInitialPoint(s(i));
275 m_status[i] = JTG_STOP;
276 SEND_MSG(
"Trajectory of index " + toString(i) +
" ended.",
279 s(i) = (*m_currentTrajGen[i])(m_t)[0];
289 if (!m_initSucceeded) {
290 SEND_WARNING_STREAM_MSG(
291 "Cannot compute signal positionDes before initialization!");
298 if (s.size() != m_n) s.resize(m_n);
300 const bool& isTriggered = m_triggerSIN(iter);
302 if (m_status[0] == JTG_TEXT_FILE) {
304 s = m_textFileTrajGen->derivate(m_t, 1);
307 }
else if (m_status[0] == JTG_SPLINE)
308 s = m_splineTrajGen->derivate(m_t, 1);
310 for (
unsigned int i = 0; i < m_n; i++)
311 s(i) = m_currentTrajGen[i]->derivate(m_t, 1)[0];
317 if (!m_initSucceeded) {
318 SEND_WARNING_STREAM_MSG(
319 "Cannot compute signal positionDes before initialization!");
326 if (s.size() != m_n) s.resize(m_n);
328 const bool& isTriggered = m_triggerSIN(iter);
330 if (m_status[0] == JTG_TEXT_FILE) {
332 s = m_textFileTrajGen->derivate(m_t, 2);
335 }
else if (m_status[0] == JTG_SPLINE)
336 s = m_splineTrajGen->derivate(m_t, 2);
338 for (
unsigned int i = 0; i < m_n; i++)
339 s(i) = m_currentTrajGen[i]->derivate(m_t, 2)[0];
349 if (id < 0 || id >=
static_cast<int>(
m_n))
350 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
352 SEND_MSG(
"Current value of component " + toString(
id) +
" is " +
359 return SEND_MSG(
"Cannot start trajectory before initialization!",
362 for (
unsigned int i = 0; i <
m_n; i++)
364 return SEND_MSG(
"You cannot control component " + toString(i) +
365 " because it is already controlled.",
369 std::string msg(
"Error while loading text file " + fileName);
370 SEND_MSG(msg, MSG_TYPE_ERROR);
371 throw std::runtime_error(msg);
376 bool needToMoveToInitConf =
false;
378 for (
unsigned int i = 0; i <
m_n; i++) {
380 if (fabs(xInit[i] - currentVal) > 0.001) {
381 needToMoveToInitConf =
true;
384 SEND_MSG(
"Component " + toString(i) +
385 " is far from initial configuration (" + toString(xInit[i]) +
386 "->" + toString(currentVal) +
")",
411 for (
unsigned int i = 0; i <
m_n; i++) {
417 const double& timeToInitConf) {
419 return SEND_MSG(
"Cannot start spline before initialization!",
422 for (
unsigned int i = 0; i <
m_n; i++)
424 return SEND_MSG(
"You cannot control component " + toString(i) +
425 " because it is already controlled.",
429 return SEND_MSG(
"Error while loading spline" + filename, MSG_TYPE_ERROR);
431 SEND_MSG(
"Spline set to " + filename +
". Now checking initial position",
434 bool needToMoveToInitConf =
false;
435 if (timeToInitConf < 0) {
437 SEND_MSG(
"Spline Ready. Set trigger to true to start playing",
443 const VectorXd& xInit = (*m_splineTrajGen)(0.0);
444 assert(xInit.size() ==
m_n);
445 for (
unsigned int i = 0; i <
m_n; i++)
447 needToMoveToInitConf =
true;
448 SEND_MSG(
"Component " + toString(i) +
449 " is too far from initial configuration so first i will "
454 if (needToMoveToInitConf) {
455 for (
unsigned int i = 0; i <
m_n; i++) {
470 SEND_MSG(
"Spline Ready. Set trigger to true to start playing", MSG_TYPE_INFO);
476 for (
unsigned int i = 0; i <
m_n; i++) {
482 const double& time) {
484 return SEND_MSG(
"Cannot start sinusoid before initialization!",
487 if (id < 0 || id >=
static_cast<int>(
m_n))
488 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
491 return SEND_MSG(
"Trajectory time must be a positive number",
495 "You cannot move the specified component because it is already "
505 "Set initial point of sinusoid to " + toString((*
m_noTrajGen[i])(
m_t)[0]),
543 const double& time) {
546 "Cannot start constant-acceleration trajectory before initialization!",
548 if (id < 0 || id >=
static_cast<int>(
m_n))
549 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
552 return SEND_MSG(
"Trajectory time must be a positive number",
556 "You cannot move the specified component because it is already "
563 SEND_MSG(
"Set initial point of const-acc trajectory to " +
573 const double& xFinal,
574 const double& f0,
const double& f1,
575 const double& time) {
577 return SEND_MSG(
"Cannot start linear chirp before initialization!",
579 if (id < 0 || id >=
static_cast<int>(
m_n))
580 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
583 return SEND_MSG(
"Trajectory time must be a positive number",
587 "You cannot move the specified component because it is already "
594 "f0 " + toString(f0) +
" cannot to be more than f1 " + toString(f1),
597 return SEND_MSG(
"Frequency has to be positive " + toString(f0),
601 return SEND_MSG(
"Error while setting initial point " +
605 return SEND_MSG(
"Error while setting final point " + toString(xFinal),
608 return SEND_MSG(
"Error while setting trajectory time " + toString(time),
611 return SEND_MSG(
"Error while setting initial frequency " + toString(f0),
614 return SEND_MSG(
"Error while setting final frequency " + toString(f1),
622 const double& time) {
624 return SEND_MSG(
"Cannot move value before initialization!", MSG_TYPE_ERROR);
626 if (id < 0 || id >=
static_cast<int>(
m_n))
627 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
629 return SEND_MSG(
"Trajectory time must be a positive number",
633 "You cannot move the specified component because it is already "
649 return SEND_MSG(
"Cannot set value before initialization!", MSG_TYPE_ERROR);
651 if (id < 0 || id >=
static_cast<int>(
m_n))
652 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
655 "You cannot set the specified component because it is already "
669 return SEND_MSG(
"Cannot stop value before initialization!", MSG_TYPE_ERROR);
673 for (
unsigned int i = 0; i <
m_n; i++) {
682 if (id < 0 || id >=
static_cast<int>(
m_n))
683 return SEND_MSG(
"Index is out of bounds", MSG_TYPE_ERROR);
717 os <<
"NdTrajectoryGenerator " << getName();
719 getProfiler().report_all(3, os);
720 }
catch (ExceptionSignal e) {