marker_plugin.cpp
Go to the documentation of this file.
00001 // *****************************************************************************
00002 //
00003 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //     * Redistributions of source code must retain the above copyright
00009 //       notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above copyright
00011 //       notice, this list of conditions and the following disclaimer in the
00012 //       documentation and/or other materials provided with the distribution.
00013 //     * Neither the name of Southwest Research Institute® (SwRI®) nor the
00014 //       names of its contributors may be used to endorse or promote products
00015 //       derived from this software without specific prior written permission.
00016 //
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //
00028 // *****************************************************************************
00029 
00030 #include <mapviz_plugins/marker_plugin.h>
00031 
00032 // C++ standard libraries
00033 #include <cmath>
00034 #include <cstdio>
00035 #include <vector>
00036 
00037 // Boost libraries
00038 #include <boost/algorithm/string.hpp>
00039 
00040 // QT libraries
00041 #include <QDialog>
00042 #include <QGLWidget>
00043 
00044 // ROS libraries
00045 #include <ros/master.h>
00046 
00047 #include <mapviz/select_topic_dialog.h>
00048 
00049 #include <swri_math_util/constants.h>
00050 
00051 // Declare plugin
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     // Set background white
00071     QPalette p(config_widget_->palette());
00072     p.setColor(QPalette::Background, Qt::white);
00073     config_widget_->setPalette(p);
00074 
00075     // Set status text red
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       // Arrow markers must have either 0 or >1 points; exactly one point is
00152       // invalid.  If we get one with 1 point, assume it's corrupt and ignore it.
00153       return;
00154     }
00155     if (!has_message_)
00156     {
00157       initialized_ = true;
00158       has_message_ = true;
00159     }
00160 
00161     // Note that unlike some plugins, this one does not store nor rely on the
00162     // source_frame_ member variable.  This one can potentially store many
00163     // messages with different source frames, so we need to store and transform
00164     // them individually.
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       // Since orientation was not implemented, many markers publish
00180       // invalid all-zero orientations, so we need to check for this
00181       // and provide a default identity transform.
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       // Handle lifetime parameter
00212       ros::Duration lifetime = marker.lifetime;
00213       if (lifetime.isZero())
00214       {
00215         markerData.expire_time = ros::TIME_MAX;
00216       }
00217       else
00218       {
00219         // Temporarily add 5 seconds to fix some existing markers.
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           // If the "points" array is empty, we'll use the pose as the base of
00232           // the arrow and scale its size based on the scale_x value.
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           // Otherwise the "points" array should have exactly two values, the
00239           // start and end of the arrow.
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           // The point we just pushed back has both the start and end of the
00249           // arrow, so the point we're pushing here is useless; we use it later
00250           // only to indicate whether the original message had two points or not.
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     // The first point in the markerData.points array always represents the
00352     // base of the arrow.
00353     StampedPoint& point = markerData.points.front();
00354     tf::Point arrowOffset;
00355     if (markerData.points.size() == 1)
00356     {
00357       // If the markerData only has a single point, that means its "point" is
00358       // the base of the arrow and the arrow's angle and length are determined
00359       // by the orientation and scale_x.
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       // If the markerData has two points, that means that the start and end points
00371       // of the arrow were explicitly specified in the original message, so the
00372       // length and angle are determined by them.
00373       point.transformed_point = transform * point.point;
00374       point.transformed_arrow_point = transform * point.arrow_point;
00375       // Also, in this mode, scale_y is the diameter of the arrow's head.
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                 // If the marker only has one point, use scale_y as the arrow width.
00476                 glLineWidth(marker.scale_y);
00477               }
00478               else
00479               {
00480                 // If the marker has both start and end points explicitly specified, use
00481                 // scale_x as the shaft diameter.
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                   // Spheres may be specified w/ only one scale value
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     // Most of the marker drawing is done using OpenGL commands, but text labels
00673     // are rendered using a QPainter.  This is intended primarily as an example
00674     // of how the QPainter works.
00675     ros::Time now = ros::Time::now();
00676 
00677     // We don't want the text to be rotated or scaled, but we do want it to be
00678     // translated appropriately.  So, we save off the current world transform
00679     // and reset it; when we actually draw the text, we'll manually translate
00680     // it to the right place.
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             // Points for the ARROW marker type are stored a bit differently
00736             // than other types, so they have their own special transform case.
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 


mapviz_plugins
Author(s): Marc Alban
autogenerated on Thu Aug 24 2017 02:46:09