joint_spline_trajectory_controller.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * Author: Stuart Glaser
32  */
33 
34 #include <boost/shared_ptr.hpp>
35 
37 #include <sstream>
38 #include "angles/angles.h"
40 
42 
43 namespace controller {
44 
45 // These functions are pulled from the spline_smoother package.
46 // They've been moved here to avoid depending on packages that aren't
47 // mature yet.
48 
49 
50 static inline void generatePowers(int n, double x, double* powers)
51 {
52  powers[0] = 1.0;
53  for (int i=1; i<=n; i++)
54  {
55  powers[i] = powers[i-1]*x;
56  }
57 }
58 
59 static void getQuinticSplineCoefficients(double start_pos, double start_vel, double start_acc,
60  double end_pos, double end_vel, double end_acc, double time, std::vector<double>& coefficients)
61 {
62  coefficients.resize(6);
63 
64  if (time == 0.0)
65  {
66  coefficients[0] = end_pos;
67  coefficients[1] = end_vel;
68  coefficients[2] = 0.5*end_acc;
69  coefficients[3] = 0.0;
70  coefficients[4] = 0.0;
71  coefficients[5] = 0.0;
72  }
73  else
74  {
75  double T[6];
76  generatePowers(5, time, T);
77 
78  coefficients[0] = start_pos;
79  coefficients[1] = start_vel;
80  coefficients[2] = 0.5*start_acc;
81  coefficients[3] = (-20.0*start_pos + 20.0*end_pos - 3.0*start_acc*T[2] + end_acc*T[2] -
82  12.0*start_vel*T[1] - 8.0*end_vel*T[1]) / (2.0*T[3]);
83  coefficients[4] = (30.0*start_pos - 30.0*end_pos + 3.0*start_acc*T[2] - 2.0*end_acc*T[2] +
84  16.0*start_vel*T[1] + 14.0*end_vel*T[1]) / (2.0*T[4]);
85  coefficients[5] = (-12.0*start_pos + 12.0*end_pos - start_acc*T[2] + end_acc*T[2] -
86  6.0*start_vel*T[1] - 6.0*end_vel*T[1]) / (2.0*T[5]);
87  }
88 }
89 
93 static void sampleQuinticSpline(const std::vector<double>& coefficients, double time,
94  double& position, double& velocity, double& acceleration)
95 {
96  // create powers of time:
97  double t[6];
98  generatePowers(5, time, t);
99 
100  position = t[0]*coefficients[0] +
101  t[1]*coefficients[1] +
102  t[2]*coefficients[2] +
103  t[3]*coefficients[3] +
104  t[4]*coefficients[4] +
105  t[5]*coefficients[5];
106 
107  velocity = t[0]*coefficients[1] +
108  2.0*t[1]*coefficients[2] +
109  3.0*t[2]*coefficients[3] +
110  4.0*t[3]*coefficients[4] +
111  5.0*t[4]*coefficients[5];
112 
113  acceleration = 2.0*t[0]*coefficients[2] +
114  6.0*t[1]*coefficients[3] +
115  12.0*t[2]*coefficients[4] +
116  20.0*t[3]*coefficients[5];
117 }
118 
119 static void getCubicSplineCoefficients(double start_pos, double start_vel,
120  double end_pos, double end_vel, double time, std::vector<double>& coefficients)
121 {
122  coefficients.resize(4);
123 
124  if (time == 0.0)
125  {
126  coefficients[0] = end_pos;
127  coefficients[1] = end_vel;
128  coefficients[2] = 0.0;
129  coefficients[3] = 0.0;
130  }
131  else
132  {
133  double T[4];
134  generatePowers(3, time, T);
135 
136  coefficients[0] = start_pos;
137  coefficients[1] = start_vel;
138  coefficients[2] = (-3.0*start_pos + 3.0*end_pos - 2.0*start_vel*T[1] - end_vel*T[1]) / T[2];
139  coefficients[3] = (2.0*start_pos - 2.0*end_pos + start_vel*T[1] + end_vel*T[1]) / T[3];
140  }
141 }
142 
143 
145  : loop_count_(0), robot_(NULL)
146 {
147 }
148 
150 {
153 }
154 
156 {
157  using namespace XmlRpc;
158  node_ = n;
159  robot_ = robot;
160 
161  // Gets all of the joints
162  XmlRpc::XmlRpcValue joint_names;
163  if (!node_.getParam("joints", joint_names))
164  {
165  ROS_ERROR("No joints given. (namespace: %s)", node_.getNamespace().c_str());
166  return false;
167  }
168  if (joint_names.getType() != XmlRpc::XmlRpcValue::TypeArray)
169  {
170  ROS_ERROR("Malformed joint specification. (namespace: %s)", node_.getNamespace().c_str());
171  return false;
172  }
173  for (int i = 0; i < joint_names.size(); ++i)
174  {
175  XmlRpcValue &name_value = joint_names[i];
176  if (name_value.getType() != XmlRpcValue::TypeString)
177  {
178  ROS_ERROR("Array of joint names should contain all strings. (namespace: %s)",
179  node_.getNamespace().c_str());
180  return false;
181  }
182 
183  pr2_mechanism_model::JointState *j = robot->getJointState((std::string)name_value);
184  if (!j) {
185  ROS_ERROR("Joint not found: %s. (namespace: %s)",
186  ((std::string)name_value).c_str(), node_.getNamespace().c_str());
187  return false;
188  }
189  joints_.push_back(j);
190  }
191 
192  // Ensures that all the joints are calibrated.
193  for (size_t i = 0; i < joints_.size(); ++i)
194  {
195  if (!joints_[i]->calibrated_)
196  {
197  ROS_ERROR("Joint %s was not calibrated (namespace: %s)",
198  joints_[i]->joint_->name.c_str(), node_.getNamespace().c_str());
199  return false;
200  }
201  }
202 
203  // Sets up pid controllers for all of the joints
204  std::string gains_ns;
205  if (!node_.getParam("gains", gains_ns))
206  gains_ns = node_.getNamespace() + "/gains";
207  pids_.resize(joints_.size());
208  for (size_t i = 0; i < joints_.size(); ++i)
209  if (!pids_[i].init(ros::NodeHandle(gains_ns + "/" + joints_[i]->joint_->name)))
210  return false;
211 
212  // Creates a dummy trajectory
214  SpecifiedTrajectory &traj = *traj_ptr;
215  traj[0].start_time = robot_->getTime().toSec();
216  traj[0].duration = 0.0;
217  traj[0].splines.resize(joints_.size());
218  for (size_t j = 0; j < joints_.size(); ++j)
219  traj[0].splines[j].coef[0] = 0.0;
220  current_trajectory_box_.set(traj_ptr);
221 
225 
226  q.resize(joints_.size());
227  qd.resize(joints_.size());
228  qdd.resize(joints_.size());
229 
232  (node_, "state", 1));
234  for (size_t j = 0; j < joints_.size(); ++j)
235  controller_state_publisher_->msg_.joint_names.push_back(joints_[j]->joint_->name);
236  controller_state_publisher_->msg_.desired.positions.resize(joints_.size());
237  controller_state_publisher_->msg_.desired.velocities.resize(joints_.size());
238  controller_state_publisher_->msg_.desired.accelerations.resize(joints_.size());
239  controller_state_publisher_->msg_.actual.positions.resize(joints_.size());
240  controller_state_publisher_->msg_.actual.velocities.resize(joints_.size());
241  controller_state_publisher_->msg_.error.positions.resize(joints_.size());
242  controller_state_publisher_->msg_.error.velocities.resize(joints_.size());
243  controller_state_publisher_->unlock();
244 
245 
246  return true;
247 }
248 
250 {
252 
253  for (size_t i = 0; i < pids_.size(); ++i)
254  pids_[i].reset();
255 
256  // Creates a "hold current position" trajectory.
258  SpecifiedTrajectory &hold = *hold_ptr;
259  hold[0].start_time = last_time_.toSec() - 0.001;
260  hold[0].duration = 0.0;
261  hold[0].splines.resize(joints_.size());
262  for (size_t j = 0; j < joints_.size(); ++j)
263  hold[0].splines[j].coef[0] = joints_[j]->position_;
264 
265  current_trajectory_box_.set(hold_ptr);
266 }
267 
269 {
270  // Checks if all the joints are calibrated.
271 
272  ros::Time time = robot_->getTime();
273  ros::Duration dt = time - last_time_;
274  last_time_ = time;
275 
277  current_trajectory_box_.get(traj_ptr);
278  if (!traj_ptr)
279  ROS_FATAL("The current trajectory can never be null");
280 
281  // Only because this is what the code originally looked like.
282  const SpecifiedTrajectory &traj = *traj_ptr;
283 
284  // Determines which segment of the trajectory to use. (Not particularly realtime friendly).
285  int seg = -1;
286  while (seg + 1 < (int)traj.size() &&
287  traj[seg+1].start_time < time.toSec())
288  {
289  ++seg;
290  }
291 
292  if (seg == -1)
293  {
294  if (traj.size() == 0)
295  ROS_ERROR("No segments in the trajectory");
296  else
297  ROS_ERROR("No earlier segments. First segment starts at %.3lf (now = %.3lf)", traj[0].start_time, time.toSec());
298  return;
299  }
300 
301  // ------ Trajectory Sampling
302 
303  for (size_t i = 0; i < q.size(); ++i)
304  {
305  sampleSplineWithTimeBounds(traj[seg].splines[i].coef, traj[seg].duration,
306  time.toSec() - traj[seg].start_time,
307  q[i], qd[i], qdd[i]);
308  }
309 
310  // ------ Trajectory Following
311 
312  std::vector<double> error(joints_.size());
313  for (size_t i = 0; i < joints_.size(); ++i)
314  {
315  error[i] = q[i] - joints_[i]->position_;
316  joints_[i]->commanded_effort_ += pids_[i].computeCommand(error[i],
317  joints_[i]->velocity_ - qd[i], dt);
318  }
319 
320  // ------ State publishing
321 
322  if (loop_count_ % 10 == 0)
323  {
325  {
326  controller_state_publisher_->msg_.header.stamp = time;
327  for (size_t j = 0; j < joints_.size(); ++j)
328  {
329  controller_state_publisher_->msg_.desired.positions[j] = q[j];
330  controller_state_publisher_->msg_.desired.velocities[j] = qd[j];
331  controller_state_publisher_->msg_.desired.accelerations[j] = qdd[j];
332  controller_state_publisher_->msg_.actual.positions[j] = joints_[j]->position_;
333  controller_state_publisher_->msg_.actual.velocities[j] = joints_[j]->velocity_;
334  controller_state_publisher_->msg_.error.positions[j] = error[j];
335  controller_state_publisher_->msg_.error.velocities[j] = joints_[j]->velocity_ - qd[j];
336  }
337  controller_state_publisher_->unlockAndPublish();
338  }
339  }
340 
341  ++loop_count_;
342 }
343 
344 void JointSplineTrajectoryController::commandCB(const trajectory_msgs::JointTrajectoryConstPtr &msg)
345 {
346  ros::Time time = last_time_;
347  ROS_DEBUG("Figuring out new trajectory at %.3lf, with data from %.3lf",
348  time.toSec(), msg->header.stamp.toSec());
349 
351  SpecifiedTrajectory &new_traj = *new_traj_ptr;
352 
353  // ------ If requested, performs a stop
354 
355  if (msg->points.empty())
356  {
357  starting();
358  return;
359  }
360 
361  // ------ Correlates the joints we're commanding to the joints in the message
362 
363  std::vector<int> lookup(joints_.size(), -1); // Maps from an index in joints_ to an index in the msg
364  for (size_t j = 0; j < joints_.size(); ++j)
365  {
366  for (size_t k = 0; k < msg->joint_names.size(); ++k)
367  {
368  if (msg->joint_names[k] == joints_[j]->joint_->name)
369  {
370  lookup[j] = k;
371  break;
372  }
373  }
374 
375  if (lookup[j] == -1)
376  {
377  ROS_ERROR("Unable to locate joint %s in the commanded trajectory.", joints_[j]->joint_->name.c_str());
378  return;
379  }
380  }
381 
382  // ------ Grabs the trajectory that we're currently following.
383 
385  current_trajectory_box_.get(prev_traj_ptr);
386  if (!prev_traj_ptr)
387  {
388  ROS_FATAL("The current trajectory can never be null");
389  return;
390  }
391  const SpecifiedTrajectory &prev_traj = *prev_traj_ptr;
392 
393  // ------ Copies over the segments from the previous trajectory that are still useful.
394 
395  // Useful segments are still relevant after the current time.
396  int first_useful = -1;
397  while (first_useful + 1 < (int)prev_traj.size() &&
398  prev_traj[first_useful + 1].start_time <= time.toSec())
399  {
400  ++first_useful;
401  }
402 
403  // Useful segments are not going to be completely overwritten by the message's splines.
404  int last_useful = -1;
405  double msg_start_time;
406  if (msg->points.size() > 0)
407  msg_start_time = (msg->header.stamp + msg->points[0].time_from_start).toSec();
408  else
409  msg_start_time = std::max(time.toSec(), msg->header.stamp.toSec());
410 
411  while (last_useful + 1 < (int)prev_traj.size() &&
412  prev_traj[last_useful + 1].start_time < msg_start_time)
413  {
414  ++last_useful;
415  }
416 
417  if (last_useful < first_useful)
418  first_useful = last_useful;
419 
420  // Copies over the old segments that were determined to be useful.
421  for (int i = std::max(first_useful,0); i <= last_useful; ++i)
422  {
423  new_traj.push_back(prev_traj[i]);
424  }
425 
426  // We always save the last segment so that we know where to stop if
427  // there are no new segments.
428  if (new_traj.size() == 0)
429  new_traj.push_back(prev_traj[prev_traj.size() - 1]);
430 
431  // ------ Determines when and where the new segments start
432 
433  // Finds the end conditions of the final segment
434  Segment &last = new_traj[new_traj.size() - 1];
435  std::vector<double> prev_positions(joints_.size());
436  std::vector<double> prev_velocities(joints_.size());
437  std::vector<double> prev_accelerations(joints_.size());
438 
439  ROS_DEBUG("Initial conditions for new set of splines:");
440  for (size_t i = 0; i < joints_.size(); ++i)
441  {
442  sampleSplineWithTimeBounds(last.splines[i].coef, last.duration,
443  msg->header.stamp.toSec() - last.start_time,
444  prev_positions[i], prev_velocities[i], prev_accelerations[i]);
445  ROS_DEBUG(" %.2lf, %.2lf, %.2lf (%s)", prev_positions[i], prev_velocities[i],
446  prev_accelerations[i], joints_[i]->joint_->name.c_str());
447  }
448 
449  // ------ Tacks on the new segments
450 
451  std::vector<double> positions;
452  std::vector<double> velocities;
453  std::vector<double> accelerations;
454 
455  std::vector<double> durations(msg->points.size());
456  durations[0] = msg->points[0].time_from_start.toSec();
457  for (size_t i = 1; i < msg->points.size(); ++i)
458  durations[i] = (msg->points[i].time_from_start - msg->points[i-1].time_from_start).toSec();
459 
460  // Checks if we should wrap
461  std::vector<double> wrap(joints_.size(), 0.0);
462  assert(!msg->points[0].positions.empty());
463  for (size_t j = 0; j < joints_.size(); ++j)
464  {
465  if (joints_[j]->joint_->type == urdf::Joint::CONTINUOUS)
466  {
467  double dist = angles::shortest_angular_distance(prev_positions[j], msg->points[0].positions[j]);
468  wrap[j] = (prev_positions[j] + dist) - msg->points[0].positions[j];
469  }
470  }
471 
472  for (size_t i = 0; i < msg->points.size(); ++i)
473  {
474  Segment seg;
475 
476  seg.start_time = (msg->header.stamp + msg->points[i].time_from_start).toSec() - durations[i];
477  seg.duration = durations[i];
478  seg.splines.resize(joints_.size());
479 
480  // Checks that the incoming segment has the right number of elements.
481 
482  if (msg->points[i].accelerations.size() != 0 && msg->points[i].accelerations.size() != joints_.size())
483  {
484  ROS_ERROR("Command point %d has %d elements for the accelerations", (int)i, (int)msg->points[i].accelerations.size());
485  return;
486  }
487  if (msg->points[i].velocities.size() != 0 && msg->points[i].velocities.size() != joints_.size())
488  {
489  ROS_ERROR("Command point %d has %d elements for the velocities", (int)i, (int)msg->points[i].velocities.size());
490  return;
491  }
492  if (msg->points[i].positions.size() != joints_.size())
493  {
494  ROS_ERROR("Command point %d has %d elements for the positions", (int)i, (int)msg->points[i].positions.size());
495  return;
496  }
497 
498  // Re-orders the joints in the command to match the interal joint order.
499 
500  accelerations.resize(msg->points[i].accelerations.size());
501  velocities.resize(msg->points[i].velocities.size());
502  positions.resize(msg->points[i].positions.size());
503  for (size_t j = 0; j < joints_.size(); ++j)
504  {
505  if (!accelerations.empty()) accelerations[j] = msg->points[i].accelerations[lookup[j]];
506  if (!velocities.empty()) velocities[j] = msg->points[i].velocities[lookup[j]];
507  if (!positions.empty()) positions[j] = msg->points[i].positions[lookup[j]] + wrap[j];
508  }
509 
510  // Converts the boundary conditions to splines.
511 
512  for (size_t j = 0; j < joints_.size(); ++j)
513  {
514  if (prev_accelerations.size() > 0 && accelerations.size() > 0)
515  {
517  prev_positions[j], prev_velocities[j], prev_accelerations[j],
518  positions[j], velocities[j], accelerations[j],
519  durations[i],
520  seg.splines[j].coef);
521  }
522  else if (prev_velocities.size() > 0 && velocities.size() > 0)
523  {
525  prev_positions[j], prev_velocities[j],
526  positions[j], velocities[j],
527  durations[i],
528  seg.splines[j].coef);
529  seg.splines[j].coef.resize(6, 0.0);
530  }
531  else
532  {
533  seg.splines[j].coef[0] = prev_positions[j];
534  if (durations[i] == 0.0)
535  seg.splines[j].coef[1] = 0.0;
536  else
537  seg.splines[j].coef[1] = (positions[j] - prev_positions[j]) / durations[i];
538  seg.splines[j].coef[2] = 0.0;
539  seg.splines[j].coef[3] = 0.0;
540  seg.splines[j].coef[4] = 0.0;
541  seg.splines[j].coef[5] = 0.0;
542  }
543  }
544 
545  // Pushes the splines onto the end of the new trajectory.
546 
547  new_traj.push_back(seg);
548 
549  // Computes the starting conditions for the next segment
550 
551  prev_positions = positions;
552  prev_velocities = velocities;
553  prev_accelerations = accelerations;
554  }
555 
556  // ------ Commits the new trajectory
557 
558  if (!new_traj_ptr)
559  {
560  ROS_ERROR("The new trajectory was null!");
561  return;
562  }
563 
564  current_trajectory_box_.set(new_traj_ptr);
565  ROS_DEBUG("The new trajectory has %d segments", (int)new_traj.size());
566 #if 0
567  for (size_t i = 0; i < std::min((size_t)20,new_traj.size()); ++i)
568  {
569  ROS_DEBUG("Segment %2d: %.3lf for %.3lf", i, new_traj[i].start_time, new_traj[i].duration);
570  for (size_t j = 0; j < new_traj[i].splines.size(); ++j)
571  {
572  ROS_DEBUG(" %.2lf %.2lf %.2lf %.2lf , %.2lf %.2lf(%s)",
573  new_traj[i].splines[j].coef[0],
574  new_traj[i].splines[j].coef[1],
575  new_traj[i].splines[j].coef[2],
576  new_traj[i].splines[j].coef[3],
577  new_traj[i].splines[j].coef[4],
578  new_traj[i].splines[j].coef[5],
579  joints_[j]->joint_->name_.c_str());
580  }
581  }
582 #endif
583 }
584 
586  pr2_controllers_msgs::QueryTrajectoryState::Request &req,
587  pr2_controllers_msgs::QueryTrajectoryState::Response &resp)
588 {
590  current_trajectory_box_.get(traj_ptr);
591  if (!traj_ptr)
592  {
593  ROS_FATAL("The current trajectory can never be null");
594  return false;
595  }
596  const SpecifiedTrajectory &traj = *traj_ptr;
597 
598  // Determines which segment of the trajectory to use
599  int seg = -1;
600  while (seg + 1 < (int)traj.size() &&
601  traj[seg+1].start_time < req.time.toSec())
602  {
603  ++seg;
604  }
605  if (seg == -1)
606  return false;
607 
608  for (size_t i = 0; i < q.size(); ++i)
609  {
610  }
611 
612 
613  resp.name.resize(joints_.size());
614  resp.position.resize(joints_.size());
615  resp.velocity.resize(joints_.size());
616  resp.acceleration.resize(joints_.size());
617  for (size_t j = 0; j < joints_.size(); ++j)
618  {
619  resp.name[j] = joints_[j]->joint_->name;
620  sampleSplineWithTimeBounds(traj[seg].splines[j].coef, traj[seg].duration,
621  req.time.toSec() - traj[seg].start_time,
622  resp.position[j], resp.velocity[j], resp.acceleration[j]);
623  }
624 
625  return true;
626 }
627 
629  const std::vector<double>& coefficients, double duration, double time,
630  double& position, double& velocity, double& acceleration)
631 {
632  if (time < 0)
633  {
634  double _;
635  sampleQuinticSpline(coefficients, 0.0, position, _, _);
636  velocity = 0;
637  acceleration = 0;
638  }
639  else if (time > duration)
640  {
641  double _;
642  sampleQuinticSpline(coefficients, duration, position, _, _);
643  velocity = 0;
644  acceleration = 0;
645  }
646  else
647  {
648  sampleQuinticSpline(coefficients, time,
649  position, velocity, acceleration);
650  }
651 }
652 
653 }
XmlRpc::XmlRpcValue::size
int size() const
controller::JointSplineTrajectoryController::Segment::start_time
double start_time
Definition: joint_spline_trajectory_controller.h:102
pr2_mechanism_model::JointState
angles::shortest_angular_distance
static double shortest_angular_distance(double from, double to)
msg
msg
controller::JointSplineTrajectoryController::commandCB
void commandCB(const trajectory_msgs::JointTrajectoryConstPtr &msg)
Definition: joint_spline_trajectory_controller.cpp:344
boost::shared_ptr
i
int i
controller::JointSplineTrajectoryController::loop_count_
int loop_count_
Definition: joint_spline_trajectory_controller.h:70
controller::JointSplineTrajectoryController::SpecifiedTrajectory
std::vector< Segment > SpecifiedTrajectory
Definition: joint_spline_trajectory_controller.h:106
controller::JointSplineTrajectoryController::current_trajectory_box_
realtime_tools::RealtimeBox< boost::shared_ptr< const SpecifiedTrajectory > > current_trajectory_box_
Definition: joint_spline_trajectory_controller.h:109
controller::JointSplineTrajectoryController::qdd
std::vector< double > qdd
Definition: joint_spline_trajectory_controller.h:117
controller::JointSplineTrajectoryController::Segment
Definition: joint_spline_trajectory_controller.h:100
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
realtime_tools::RealtimeBox::get
void get(T &ref)
controller::getCubicSplineCoefficients
static void getCubicSplineCoefficients(double start_pos, double start_vel, double end_pos, double end_vel, double time, std::vector< double > &coefficients)
Definition: joint_spline_trajectory_controller.cpp:119
ROS_DEBUG
#define ROS_DEBUG(...)
TimeBase< Time, Duration >::toSec
double toSec() const
ros::NodeHandle::advertiseService
ServiceServer advertiseService(AdvertiseServiceOptions &ops)
XmlRpc
ros::Subscriber::shutdown
void shutdown()
controller::JointSplineTrajectoryController::starting
void starting()
Definition: joint_spline_trajectory_controller.cpp:249
controller::JointSplineTrajectoryController::init
bool init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n)
Definition: joint_spline_trajectory_controller.cpp:155
controller::generatePowers
static void generatePowers(int n, double x, double *powers)
Definition: joint_spline_trajectory_controller.cpp:50
controller::JointSplineTrajectoryController
Definition: joint_spline_trajectory_controller.h:57
realtime_tools::RealtimePublisher
controller::JointSplineTrajectoryController::serve_query_state_
ros::ServiceServer serve_query_state_
Definition: joint_spline_trajectory_controller.h:83
controller::JointSplineTrajectoryController::~JointSplineTrajectoryController
~JointSplineTrajectoryController()
Definition: joint_spline_trajectory_controller.cpp:149
controller::JointSplineTrajectoryController::last_time_
ros::Time last_time_
Definition: joint_spline_trajectory_controller.h:72
controller
pr2_mechanism_model::RobotState
controller::JointSplineTrajectoryController::qd
std::vector< double > qd
Definition: joint_spline_trajectory_controller.h:117
k
int k
pr2_mechanism_model::RobotState::getJointState
JointState * getJointState(const std::string &name)
controller::JointSplineTrajectoryController::update
void update()
Definition: joint_spline_trajectory_controller.cpp:268
controller::JointSplineTrajectoryController::q
std::vector< double > q
Definition: joint_spline_trajectory_controller.h:117
ROS_ERROR
#define ROS_ERROR(...)
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(my_controller_ns::MyControllerClass, pr2_controller_interface::Controller)
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
controller::JointSplineTrajectoryController::pids_
std::vector< control_toolbox::Pid > pids_
Definition: joint_spline_trajectory_controller.h:74
controller::JointSplineTrajectoryController::controller_state_publisher_
boost::scoped_ptr< realtime_tools::RealtimePublisher< pr2_controllers_msgs::JointTrajectoryControllerState > > controller_state_publisher_
Definition: joint_spline_trajectory_controller.h:87
controller::getQuinticSplineCoefficients
static void getQuinticSplineCoefficients(double start_pos, double start_vel, double start_acc, double end_pos, double end_vel, double end_acc, double time, std::vector< double > &coefficients)
Definition: joint_spline_trajectory_controller.cpp:59
XmlRpc::XmlRpcValue::getType
const Type & getType() const
controller::JointSplineTrajectoryController::sub_command_
ros::Subscriber sub_command_
Definition: joint_spline_trajectory_controller.h:79
ROS_FATAL
#define ROS_FATAL(...)
controller::JointSplineTrajectoryController::Segment::splines
std::vector< Spline > splines
Definition: joint_spline_trajectory_controller.h:104
pr2_controller_interface::Controller
controller::JointSplineTrajectoryController::sampleSplineWithTimeBounds
static void sampleSplineWithTimeBounds(const std::vector< double > &coefficients, double duration, double time, double &position, double &velocity, double &acceleration)
Definition: joint_spline_trajectory_controller.cpp:628
XmlRpc::XmlRpcValue::TypeArray
TypeArray
pr2_mechanism_model::RobotState::getTime
ros::Time getTime()
ros::Time
controller::JointSplineTrajectoryController::node_
ros::NodeHandle node_
Definition: joint_spline_trajectory_controller.h:76
controller::JointSplineTrajectoryController::JointSplineTrajectoryController
JointSplineTrajectoryController()
Definition: joint_spline_trajectory_controller.cpp:144
controller::sampleQuinticSpline
static void sampleQuinticSpline(const std::vector< double > &coefficients, double time, double &position, double &velocity, double &acceleration)
Samples a quintic spline segment at a particular time.
Definition: joint_spline_trajectory_controller.cpp:93
class_list_macros.hpp
controller::JointSplineTrajectoryController::joints_
std::vector< pr2_mechanism_model::JointState * > joints_
Definition: joint_spline_trajectory_controller.h:73
controller::JointSplineTrajectoryController::queryStateService
bool queryStateService(pr2_controllers_msgs::QueryTrajectoryState::Request &req, pr2_controllers_msgs::QueryTrajectoryState::Response &resp)
Definition: joint_spline_trajectory_controller.cpp:585
ros::ServiceServer::shutdown
void shutdown()
controller::JointSplineTrajectoryController::Segment::duration
double duration
Definition: joint_spline_trajectory_controller.h:103
ros::NodeHandle::getNamespace
const std::string & getNamespace() const
joint_spline_trajectory_controller.h
realtime_tools::RealtimeBox::set
void set(const T &value)
ros::Duration
controller::JointSplineTrajectoryController::robot_
pr2_mechanism_model::RobotState * robot_
Definition: joint_spline_trajectory_controller.h:71
XmlRpc::XmlRpcValue
ros::NodeHandle
angles.h
error
def error(*args, **kwargs)


robot_mechanism_controllers
Author(s): John Hsu, Melonee Wise, Stuart Glaser
autogenerated on Sat Nov 12 2022 03:33:22