MultiRobotInfoVisual.cpp
Go to the documentation of this file.
2 #include <boost/format.hpp>
3 
4 namespace tuw_multi_robot_rviz {
5 
6  using RA = RobotAttributes;
7 
8  RA::RobotAttributes(size_t id,
9  std::string &robot_name,
10  double rad,
11  buf_type &pose,
12  Ogre::ColourValue color,
13  Ogre::SceneManager *_scene_manager,
14  Ogre::SceneNode *_parent_node)
15  : robot_id(id),
16  robot_name(robot_name),
17  scene_manager(_scene_manager),
18  frame_node(_parent_node),
19  robot_radius(rad),
20  color(color),
21  disabled(false),
22  path_stale(true),
23  seg_id_current(0)
24  {
25  updatePose(pose);
26  text = nullptr;
27  arrow = nullptr;
28  circle = nullptr;
29  route = nullptr;
30  sub_route = ros::NodeHandle("").subscribe<tuw_multi_robot_msgs::Route>(robot_name + "/route", 1, boost::bind(&RobotAttributes::cbRoute, this, _1, id));
31  path_length_ = 0;
32  }
33 
35  {
36  //delete circle;
37  //delete arrow;
38  }
39 
40  void RA::render()
41  {
42  //TODO: this needs to be done otherwise rviz crashes when all arrows are painted at position zero (which is a bad indicator for rviz...)
43  if (current_pos.x == 0 && current_pos.y == 0 && current_pos.z == 0)
44  return;
45 
46  if (arrow == nullptr || circle == nullptr)
47  {
48  make_robot();
49  make_route();
50  } else {
51  updateArrow();
52  updateCircle();
53  updateText();
54  }
55  }
56 
57  //only called once! not consecutively
59  {
60  route.reset(new tuw_multi_robot_msgs::Route (*_event.getMessage() ) );
61  }
62 
63  void RA::updateCircle(bool first_time)
64  {
65  if (first_time)
66  circle->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
67  else
68  circle->beginUpdate(0);
69 
70  double accuracy = 20;
71  double factor = 2.0 * M_PI / accuracy;
72 
73  double theta=0.0;
74  unsigned int point_index = 0;
75  for (; theta < 2.0*M_PI; theta += factor) {
76  double s_theta = robot_radius * sin(theta);
77  double c_theta = robot_radius * cos(theta);
78  circle->position(Ogre::Vector3(c_theta,s_theta,0) + current_pos);
79  circle->colour(color);
80  circle->index(point_index++);
81  }
82 
83  circle->index(0);
84  circle->end();
85  }
86 
87  void RA::updateArrow(bool first_time)
88  {
89  if (first_time)
90  arrow->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_TRIANGLE_LIST);
91  else
92  arrow->beginUpdate(0);
93 
94  double accuracy = 3;
95  double factor = 2.0 * M_PI / accuracy;
96 
97  double theta=0.0;
98  unsigned int point_index = 0;
99  for (; point_index < accuracy; theta += factor) {
100  double s_theta = robot_radius * sin(theta);
101  double c_theta = robot_radius * cos(theta);
102  Ogre::Vector3 local_pose = Ogre::Vector3(c_theta, s_theta, 0);
103  Ogre::Matrix3 r_orient;
104  current_orient.ToRotationMatrix(r_orient);
105  local_pose = r_orient * local_pose;
106  if (point_index==0)
107  {
108  theta +=0.5;
109  } else if (point_index==1)
110  {
111  theta -=1.0;
112  }
113  arrow->position(local_pose + current_pos);
114  arrow->colour(color);
115  arrow->index(point_index++);
116  }
117  arrow->triangle(0,1,2);
118 
119  arrow->index(0);
120  arrow->end();
121  }
122 
124  {
125  if (text == nullptr)
126  {
127  updateText(true);
128  }
129  else
130  {
131  updateText(false);
132  }
133  }
134 
135  void RA::updateText(bool first_time)
136  {
137 
138  if (first_time)
139  {
141  text->setCharacterHeight(0.2);
142  }
143 
144  std::string capt = (boost::format("%d: %.2f") % this->robot_id % this->getPathLength()).str();
145  text->setCaption(capt);
146  text->setPosition(current_pos - Ogre::Vector3(0.25,0.25,0));
147 
148  }
149 
151  {
152  arrow = this->scene_manager->createManualObject("r_arrow_" + std::to_string(robot_id));
153  circle = this->scene_manager->createManualObject("r_circle_" + std::to_string(robot_id));
154 
155  //Arrow
156  {
157  updateArrow(true);
158 
159  frame_node->createChildSceneNode()->attachObject(arrow);
160  }
161 
162  //Circle
163  {
164  updateCircle(true);
165 
166  frame_node->createChildSceneNode()->attachObject(circle);
167  }
168  }
169 
170  MultiRobotInfoVisual::MultiRobotInfoVisual(Ogre::SceneManager* _scene_manager, Ogre::SceneNode* _parent_node) : scene_manager_(_scene_manager), frame_node_(_parent_node->createChildSceneNode())
171  {
173  }
174 
176  {
177  scene_manager_->destroySceneNode(frame_node_);
178  }
179 
181  {
182  recycle_thresh_ = newDur;
183  }
184 
186  {
187  default_size_ = c;
188  for (auto &it : robot2attribute_map_)
189  {
190  it.second->setPoseBufferLength(default_size_);
191  }
192  }
193 
194  std::vector<std::string> MultiRobotInfoVisual::recycle()
195  {
196  std::vector<std::string> mark_for_deletion;
197  auto ts_now = ros::Time::now();
198  for (auto &elem : recycle_map_)
199  {
200  auto dur = ts_now - elem.second;
201  if (dur > recycle_thresh_)
202  {
203  mark_for_deletion.push_back(elem.first);
204  }
205  }
206 
207  for (const std::string &elem : mark_for_deletion)
208  {
209  auto it_pose = robot2attribute_map_.find(elem);
210  if (it_pose != robot2attribute_map_.end())
211  {
212  robot2attribute_map_.erase(it_pose);
213  }
214 
215  auto it_rcle = recycle_map_.find(elem);
216  if (it_rcle != recycle_map_.end())
217  {
218  recycle_map_.erase(it_rcle);
219  }
220  }
221 
222  return std::move(mark_for_deletion);
223  }
224 
225  void MultiRobotInfoVisual::enableRobot(const std::string &rName)
226  {
227  auto it = disabled_robots_.find(rName);
228  if (it != disabled_robots_.end())
229  {
230  disabled_robots_.erase(it);
231  }
232  }
233 
234  void MultiRobotInfoVisual::disableRobot(const std::string &rName)
235  {
236  disabled_robots_.insert(rName);
237  auto it = robot2attribute_map_.find(rName);
238  if (robot2attribute_map_.end() != it)
239  {
240  //No need for detach objects call since this is handled in the SceneNode destructor
241  it->second->setDisabled();
242  }
243  }
244 
246  {
247  for (map_iterator it = robot2attribute_map_.begin(); it != robot2attribute_map_.end(); ++it)
248  {
249 
250  if (disabled_robots_.find(it->first) != disabled_robots_.end())
251  {
252  return;
253  }
254 
255  //TODO: for now only the last pose is shown
256  it->second->render();
257 
258  } //end for
259 
261  }
262 
263  void MultiRobotInfoVisual::setMessage(const tuw_multi_robot_msgs::RobotInfoConstPtr _msg)
264  {
265  map_iterator it = robot2attribute_map_.find(_msg->robot_name);
266  if (it == robot2attribute_map_.end())
267  {
268  double robot_radius = _msg->shape_variables.size() ? _msg->shape_variables[0] : 1.0;
269  boost::circular_buffer<geometry_msgs::PoseWithCovariance> pose;
270  pose.set_capacity(default_size_);
271  std::string rn = _msg->robot_name;
272  std::shared_ptr<RA> robot_attr = std::make_shared<RA>(id_cnt++,
273  rn,
274  robot_radius,
275  pose,
276  color_pose_,
278  frame_node_);
279 
280  robot2attribute_map_.insert(internal_map_type(rn, robot_attr));
281  it = robot2attribute_map_.find(_msg->robot_name);
282 
283  recycle_map_.insert(std::pair<std::string, ros::Time>(_msg->robot_name, ros::Time(0)));
284  }
285 
286  it->second->updatePose(_msg->pose);
287  it->second->robot_radius = _msg->shape_variables.size() ? _msg->shape_variables[0] : 1.0;
288 
290  {
291  doRender();
292  }
293  }
294 
295  void MultiRobotInfoVisual::setFramePosition(const Ogre::Vector3& position)
296  {
297  frame_node_->setPosition(position);
298  }
299 
300  void MultiRobotInfoVisual::setFrameOrientation(const Ogre::Quaternion& orientation)
301  {
302  frame_node_->setOrientation(orientation);
303  }
304 
306  {
307  //for (auto &it : robot_renderings_map_)
308  //{
309  // //for (auto &renderings : it.second)
310  // //{
311  // // renderings->setScale(Ogre::Vector3(scale,scale,scale));
312  // //}
313  //}
314  }
315 
316  void MultiRobotInfoVisual::setColorPose(Ogre::ColourValue color)
317  {
318  color_pose_ = color;
319  for (auto &it : robot2attribute_map_)
320  {
321  it.second->updateColor(color);
322  }
323  }
324 }
std::map< std::string, std::shared_ptr< RobotAttributes > >::iterator map_iterator
std::unique_ptr< TextVisual > text
boost::shared_ptr< M > getMessage() const
void setMessage(const tuw_multi_robot_msgs::RobotInfoConstPtr _msg)
void updatePose(const geometry_msgs::PoseWithCovariance &pose)
std::shared_ptr< tuw_multi_robot_msgs::Route > route
boost::circular_buffer< geometry_msgs::PoseWithCovariance > buf_type
RobotAttributes(size_t id, std::string &rname, double rad, buf_type &pose, Ogre::ColourValue color, Ogre::SceneManager *_scene_manager, Ogre::SceneNode *_parent_node)
void setFramePosition(const Ogre::Vector3 &_position)
void updateCircle(bool first_time=false)
std::pair< std::string, std::shared_ptr< RobotAttributes > > internal_map_type
MultiRobotInfoVisual(Ogre::SceneManager *_scene_manager, Ogre::SceneNode *_parent_node)
void cbRoute(const ros::MessageEvent< const tuw_multi_robot_msgs::Route > &_event, int _topic)
static Time now()
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
void setFrameOrientation(const Ogre::Quaternion &orientation)


tuw_multi_robot_rviz
Author(s): Benjamin Binder
autogenerated on Mon Feb 28 2022 23:57:45