36#include <rviz_common/properties/bool_property.hpp>
37#include <rviz_common/validate_floats.hpp>
38#include <rviz_common/display_context.hpp>
40#include <rviz_default_plugins/displays/interactive_markers/interactive_marker_namespace_property.hpp>
51 valid = valid && rviz_common::validateFloats(msg.pose);
52 valid = valid && rviz_common::validateFloats(msg.scale);
53 for (
const auto&
control : msg.controls)
55 valid = valid && rviz_common::validateFloats(
control.orientation);
56 for (
const auto& marker :
control.markers)
58 valid = valid && rviz_common::validateFloats(marker.pose);
59 valid = valid && rviz_common::validateFloats(marker.scale);
60 valid = valid && rviz_common::validateFloats(marker.color);
61 valid = valid && rviz_common::validateFloats(marker.points);
69 interactive_marker_namespace_property_ =
70 new InteractiveMarkerNamespaceProperty(
"Interactive Markers Namespace",
"",
71 "Namespace of the interactive marker server to connect to.",
this,
74 show_descriptions_property_ =
75 new rviz_common::properties::BoolProperty(
"Show Descriptions",
true,
76 "Whether or not to show the descriptions of each Interactive Marker.",
79 show_axes_property_ =
new rviz_common::properties::BoolProperty(
80 "Show Axes",
false,
"Whether or not to show the axes of each Interactive Marker.",
this, SLOT(
updateShowAxes()));
82 show_visual_aids_property_ =
new rviz_common::properties::BoolProperty(
83 "Show Visual Aids",
false,
"Whether or not to show visual helpers while moving/rotating Interactive Markers.",
86 enable_transparency_property_ =
new rviz_common::properties::BoolProperty(
87 "Enable Transparency",
true,
88 "Whether or not to allow transparency for auto-completed markers (e.g. rings and arrows).",
this,
101 rclcpp::NodeOptions options;
102 options.arguments({
"--ros-args",
"-r",
103 "__node:=" + std::string(
"interactive_marker_display_") +
104 std::to_string(
reinterpret_cast<std::size_t
>(
this)) });
105 pnode_ = rclcpp::Node::make_shared(
"_",
"", options);
106 private_executor_ = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
107 private_executor_->add_node(pnode_);
109 private_executor_thread_ = std::thread([
this]() { private_executor_->spin(); });
110 auto frame_transformer = context_->getFrameManager()->getTransformer();
112 interactive_marker_client_ = std::make_unique<interactive_markers::InteractiveMarkerClient>(
113 pnode_, frame_transformer, fixed_frame_.toStdString());
115 interactive_marker_client_->setInitializeCallback(
116 [
this](
const visualization_msgs::srv::GetInteractiveMarkers::Response::SharedPtr& msg) {
117 return initializeCallback(msg);
119 interactive_marker_client_->setUpdateCallback(
120 [
this](
const visualization_msgs::msg::InteractiveMarkerUpdate::ConstSharedPtr& msg) {
121 return updateCallback(msg);
123 interactive_marker_client_->setResetCallback([
this]() {
return resetCallback(); });
124 interactive_marker_client_->setStatusCallback(
125 [
this](interactive_markers::InteractiveMarkerClient::Status status,
const std::string& message) {
126 return statusCallback(status, message);
146 if (interactive_marker_namespace_property_->isEmpty())
148 setStatus(rviz_common::properties::StatusProperty::Error,
"Interactive Marker Client",
149 QString(
"Error connecting: empty namespace"));
156void InteractiveMarkerDisplay::subscribe()
158 const std::string topic_namespace = interactive_marker_namespace_property_->getNamespaceStd();
159 if (isEnabled() && !topic_namespace.empty())
161 interactive_marker_client_->connect(topic_namespace);
167 interactive_marker_client_->publishFeedback(feedback);
171 const std::string& name,
const std::string& text)
173 setStatusStd(level, name, text);
176void InteractiveMarkerDisplay::unsubscribe()
178 if (interactive_marker_client_)
180 interactive_marker_client_->disconnect();
190 interactive_marker_client_->update();
192 for (
const auto& name_marker_pair : interactive_markers_map_)
194 name_marker_pair.second->update();
198void InteractiveMarkerDisplay::updateMarkers(
const std::vector<visualization_msgs::msg::InteractiveMarker>& markers)
200 for (
const visualization_msgs::msg::InteractiveMarker& marker : markers)
204 setStatusStd(rviz_common::properties::StatusProperty::Error, marker.name,
"Marker contains invalid floats!");
207 RVIZ_COMMON_LOG_DEBUG_STREAM(
"Processing interactive marker '" << marker.name <<
"'. " << marker.controls.size());
209 auto int_marker_entry = interactive_markers_map_.find(marker.name);
211 if (int_marker_entry == interactive_markers_map_.end())
214 interactive_markers_map_
215 .insert(std::make_pair(marker.name, std::make_shared<InteractiveMarker>(getSceneNode(), context_)))
217 connect(int_marker_entry->second.get(), SIGNAL(userFeedback(visualization_msgs::msg::InteractiveMarkerFeedback&)),
218 this, SLOT(
publishFeedback(visualization_msgs::msg::InteractiveMarkerFeedback&)));
220 int_marker_entry->second.get(),
221 SIGNAL(statusUpdate(rviz_common::properties::StatusProperty::Level,
const std::string&,
const std::string&)),
223 SLOT(
onStatusUpdate(rviz_common::properties::StatusProperty::Level,
const std::string&,
const std::string&)));
226 if (int_marker_entry->second->processMessage(marker))
228 int_marker_entry->second->setShowAxes(show_axes_property_->getBool());
229 int_marker_entry->second->setShowVisualAids(show_visual_aids_property_->getBool());
230 int_marker_entry->second->setShowDescription(show_descriptions_property_->getBool());
240void InteractiveMarkerDisplay::eraseAllMarkers()
242 interactive_markers_map_.clear();
243 deleteStatusStd(
"Interactive Marker Client");
246void InteractiveMarkerDisplay::eraseMarkers(
const std::vector<std::string>& erases)
248 for (
const std::string& marker_name : erases)
250 interactive_markers_map_.erase(marker_name);
251 deleteStatusStd(marker_name);
255void InteractiveMarkerDisplay::updatePoses(
256 const std::vector<visualization_msgs::msg::InteractiveMarkerPose>& marker_poses)
258 for (
const visualization_msgs::msg::InteractiveMarkerPose& marker_pose : marker_poses)
260 if (!rviz_common::validateFloats(marker_pose.pose))
262 setStatusStd(rviz_common::properties::StatusProperty::Error, marker_pose.name,
263 "Pose message contains invalid floats!");
267 auto int_marker_entry = interactive_markers_map_.find(marker_pose.name);
269 if (int_marker_entry != interactive_markers_map_.end())
271 int_marker_entry->second->processMessage(marker_pose);
275 setStatusStd(rviz_common::properties::StatusProperty::Error, marker_pose.name,
276 "Pose received for non-existing marker '" + marker_pose.name);
283void InteractiveMarkerDisplay::initializeCallback(
284 const visualization_msgs::srv::GetInteractiveMarkers::Response::SharedPtr& msg)
287 updateMarkers(msg->markers);
290void InteractiveMarkerDisplay::updateCallback(
const visualization_msgs::msg::InteractiveMarkerUpdate::ConstSharedPtr& msg)
292 updateMarkers(msg->markers);
293 updatePoses(msg->poses);
294 eraseMarkers(msg->erases);
297void InteractiveMarkerDisplay::resetCallback()
300 deleteStatusStd(
"Interactive Marker Client");
303void InteractiveMarkerDisplay::statusCallback(interactive_markers::InteractiveMarkerClient::Status status,
304 const std::string& message)
306 rviz_common::properties::StatusProperty::Level rviz_level;
309 case interactive_markers::InteractiveMarkerClient::STATUS_DEBUG:
310 rviz_level = rviz_common::properties::StatusProperty::Ok;
312 case interactive_markers::InteractiveMarkerClient::STATUS_INFO:
313 rviz_level = rviz_common::properties::StatusProperty::Ok;
315 case interactive_markers::InteractiveMarkerClient::STATUS_WARN:
316 rviz_level = rviz_common::properties::StatusProperty::Warn;
318 case interactive_markers::InteractiveMarkerClient::STATUS_ERROR:
319 rviz_level = rviz_common::properties::StatusProperty::Error;
322 RVIZ_COMMON_LOG_WARNING(
"Unexpected status level from interactive marker client received");
323 rviz_level = rviz_common::properties::StatusProperty::Error;
325 setStatusStd(rviz_level,
"Interactive Marker Client", message);
330 if (interactive_marker_client_)
332 interactive_marker_client_->setTargetFrame(fixed_frame_.toStdString());
346 bool show = show_descriptions_property_->getBool();
348 for (
const auto& name_marker_pair : interactive_markers_map_)
350 name_marker_pair.second->setShowDescription(show);
356 bool show = show_axes_property_->getBool();
358 for (
const auto& name_marker_pair : interactive_markers_map_)
360 name_marker_pair.second->setShowAxes(show);
366 bool show = show_visual_aids_property_->getBool();
368 for (
const auto& name_marker_pair : interactive_markers_map_)
370 name_marker_pair.second->setShowVisualAids(show);
378 interactive_marker_client_->setEnableAutocompleteTransparency(enable_transparency_property_->getBool());
385#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(cached_ik_kinematics_plugin::CachedIKKinematicsPlugin< kdl_kinematics_plugin::KDLKinematicsPlugin >, kinematics::KinematicsBase)
Displays Interactive Markers.
InteractiveMarkerDisplay()
void publishFeedback(visualization_msgs::msg::InteractiveMarkerFeedback &feedback)
void onDisable() override
void updateEnableTransparency()
void update(float wall_dt, float ros_dt) override
void fixedFrameChanged() override
void updateShowDescriptions()
void onStatusUpdate(rviz_common::properties::StatusProperty::Level level, const std::string &name, const std::string &text)
void updateShowVisualAids()
void onInitialize() override
bool validateFloats(const visualization_msgs::msg::InteractiveMarker &msg)