Robowflex  v0.1
Making MoveIt Easy
visualization.cpp
Go to the documentation of this file.
1 /* Author: Zachary Kingston, Constantinos Chamzas */
2 
3 #include <boost/range/combine.hpp>
4 
5 #include <moveit_msgs/DisplayRobotState.h>
6 #include <moveit_msgs/DisplayTrajectory.h>
7 #include <moveit_msgs/PlanningScene.h>
8 #include <visualization_msgs/Marker.h>
9 #include <visualization_msgs/MarkerArray.h>
10 
11 #include <moveit/robot_state/conversions.h>
12 
13 #include <robowflex_library/util.h>
19 #include <robowflex_library/log.h>
24 #include <robowflex_library/tf.h>
26 
27 using namespace robowflex;
28 
29 namespace
30 {
31  Eigen::Vector4d getRandomColor()
32  {
33  Eigen::Vector4d color;
34  color::turbo(RNG::uniform01(), color);
35  return color;
36  }
37 }; // namespace
38 
40  : robot_(robot), nh_("/" + name)
41 {
42  std::string description;
43  robot_->getHandlerConst().getParam(Robot::ROBOT_DESCRIPTION, description);
44  std::string semantic;
45  robot_->getHandlerConst().getParam(Robot::ROBOT_DESCRIPTION + Robot::ROBOT_SEMANTIC, semantic);
46 
47  nh_.setParam(Robot::ROBOT_DESCRIPTION, description);
49 
50  trajectory_pub_ = nh_.advertise<moveit_msgs::DisplayTrajectory>("trajectory", 1);
51  state_pub_ = nh_.advertise<moveit_msgs::DisplayRobotState>("state", 1);
52  scene_pub_ = nh_.advertise<moveit_msgs::PlanningScene>("scene", 1);
53  pcd_pub_ = nh_.advertise<sensor_msgs::PointCloud2>("pcd", 1);
54  marker_pub_ = nh_.advertise<visualization_msgs::MarkerArray>("/visualization_marker_array", 100);
55 }
56 
58 {
59  updateTrajectory(response.trajectory_);
60 }
61 
63 {
64  updateTrajectory(trajectory.getTrajectoryConst());
65 }
66 
67 void IO::RVIZHelper::updateTrajectory(const robot_trajectory::RobotTrajectoryPtr &trajectory)
68 {
69  moveit_msgs::RobotTrajectory msg;
71 
72  updateTrajectory(msg, trajectory->getFirstWayPoint());
73 }
74 
75 void IO::RVIZHelper::updateTrajectory(const moveit_msgs::RobotTrajectory &traj,
76  const moveit::core::RobotState &start)
77 {
78  moveit_msgs::DisplayTrajectory out;
79 
80  out.model_id = robot_->getModelName();
81  out.trajectory.push_back(traj);
82  moveit::core::robotStateToRobotStateMsg(start, out.trajectory_start);
83 
84  if (trajectory_pub_.getNumSubscribers() < 1)
85  {
86  RBX_INFO("Waiting for Trajectory subscribers...");
87 
88  ros::WallDuration pause(0.1);
89  while (trajectory_pub_.getNumSubscribers() < 1)
90  pause.sleep();
91  }
92 
93  trajectory_pub_.publish(out);
94 }
95 
97 {
98  moveit_msgs::DisplayTrajectory out;
99  out.model_id = robot_->getModelName();
100 
101  bool set = false;
102  for (const auto &traj : trajectories)
103  {
104  if (!set)
105  {
106  moveit::core::robotStateToRobotStateMsg(traj->getFirstWayPoint(), out.trajectory_start);
107  set = true;
108  }
109 
110  moveit_msgs::RobotTrajectory msg;
111  traj->getRobotTrajectoryMsg(msg);
112  out.trajectory.push_back(msg);
113  }
114 
115  if (trajectory_pub_.getNumSubscribers() < 1)
116  {
117  RBX_INFO("Waiting for Trajectory subscribers...");
118 
119  ros::WallDuration pause(0.1);
120  while (trajectory_pub_.getNumSubscribers() < 1)
121  pause.sleep();
122  }
123 
124  trajectory_pub_.publish(out);
125 }
126 
128 {
129  auto moveit_trajectories = std::vector<robot_trajectory::RobotTrajectoryPtr>();
130 
131  for (const auto &response : responses)
132  if (response.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
133  moveit_trajectories.push_back(response.trajectory_);
134 
135  updateTrajectories(moveit_trajectories);
136 }
137 
139 {
140  auto moveit_trajectories = std::vector<robot_trajectory::RobotTrajectoryPtr>();
141 
142  for (const auto &traj : trajectories)
143  moveit_trajectories.push_back(traj->getTrajectory());
144 
145  updateTrajectories(moveit_trajectories);
146 }
147 
148 void IO::RVIZHelper::visualizeState(const robot_state::RobotStatePtr &state)
149 {
150  if (state_pub_.getNumSubscribers() < 1)
151  {
152  RBX_INFO("Waiting for State subscribers...");
153 
154  ros::WallDuration pause(0.1);
155  while (state_pub_.getNumSubscribers() < 1)
156  pause.sleep();
157  }
158 
159  moveit_msgs::DisplayRobotState out;
160  moveit::core::robotStateToRobotStateMsg(*state, out.state);
161 
162  state_pub_.publish(out);
163 }
164 
166 {
167  auto state = robot_->allocState();
168 
169  sensor_msgs::JointState joint_state;
170  joint_state.name = robot_->getJointNames();
171  joint_state.position = state_vec;
172 
173  moveit::core::jointStateToRobotState(joint_state, *state);
174 
175  visualizeState(state);
176 }
177 
179 {
180  visualizeState(robot_->getScratchStateConst());
181 }
182 
183 void IO::RVIZHelper::fillMarker(visualization_msgs::Marker &marker, const std::string &base_frame,
184  const RobotPose &pose, const Eigen::Vector4d &color,
185  const Eigen::Vector3d &scale) const
186 {
187  marker.header.frame_id = base_frame;
188  marker.frame_locked = true;
189 
190  marker.header.stamp = ros::Time().now();
191  marker.ns = "/robowflex";
192  marker.id = markers_.size();
193 
194  marker.action = visualization_msgs::Marker::ADD;
195  marker.pose = TF::poseEigenToMsg(pose);
196  marker.scale = TF::vectorEigenToMsg(scale);
197 
198  marker.color.r = color[0];
199  marker.color.g = color[1];
200  marker.color.b = color[2];
201  marker.color.a = color[3];
202 }
203 
204 void IO::RVIZHelper::addArrowMarker(const std::string &name, const std::string &base_frame,
205  const RobotPose &pose, const Eigen::Vector4d &color,
206  const Eigen::Vector3d &scale)
207 {
208  visualization_msgs::Marker marker;
209  fillMarker(marker, base_frame, pose, color, scale);
210 
211  marker.type = visualization_msgs::Marker::ARROW;
212 
213  addMarker(marker, name);
214 }
215 
217  const std::string &base_frame, const RobotPose &pose, double height,
218  const Eigen::Vector4d &color)
219 {
220  visualization_msgs::Marker marker;
221  fillMarker(marker, base_frame, pose, color, {0, 0, height});
222 
223  marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
224  marker.text = text;
225 
226  addMarker(marker, name);
227 }
228 
230  const std::vector<Eigen::Vector4d> &colors, double scale)
231 {
232  visualization_msgs::Marker marker;
233 
234  fillMarker(marker, //
235  "map", //
236  RobotPose::Identity(), //
237  getRandomColor(), //
238  Eigen::Vector3d{scale, 1, 1});
239 
240  marker.type = visualization_msgs::Marker::LINE_LIST;
241 
242  if (points.size() != colors.size())
243  throw Exception(1, "Mismatch between points and colors sizes!");
244 
245  for (std::size_t i = 0; i < points.size(); ++i)
246  {
247  marker.points.emplace_back(TF::pointEigenToMsg(points[i]));
248  std_msgs::ColorRGBA mcolor;
249  mcolor.r = colors[i][0];
250  mcolor.g = colors[i][1];
251  mcolor.b = colors[i][2];
252  mcolor.a = colors[i][3];
253  marker.colors.emplace_back(mcolor);
254  }
255 
256  addMarker(marker, name);
257 }
258 
259 void IO::RVIZHelper::addTransformMarker(const std::string &name, const std::string &base_frame,
260  const RobotPose &pose, double scale)
261 {
262  const auto &arrow_size = Eigen::Vector3d{0.1, 0.008, 0.003}; // A nice default size of arrow
263  const auto &z_rot90 = TF::createPoseXYZ(0, 0, 0, 0, 0, constants::half_pi);
264  const auto &y_rot90 = TF::createPoseXYZ(0, 0, 0, 0, -constants::half_pi, 0);
265 
266  addArrowMarker(name + "X", base_frame, pose, color::RED, scale * arrow_size);
267  addArrowMarker(name + "Y", base_frame, pose * z_rot90, color::GREEN, scale * arrow_size);
268  addArrowMarker(name + "Z", base_frame, pose * y_rot90, color::BLUE, scale * arrow_size);
269 }
270 
272  const std::string &base_frame, const RobotPose &pose,
273  const Eigen::Vector4d &color)
274 {
275  visualization_msgs::Marker marker;
276 
277  auto scale = geometry->getDimensions();
278  switch (geometry->getType())
279  {
281  marker.type = visualization_msgs::Marker::CUBE;
282  break;
284  marker.type = visualization_msgs::Marker::SPHERE;
285  scale[1] = scale[2] = scale[0]; // Copy radius to other dimensions
286  break;
288  marker.type = visualization_msgs::Marker::CYLINDER;
289  {
290  auto scale2 = scale;
291  scale[0] = scale[1] = 2 * scale2[0]; // Copy radius to first two (x & y)
292  scale[2] = scale2[1];
293  }
294  break;
296  scale[0] = scale[1] = scale[2] = 1; // Meshes are unscalable.
297  if (!geometry->getResource().empty())
298  {
299  marker.type = visualization_msgs::Marker::MESH_RESOURCE;
300  marker.mesh_resource = geometry->getResource();
301  marker.mesh_use_embedded_materials = true;
302  }
303  else if (!geometry->getVertices().empty())
304  {
305  auto msg = geometry->getMeshMsg();
306  marker.type = visualization_msgs::Marker::TRIANGLE_LIST;
307  for (std::size_t i = 0; i < msg.triangles.size(); ++i)
308  {
309  marker.points.push_back(msg.vertices[msg.triangles[i].vertex_indices[0]]);
310  marker.points.push_back(msg.vertices[msg.triangles[i].vertex_indices[1]]);
311  marker.points.push_back(msg.vertices[msg.triangles[i].vertex_indices[2]]);
312  }
313  }
314  break;
315 
316  default:
317  RBX_ERROR("Unsupported geometry for marker.");
318  return;
319  };
320 
321  fillMarker(marker, base_frame, pose, color, scale);
322 
323  addMarker(marker, name);
324 }
325 
326 void IO::RVIZHelper::addGoalMarker(const std::string &name, const moveit_msgs::MotionPlanRequest &request)
327 {
328  const auto &goals = request.goal_constraints;
329 
330  // Iterate over each goal (an "or"-ing together of different constraints)
331  for (const auto &goal : goals)
332  {
333  auto color = getRandomColor(); // Use the same color for all elements of this goal
334  color[3] = 0.7; // Make slightly transparent
335 
336  for (const auto &pg : goal.position_constraints)
337  {
338  const auto &pname = pg.link_name;
339  const auto &base_frame = pg.header.frame_id;
340 
341  // Get global transform of position constraint
342  RobotPose pose;
343  if (base_frame == robot_->getModelConst()->getModelFrame())
344  {
345  pose.setIdentity();
346  }
347  else
348  {
349  pose = robot_->getLinkTF(pg.header.frame_id);
350  }
351  pose.translate(TF::vectorMsgToEigen(pg.target_point_offset));
352 
353  // Iterate over all position primitives and their poses
354  for (const auto &primitive :
355  boost::combine(pg.constraint_region.primitives, pg.constraint_region.primitive_poses))
356  {
357  shape_msgs::SolidPrimitive solid;
358  geometry_msgs::Pose solid_pose;
359  boost::tie(solid, solid_pose) = primitive;
360 
361  // Compute transform of bounding volume
362  auto frame = pose * TF::poseMsgToEigen(solid_pose);
363 
364  // Add geometry marker associated with this solid primitive
365  addGeometryMarker(name, Geometry::makeSolidPrimitive(solid), base_frame, frame, color);
366 
367  // Iterate over all orientation constraints for the same link as the
368  // position constraint
369  for (const auto &og : goal.orientation_constraints)
370  {
371  const auto &oname = og.link_name;
372  if (oname != pname)
373  continue;
374 
375  auto q = TF::quaternionMsgToEigen(og.orientation);
376 
377  // Arrow display frame.
378  RobotPose qframe = RobotPose::Identity();
379  qframe.translate(frame.translation()); // Place arrows at the origin
380  // of the position volume
381 
382  Eigen::Vector3d scale = {0.1, 0.008, 0.003}; // A nice default size of arrow
383 
384  // Display primary orientation slightly larger
385  addArrowMarker(name, base_frame, qframe * q, color, 1.5 * scale);
386 
387  // Zip together tolerances and axes, and iterate over them to display
388  // orientation bounds
389  const auto tolerances = {og.absolute_x_axis_tolerance, //
390  og.absolute_y_axis_tolerance, //
391  og.absolute_z_axis_tolerance};
392  const auto axes = {Eigen::Vector3d::UnitX(), //
393  Eigen::Vector3d::UnitY(), //
394  Eigen::Vector3d::UnitZ()};
395  for (const auto &angles : boost::combine(tolerances, axes))
396  {
397  double value;
398  Eigen::Vector3d axis;
399  boost::tie(value, axis) = angles;
400 
401  // Show boundaries of tolerances as smaller arrows.
402  auto q1 = TF::offsetOrientation(q, axis, value);
403  addArrowMarker(name, base_frame, qframe * q1, color, scale);
404 
405  auto q2 = TF::offsetOrientation(q, axis, -value);
406  addArrowMarker(name, base_frame, qframe * q2, color, scale);
407  }
408  }
409  }
410 
411  // TODO: Implement
412  // for (const auto &mesh :
413  // boost::combine(pg.constraint_region.meshes,
414  // pg.constraint_region.mesh_poses))
415  // {
416  // }
417  }
418  }
419 }
420 
422 {
423  addGoalMarker(name, request.getRequestConst());
424 }
425 
427 {
428  for (auto &marker : markers_)
429  marker.second.action = visualization_msgs::Marker::DELETE;
430 }
431 
433 {
434  auto markers = markers_.equal_range(name);
435 
436  for (auto it = markers.first; it != markers.second; ++it)
437  it->second.action = visualization_msgs::Marker::DELETE;
438 }
439 
440 void IO::RVIZHelper::addMarker(const visualization_msgs::Marker &marker, const std::string &name)
441 {
442  markers_.emplace(name, marker);
443 }
444 
445 void IO::RVIZHelper::addMarker(double x, double y, double z, const std::string &name)
446 {
447  visualization_msgs::Marker marker;
448  const std::string &base_frame = "map";
449 
450  const auto &pose = TF::createPoseXYZ(x, y, z);
451 
452  const auto &scale = Eigen::Vector3d{0.05, 0.05, 0.05};
453  const auto &color = getRandomColor();
454 
455  fillMarker(marker, base_frame, pose, color, scale);
456 
457  marker.type = visualization_msgs::Marker::SPHERE;
458 
459  addMarker(marker, name);
460 }
461 
462 void IO::RVIZHelper::addMarker(const Eigen::Vector3d &point, const std::string &name)
463 {
464  addMarker(point.x(), point.y(), point.z(), name);
465 }
466 
468 {
469  updateScene(nullptr);
470 }
471 
473 {
474  if (scene_pub_.getNumSubscribers() < 1)
475  {
476  RBX_INFO("Waiting for Scene subscribers...");
477 
478  ros::WallDuration pause(0.1);
479  while (scene_pub_.getNumSubscribers() < 1)
480  pause.sleep();
481  }
482 
483  moveit_msgs::PlanningScene to_pub;
484  if (scene != nullptr)
485  {
486  to_pub = scene->getMessage();
487  to_pub.is_diff = true;
488  }
489 
490  scene_pub_.publish(to_pub);
491 }
492 
493 void IO::RVIZHelper::updatePCD(const sensor_msgs::PointCloud2 &msg)
494 {
495  if (pcd_pub_.getNumSubscribers() < 1)
496  {
497  RBX_INFO("Waiting for pcd subscribers...");
498 
499  ros::WallDuration pause(0.1);
500  while (pcd_pub_.getNumSubscribers() < 1)
501  pause.sleep();
502  }
503 
504  pcd_pub_.publish(msg);
505 }
506 
508 {
509  visualization_msgs::MarkerArray msg;
510 
512  for (auto &marker : markers_)
513  {
514  msg.markers.emplace_back(marker.second);
515 
516  if (marker.second.action == visualization_msgs::Marker::ADD)
517  marker.second.action = visualization_msgs::Marker::MODIFY;
518 
519  else if (marker.second.action == visualization_msgs::Marker::DELETE)
520  remove.push_back(marker.first);
521  }
522 
523  if (marker_pub_.getNumSubscribers() < 1)
524  {
525  RBX_INFO("Waiting for MarkerArray subscribers...");
526 
527  ros::WallDuration pause(0.1);
528  while (marker_pub_.getNumSubscribers() < 1)
529  pause.sleep();
530  }
531 
532  marker_pub_.publish(msg);
533 
534  for (auto &marker : remove)
535  markers_.erase(markers_.find(marker));
536 }
void getRobotTrajectoryMsg(moveit_msgs::RobotTrajectory &trajectory) const
const robot_state::RobotState & getFirstWayPoint() const
Exception that contains a message and an error code.
Definition: util.h:15
A const shared pointer wrapper for robowflex::Geometry.
@ CYLINDER
Solid primitive cylinder. Uses two dimensions (height, radius).
Definition: geometry.h:47
@ MESH
Mesh. Dimensions scale along x, y, z.
Definition: geometry.h:49
@ BOX
Solid primitive box. Uses three dimensions (x, y, z).
Definition: geometry.h:45
@ SPHERE
Solid primitive sphere. Uses one dimension (radius).
Definition: geometry.h:46
static GeometryPtr makeSolidPrimitive(const shape_msgs::SolidPrimitive &msg)
Create a solid primitive.
Definition: geometry.cpp:68
void addMarker(const visualization_msgs::Marker &marker, const std::string &name="")
Add a marker message (under the name "name") to the scene.
void removeMarker(const std::string &name)
Removes a marker that was added through addMarker().
void removeAllMarkers()
Removes all markers that were added through addMarker().
ros::Publisher marker_pub_
Marker publisher.
void addLineMarker(const std::string &name, const std::vector< Eigen::Vector3d > &points, const std::vector< Eigen::Vector4d > &colors, double scale)
Add a set of lines as markers.
ros::Publisher pcd_pub_
Pointcloud publisher.
void updateTrajectories(const std::vector< robot_trajectory::RobotTrajectoryPtr > &trajectories)
Updates the trajectory being visualized to a list of trajectories.
ros::Publisher scene_pub_
Scene publisher.
ros::Publisher trajectory_pub_
Trajectory publisher.
ros::NodeHandle nh_
Handle for publishing.
void visualizeState(const robot_state::RobotStatePtr &state)
Visualizes a robot state.
RobotConstPtr robot_
Robot being visualized.
void updateMarkers()
Displays the managed list of markers. Keeps track of whether markers have already been displayed and ...
void removeScene()
Removes the scene being visualized.
RVIZHelper(const RobotConstPtr &robot, const std::string &name="robowflex")
Constructor. All parameters are placed under /name. This helper puts trajectories under /name/traject...
void visualizeCurrentState()
Visualize the current state of the robot.
void addArrowMarker(const std::string &name, const std::string &base_frame, const RobotPose &pose, const Eigen::Vector4d &color, const Eigen::Vector3d &scale)
Adds an arrow marker to the managed list of markers. Displayed after an updateMarkers() call.
void fillMarker(visualization_msgs::Marker &marker, const std::string &base_frame, const RobotPose &pose, const Eigen::Vector4d &color, const Eigen::Vector3d &scale) const
Fills a marker in with some common default information.
ros::Publisher state_pub_
State publisher.
void updatePCD(const sensor_msgs::PointCloud2 &msg)
Updates the pointcloud being visualized.
void updateScene(const SceneConstPtr &scene)
Updates the scene being visualized.
void addGeometryMarker(const std::string &name, const GeometryConstPtr &geometry, const std::string &base_frame, const RobotPose &pose, const Eigen::Vector4d &color=color::WHITE)
Add a marker to the managed list of markers. Displayed after an updateMarkers() call.
void addGoalMarker(const std::string &name, const MotionRequestBuilder &request)
Adds the current goal of the motion request builder as a set of markers in the marker array.
void addTextMarker(const std::string &name, const std::string &text, const std::string &base_frame, const RobotPose &pose, double height, const Eigen::Vector4d &color=color::WHITE)
Adds a text marker to the managed list of markers. Displayed after updateMarkers().
void updateTrajectory(const planning_interface::MotionPlanResponse &response)
Updates the trajectory being visualized.
void addTransformMarker(const std::string &name, const std::string &base_frame, const RobotPose &pose, double scale=1)
Add a transform marker to the managed list of markers. Displayed after an updateMarkers() call.
A helper class to build motion planning requests for a robowflex::Planner.
Definition: builder.h:34
const planning_interface::MotionPlanRequest & getRequestConst() const
Get a const reference to the currently built motion planning request.
Definition: builder.cpp:538
A const shared pointer wrapper for robowflex::Robot.
static const std::string ROBOT_DESCRIPTION
Default robot description name.
static const std::string ROBOT_SEMANTIC
Default robot semantic description suffix.
A const shared pointer wrapper for robowflex::Scene.
The Trajectory class is a wrapper around MoveIt!'s robot_trajectory::RobotTrajectory,...
Definition: trajectory.h:43
T emplace_back(T... args)
#define RBX_ERROR(fmt,...)
Output a error logging message.
Definition: log.h:102
#define RBX_INFO(fmt,...)
Output a info logging message.
Definition: log.h:118
bool jointStateToRobotState(const sensor_msgs::JointState &joint_state, RobotState &state)
void robotStateToRobotStateMsg(const RobotState &state, moveit_msgs::RobotState &robot_state, bool copy_attached_bodies=true)
Functions for loading and animating robots in Blender.
double uniform01()
Generate a random real in [0,1).
Definition: random.cpp:20
geometry_msgs::Vector3 vectorEigenToMsg(const Eigen::Vector3d &vector)
Converts an Eigen::Vector3d to a vector message.
Definition: tf.cpp:104
Eigen::Vector3d vectorMsgToEigen(const geometry_msgs::Vector3 &msg)
Converts a vector message to an Eigen::Vector3d.
Definition: tf.cpp:94
RobotPose poseMsgToEigen(const geometry_msgs::Pose &msg)
Converts a pose message to RobotPose.
Definition: tf.cpp:114
RobotPose createPoseXYZ(double x, double y, double z)
Creates a robot pose from a linear component and zero orientation.
Definition: tf.cpp:14
geometry_msgs::Pose poseEigenToMsg(const RobotPose &pose)
Converts an RobotPose to a pose message.
Definition: tf.cpp:120
Eigen::Quaterniond quaternionMsgToEigen(const geometry_msgs::Quaternion &msg)
Converts a quaternion message to Eigen::Quaterniond.
Definition: tf.cpp:135
geometry_msgs::Point pointEigenToMsg(const Eigen::Vector3d &vector)
Converts an Eigen::Vector3d to a point message.
Definition: tf.cpp:84
Eigen::Quaterniond offsetOrientation(const Eigen::Quaterniond &orientation, const Eigen::Vector3d &axis, double value)
Offset an orientation by a rotation about an axis.
Definition: tf.cpp:228
static const Eigen::Vector4d GREEN
Definition: colormap.h:60
static const Eigen::Vector4d RED
Definition: colormap.h:57
void turbo(double s, Eigen::Ref< Eigen::Vector4d > color)
Maps a scalar s in [0, 1] to the Turbo colormap.
Definition: colormap.cpp:339
static const Eigen::Vector4d BLUE
Definition: colormap.h:61
static const double half_pi
Definition: constants.h:22
Main namespace. Contains all library classes and functions.
Definition: scene.cpp:25
std::decay< decltype(std::declval< moveit::core::Transforms >().getTransform("")) >::type RobotPose
A pose (point in SE(3)) used in various functions. Defined from what MoveIt! uses.
Definition: adapter.h:24
Functions for loading and animating scenes in Blender.
T size(T... args)
robot_trajectory::RobotTrajectoryPtr trajectory_
robot_trajectory::RobotTrajectory trajectory(rmodel,"right_arm")