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) {