Robowflex  v0.1
Making MoveIt Easy
trajectory.cpp
Go to the documentation of this file.
1 /* Author: Constantinos Chamzas, Zachary Kingston */
2 
4 
5 #include <moveit/trajectory_processing/iterative_time_parameterization.h>
6 
8 #include <robowflex_library/io.h>
10 #include <robowflex_library/log.h>
13 #include <robowflex_library/util.h>
14 #include <robowflex_library/yaml.h>
15 
16 using namespace robowflex;
17 
19  : trajectory_(new robot_trajectory::RobotTrajectory(robot->getModelConst(), group))
20 {
21 }
22 
24  : trajectory_(new robot_trajectory::RobotTrajectory(trajectory))
25 {
26 }
27 
28 Trajectory::Trajectory(robot_trajectory::RobotTrajectoryPtr trajectory)
29  : trajectory_(new robot_trajectory::RobotTrajectory(*trajectory))
30 {
31 }
32 
33 void Trajectory::useMessage(const robot_state::RobotState &reference_state,
34  const moveit_msgs::RobotTrajectory &msg)
35 {
36  trajectory_->setRobotTrajectoryMsg(reference_state, msg);
37 }
38 
39 void Trajectory::useMessage(const robot_state::RobotState &reference_state,
40  const trajectory_msgs::JointTrajectory &msg)
41 {
42  trajectory_->setRobotTrajectoryMsg(reference_state, msg);
43 }
44 
45 bool Trajectory::toYAMLFile(const std::string &filename) const
46 {
47  moveit_msgs::RobotTrajectory msg;
48  trajectory_->getRobotTrajectoryMsg(msg);
49 
50  YAML::Node node = robowflex::IO::toNode(msg);
51  return robowflex::IO::YAMLToFile(node, filename);
52 }
53 
54 bool Trajectory::fromYAMLFile(const robot_state::RobotState &reference_state, const std::string &filename)
55 {
56  moveit_msgs::RobotTrajectory msg;
57  if (!IO::YAMLFileToMessage(msg, filename))
58  return false;
59 
60  useMessage(reference_state, msg);
61  return true;
62 }
63 
64 void Trajectory::addSuffixWaypoint(const robot_state::RobotState &state, double dt)
65 {
66  trajectory_->addSuffixWayPoint(state, dt);
67 }
68 
69 const robot_trajectory::RobotTrajectoryPtr &Trajectory::getTrajectoryConst() const
70 {
71  return trajectory_;
72 }
73 
74 robot_trajectory::RobotTrajectoryPtr &Trajectory::getTrajectory()
75 {
76  return trajectory_;
77 }
78 
79 moveit_msgs::RobotTrajectory Trajectory::getMessage() const
80 {
81  moveit_msgs::RobotTrajectory msg;
82  trajectory_->getRobotTrajectoryMsg(msg);
83  return msg;
84 }
85 
87 {
88  return trajectory_->getWayPointCount();
89 }
90 
91 bool Trajectory::computeTimeParameterization(double max_velocity, double max_acceleration)
92 {
94  return parameterizer.computeTimeStamps(*trajectory_, max_velocity, max_acceleration);
95 }
96 
98  double max_velocity, double max_acceleration)
99 {
101  return parameterizer.computeTimeStamps(trajectory, max_velocity, max_acceleration);
102 }
103 
104 void Trajectory::interpolate(unsigned int count)
105 {
106 #if ROBOWFLEX_AT_LEAST_KINETIC
107  if (count < getNumWaypoints() || trajectory_->getWayPointCount() < 2)
108  return;
109 
110  // the remaining length of the path we need to add states along
111  double total_length = getLength();
112 
113  // the Number of segments that exist in this path.
114  const int n1 = getNumWaypoints() - 1;
115  int added = 0;
116 
117  for (int seg = 0; seg < n1; ++seg)
118  {
119  // Last waypoint that has not been interpolated.
120  int i = seg + added;
121  auto s0 = trajectory_->getWayPointPtr(i); // First point of the (uninterploated) segment
122  auto s2 = trajectory_->getWayPointPtr(i + 1); // Last point of the (uninterploated) segment
123 
124  // compute an approximate number of states the following segment needs to contain; this includes
125  // endpoints
126  double segment_length = s0->distance(*s2);
127  int ns = (int)floor(0.5 + (double)count * segment_length / total_length) + 1;
128 
129  // if more than endpoints are needed
130  if (ns > 2)
131  {
132  ns -= 2; // subtract endpoints
133 
134  // compute intermediate states
135  for (int j = 1; j < ns; j++)
136  {
137  // The state to be inserted
138  auto s1 = std::make_shared<robot_state::RobotState>(trajectory_->getRobotModel());
139  double dt = double(j) / double(ns);
140 
141  s0->interpolate(*s2, dt, *s1);
142  s1->update(true);
143  trajectory_->insertWayPoint(i + j, *s1, dt);
144  // count how many stated have been added
145  added++;
146  }
147  }
148  }
149 
150  RBX_INFO("Added %d extra states in the trajectory", added);
151  return;
152 
153 #endif
154  throw Exception(1, "Not Implemented");
155 }
156 
158 {
160  const auto &msg = getMessage();
161  for (const auto &p : msg.joint_trajectory.points)
162  traj_vec.emplace_back(p.positions);
163 
164  return traj_vec;
165 }
166 
168 {
169  return getMessage().joint_trajectory.joint_names;
170 }
171 
172 Trajectory &Trajectory::append(const Trajectory &source, double dt, size_t start_index, size_t end_index)
173 {
174  trajectory_->append(*source.getTrajectoryConst(), dt, start_index, end_index);
175  return *this;
176 }
177 
178 double Trajectory::getLength(const PathMetric &metric) const
179 {
180  double length = 0.0;
181 
182  for (std::size_t k = 1; k < trajectory_->getWayPointCount(); ++k)
183  {
184  const auto &s1 = trajectory_->getWayPoint(k - 1);
185  const auto &s2 = trajectory_->getWayPoint(k);
186 
187  if (metric)
188  length += metric(s1, s2);
189  else
190  length += s1.distance(s2);
191  }
192 
193  return length;
194 }
195 
197 {
198  bool correct = true;
199 
200  for (std::size_t k = 0; k < trajectory_->getWayPointCount(); ++k)
201  {
202  auto s = trajectory_->getWayPointPtr(k);
203  if (!s->satisfiesBounds())
204  return false;
205 
206  const auto result = scene->checkCollision(*s);
207  if (result.collision)
208  return false;
209  }
210 
211  return correct;
212 }
213 
215 {
216  double minimum = std::numeric_limits<double>::max();
217  double maximum = 0;
218  double average = 0;
219 
220  for (std::size_t k = 0; k < trajectory_->getWayPointCount(); ++k)
221  {
222  const auto &s = trajectory_->getWayPointPtr(k);
223  double clearance = scene->distanceToCollision(*s);
224  if (clearance > 0.0)
225  {
226  average += clearance;
227  maximum = (maximum > clearance) ? maximum : clearance;
228  minimum = (minimum < clearance) ? minimum : clearance;
229  }
230  }
231 
232  average /= trajectory_->getWayPointCount();
233 
234  return std::make_tuple(average, minimum, maximum);
235 }
236 
237 double Trajectory::getSmoothness(const PathMetric &metric) const
238 {
239  double smoothness = 0.0;
240 
241  auto distance =
242  (metric) ? metric : [](const robot_state::RobotState &a, const robot_state::RobotState &b) {
243  return a.distance(b);
244  };
245 
246  // compute smoothness
247  if (trajectory_->getWayPointCount() > 2)
248  {
249  double a = distance(trajectory_->getWayPoint(0), trajectory_->getWayPoint(1));
250  for (std::size_t k = 2; k < trajectory_->getWayPointCount(); ++k)
251  {
252  // view the trajectory_->as a sequence of segments, and look at the triangles it forms:
253  // s1
254  // /\ s4
255  // a / \ b |
256  // / \ |
257  // /......\_______|
258  // s0 c s2 s3
259  //
260 
261  // use Pythagoras generalized theorem to find the cos of the angle between segments a and b
262  double b = distance(trajectory_->getWayPoint(k - 1), trajectory_->getWayPoint(k));
263  double cdist = distance(trajectory_->getWayPoint(k - 2), trajectory_->getWayPoint(k));
264  double acos_value = (a * a + b * b - cdist * cdist) / (2.0 * a * b);
265  if (acos_value > -1.0 && acos_value < 1.0)
266  {
267  // the smoothness is actually the outside angle of the one we compute
268  double angle = (constants::pi - acos(acos_value));
269 
270  // and we normalize by the length of the segments
271  double u = 2.0 * angle; /// (a + b);
272  smoothness += u * u;
273  }
274 
275  a = b;
276  }
277 
278  smoothness /= trajectory_->getWayPointCount();
279  }
280 
281  return smoothness;
282 }
283 
285 {
286  const auto &last = trajectory_->getLastWayPoint();
287 
289 
290  const auto &names = last.getVariableNames();
291  const auto &values = last.getVariablePositions();
292 
293  for (std::size_t i = 0; i < names.size(); ++i)
294  map.emplace(names[i], values[i]);
295 
296  return map;
297 }
Exception that contains a message and an error code.
Definition: util.h:15
A const shared pointer wrapper for robowflex::Robot.
A const shared pointer wrapper for robowflex::Scene.
The Trajectory class is a wrapper around MoveIt!'s robot_trajectory::RobotTrajectory,...
Definition: trajectory.h:43
Trajectory(const RobotConstPtr &robot, const std::string &group)
Constructor for an empty trajectory.
Definition: trajectory.cpp:18
void interpolate(unsigned int count)
Insert a number of states in a path so that the path is made up of exactly count states....
Definition: trajectory.cpp:104
bool computeTimeParameterization(double max_velocity=1., double max_acceleration=1.)
Computes the time parameterization of a path according to a desired max velocity or acceleration.
Definition: trajectory.cpp:91
Trajectory & append(const Trajectory &source, double dt, size_t start_index=0, size_t end_index=std::numeric_limits< std::size_t >::max())
Adds a specified part of a trajectory to the end of the current trajectory. The default,...
Definition: trajectory.cpp:172
std::map< std::string, double > getFinalPositions() const
Returns the joint positions from the last state in a planned trajectory in response.
Definition: trajectory.cpp:284
robot_trajectory::RobotTrajectoryPtr trajectory_
Definition: trajectory.h:218
std::vector< std::vector< double > > vectorize() const
Converts a trajectory into a vector of position vectors. The values are in the same order as reported...
Definition: trajectory.cpp:157
bool fromYAMLFile(const robot_state::RobotState &reference_state, const std::string &filename)
Load a trajectory from a YAML file.
Definition: trajectory.cpp:54
const robot_trajectory::RobotTrajectoryPtr & getTrajectoryConst() const
Get a const reference to the trajectory.
Definition: trajectory.cpp:69
std::vector< std::string > getJointNames() const
Get the names of the variables that make up this trajectory, in the same order as in MoveIt JointMode...
Definition: trajectory.cpp:167
void addSuffixWaypoint(const robot_state::RobotState &state, double dt=1.)
Add a waypoint at the end of the trajectory.
Definition: trajectory.cpp:64
bool toYAMLFile(const std::string &filename) const
Dump a trajectory to a file.
Definition: trajectory.cpp:45
double getLength(const PathMetric &metric={}) const
Get the length of a path. Optionally, a metric can be specified other than the default (the L2 norm).
Definition: trajectory.cpp:178
std::tuple< double, double, double > getClearance(const SceneConstPtr &scene) const
Get the average, minimum, and maximum clearance of a path.
Definition: trajectory.cpp:214
bool isCollisionFree(const SceneConstPtr &scene) const
Checks if a path is collsion free.
Definition: trajectory.cpp:196
robot_trajectory::RobotTrajectoryPtr & getTrajectory()
Get a reference to the trajectory.
Definition: trajectory.cpp:74
double getSmoothness(const PathMetric &metric={}) const
Get the smoothness of a path relative to some metric. See internal function documentation for details...
Definition: trajectory.cpp:237
void useMessage(const robot_state::RobotState &reference_state, const moveit_msgs::RobotTrajectory &msg)
Set the trajectory to be the same as a message.
Definition: trajectory.cpp:33
moveit_msgs::RobotTrajectory getMessage() const
Get the message that describes the trajectory.
Definition: trajectory.cpp:79
std::size_t getNumWaypoints() const
Returns the number of waypoints of the trajectory.
Definition: trajectory.cpp:86
bool computeTimeStamps(robot_trajectory::RobotTrajectory &trajectory, const double max_velocity_scaling_factor=1.0, const double max_acceleration_scaling_factor=1.0) const
T emplace_back(T... args)
T emplace(T... args)
#define RBX_INFO(fmt,...)
Output a info logging message.
Definition: log.h:118
T make_tuple(T... args)
T max(T... args)
Functions for loading and animating robots in Blender.
bool YAMLToFile(const YAML::Node &node, const std::string &file)
Write the contents of a YAML node out to a potentially new file.
YAML::Node toNode(const geometry_msgs::Pose &msg)
Converts a pose message to YAML.
Definition: yaml.cpp:1874
bool YAMLFileToMessage(T &msg, const std::string &file)
Load a message (or YAML convertable object) from a file.
static const double pi
Definition: constants.h:21
Main namespace. Contains all library classes and functions.
Definition: scene.cpp:25
Functions for loading and animating scenes in Blender.
robot_trajectory::RobotTrajectory trajectory(rmodel,"right_arm")