chomp_trajectory.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2009, Willow Garage, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Willow Garage nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 /* Author: Mrinal Kalakrishnan */
36 
37 #include <ros/ros.h>
39 #include <iostream>
40 
41 namespace chomp
42 {
43 ChompTrajectory::ChompTrajectory(const moveit::core::RobotModelConstPtr& robot_model, double duration,
44  double discretization, std::string group_name)
45  : planning_group_name_(group_name)
46  , num_points_((duration / discretization) + 1)
47  , discretization_(discretization)
48  , duration_(duration)
49  , start_index_(1)
50  , end_index_(num_points_ - 2)
51 {
52  const moveit::core::JointModelGroup* model_group = robot_model->getJointModelGroup(planning_group_name_);
53  num_joints_ = model_group->getActiveJointModels().size();
54  init();
55 }
56 
57 ChompTrajectory::ChompTrajectory(const moveit::core::RobotModelConstPtr& robot_model, int num_points,
58  double discretization, std::string group_name)
59  : planning_group_name_(group_name)
60  , num_points_(num_points)
61  , discretization_(discretization)
62  , duration_((num_points - 1) * discretization)
63  , start_index_(1)
64  , end_index_(num_points_ - 2)
65 {
66  const moveit::core::JointModelGroup* model_group = robot_model->getJointModelGroup(planning_group_name_);
67  num_joints_ = model_group->getActiveJointModels().size();
68  init();
69 }
70 
71 ChompTrajectory::ChompTrajectory(const ChompTrajectory& source_traj, const std::string& planning_group,
72  int diff_rule_length)
73  : planning_group_name_(planning_group), discretization_(source_traj.discretization_)
74 {
75  num_joints_ = source_traj.getNumJoints();
76 
77  // figure out the num_points_:
78  // we need diff_rule_length-1 extra points on either side:
79  int start_extra = (diff_rule_length - 1) - source_traj.start_index_;
80  int end_extra = (diff_rule_length - 1) - ((source_traj.num_points_ - 1) - source_traj.end_index_);
81 
82  num_points_ = source_traj.num_points_ + start_extra + end_extra;
83  start_index_ = diff_rule_length - 1;
84  end_index_ = (num_points_ - 1) - (diff_rule_length - 1);
86 
87  // allocate the memory:
88  init();
89 
91 
92  // now copy the trajectories over:
93  for (int i = 0; i < num_points_; i++)
94  {
95  int source_traj_point = i - start_extra;
96  if (source_traj_point < 0)
97  source_traj_point = 0;
98  if (source_traj_point >= source_traj.num_points_)
99  source_traj_point = source_traj.num_points_ - 1;
100  full_trajectory_index_[i] = source_traj_point;
101  for (int j = 0; j < num_joints_; j++)
102  {
103  (*this)(i, j) = source_traj(source_traj_point, j);
104  }
105  }
106 }
107 
108 ChompTrajectory::ChompTrajectory(const moveit::core::RobotModelConstPtr& robot_model, const std::string& planning_group,
109  const trajectory_msgs::JointTrajectory& traj)
110  : planning_group_name_(planning_group)
111 {
112  const moveit::core::JointModelGroup* model_group = robot_model->getJointModelGroup(planning_group_name_);
113  num_joints_ = model_group->getActiveJointModels().size();
114  double discretization = (traj.points[1].time_from_start - traj.points[0].time_from_start).toSec();
115 
116  double discretization2 = (traj.points[2].time_from_start - traj.points[1].time_from_start).toSec();
117 
118  if (fabs(discretization2 - discretization) > .001)
119  {
120  ROS_WARN_STREAM("Trajectory Discretization not constant " << discretization << " " << discretization2);
121  }
122  discretization_ = discretization;
123 
124  num_points_ = traj.points.size() + 1;
125  duration_ = (traj.points.back().time_from_start - traj.points[0].time_from_start).toSec();
126 
127  start_index_ = 1;
128  end_index_ = num_points_ - 2;
129 
130  init();
131 
132  for (int i = 0; i < num_points_; i++)
133  {
134  for (int j = 0; j < num_joints_; j++)
135  {
136  trajectory_(i, j) = 0.0;
137  }
138  }
139  overwriteTrajectory(traj);
140 }
141 
143 {
144 }
145 
146 void ChompTrajectory::overwriteTrajectory(const trajectory_msgs::JointTrajectory& traj)
147 {
148  for (unsigned int i = 1; i <= traj.points.size(); i++)
149  {
150  for (unsigned int j = 0; j < traj.joint_names.size(); j++)
151  {
152  trajectory_(i, j) = traj.points[i - 1].positions[j];
153  }
154  }
155 }
156 
158 {
160  trajectory_ = Eigen::MatrixXd(num_points_, num_joints_);
161 }
162 
164 {
165  int num_vars_free = end_index_ - start_index_ + 1;
166  for (int i = 0; i < num_joints_; i++)
167  {
168  trajectory_.block(start_index_, i, num_vars_free, 1) =
169  group_trajectory.trajectory_.block(group_trajectory.start_index_, i, num_vars_free, 1);
170  }
171 }
172 
174 {
175  double start_index = start_index_ - 1;
176  double end_index = end_index_ + 1;
177  for (int i = 0; i < num_joints_; i++)
178  {
179  double theta = ((*this)(end_index, i) - (*this)(start_index, i)) / (end_index - 1);
180  for (int j = start_index + 1; j < end_index; j++)
181  {
182  (*this)(j, i) = (*this)(start_index, i) + j * theta;
183  }
184  }
185 }
186 
188 {
189  double start_index = start_index_ - 1;
190  double end_index = end_index_ + 1;
191  double dt = 0.001;
192  std::vector<double> coeffs(4, 0);
193  double total_time = (end_index - 1) * dt;
194  for (int i = 0; i < num_joints_; i++)
195  {
196  coeffs[0] = (*this)(start_index, i);
197  coeffs[2] = (3 / (pow(total_time, 2))) * ((*this)(end_index, i) - (*this)(start_index, i));
198  coeffs[3] = (-2 / (pow(total_time, 3))) * ((*this)(end_index, i) - (*this)(start_index, i));
199 
200  double t;
201  for (int j = start_index + 1; j < end_index; j++)
202  {
203  t = j * dt;
204  (*this)(j, i) = coeffs[0] + coeffs[2] * pow(t, 2) + coeffs[3] * pow(t, 3);
205  }
206  }
207 }
208 
210 {
211  double start_index = start_index_ - 1;
212  double end_index = end_index_ + 1;
213  double T[6]; // powers of the time duration
214  T[0] = 1.0;
215  T[1] = (end_index - start_index) * discretization_;
216 
217  for (int i = 2; i <= 5; i++)
218  T[i] = T[i - 1] * T[1];
219 
220  // calculate the spline coefficients for each joint:
221  // (these are for the special case of zero start and end vel and acc)
222  double coeff[num_joints_][6];
223  for (int i = 0; i < num_joints_; i++)
224  {
225  double x0 = (*this)(start_index, i);
226  double x1 = (*this)(end_index, i);
227  coeff[i][0] = x0;
228  coeff[i][1] = 0;
229  coeff[i][2] = 0;
230  coeff[i][3] = (-20 * x0 + 20 * x1) / (2 * T[3]);
231  coeff[i][4] = (30 * x0 - 30 * x1) / (2 * T[4]);
232  coeff[i][5] = (-12 * x0 + 12 * x1) / (2 * T[5]);
233  }
234 
235  // now fill in the joint positions at each time step
236  for (int i = start_index + 1; i < end_index; i++)
237  {
238  double t[6]; // powers of the time index point
239  t[0] = 1.0;
240  t[1] = (i - start_index) * discretization_;
241  for (int k = 2; k <= 5; k++)
242  t[k] = t[k - 1] * t[1];
243 
244  for (int j = 0; j < num_joints_; j++)
245  {
246  (*this)(i, j) = 0.0;
247  for (int k = 0; k <= 5; k++)
248  {
249  (*this)(i, j) += t[k] * coeff[j][k];
250  }
251  }
252  }
253 }
254 
255 bool ChompTrajectory::fillInFromTrajectory(moveit_msgs::MotionPlanDetailedResponse& res)
256 {
257  // create a RobotTrajectory msg to obtain the trajectory from the MotionPlanDetailedResponse object
258  moveit_msgs::RobotTrajectory trajectory_msg = res.trajectory[0];
259 
260  // get the default number of points in the CHOMP trajectory
261  int num_chomp_trajectory_points = (*this).getNumPoints();
262  // get the number of points in the response trajectory obtained from OMPL
263  int num_response_points = trajectory_msg.joint_trajectory.points.size();
264 
265  // check if input trajectory has less than two states (start and goal), function returns false if condition is true
266  if (num_response_points < 2)
267  return false;
268 
269  // get the number of joints for each robot state
270  int num_joints_trajectory = trajectory_msg.joint_trajectory.points[0].positions.size();
271 
272  // variables for populating the CHOMP trajectory with correct number of trajectory points
273  int repeated_factor = num_chomp_trajectory_points / num_response_points;
274  int repeated_balance_factor = num_chomp_trajectory_points % num_response_points;
275 
276  // response_point_id stores the point at the stored index location.
277  int response_point_id = 0;
278  if (num_chomp_trajectory_points >= num_response_points)
279  {
280  for (int i = 0; i < num_response_points; i++)
281  {
282  // following for loop repeats each OMPL trajectory pose/row 'repeated_factor' times; alternatively, there could
283  // also be a linear interpolation between these points later if required
284  for (int k = 0; k < repeated_factor; k++)
285  {
286  assignCHOMPTrajectoryPointFromInputTrajectoryPoint(trajectory_msg, num_joints_trajectory, i, response_point_id);
287  response_point_id++;
288  }
289 
290  // this populates the CHOMP trajectory row for the remainder number of rows.
291  if (i < repeated_balance_factor)
292  {
293  assignCHOMPTrajectoryPointFromInputTrajectoryPoint(trajectory_msg, num_joints_trajectory, i, response_point_id);
294  response_point_id++;
295  } // end of if
296  } // end of for loop for loading in the trajectory poses/rows
297  }
298  else
299  {
300  // perform a decimation sampling in this block if the number of trajectory points in the MotionPlanDetailedResponse
301  // res object is more than the number of points in the CHOMP trajectory
302  double decimation_sampling_factor = ((double)num_response_points) / ((double)num_chomp_trajectory_points);
303 
304  for (int i = 0; i < num_chomp_trajectory_points; i++)
305  {
306  int sampled_point = floor(i * decimation_sampling_factor);
307  assignCHOMPTrajectoryPointFromInputTrajectoryPoint(trajectory_msg, num_joints_trajectory, sampled_point, i);
308  }
309  } // end of else
310  return true;
311 }
312 
313 void ChompTrajectory::assignCHOMPTrajectoryPointFromInputTrajectoryPoint(moveit_msgs::RobotTrajectory trajectory_msg,
314  int num_joints_trajectory,
315  int trajectory_msgs_point_index,
316  int chomp_trajectory_point_index)
317 {
318  // following loop iterates over all joints for a single robot pose, it assigns the corresponding input trajectory
319  // points into CHOMP trajectory points
320  for (int j = 0; j < num_joints_trajectory; j++)
321  (*this)(chomp_trajectory_point_index, j) =
322  trajectory_msg.joint_trajectory.points[trajectory_msgs_point_index].positions[j];
323 }
324 
325 } // namespace chomp
ChompTrajectory(const moveit::core::RobotModelConstPtr &robot_model, double duration, double discretization, std::string groupName)
Constructs a trajectory for a given robot model, trajectory duration, and discretization.
bool fillInFromTrajectory(moveit_msgs::MotionPlanDetailedResponse &res)
Receives the path obtained from a given MotionPlanDetailedResponse res object&#39;s trajectory (e...
virtual ~ChompTrajectory()
Destructor.
void fillInCubicInterpolation()
Generates a cubic interpolation of the trajectory from the start index to end index.
std::vector< int > full_trajectory_index_
void assignCHOMPTrajectoryPointFromInputTrajectoryPoint(moveit_msgs::RobotTrajectory trajectory_msg, int num_joints_trajectory, int trajectory_msgs_point, int chomp_trajectory_point)
Eigen::MatrixXd trajectory_
void init()
Allocates memory for the trajectory.
void fillInMinJerk()
Generates a minimum jerk trajectory from the start index to end index.
std::string planning_group_name_
void updateFromGroupTrajectory(const ChompTrajectory &group_trajectory)
Updates the full trajectory (*this) from the group trajectory.
#define ROS_WARN_STREAM(args)
Represents a discretized joint-space trajectory for CHOMP.
void overwriteTrajectory(const trajectory_msgs::JointTrajectory &traj)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
void fillInLinearInterpolation()
Generates a linearly interpolated trajectory from the start index to end index.
const std::vector< const JointModel * > & getActiveJointModels() const
int getNumJoints() const
Gets the number of joints in each trajectory point.


chomp_motion_planner
Author(s): Gil Jones , Mrinal Kalakrishnan
autogenerated on Sun Oct 18 2020 13:17:08