3 #include <boost/range/combine.hpp>
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>
11 #include <moveit/robot_state/conversions.h>
31 Eigen::Vector4d getRandomColor()
33 Eigen::Vector4d color;
40 : robot_(
robot), nh_(
"/" + name)
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);
64 updateTrajectory(
trajectory.getTrajectoryConst());
69 moveit_msgs::RobotTrajectory msg;
78 moveit_msgs::DisplayTrajectory out;
80 out.model_id = robot_->getModelName();
81 out.trajectory.push_back(traj);
84 if (trajectory_pub_.getNumSubscribers() < 1)
86 RBX_INFO(
"Waiting for Trajectory subscribers...");
88 ros::WallDuration pause(0.1);
89 while (trajectory_pub_.getNumSubscribers() < 1)
93 trajectory_pub_.publish(out);
98 moveit_msgs::DisplayTrajectory out;
99 out.model_id = robot_->getModelName();
102 for (
const auto &traj : trajectories)
110 moveit_msgs::RobotTrajectory msg;
111 traj->getRobotTrajectoryMsg(msg);
112 out.trajectory.push_back(msg);
115 if (trajectory_pub_.getNumSubscribers() < 1)
117 RBX_INFO(
"Waiting for Trajectory subscribers...");
119 ros::WallDuration pause(0.1);
120 while (trajectory_pub_.getNumSubscribers() < 1)
124 trajectory_pub_.publish(out);
131 for (
const auto &response : responses)
132 if (response.error_code_.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
133 moveit_trajectories.push_back(response.trajectory_);
135 updateTrajectories(moveit_trajectories);
142 for (
const auto &traj : trajectories)
143 moveit_trajectories.push_back(traj->getTrajectory());
145 updateTrajectories(moveit_trajectories);
150 if (state_pub_.getNumSubscribers() < 1)
152 RBX_INFO(
"Waiting for State subscribers...");
154 ros::WallDuration pause(0.1);
155 while (state_pub_.getNumSubscribers() < 1)
159 moveit_msgs::DisplayRobotState out;
162 state_pub_.publish(out);
167 auto state = robot_->allocState();
169 sensor_msgs::JointState joint_state;
170 joint_state.name = robot_->getJointNames();
171 joint_state.position = state_vec;
175 visualizeState(state);
180 visualizeState(robot_->getScratchStateConst());
184 const RobotPose &pose,
const Eigen::Vector4d &color,
185 const Eigen::Vector3d &scale)
const
187 marker.header.frame_id = base_frame;
188 marker.frame_locked =
true;
190 marker.header.stamp = ros::Time().now();
191 marker.ns =
"/robowflex";
192 marker.id = markers_.
size();
194 marker.action = visualization_msgs::Marker::ADD;
198 marker.color.r = color[0];
199 marker.color.g = color[1];
200 marker.color.b = color[2];
201 marker.color.a = color[3];
205 const RobotPose &pose,
const Eigen::Vector4d &color,
206 const Eigen::Vector3d &scale)
208 visualization_msgs::Marker marker;
209 fillMarker(marker, base_frame, pose, color, scale);
211 marker.type = visualization_msgs::Marker::ARROW;
213 addMarker(marker, name);
218 const Eigen::Vector4d &color)
220 visualization_msgs::Marker marker;
221 fillMarker(marker, base_frame, pose, color, {0, 0, height});
223 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
226 addMarker(marker, name);
232 visualization_msgs::Marker marker;
236 RobotPose::Identity(),
238 Eigen::Vector3d{scale, 1, 1});
240 marker.type = visualization_msgs::Marker::LINE_LIST;
243 throw Exception(1,
"Mismatch between points and colors sizes!");
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];
256 addMarker(marker, name);
262 const auto &arrow_size = Eigen::Vector3d{0.1, 0.008, 0.003};
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);
273 const Eigen::Vector4d &color)
275 visualization_msgs::Marker marker;
277 auto scale = geometry->getDimensions();
278 switch (geometry->getType())
281 marker.type = visualization_msgs::Marker::CUBE;
284 marker.type = visualization_msgs::Marker::SPHERE;
285 scale[1] = scale[2] = scale[0];
288 marker.type = visualization_msgs::Marker::CYLINDER;
291 scale[0] = scale[1] = 2 * scale2[0];
292 scale[2] = scale2[1];
296 scale[0] = scale[1] = scale[2] = 1;
297 if (!geometry->getResource().empty())
299 marker.type = visualization_msgs::Marker::MESH_RESOURCE;
300 marker.mesh_resource = geometry->getResource();
301 marker.mesh_use_embedded_materials =
true;
303 else if (!geometry->getVertices().empty())
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)
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]]);
317 RBX_ERROR(
"Unsupported geometry for marker.");
321 fillMarker(marker, base_frame, pose, color, scale);
323 addMarker(marker, name);
328 const auto &goals = request.goal_constraints;
331 for (
const auto &goal : goals)
333 auto color = getRandomColor();
336 for (
const auto &pg : goal.position_constraints)
338 const auto &pname = pg.link_name;
339 const auto &base_frame = pg.header.frame_id;
343 if (base_frame == robot_->getModelConst()->getModelFrame())
349 pose = robot_->getLinkTF(pg.header.frame_id);
354 for (
const auto &primitive :
355 boost::combine(pg.constraint_region.primitives, pg.constraint_region.primitive_poses))
357 shape_msgs::SolidPrimitive solid;
358 geometry_msgs::Pose solid_pose;
359 boost::tie(solid, solid_pose) = primitive;
369 for (
const auto &og : goal.orientation_constraints)
371 const auto &oname = og.link_name;
378 RobotPose qframe = RobotPose::Identity();
379 qframe.translate(
frame.translation());
382 Eigen::Vector3d scale = {0.1, 0.008, 0.003};
385 addArrowMarker(name, base_frame, qframe * q, color, 1.5 * scale);
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))
398 Eigen::Vector3d axis;
399 boost::tie(value, axis) = angles;
403 addArrowMarker(name, base_frame, qframe * q1, color, scale);
406 addArrowMarker(name, base_frame, qframe * q2, color, scale);
428 for (
auto &marker : markers_)
429 marker.second.action = visualization_msgs::Marker::DELETE;
434 auto markers = markers_.equal_range(name);
436 for (
auto it = markers.first; it != markers.second; ++it)
437 it->second.action = visualization_msgs::Marker::DELETE;
442 markers_.emplace(name, marker);
447 visualization_msgs::Marker marker;
452 const auto &scale = Eigen::Vector3d{0.05, 0.05, 0.05};
453 const auto &color = getRandomColor();
455 fillMarker(marker, base_frame, pose, color, scale);
457 marker.type = visualization_msgs::Marker::SPHERE;
459 addMarker(marker, name);
464 addMarker(point.x(), point.y(), point.z(), name);
469 updateScene(
nullptr);
474 if (scene_pub_.getNumSubscribers() < 1)
476 RBX_INFO(
"Waiting for Scene subscribers...");
478 ros::WallDuration pause(0.1);
479 while (scene_pub_.getNumSubscribers() < 1)
483 moveit_msgs::PlanningScene to_pub;
484 if (
scene !=
nullptr)
486 to_pub =
scene->getMessage();
487 to_pub.is_diff =
true;
490 scene_pub_.publish(to_pub);
495 if (pcd_pub_.getNumSubscribers() < 1)
497 RBX_INFO(
"Waiting for pcd subscribers...");
499 ros::WallDuration pause(0.1);
500 while (pcd_pub_.getNumSubscribers() < 1)
504 pcd_pub_.publish(msg);
509 visualization_msgs::MarkerArray msg;
512 for (
auto &marker : markers_)
514 msg.markers.emplace_back(marker.second);
516 if (marker.second.action == visualization_msgs::Marker::ADD)
517 marker.second.action = visualization_msgs::Marker::MODIFY;
519 else if (marker.second.action == visualization_msgs::Marker::DELETE)
520 remove.push_back(marker.first);
523 if (marker_pub_.getNumSubscribers() < 1)
525 RBX_INFO(
"Waiting for MarkerArray subscribers...");
527 ros::WallDuration pause(0.1);
528 while (marker_pub_.getNumSubscribers() < 1)
532 marker_pub_.publish(msg);
534 for (
auto &marker : remove)
535 markers_.erase(markers_.find(marker));
void getRobotTrajectoryMsg(moveit_msgs::RobotTrajectory &trajectory) const
const robot_state::RobotState & getFirstWayPoint() const
Exception that contains a message and an error code.
A const shared pointer wrapper for robowflex::Geometry.
@ CYLINDER
Solid primitive cylinder. Uses two dimensions (height, radius).
@ MESH
Mesh. Dimensions scale along x, y, z.
@ BOX
Solid primitive box. Uses three dimensions (x, y, z).
@ SPHERE
Solid primitive sphere. Uses one dimension (radius).
static GeometryPtr makeSolidPrimitive(const shape_msgs::SolidPrimitive &msg)
Create a solid primitive.
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.
const planning_interface::MotionPlanRequest & getRequestConst() const
Get a const reference to the currently built motion planning request.
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,...
T emplace_back(T... args)
#define RBX_ERROR(fmt,...)
Output a error logging message.
#define RBX_INFO(fmt,...)
Output a info logging message.
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).
geometry_msgs::Vector3 vectorEigenToMsg(const Eigen::Vector3d &vector)
Converts an Eigen::Vector3d to a vector message.
Eigen::Vector3d vectorMsgToEigen(const geometry_msgs::Vector3 &msg)
Converts a vector message to an Eigen::Vector3d.
RobotPose poseMsgToEigen(const geometry_msgs::Pose &msg)
Converts a pose message to RobotPose.
RobotPose createPoseXYZ(double x, double y, double z)
Creates a robot pose from a linear component and zero orientation.
geometry_msgs::Pose poseEigenToMsg(const RobotPose &pose)
Converts an RobotPose to a pose message.
Eigen::Quaterniond quaternionMsgToEigen(const geometry_msgs::Quaternion &msg)
Converts a quaternion message to Eigen::Quaterniond.
geometry_msgs::Point pointEigenToMsg(const Eigen::Vector3d &vector)
Converts an Eigen::Vector3d to a point message.
Eigen::Quaterniond offsetOrientation(const Eigen::Quaterniond &orientation, const Eigen::Vector3d &axis, double value)
Offset an orientation by a rotation about an axis.
static const Eigen::Vector4d GREEN
static const Eigen::Vector4d RED
void turbo(double s, Eigen::Ref< Eigen::Vector4d > color)
Maps a scalar s in [0, 1] to the Turbo colormap.
static const Eigen::Vector4d BLUE
static const double half_pi
Main namespace. Contains all library classes and functions.
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.
Functions for loading and animating scenes in Blender.
robot_trajectory::RobotTrajectoryPtr trajectory_
robot_trajectory::RobotTrajectory trajectory(rmodel,"right_arm")