task_display.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Bielefeld University
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 Bielefeld University 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: Robert Haschke
36  Desc: Monitor manipulation tasks and visualize their solutions
37 */
38 
39 #include "task_display.h"
40 #include "task_panel.h"
41 #include "task_list_model.h"
42 #include "meta_task_list_model.h"
47 #include <moveit_task_constructor_msgs/GetSolution.h>
48 
51 
52 #include <rviz/display_context.h>
56 #include <rviz/frame_manager.h>
57 #include <OgreSceneNode.h>
58 #include <QTimer>
59 
60 namespace moveit_rviz_plugin {
61 
62 TaskDisplay::TaskDisplay() : Display(), panel_requested_(false), received_task_description_(false) {
63  task_list_model_.reset(new TaskListModel);
64 
65  MetaTaskListModel::instance().insertModel(task_list_model_.get(), this);
66 
67  connect(task_list_model_.get(), SIGNAL(rowsInserted(QModelIndex, int, int)), this,
68  SLOT(onTasksInserted(QModelIndex, int, int)));
69  connect(task_list_model_.get(), SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this,
70  SLOT(onTasksRemoved(QModelIndex, int, int)));
71  connect(task_list_model_.get(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
72  SLOT(onTaskDataChanged(QModelIndex, QModelIndex)));
73 
74  robot_description_property_ = new rviz::StringProperty(
75  "Robot Description", "robot_description", "The name of the ROS parameter where the URDF for the robot is loaded",
76  this, SLOT(changedRobotDescription()), this);
77 
78  task_solution_topic_property_ = new rviz::RosTopicProperty(
79  "Task Solution Topic", "", ros::message_traits::datatype<moveit_task_constructor_msgs::Solution>(),
80  "The topic on which task solutions (moveit_msgs::Solution messages) are received", this,
81  SLOT(changedTaskSolutionTopic()), this);
82 
83  trajectory_visual_.reset(new TaskSolutionVisualization(this, this));
84  connect(trajectory_visual_.get(), SIGNAL(activeStageChanged(size_t)), task_list_model_.get(),
85  SLOT(highlightStage(size_t)));
86 
87  tasks_property_ = new rviz::Property("Tasks", QVariant(), "Tasks received on monitored topic", this);
88 }
89 
91  if (panel_requested_)
92  TaskPanel::release(); // Indicate that we don't need a TaskPanel anymore
93 }
94 
96  Display::onInitialize();
97  trajectory_visual_->onInitialize(scene_node_, context_);
98  task_list_model_->setDisplayContext(context_);
99 }
100 
101 inline void TaskDisplay::requestPanel() {
102  if (panel_requested_)
103  return; // already done
104 
105  // Create a new TaskPanel if not yet done.
106  // This cannot be done in initialize(), because Panel loading follows Display loading in rviz.
107  panel_requested_ = true;
109 }
110 
113 
114  if (!rdf_loader_->getURDF()) {
115  this->setStatus(rviz::StatusProperty::Error, "Robot Model",
116  "Failed to load from parameter " + robot_description_property_->getString());
117  return;
118  }
119  this->setStatus(rviz::StatusProperty::Ok, "Robot Model", "Successfully loaded");
120 
121  const srdf::ModelSharedPtr& srdf =
122  rdf_loader_->getSRDF() ? rdf_loader_->getSRDF() : srdf::ModelSharedPtr(new srdf::Model());
123  robot_model_.reset(new moveit::core::RobotModel(rdf_loader_->getURDF(), srdf));
124 
125  // Send to child class
126  trajectory_visual_->onRobotModelLoaded(robot_model_);
127  trajectory_visual_->onEnable();
128 
129  // share the planning scene with task models
130  task_list_model_->setScene(trajectory_visual_->getScene());
131 
132  // perform any postponed subscription to topics (after scene is well-defined)
134 }
135 
136 void TaskDisplay::reset() {
137  Display::reset();
138  loadRobotModel();
139  trajectory_visual_->reset();
140 }
141 
142 void TaskDisplay::save(rviz::Config config) const {
143  Display::save(config);
144 }
145 
146 void TaskDisplay::load(const rviz::Config& config) {
147  Display::load(config);
148 }
149 
150 void TaskDisplay::onEnable() {
151  Display::onEnable();
152  loadRobotModel();
154 }
155 
156 void TaskDisplay::onDisable() {
157  Display::onDisable();
158  trajectory_visual_->onDisable();
159 }
160 
162  Display::fixedFrameChanged();
164 }
165 
167  if (!robot_model_)
168  return;
169 
170  Ogre::Vector3 position;
171  Ogre::Quaternion orientation;
172 
173  context_->getFrameManager()->getTransform(robot_model_->getModelFrame(), ros::Time(0), position, orientation);
174 
175  scene_node_->setPosition(position);
176  scene_node_->setOrientation(orientation);
177 }
178 
179 void TaskDisplay::update(float wall_dt, float ros_dt) {
180  requestPanel();
181  Display::update(wall_dt, ros_dt);
183  trajectory_visual_->update(wall_dt, ros_dt);
184 }
185 
186 void TaskDisplay::setName(const QString& name) {
187  BoolProperty::setName(name);
188  trajectory_visual_->setName(name);
189 }
190 
192  if (isEnabled())
193  reset();
194  else
195  loadRobotModel();
196 }
197 
198 void TaskDisplay::taskDescriptionCB(const moveit_task_constructor_msgs::TaskDescriptionConstPtr& msg) {
199  setStatus(rviz::StatusProperty::Ok, "Task Monitor", "OK");
200  requestPanel();
201  task_list_model_->processTaskDescriptionMessage(*msg, update_nh_,
202  base_ns_ + GET_SOLUTION_SERVICE "_" + msg->task_id);
203 
204  // Start listening to other topics if this is the first description
205  // Waiting for the description ensures we do not receive data that cannot be interpreted yet
206  if (!received_task_description_ && !msg->stages.empty()) {
210  }
211 }
212 
213 void TaskDisplay::taskStatisticsCB(const moveit_task_constructor_msgs::TaskStatisticsConstPtr& msg) {
214  setStatus(rviz::StatusProperty::Ok, "Task Monitor", "OK");
215  task_list_model_->processTaskStatisticsMessage(*msg);
216 }
217 
218 void TaskDisplay::taskSolutionCB(const moveit_task_constructor_msgs::SolutionConstPtr& msg) {
219  setStatus(rviz::StatusProperty::Ok, "Task Monitor", "OK");
220  try {
221  const DisplaySolutionPtr& s = task_list_model_->processSolutionMessage(*msg);
222  if (s)
223  trajectory_visual_->showTrajectory(s, false);
224  else
225  setSolutionStatus(false);
226  } catch (const std::invalid_argument& e) {
227  ROS_ERROR_STREAM(e.what());
228  setSolutionStatus(false, e.what());
229  }
230 }
231 
233  // postpone setup until scene is well-defined
234  if (!trajectory_visual_->getScene())
235  return;
236 
240 
242 
243  // generate task monitoring topics from solution topic
244  const QString& solution_topic = task_solution_topic_property_->getString();
245  if (!solution_topic.endsWith(QString("/").append(SOLUTION_TOPIC))) {
246  setStatus(rviz::StatusProperty::Error, "Task Monitor",
247  QString("Invalid topic. Expecting a name ending on \"/%1\"").arg(SOLUTION_TOPIC));
248  return;
249  }
250 
251  base_ns_ = solution_topic.toStdString().substr(0, solution_topic.length() - strlen(SOLUTION_TOPIC));
252 
253  // listen to task descriptions updates
255 
256  setStatus(rviz::StatusProperty::Warn, "Task Monitor", "No messages received");
257 }
258 
259 void TaskDisplay::setSolutionStatus(bool ok, const char* msg) {
260  if (ok)
261  setStatus(rviz::StatusProperty::Ok, "Solution", "Ok");
262  else
263  setStatus(rviz::StatusProperty::Warn, "Solution", msg ? msg : "Retrieval failed");
264 }
265 
266 void TaskDisplay::onTasksInserted(const QModelIndex& parent, int first, int last) {
267  if (parent.isValid())
268  return; // only handle top-level items
269 
270  TaskListModel* m = static_cast<TaskListModel*>(sender());
271  for (; first <= last; ++first) {
272  QModelIndex idx = m->index(first, 0, parent);
273  tasks_property_->addChild(new rviz::Property(idx.data().toString(), idx.sibling(idx.row(), 1).data()), first);
274  }
275 }
276 
277 void TaskDisplay::onTasksRemoved(const QModelIndex& parent, int first, int last) {
278  if (parent.isValid())
279  return; // only handle top-level items
280 
281  for (; first <= last; ++first)
282  delete tasks_property_->takeChildAt(first);
283 
284  trajectory_visual_->reset();
285 }
286 
287 void TaskDisplay::onTaskDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) {
288  if (topLeft.parent().isValid())
289  return; // only handle top-level items
290 
291  for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
292  rviz::Property* child = tasks_property_->childAt(row);
293  assert(child);
294 
295  if (topLeft.column() <= 0 && 0 <= bottomRight.column()) // name changed
296  child->setName(topLeft.sibling(row, 0).data().toString());
297  if (topLeft.column() <= 1 && 1 <= bottomRight.column()) // #solutions changed
298  child->setValue(topLeft.sibling(row, 1).data());
299  }
300 }
301 
302 } // namespace moveit_rviz_plugin
robot_model.h
moveit_rviz_plugin::TaskDisplay::setSolutionStatus
void setSolutionStatus(bool ok, const char *msg="")
Definition: task_display.cpp:291
rviz::Display::isEnabled
bool isEnabled() const
rviz::Property::childAt
Property * childAt(int index) const
rviz::RosTopicProperty
moveit_rviz_plugin::TaskDisplay::trajectory_visual_
std::unique_ptr< TaskSolutionVisualization > trajectory_visual_
Definition: task_display.h:126
marker_visualization.h
rviz::Property::setName
virtual void setName(const QString &name)
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
moveit_rviz_plugin::TaskDisplay::onTaskDataChanged
void onTaskDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
Definition: task_display.cpp:319
rviz::StatusProperty::Error
Error
introspection.h
moveit_rviz_plugin::TaskDisplay::task_statistics_sub
ros::Subscriber task_statistics_sub
Definition: task_display.h:123
s
XmlRpcServer s
moveit_rviz_plugin::MetaTaskListModel::insertModel
bool insertModel(TaskListModel *model, TaskDisplay *display)
insert a new TaskListModel together with it's associated display
Definition: meta_task_list_model.cpp:84
moveit_rviz_plugin::TaskDisplay::robot_description_property_
rviz::StringProperty * robot_description_property_
Definition: task_display.h:141
moveit_rviz_plugin::TaskDisplay::onTasksRemoved
void onTasksRemoved(const QModelIndex &parent, int first, int last)
Definition: task_display.cpp:309
rdf_loader.h
frame_manager.h
moveit::core::RobotModel
moveit_rviz_plugin::TaskDisplay::tasks_property_
rviz::Property * tasks_property_
Definition: task_display.h:143
srdf::ModelSharedPtr
std::shared_ptr< Model > ModelSharedPtr
rviz::Property::addChild
virtual void addChild(Property *child, int index=-1)
ros::Subscriber::shutdown
void shutdown()
STATISTICS_TOPIC
#define STATISTICS_TOPIC
moveit_rviz_plugin::TaskDisplay::task_solution_topic_property_
rviz::RosTopicProperty * task_solution_topic_property_
Definition: task_display.h:142
moveit_rviz_plugin::TaskDisplay::save
void save(rviz::Config config) const override
Definition: task_display.cpp:174
moveit_rviz_plugin::TaskDisplay::taskDescriptionCB
void taskDescriptionCB(const moveit_task_constructor_msgs::TaskDescriptionConstPtr &msg)
Definition: task_display.cpp:230
moveit_rviz_plugin::TaskDisplay::TaskDisplay
TaskDisplay()
Definition: task_display.cpp:94
rviz::Property
moveit_rviz_plugin::TaskDisplay::task_solution_sub
ros::Subscriber task_solution_sub
Definition: task_display.h:121
rviz::Display::setStatus
virtual void setStatus(StatusProperty::Level level, const QString &name, const QString &text)
moveit_rviz_plugin::TaskDisplay::taskStatisticsCB
void taskStatisticsCB(const moveit_task_constructor_msgs::TaskStatisticsConstPtr &msg)
Definition: task_display.cpp:245
moveit_rviz_plugin::TaskDisplay::calculateOffsetPosition
void calculateOffsetPosition()
Definition: task_display.cpp:198
moveit_rviz_plugin::TaskListModel
Definition: task_list_model.h:120
GET_SOLUTION_SERVICE
#define GET_SOLUTION_SERVICE
moveit_rviz_plugin::TaskDisplay::received_task_description_
bool received_task_description_
Definition: task_display.h:138
rviz::Property::setValue
virtual bool setValue(const QVariant &new_value)
rviz::Display::scene_node_
Ogre::SceneNode * scene_node_
moveit_rviz_plugin::TaskDisplay::rdf_loader_
rdf_loader::RDFLoaderPtr rdf_loader_
Definition: task_display.h:132
rviz::StringProperty
rviz::StringProperty::getStdString
std::string getStdString()
rviz::StatusProperty::Ok
Ok
moveit_rviz_plugin::TaskDisplay::onEnable
void onEnable() override
Definition: task_display.cpp:182
rviz::StatusProperty::Warn
Warn
rviz::Property::takeChildAt
virtual Property * takeChildAt(int index)
moveit_rviz_plugin::TaskDisplay::changedRobotDescription
void changedRobotDescription()
Slot Event Functions.
Definition: task_display.cpp:223
moveit_rviz_plugin::TaskDisplay::onInitialize
void onInitialize() override
Definition: task_display.cpp:127
rviz::StringProperty::getString
QString getString()
SOLUTION_TOPIC
#define SOLUTION_TOPIC
rdf_loader::RDFLoader
task_display.h
task_panel.h
moveit_rviz_plugin::TaskDisplay::onDisable
void onDisable() override
Definition: task_display.cpp:188
moveit_rviz_plugin::TaskDisplay::fixedFrameChanged
void fixedFrameChanged() override
Definition: task_display.cpp:193
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
rviz::DisplayContext::getFrameManager
virtual FrameManager * getFrameManager() const=0
moveit_rviz_plugin::TaskPanel::release
static void release()
Definition: task_panel.cpp:201
moveit_rviz_plugin::TaskDisplay::~TaskDisplay
~TaskDisplay() override
Definition: task_display.cpp:122
moveit_rviz_plugin
task_solution_visualization.h
meta_task_list_model.h
rviz::DisplayContext::getWindowManager
virtual WindowManagerInterface * getWindowManager() const=0
rviz::FrameManager::getTransform
bool getTransform(const Header &header, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
m
m
moveit_rviz_plugin::TaskDisplay::taskSolutionCB
void taskSolutionCB(const moveit_task_constructor_msgs::SolutionConstPtr &msg)
Definition: task_display.cpp:250
append
ROSCPP_DECL std::string append(const std::string &left, const std::string &right)
rviz::Display::context_
DisplayContext * context_
task_list_model.h
moveit_rviz_plugin::TaskDisplay::setName
void setName(const QString &name) override
Definition: task_display.cpp:218
moveit_rviz_plugin::TaskDisplay::changedTaskSolutionTopic
void changedTaskSolutionTopic()
Definition: task_display.cpp:264
ros::Time
moveit_rviz_plugin::TaskDisplay::requestPanel
void requestPanel()
Definition: task_display.cpp:133
moveit_rviz_plugin::TaskDisplay::robot_model_
moveit::core::RobotModelConstPtr robot_model_
Definition: task_display.h:133
moveit_rviz_plugin::TaskDisplay::task_list_model_
std::unique_ptr< TaskListModel > task_list_model_
Definition: task_display.h:128
status_property.h
moveit_rviz_plugin::TaskDisplay::update
void update(float wall_dt, float ros_dt) override
Definition: task_display.cpp:211
moveit_rviz_plugin::MetaTaskListModel::instance
static MetaTaskListModel & instance()
Definition: meta_task_list_model.cpp:79
srdf
moveit_rviz_plugin::TaskDisplay::load
void load(const rviz::Config &config) override
Definition: task_display.cpp:178
moveit_rviz_plugin::TaskDisplay::task_description_sub
ros::Subscriber task_description_sub
Definition: task_display.h:122
moveit_rviz_plugin::TaskDisplay::onTasksInserted
void onTasksInserted(const QModelIndex &parent, int first, int last)
Definition: task_display.cpp:298
string_property.h
moveit_rviz_plugin::TaskDisplay::loadRobotModel
void loadRobotModel()
Definition: task_display.cpp:143
moveit_rviz_plugin::TaskDisplay::base_ns_
std::string base_ns_
Definition: task_display.h:136
srdf::Model
moveit_rviz_plugin::TaskDisplay::reset
void reset() override
Definition: task_display.cpp:168
rviz::Config
rviz::Display::update_nh_
ros::NodeHandle update_nh_
ros_topic_property.h
moveit_rviz_plugin::TaskDisplay::panel_requested_
bool panel_requested_
Definition: task_display.h:129
display_solution.h
moveit_rviz_plugin::TaskPanel::request
static void request(rviz::WindowManagerInterface *window_manager)
Definition: task_panel.cpp:188
display_context.h


visualization
Author(s): Robert Haschke
autogenerated on Thu Feb 27 2025 03:39:51