00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <mapviz_plugins/marker_plugin.h>
00031
00032
00033 #include <cmath>
00034 #include <cstdio>
00035 #include <vector>
00036
00037
00038 #include <boost/algorithm/string.hpp>
00039
00040
00041 #include <QDialog>
00042 #include <QGLWidget>
00043
00044
00045 #include <ros/master.h>
00046
00047 #include <mapviz/select_topic_dialog.h>
00048
00049 #include <swri_math_util/constants.h>
00050
00051
00052 #include <pluginlib/class_list_macros.h>
00053 PLUGINLIB_DECLARE_CLASS(
00054 mapviz_plugins,
00055 marker,
00056 mapviz_plugins::MarkerPlugin,
00057 mapviz::MapvizPlugin)
00058
00059 namespace mapviz_plugins
00060 {
00061 #define IS_INSTANCE(msg, type) \
00062 (msg->getDataType() == ros::message_traits::datatype<type>())
00063
00064 MarkerPlugin::MarkerPlugin() :
00065 config_widget_(new QWidget()),
00066 connected_(false)
00067 {
00068 ui_.setupUi(config_widget_);
00069
00070
00071 QPalette p(config_widget_->palette());
00072 p.setColor(QPalette::Background, Qt::white);
00073 config_widget_->setPalette(p);
00074
00075
00076 QPalette p3(ui_.status->palette());
00077 p3.setColor(QPalette::Text, Qt::red);
00078 ui_.status->setPalette(p3);
00079
00080 QObject::connect(ui_.selecttopic, SIGNAL(clicked()), this, SLOT(SelectTopic()));
00081 QObject::connect(ui_.topic, SIGNAL(editingFinished()), this, SLOT(TopicEdited()));
00082
00083 startTimer(1000);
00084 }
00085
00086 MarkerPlugin::~MarkerPlugin()
00087 {
00088 }
00089
00090 void MarkerPlugin::SelectTopic()
00091 {
00092 ros::master::TopicInfo topic = mapviz::SelectTopicDialog::selectTopic(
00093 "visualization_msgs/Marker",
00094 "visualization_msgs/MarkerArray");
00095
00096 if (topic.name.empty())
00097 {
00098 return;
00099 }
00100
00101 ui_.topic->setText(QString::fromStdString(topic.name));
00102 TopicEdited();
00103 }
00104
00105 void MarkerPlugin::TopicEdited()
00106 {
00107 std::string topic = ui_.topic->text().trimmed().toStdString();
00108 if (topic != topic_)
00109 {
00110 initialized_ = false;
00111 markers_.clear();
00112 has_message_ = false;
00113 PrintWarning("No messages received.");
00114
00115 marker_sub_.shutdown();
00116 connected_ = false;
00117
00118 topic_ = topic;
00119 if (!topic.empty())
00120 {
00121 marker_sub_ = node_.subscribe<topic_tools::ShapeShifter>(
00122 topic_, 100, &MarkerPlugin::handleMessage, this);
00123
00124 ROS_INFO("Subscribing to %s", topic_.c_str());
00125 }
00126 }
00127 }
00128
00129 void MarkerPlugin::handleMessage(const topic_tools::ShapeShifter::ConstPtr& msg)
00130 {
00131 connected_ = true;
00132 if (IS_INSTANCE(msg, visualization_msgs::Marker))
00133 {
00134 handleMarker(*(msg->instantiate<visualization_msgs::Marker>()));
00135 }
00136 else if (IS_INSTANCE(msg, visualization_msgs::MarkerArray))
00137 {
00138 handleMarkerArray(*(msg->instantiate<visualization_msgs::MarkerArray>()));
00139 }
00140 else
00141 {
00142 PrintError("Unknown message type: " + msg->getDataType());
00143 }
00144 }
00145
00146 void MarkerPlugin::handleMarker(const visualization_msgs::Marker &marker)
00147 {
00148 if (marker.type == visualization_msgs::Marker::ARROW &&
00149 marker.points.size() == 1)
00150 {
00151
00152
00153 return;
00154 }
00155 if (!has_message_)
00156 {
00157 initialized_ = true;
00158 has_message_ = true;
00159 }
00160
00161
00162
00163
00164
00165
00166 if (marker.action == visualization_msgs::Marker::ADD)
00167 {
00168 MarkerData& markerData = markers_[marker.ns][marker.id];
00169 markerData.stamp = marker.header.stamp;
00170 markerData.display_type = marker.type;
00171 markerData.color = QColor::fromRgbF(marker.color.r, marker.color.g, marker.color.b, marker.color.a);
00172 markerData.scale_x = static_cast<float>(marker.scale.x);
00173 markerData.scale_y = static_cast<float>(marker.scale.y);
00174 markerData.scale_z = static_cast<float>(marker.scale.z);
00175 markerData.transformed = true;
00176 markerData.source_frame = marker.header.frame_id;
00177
00178
00179
00180
00181
00182 tf::Quaternion orientation(0.0, 0.0, 0.0, 1.0);
00183 if (marker.pose.orientation.x ||
00184 marker.pose.orientation.y ||
00185 marker.pose.orientation.z ||
00186 marker.pose.orientation.w)
00187 {
00188 orientation = tf::Quaternion(marker.pose.orientation.x,
00189 marker.pose.orientation.y,
00190 marker.pose.orientation.z,
00191 marker.pose.orientation.w);
00192 }
00193
00194 markerData.local_transform = swri_transform_util::Transform(
00195 tf::Transform(
00196 orientation,
00197 tf::Vector3(marker.pose.position.x,
00198 marker.pose.position.y,
00199 marker.pose.position.z)));
00200
00201 markerData.points.clear();
00202 markerData.text = std::string();
00203
00204 swri_transform_util::Transform transform;
00205 if (!GetTransform(markerData.source_frame, marker.header.stamp, transform))
00206 {
00207 markerData.transformed = false;
00208 PrintError("No transform between " + markerData.source_frame + " and " + target_frame_);
00209 }
00210
00211
00212 ros::Duration lifetime = marker.lifetime;
00213 if (lifetime.isZero())
00214 {
00215 markerData.expire_time = ros::TIME_MAX;
00216 }
00217 else
00218 {
00219
00220 markerData.expire_time = ros::Time::now() + lifetime + ros::Duration(5);
00221 }
00222
00223 if (markerData.display_type == visualization_msgs::Marker::ARROW)
00224 {
00225 StampedPoint point;
00226 point.color = markerData.color;
00227 point.orientation = orientation;
00228
00229 if (marker.points.empty())
00230 {
00231
00232
00233 point.point = markerData.local_transform * tf::Point(0.0, 0.0, 0.0);
00234 point.arrow_point = markerData.local_transform * tf::Point(1.0, 0.0, 0.0);
00235 }
00236 else
00237 {
00238
00239
00240 point.point = markerData.local_transform * tf::Point(marker.points[0].x, marker.points[0].y, marker.points[0].z);
00241 point.arrow_point = markerData.local_transform * tf::Point(marker.points[1].x, marker.points[1].y, marker.points[1].z);
00242 }
00243
00244 markerData.points.push_back(point);
00245
00246 if (!marker.points.empty())
00247 {
00248
00249
00250
00251 markerData.points.push_back(StampedPoint());
00252 }
00253
00254 transformArrow(markerData, transform);
00255 }
00256 else if (markerData.display_type == visualization_msgs::Marker::CYLINDER ||
00257 markerData.display_type == visualization_msgs::Marker::SPHERE ||
00258 markerData.display_type == visualization_msgs::Marker::SPHERE_LIST)
00259 {
00260 StampedPoint point;
00261 point.color = markerData.color;
00262 if (markerData.display_type == visualization_msgs::Marker::CYLINDER ||
00263 markerData.display_type == visualization_msgs::Marker::SPHERE)
00264 {
00265 point.point = tf::Point(0.0, 0.0, 0.0);
00266 point.transformed_point = transform * (markerData.local_transform * point.point);
00267 markerData.points.push_back(point);
00268 }
00269 else
00270 {
00271 Q_FOREACH (const geometry_msgs::Point& markerPoint, marker.points)
00272 {
00273 point.point = tf::Point(markerPoint.x, markerPoint.y, markerPoint.z);
00274 point.transformed_point = transform * (markerData.local_transform * point.point);
00275 markerData.points.push_back(point);
00276 }
00277 }
00278 }
00279 else if (markerData.display_type == visualization_msgs::Marker::CUBE)
00280 {
00281 StampedPoint point;
00282 point.color = markerData.color;
00283
00284 point.point = tf::Point(marker.scale.x / 2, marker.scale.y / 2, 0.0);
00285 point.transformed_point = transform * (markerData.local_transform * point.point);
00286 markerData.points.push_back(point);
00287
00288 point.point = tf::Point(-marker.scale.x / 2, marker.scale.y / 2, 0.0);
00289 point.transformed_point = transform * (markerData.local_transform * point.point);
00290 markerData.points.push_back(point);
00291
00292 point.point = tf::Point(-marker.scale.x / 2, -marker.scale.y / 2, 0.0);
00293 point.transformed_point = transform * (markerData.local_transform * point.point);
00294 markerData.points.push_back(point);
00295
00296 point.point = tf::Point(marker.scale.x / 2, -marker.scale.y / 2, 0.0);
00297 point.transformed_point = transform * (markerData.local_transform * point.point);
00298 markerData.points.push_back(point);
00299 }
00300 else if (markerData.display_type == visualization_msgs::Marker::TEXT_VIEW_FACING)
00301 {
00302 StampedPoint point;
00303 point.point = tf::Point(0.0, 0.0, 0.0);
00304 point.transformed_point = transform * (markerData.local_transform * point.point);
00305 point.color = markerData.color;
00306
00307 markerData.points.push_back(point);
00308 markerData.text = marker.text;
00309 }
00310 else
00311 {
00312 for (unsigned int i = 0; i < marker.points.size(); i++)
00313 {
00314 StampedPoint point;
00315 point.point = tf::Point(marker.points[i].x, marker.points[i].y, marker.points[i].z);
00316 point.transformed_point = transform * (markerData.local_transform * point.point);
00317
00318 if (i < marker.colors.size())
00319 {
00320 point.color = QColor::fromRgbF(
00321 marker.colors[i].r,
00322 marker.colors[i].g,
00323 marker.colors[i].b,
00324 marker.colors[i].a);
00325 }
00326 else
00327 {
00328 point.color = markerData.color;
00329 }
00330
00331 markerData.points.push_back(point);
00332 }
00333 }
00334 }
00335 else
00336 {
00337 markers_[marker.ns].erase(marker.id);
00338 }
00339 }
00340
00348 void MarkerPlugin::transformArrow(MarkerData& markerData,
00349 const swri_transform_util::Transform& transform)
00350 {
00351
00352
00353 StampedPoint& point = markerData.points.front();
00354 tf::Point arrowOffset;
00355 if (markerData.points.size() == 1)
00356 {
00357
00358
00359
00360 point.transformed_point = transform * (markerData.local_transform * point.point);
00361 tf::Transform arrow_tf(tf::Transform(
00362 transform.GetOrientation()) * point.orientation,
00363 tf::Point(0.0, 0.0, 0.0));
00364 point.transformed_arrow_point = point.transformed_point +
00365 arrow_tf * point.arrow_point * markerData.scale_x;
00366 arrowOffset = tf::Point(0.25, 0.0, 0.0);
00367 }
00368 else
00369 {
00370
00371
00372
00373 point.transformed_point = transform * point.point;
00374 point.transformed_arrow_point = transform * point.arrow_point;
00375
00376 arrowOffset = tf::Point(0.25 * markerData.scale_y, 0.0, 0.0);
00377 }
00378
00379 tf::Vector3 pointDiff = point.transformed_arrow_point - point.transformed_point;
00380 double angle = std::atan2(pointDiff.getY(), pointDiff.getX());
00381
00382 tf::Transform left_tf(tf::createQuaternionFromRPY(0, 0, M_PI*0.75 + angle));
00383 tf::Transform right_tf(tf::createQuaternionFromRPY(0, 0, -M_PI*0.75 + angle));
00384
00385 point.transformed_arrow_left = point.transformed_arrow_point + left_tf * arrowOffset;
00386 point.transformed_arrow_right = point.transformed_arrow_point + right_tf * arrowOffset;
00387 }
00388
00389 void MarkerPlugin::handleMarkerArray(const visualization_msgs::MarkerArray &markers)
00390 {
00391 for (unsigned int i = 0; i < markers.markers.size(); i++)
00392 {
00393 handleMarker(markers.markers[i]);
00394 }
00395 }
00396
00397 void MarkerPlugin::PrintError(const std::string& message)
00398 {
00399 if (message == ui_.status->text().toStdString())
00400 {
00401 return;
00402 }
00403
00404 ROS_ERROR("Error: %s", message.c_str());
00405 QPalette p(ui_.status->palette());
00406 p.setColor(QPalette::Text, Qt::red);
00407 ui_.status->setPalette(p);
00408 ui_.status->setText(message.c_str());
00409 }
00410
00411 void MarkerPlugin::PrintInfo(const std::string& message)
00412 {
00413 if (message == ui_.status->text().toStdString())
00414 {
00415 return;
00416 }
00417
00418 ROS_INFO("%s", message.c_str());
00419 QPalette p(ui_.status->palette());
00420 p.setColor(QPalette::Text, Qt::green);
00421 ui_.status->setPalette(p);
00422 ui_.status->setText(message.c_str());
00423 }
00424
00425 void MarkerPlugin::PrintWarning(const std::string& message)
00426 {
00427 if (message == ui_.status->text().toStdString())
00428 {
00429 return;
00430 }
00431
00432 ROS_WARN("%s", message.c_str());
00433 QPalette p(ui_.status->palette());
00434 p.setColor(QPalette::Text, Qt::darkYellow);
00435 ui_.status->setPalette(p);
00436 ui_.status->setText(message.c_str());
00437 }
00438
00439 QWidget* MarkerPlugin::GetConfigWidget(QWidget* parent)
00440 {
00441 config_widget_->setParent(parent);
00442
00443 return config_widget_;
00444 }
00445
00446 bool MarkerPlugin::Initialize(QGLWidget* canvas)
00447 {
00448 canvas_ = canvas;
00449
00450 return true;
00451 }
00452
00453 void MarkerPlugin::Draw(double x, double y, double scale)
00454 {
00455 ros::Time now = ros::Time::now();
00456
00457 std::map<std::string, std::map<int, MarkerData> >::iterator nsIter;
00458 for (nsIter = markers_.begin(); nsIter != markers_.end(); ++nsIter)
00459 {
00460 std::map<int, MarkerData>::iterator markerIter;
00461 for (markerIter = nsIter->second.begin(); markerIter != nsIter->second.end();)
00462 {
00463 MarkerData& marker = markerIter->second;
00464
00465 if (marker.expire_time > now)
00466 {
00467 if (marker.transformed)
00468 {
00469 glColor4d(marker.color.redF(), marker.color.greenF(), marker.color.blueF(), marker.color.alphaF());
00470
00471 if (marker.display_type == visualization_msgs::Marker::ARROW)
00472 {
00473 if (marker.points.size() == 1)
00474 {
00475
00476 glLineWidth(marker.scale_y);
00477 }
00478 else
00479 {
00480
00481
00482 glLineWidth(marker.scale_x);
00483 }
00484 glBegin(GL_LINES);
00485
00486 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00487 for (; point_it != marker.points.end(); ++point_it)
00488 {
00489 glColor4d(
00490 point_it->color.redF(),
00491 point_it->color.greenF(),
00492 point_it->color.blueF(),
00493 point_it->color.alphaF());
00494
00495 glVertex2d(
00496 point_it->transformed_point.getX(),
00497 point_it->transformed_point.getY());
00498 glVertex2d(
00499 point_it->transformed_arrow_point.getX(),
00500 point_it->transformed_arrow_point.getY());
00501 glVertex2d(
00502 point_it->transformed_arrow_point.getX(),
00503 point_it->transformed_arrow_point.getY());
00504 glVertex2d(
00505 point_it->transformed_arrow_left.getX(),
00506 point_it->transformed_arrow_left.getY());
00507 glVertex2d(
00508 point_it->transformed_arrow_point.getX(),
00509 point_it->transformed_arrow_point.getY());
00510 glVertex2d(
00511 point_it->transformed_arrow_right.getX(),
00512 point_it->transformed_arrow_right.getY());
00513 }
00514
00515 glEnd();
00516 }
00517 else if (marker.display_type == visualization_msgs::Marker::LINE_STRIP)
00518 {
00519 glLineWidth(marker.scale_x);
00520 glBegin(GL_LINE_STRIP);
00521
00522 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00523 for (; point_it != marker.points.end(); ++point_it)
00524 {
00525 glColor4d(
00526 point_it->color.redF(),
00527 point_it->color.greenF(),
00528 point_it->color.blueF(),
00529 point_it->color.alphaF());
00530
00531 glVertex2d(
00532 point_it->transformed_point.getX(),
00533 point_it->transformed_point.getY());
00534 }
00535
00536 glEnd();
00537 }
00538 else if (marker.display_type == visualization_msgs::Marker::LINE_LIST)
00539 {
00540 glLineWidth(marker.scale_x);
00541 glBegin(GL_LINES);
00542
00543 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00544 for (; point_it != marker.points.end(); ++point_it)
00545 {
00546 glColor4d(
00547 point_it->color.redF(),
00548 point_it->color.greenF(),
00549 point_it->color.blueF(),
00550 point_it->color.alphaF());
00551
00552 glVertex2d(
00553 point_it->transformed_point.getX(),
00554 point_it->transformed_point.getY());
00555 }
00556
00557 glEnd();
00558 }
00559 else if (marker.display_type == visualization_msgs::Marker::POINTS)
00560 {
00561 glPointSize(marker.scale_x);
00562 glBegin(GL_POINTS);
00563
00564 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00565 for (; point_it != marker.points.end(); ++point_it)
00566 {
00567 glColor4d(
00568 point_it->color.redF(),
00569 point_it->color.greenF(),
00570 point_it->color.blueF(),
00571 point_it->color.alphaF());
00572
00573 glVertex2d(
00574 point_it->transformed_point.getX(),
00575 point_it->transformed_point.getY());
00576 }
00577
00578 glEnd();
00579 }
00580 else if (marker.display_type == visualization_msgs::Marker::TRIANGLE_LIST)
00581 {
00582 glBegin(GL_TRIANGLES);
00583
00584 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00585 for (; point_it != marker.points.end(); ++point_it)
00586 {
00587 glColor4d(
00588 point_it->color.redF(),
00589 point_it->color.greenF(),
00590 point_it->color.blueF(),
00591 point_it->color.alphaF());
00592
00593 glVertex2d(
00594 point_it->transformed_point.getX(),
00595 point_it->transformed_point.getY());
00596 }
00597
00598 glEnd();
00599 }
00600 else if (marker.display_type == visualization_msgs::Marker::CYLINDER ||
00601 marker.display_type == visualization_msgs::Marker::SPHERE ||
00602 marker.display_type == visualization_msgs::Marker::SPHERE_LIST)
00603 {
00604 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00605 for (; point_it != marker.points.end(); ++point_it)
00606 {
00607 glColor4d(
00608 point_it->color.redF(),
00609 point_it->color.greenF(),
00610 point_it->color.blueF(),
00611 point_it->color.alphaF());
00612
00613
00614 glBegin(GL_TRIANGLE_FAN);
00615
00616
00617 double marker_x = point_it->transformed_point.getX();
00618 double marker_y = point_it->transformed_point.getY();
00619
00620 glVertex2d(marker_x, marker_y);
00621
00622 for (int32_t i = 0; i <= 360; i += 10)
00623 {
00624 double radians = static_cast<double>(i) * static_cast<double>(swri_math_util::_deg_2_rad);
00625
00626 if(marker.scale_y == 0.0)
00627 {
00628 marker.scale_y = marker.scale_x;
00629 }
00630 glVertex2d(
00631 marker_x + std::sin(radians) * marker.scale_x,
00632 marker_y + std::cos(radians) * marker.scale_y);
00633 }
00634
00635 glEnd();
00636 }
00637 }
00638 else if (marker.display_type == visualization_msgs::Marker::CUBE ||
00639 marker.display_type == visualization_msgs::Marker::CUBE_LIST)
00640 {
00641 std::list<StampedPoint>::iterator point_it = marker.points.begin();
00642 glBegin(GL_TRIANGLE_FAN);
00643 for (; point_it != marker.points.end(); ++point_it)
00644 {
00645 glColor4d(
00646 point_it->color.redF(),
00647 point_it->color.greenF(),
00648 point_it->color.blueF(),
00649 point_it->color.alphaF());
00650
00651 glVertex2d(point_it->transformed_point.getX(), point_it->transformed_point.getY());
00652 }
00653 glEnd();
00654 }
00655
00656 PrintInfo("OK");
00657 }
00658
00659 ++markerIter;
00660 }
00661 else
00662 {
00663 PrintInfo("OK");
00664 markerIter = nsIter->second.erase(markerIter);
00665 }
00666 }
00667 }
00668 }
00669
00670 void MarkerPlugin::Paint(QPainter* painter, double x, double y, double scale)
00671 {
00672
00673
00674
00675 ros::Time now = ros::Time::now();
00676
00677
00678
00679
00680
00681 QTransform tf = painter->worldTransform();
00682 QFont font("Helvetica", 10);
00683 painter->setFont(font);
00684 painter->save();
00685 painter->resetTransform();
00686
00687 std::map<std::string, std::map<int, MarkerData> >::iterator nsIter;
00688 for (nsIter = markers_.begin(); nsIter != markers_.end(); ++nsIter)
00689 {
00690 std::map<int, MarkerData>::iterator markerIter;
00691 for (markerIter = nsIter->second.begin(); markerIter != nsIter->second.end(); ++markerIter)
00692 {
00693 MarkerData& marker = markerIter->second;
00694
00695 if (marker.display_type != visualization_msgs::Marker::TEXT_VIEW_FACING ||
00696 marker.expire_time <= now ||
00697 !marker.transformed)
00698 {
00699 continue;
00700 }
00701
00702 QPen pen(QBrush(QColor(marker.color.red(), marker.color.green(),
00703 marker.color.blue())), 1);
00704 painter->setPen(pen);
00705
00706 StampedPoint& rosPoint = marker.points.front();
00707 QPointF point = tf.map(QPointF(rosPoint.transformed_point.x(),
00708 rosPoint.transformed_point.y()));
00709 painter->drawText(point, QString(marker.text.c_str()));
00710
00711 PrintInfo("OK");
00712 }
00713 }
00714
00715 painter->restore();
00716 }
00717
00718 void MarkerPlugin::Transform()
00719 {
00720 std::map<std::string, std::map<int, MarkerData> >::iterator nsIter;
00721 for (nsIter = markers_.begin(); nsIter != markers_.end(); ++nsIter)
00722 {
00723 std::map<int, MarkerData>::iterator markerIter;
00724 for (markerIter = nsIter->second.begin(); markerIter != nsIter->second.end(); ++markerIter)
00725 {
00726 MarkerData& marker = markerIter->second;
00727
00728 swri_transform_util::Transform transform;
00729 if (GetTransform(marker.source_frame, marker.stamp, transform))
00730 {
00731 marker.transformed = true;
00732
00733 if (marker.display_type == visualization_msgs::Marker::ARROW)
00734 {
00735
00736
00737 transformArrow(marker, transform);
00738 }
00739 else
00740 {
00741 std::list<StampedPoint>::iterator point_it;
00742 for (point_it = marker.points.begin(); point_it != marker.points.end(); ++point_it)
00743 {
00744 point_it->transformed_point = transform * (marker.local_transform * point_it->point);
00745 }
00746 }
00747 }
00748 else
00749 {
00750 marker.transformed = false;
00751 }
00752 }
00753 }
00754 }
00755
00756 void MarkerPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
00757 {
00758 if (node["topic"])
00759 {
00760 std::string topic;
00761 node["topic"] >> topic;
00762 ui_.topic->setText(boost::trim_copy(topic).c_str());
00763
00764 TopicEdited();
00765 }
00766 }
00767
00768 void MarkerPlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
00769 {
00770 emitter << YAML::Key << "topic" << YAML::Value << boost::trim_copy(ui_.topic->text().toStdString());
00771 }
00772
00773 void MarkerPlugin::timerEvent(QTimerEvent *event)
00774 {
00775 bool new_connected = (marker_sub_.getNumPublishers() > 0);
00776 if (connected_ && !new_connected)
00777 {
00778 marker_sub_.shutdown();
00779 if (!topic_.empty())
00780 {
00781 marker_sub_ = node_.subscribe<topic_tools::ShapeShifter>(
00782 topic_, 100, &MarkerPlugin::handleMessage, this);
00783 }
00784 }
00785 connected_ = new_connected;
00786 }
00787 }
00788