overlay_diagnostic_display.cpp
Go to the documentation of this file.
00001 // -*- mode: c++; -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2014, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 
00036 #include "overlay_diagnostic_display.h"
00037 
00038 #include <OGRE/OgreMaterialManager.h>
00039 #include <OGRE/OgreTextureManager.h>
00040 #include <OGRE/OgreTexture.h>
00041 #include <OGRE/OgreHardwarePixelBuffer.h>
00042 #include <OGRE/OgreTechnique.h>
00043 
00044 #include <rviz/uniform_string_stream.h>
00045 #include <rviz/display_context.h>
00046 #include <rviz/view_manager.h>
00047 #include <rviz/render_panel.h>
00048 
00049 namespace jsk_rviz_plugins
00050 {
00051   const double overlay_diagnostic_animation_duration = 5.0;
00052   const double overlay_diagnostic_animation_transition_duration = 0.2;
00053   OverlayDiagnosticDisplay::OverlayDiagnosticDisplay()
00054     : previous_state_(STALL_STATE), Display()
00055   {
00056     ros_topic_property_ = new rviz::RosTopicProperty(
00057       "Topic", "/diagnostics_agg",
00058       ros::message_traits::datatype<diagnostic_msgs::DiagnosticArray>(),
00059       "diagnostic_msgs::DiagnosticArray topic to subscribe to.",
00060       this, SLOT( updateRosTopic() ));
00061     diagnostics_namespace_property_ = new rviz::EditableEnumProperty(
00062       "diagnostics namespace", "/",
00063       "diagnostics namespace to visualize diagnostics",
00064       this, SLOT(updateDiagnosticsNamespace()));
00065     type_property_ = new rviz::EnumProperty(
00066       "type", "SAC", "Type of visualization", this, SLOT(updateType()));
00067     type_property_->addOptionStd("SAC", 0);
00068     type_property_->addOptionStd("EVA", 1);
00069     top_property_ = new rviz::IntProperty(
00070       "top", 128,
00071       "top positoin",
00072       this, SLOT(updateTop()));
00073     left_property_ = new rviz::IntProperty(
00074       "left", 128,
00075       "left positoin",
00076       this, SLOT(updateLeft()));
00077     size_property_ = new rviz::IntProperty(
00078       "size", 128,
00079       "size of the widget",
00080       this, SLOT(updateSize()));
00081     size_property_->setMin(1);
00082     alpha_property_ = new rviz::FloatProperty(
00083       "alpha", 0.8,
00084       "alpha value",
00085       this, SLOT(updateAlpha()));
00086     alpha_property_->setMin(0.0);
00087     alpha_property_->setMax(1.0);
00088     stall_duration_property_ = new rviz::FloatProperty(
00089       "stall duration", 5.0,
00090       "seconds to be regarded as stalled",
00091       this, SLOT(updateStallDuration())
00092       );
00093     stall_duration_property_->setMin(0.0);
00094   }
00095 
00096   OverlayDiagnosticDisplay::~OverlayDiagnosticDisplay()
00097   {
00098     if (overlay_) {
00099       overlay_->hide();
00100     }
00101     // panel_material_->unload();
00102     // Ogre::MaterialManager::getSingleton().remove(panel_material_->getName());
00103     delete ros_topic_property_;
00104     delete diagnostics_namespace_property_;
00105     delete top_property_;
00106     delete left_property_;
00107     delete alpha_property_;
00108     delete size_property_;
00109     delete type_property_;
00110   }
00111 
00112   void OverlayDiagnosticDisplay::processMessage(
00113     const diagnostic_msgs::DiagnosticArray::ConstPtr& msg)
00114   {
00115     boost::mutex::scoped_lock(mutex_);
00116     //std::make_shared<diagnostic_msgs::DiagnosticStatus>
00117     // update namespaces_ if needed
00118     std::set<std::string> new_namespaces;
00119     for (size_t i = 0; i < msg->status.size(); i++) {
00120       new_namespaces.insert(msg->status[i].name);
00121     }
00122     
00123     std::set<std::string> difference_namespaces;
00124     std::set_difference(namespaces_.begin(), namespaces_.end(),
00125                         new_namespaces.begin(), new_namespaces.end(),
00126                         std::inserter(difference_namespaces,
00127                                       difference_namespaces.end()));
00128     if (difference_namespaces.size() != 0) {
00129       namespaces_ = new_namespaces;
00130       fillNamespaceList();
00131     }
00132     else {
00133       difference_namespaces.clear();
00134       std::set_difference(new_namespaces.begin(), new_namespaces.end(),
00135                           namespaces_.begin(), namespaces_.end(),
00136                           std::inserter(difference_namespaces,
00137                                         difference_namespaces.end()));
00138       if (difference_namespaces.size() != 0) {
00139         namespaces_ = new_namespaces;
00140         fillNamespaceList();
00141       }
00142     }
00143     
00144     if (diagnostics_namespace_.length() == 0) {
00145       return;
00146     }
00147 
00148     for (size_t i = 0; i < msg->status.size(); i++) {
00149       diagnostic_msgs::DiagnosticStatus status = msg->status[i];
00150       if (status.name == diagnostics_namespace_) {
00151         latest_status_
00152           = std::make_shared<diagnostic_msgs::DiagnosticStatus>(status);
00153         latest_message_time_ = ros::WallTime::now();
00154         break;
00155       }
00156     }
00157   }
00158 
00159   void OverlayDiagnosticDisplay::update(float wall_dt, float ros_dt)
00160   {
00161     boost::mutex::scoped_lock(mutex_);
00162     if (!isEnabled()) {
00163       return;
00164     }
00165     if (!overlay_) {
00166       static int count = 0;
00167       rviz::UniformStringStream ss;
00168       ss << "OverlayDiagnosticDisplayObject" << count++;
00169       overlay_.reset(new OverlayObject(ss.str()));
00170       overlay_->show();
00171       animation_start_time_ = ros::WallTime::now();
00172     }
00173     t_ += wall_dt;
00174 
00175     // check if the widget should animate
00176     if (!is_animating_) {
00177       if (previous_state_ != getLatestState()) {
00178         is_animating_ = true;
00179         animation_start_time_ = ros::WallTime::now();
00180       }
00181     }
00182     else {
00183       if (!isAnimating()) {     // animation time is over
00184         is_animating_ = false;
00185         previous_state_ = getLatestState();
00186       }
00187     }
00188     
00189     overlay_->updateTextureSize(size_, size_);
00190     redraw();
00191     overlay_->setDimensions(overlay_->getTextureWidth(),
00192                             overlay_->getTextureHeight());
00193     overlay_->setPosition(left_, top_);
00194     t_ = fmod(t_, overlay_diagnostic_animation_duration);
00195   }
00196 
00197   bool OverlayDiagnosticDisplay::isAnimating()
00198   {
00199     return ((ros::WallTime::now() - animation_start_time_).toSec() < overlay_diagnostic_animation_transition_duration);
00200   }
00201   
00202   double OverlayDiagnosticDisplay::animationRate()
00203   {
00204     return ((ros::WallTime::now() - animation_start_time_).toSec() / overlay_diagnostic_animation_transition_duration);
00205   }
00206   
00207   void OverlayDiagnosticDisplay::onEnable()
00208   {
00209     t_ = 0.0;
00210     if (overlay_) {
00211       overlay_->show();
00212     }
00213     subscribe();
00214   }
00215 
00216   void OverlayDiagnosticDisplay::onDisable()
00217   {
00218     ROS_INFO("onDisable");
00219     if (overlay_) {
00220       overlay_->hide();
00221     }
00222     unsubscribe();
00223   }
00224 
00225   void OverlayDiagnosticDisplay::onInitialize()
00226   {
00227     
00228     ROS_DEBUG("onInitialize");
00229     updateType();
00230     updateDiagnosticsNamespace();
00231     updateSize();
00232     updateAlpha();
00233     updateLeft();
00234     updateTop();
00235     updateStallDuration();
00236     updateRosTopic();
00237   }
00238   
00239   void OverlayDiagnosticDisplay::unsubscribe()
00240   {
00241     sub_.shutdown();
00242   }
00243   
00244   void OverlayDiagnosticDisplay::subscribe()
00245   {
00246     ros::NodeHandle n;
00247     sub_ = n.subscribe(ros_topic_property_->getTopicStd(),
00248                        1,
00249                        &OverlayDiagnosticDisplay::processMessage,
00250                        this);
00251   }
00252 
00253   bool OverlayDiagnosticDisplay::isStalled()
00254   {
00255     if (latest_status_) {
00256       ros::WallDuration message_duration
00257         = ros::WallTime::now() - latest_message_time_;
00258       if (message_duration.toSec() < stall_duration_) {
00259         return false;
00260       }
00261       else {
00262         return true;
00263       }
00264     }
00265     else {
00266       return true;
00267     }
00268   }
00269   
00270   std::string OverlayDiagnosticDisplay::statusText()
00271   {
00272     if (latest_status_) {
00273       if (!isStalled()) {
00274         if (latest_status_->level == diagnostic_msgs::DiagnosticStatus::OK) {
00275           return "OK";
00276         }
00277         else if (latest_status_->level == diagnostic_msgs::DiagnosticStatus::WARN) {
00278           return "WARN";
00279         }
00280         else if (latest_status_->level == diagnostic_msgs::DiagnosticStatus::ERROR) {
00281           return "ERROR";
00282         }
00283         else {
00284           return "UNKNOWN";
00285         }
00286       }
00287       else {
00288         return "UNKNOWN";
00289       }
00290     }
00291     else {
00292       return "UNKNOWN";
00293     }
00294   }
00295   
00296   OverlayDiagnosticDisplay::State
00297   OverlayDiagnosticDisplay::getLatestState()
00298   {
00299     if (latest_status_) {
00300       if (!isStalled()) {
00301         if (latest_status_->level == diagnostic_msgs::DiagnosticStatus::OK) {
00302           return OK_STATE;
00303         }
00304         else if (latest_status_->level
00305                  == diagnostic_msgs::DiagnosticStatus::WARN) {
00306           return WARN_STATE;
00307         }
00308         else if (latest_status_->level
00309                  == diagnostic_msgs::DiagnosticStatus::ERROR) {
00310           return ERROR_STATE;
00311         }
00312         else {
00313           return STALL_STATE;
00314         }
00315       }
00316       else {
00317         return STALL_STATE;
00318       }
00319     }
00320     else {
00321       return STALL_STATE;
00322     } 
00323   }
00324 
00325   QColor OverlayDiagnosticDisplay::foregroundColor()
00326   {
00327     QColor ok_color(25, 255, 240, alpha_ * 255.0);
00328     QColor warn_color(240, 173, 78, alpha_ * 255.0);
00329     QColor error_color(217, 83, 79, alpha_ * 255.0);
00330     QColor stall_color(151, 151, 151, alpha_ * 255.0);
00331     //QColor fg_color = stall_color;
00332     State state = getLatestState();
00333     if (state == OK_STATE) {
00334       return ok_color;
00335     }
00336     else if (state == WARN_STATE) {
00337       return warn_color;
00338     }
00339     else if (state == ERROR_STATE) {
00340       return error_color;
00341     }
00342     else {
00343       return stall_color;
00344     }
00345   }
00346 
00347   QColor OverlayDiagnosticDisplay::textColor()
00348   {
00349     QColor ok_color(40, 40, 40,  alpha_ * 255.0);
00350     QColor warn_color(255, 255, 255, alpha_ * 255.0);
00351     QColor error_color(240, 173, 78, alpha_ * 255.0);
00352     QColor stall_color(240, 173, 78, alpha_ * 255.0);
00353     //QColor fg_color = stall_color;
00354     State state = getLatestState();
00355     if (state == OK_STATE) {
00356       return ok_color;
00357     }
00358     else if (state == WARN_STATE) {
00359       return warn_color;
00360     }
00361     else if (state == ERROR_STATE) {
00362       return error_color;
00363     }
00364     else {
00365       return stall_color;
00366     }
00367   }
00368 
00369 
00370   
00371   QColor OverlayDiagnosticDisplay::blendColor(QColor a, QColor b, double a_rate) {
00372     QColor ret (a.red() * a_rate + b.red() * (1 - a_rate),
00373                 a.green() * a_rate + b.green() * (1 - a_rate),
00374                 a.blue() * a_rate + b.blue() * (1 - a_rate),
00375                 a.alpha() * a_rate + b.alpha() * (1 - a_rate));
00376     return ret;
00377   }
00378 
00379   double OverlayDiagnosticDisplay::textWidth(QPainter& painter, double font_size, const std::string& text)
00380   {
00381     painter.save();
00382     const double r = size_ / 128.0;
00383     QFont font("Liberation Sans", font_size * r, font_size * r, QFont::Bold);
00384     QPen pen;
00385     QPainterPath path;
00386     pen.setWidth(1);
00387     painter.setFont(font);
00388     painter.setPen(pen);
00389     QFontMetrics metrics(font);
00390     const int text_width = metrics.width(text.c_str());
00391     const int text_height = metrics.height();
00392     painter.restore();
00393     return text_width;
00394   }
00395 
00396   double OverlayDiagnosticDisplay::textHeight(QPainter& painter, double font_size)
00397   {
00398     painter.save();
00399     const double r = size_ / 128.0;
00400     QFont font("Liberation Sans", font_size * r, font_size * r, QFont::Bold);
00401     QPen pen;
00402     QPainterPath path;
00403     pen.setWidth(1);
00404     painter.setFont(font);
00405     painter.setPen(pen);
00406     QFontMetrics metrics(font);
00407     const int text_height = metrics.height();
00408     painter.restore();
00409     return text_height;
00410   }
00411   
00412   
00413   double OverlayDiagnosticDisplay::drawAnimatingText(QPainter& painter,
00414                                                      QColor fg_color,
00415                                                      const double height,
00416                                                      const double font_size,
00417                                                      const std::string text)
00418   {
00419     const double r = size_ / 128.0;
00420     QFont font("Liberation Sans", font_size * r, font_size * r, false);
00421     QPen pen;
00422     QPainterPath path;
00423     pen.setWidth(1);
00424     pen.setColor(blendColor(fg_color, Qt::white, 0.5));
00425     painter.setFont(font);
00426     painter.setPen(pen);
00427     painter.setBrush(fg_color);
00428     QFontMetrics metrics(font);
00429     const int text_width = metrics.width(text.c_str());
00430     const int text_height = metrics.height();
00431     if (overlay_->getTextureWidth() > text_width) {
00432       path.addText((overlay_->getTextureWidth() - text_width) / 2.0,
00433                    height,
00434                    font, text.c_str());
00435     }
00436     else {
00437       double left = - fmod(t_, overlay_diagnostic_animation_duration) /
00438         overlay_diagnostic_animation_duration * text_width * 2 + text_width;
00439       path.addText(left, height, font, text.c_str());
00440     }
00441     painter.drawPath(path);
00442     return text_height;
00443   }
00444   
00445   void OverlayDiagnosticDisplay::drawText(QPainter& painter, QColor fg_color,
00446                                           const std::string& text)
00447   {
00448     double status_size = drawAnimatingText(painter, fg_color,
00449                                            overlay_->getTextureHeight() / 3.0,
00450                                            20, text);
00451     double namespace_size = drawAnimatingText(painter, fg_color,
00452                                               overlay_->getTextureHeight() / 3.0 + status_size,
00453                                               10, diagnostics_namespace_);
00454     std::string message;
00455     if (latest_status_) {
00456       if (!isStalled()) {
00457         message = latest_status_->message;
00458       }
00459       else {
00460         message = "stalled";
00461       }
00462     }
00463     else {
00464       message = "stalled";
00465     }
00466     drawAnimatingText(painter, fg_color,
00467                       overlay_->getTextureHeight() / 3.0
00468                       + status_size + namespace_size,
00469                       10, message);
00470   }
00471 
00472   void OverlayDiagnosticDisplay::drawSAC(QImage& Hud)
00473   {
00474     QColor fg_color = foregroundColor();
00475     // draw outer circle
00476     // line-width - margin - inner-line-width < size
00477     QPainter painter( &Hud );
00478     const int line_width = 10;
00479     const int margin = 10;
00480     const int inner_line_width = 20;
00481     
00482     painter.setRenderHint(QPainter::Antialiasing, true);
00483     painter.setPen(QPen(fg_color, line_width, Qt::SolidLine));
00484     painter.drawEllipse(line_width / 2, line_width / 2,
00485                         overlay_->getTextureWidth() - line_width,
00486                         overlay_->getTextureHeight() - line_width);
00487     
00488     painter.setPen(QPen(fg_color, inner_line_width, Qt::SolidLine));    
00489     const double start_angle = fmod(t_, overlay_diagnostic_animation_duration) /
00490       overlay_diagnostic_animation_duration * 360;
00491     const double draw_angle = 250;
00492     const double inner_circle_start
00493       = line_width + margin + inner_line_width / 2.0;
00494     drawText(painter, fg_color, statusText());
00495   }
00496 
00497   void OverlayDiagnosticDisplay::drawEVAConnectedRectangle(QPainter& painter,
00498                                                            QColor color,
00499                                                            QColor small_color,
00500                                                            int width)
00501   {
00502     double S = size_;
00503     double A = S * 0.1;
00504     double B = 0.2 * S;
00505     double C = 0.2;
00506     painter.setPen(QPen(color, width, Qt::SolidLine));
00507     QPainterPath large_rectangle_path;
00508     large_rectangle_path.moveTo(A, S - B);
00509     large_rectangle_path.lineTo(A, S);
00510     large_rectangle_path.lineTo(S, B);
00511     large_rectangle_path.lineTo(S, 0);
00512     painter.setPen(Qt::NoPen);
00513     painter.fillPath(large_rectangle_path, QBrush(color));
00514     QPainterPath small_rectangle_path;
00515     small_rectangle_path.moveTo(A, S - B);
00516     small_rectangle_path.lineTo(A, S - B + C * B);
00517     small_rectangle_path.lineTo(A + (S - A) * C, S - B + C * B - (S - B) * C);
00518     small_rectangle_path.lineTo(A + (S - A) * C, S - B - (S - B) * C);
00519     painter.setPen(Qt::NoPen);
00520     painter.fillPath(small_rectangle_path, QBrush(small_color));
00521   }
00522 
00523   void OverlayDiagnosticDisplay::drawEVANonConnectedRectangle(QPainter& painter,
00524                                                               QColor color,
00525                                                               QColor small_color,
00526                                                               int width,
00527                                                               double D)
00528   {
00529     double S = size_;
00530     double A = S * 0.1;
00531     double B = 0.2 * S;
00532     double C = 0.2;
00533     //double D = 0.05 * S;
00534     painter.setPen(QPen(color, width, Qt::SolidLine));
00535     QPainterPath large_rectangle_path;
00536     large_rectangle_path.moveTo(A, S - B);
00537     large_rectangle_path.lineTo(A, S);
00538     double r0 = (S - A - D) / 2 / (S - A);
00539     large_rectangle_path.lineTo(A + (S - A - D) / 2, S - r0 * (S - B));
00540     large_rectangle_path.lineTo(A + (S - A - D) / 2, S - r0 * (S - B) - B);
00541     painter.setPen(Qt::NoPen);
00542     painter.fillPath(large_rectangle_path, QBrush(color));
00543 
00544     QPainterPath large_rectangle_path2;
00545     large_rectangle_path2.moveTo(S - (S - A - D) / 2, (S - B) * r0);
00546     large_rectangle_path2.lineTo(S - (S - A - D) / 2, (S - B) * r0 + B);
00547     large_rectangle_path2.lineTo(S, B);
00548     large_rectangle_path2.lineTo(S, 0);
00549     painter.setPen(Qt::NoPen);
00550     painter.fillPath(large_rectangle_path2, QBrush(color));
00551     
00552     QPainterPath small_rectangle_path;
00553     small_rectangle_path.moveTo(A, S - B);
00554     small_rectangle_path.lineTo(A, S - B + C * B);
00555     small_rectangle_path.lineTo(A + (S - A) * C, S - B + C * B - (S - B) * C);
00556     small_rectangle_path.lineTo(A + (S - A) * C, S - B - (S - B) * C);
00557     painter.setPen(Qt::NoPen);
00558     painter.fillPath(small_rectangle_path, QBrush(small_color));
00559   }
00560   
00561   void OverlayDiagnosticDisplay::drawEVA(QImage& Hud)
00562   {
00563     QColor line_color(240, 173, 78, alpha_ * 255.0);
00564     QColor rectangle_color = foregroundColor();
00565     QColor small_rectangle_color(line_color);
00566     QPainter painter(&Hud);
00567     State close_state = OK_STATE;
00568     int line_width = 2;
00569     double S = size_;
00570     double A = S * 0.1;
00571     double B = 0.2 * S;
00572     double C = 0.2;
00573     double max_gap = 0.05 * S;
00574     painter.setRenderHint(QPainter::Antialiasing, true);
00575     painter.setPen(QPen(line_color, line_width, Qt::SolidLine));
00576     painter.drawLine(QPoint(0, 0), QPoint(0, S));
00577     painter.drawLine(QPoint(0, S - B / 2), QPoint(A, S - B / 2));
00578     if (isAnimating()) {
00579       // check animation direction
00580       double r = animationRate();
00581       if (previous_state_ == close_state) { // close -> open
00582         drawEVANonConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width, max_gap * r);
00583       }
00584       else if (getLatestState() == close_state) { // open -> close
00585         drawEVANonConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width, max_gap * (1 - r));
00586       }
00587       else {                    // open -> open
00588         drawEVANonConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width, max_gap);
00589       }
00590     }
00591     else {
00592       State state = getLatestState();
00593       if (state == close_state) {
00594         drawEVAConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width);
00595       }
00596       else {
00597         drawEVANonConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width, max_gap);
00598       }
00599     }
00600     painter.setPen(QPen(textColor(), 2 * line_width, Qt::SolidLine));
00601     painter.setFont(QFont("Liberation Sans", 12, QFont::Bold));
00602     double theta = atan2(S - B, S - A) / M_PI * 180;
00603     double text_box_height = cos(theta*M_PI/180) * B;
00604     double text_box_width = (S - A) / cos(theta*M_PI/180) - sin(theta*M_PI/180) * B * 2;
00605     double text_width = textWidth(painter, 12, diagnostics_namespace_);
00606     
00607     painter.translate(A, S - B);
00608     painter.rotate(-theta);
00609     if (text_width > text_box_width) {
00610       double text_left = - fmod(t_, overlay_diagnostic_animation_duration) /
00611         overlay_diagnostic_animation_duration * text_width;
00612       painter.drawText(QRectF(text_left, 0, text_width*2, text_box_height), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
00613                        diagnostics_namespace_.c_str());
00614     }
00615     else {
00616       painter.drawText(QRectF(0, 0, text_box_width, text_box_height), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
00617                        diagnostics_namespace_.c_str());
00618     }
00619   }
00620   
00621   void OverlayDiagnosticDisplay::redraw()
00622   {
00623     ScopedPixelBuffer buffer = overlay_->getBuffer();
00624     QColor transparent(0, 0, 0, 0.0);    
00625     QImage Hud = buffer.getQImage(*overlay_, transparent);
00626     if (type_ == 0) {
00627       drawSAC(Hud);
00628     }
00629     else if (type_ == 1) {
00630       drawEVA(Hud);
00631     }
00632   }
00633 
00634   void OverlayDiagnosticDisplay::fillNamespaceList()
00635   {
00636     //QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
00637     diagnostics_namespace_property_->clearOptions();
00638     for (std::set<std::string>::iterator it = namespaces_.begin();
00639          it != namespaces_.end();
00640          it++) {
00641       diagnostics_namespace_property_->addOptionStd(*it);
00642     }
00643     diagnostics_namespace_property_->sortOptions();
00644   }
00645   
00646   void OverlayDiagnosticDisplay::updateRosTopic()
00647   {
00648     latest_status_.reset();
00649     unsubscribe();
00650     subscribe();
00651   }
00652 
00653   void OverlayDiagnosticDisplay::updateDiagnosticsNamespace()
00654   {
00655     latest_status_.reset();
00656     diagnostics_namespace_ = diagnostics_namespace_property_->getStdString();
00657   }
00658   
00659   void OverlayDiagnosticDisplay::updateSize()
00660   {
00661     size_ = size_property_->getInt();
00662   }
00663 
00664   void OverlayDiagnosticDisplay::updateAlpha()
00665   {
00666     alpha_ = alpha_property_->getFloat();
00667   }
00668 
00669   void OverlayDiagnosticDisplay::updateTop()
00670   {
00671     top_ = top_property_->getInt();
00672   }
00673   
00674   void OverlayDiagnosticDisplay::updateLeft()
00675   {
00676     left_ = left_property_->getInt();
00677   }
00678   
00679   void OverlayDiagnosticDisplay::updateStallDuration()
00680   {
00681     stall_duration_ = stall_duration_property_->getFloat();
00682   }
00683 
00684   bool OverlayDiagnosticDisplay::isInRegion(int x, int y)
00685   {
00686     return (top_ < y && top_ + size_ > y &&
00687             left_ < x && left_ + size_ > x);
00688   }
00689 
00690   void OverlayDiagnosticDisplay::movePosition(int x, int y)
00691   {
00692     top_ = y;
00693     left_ = x;
00694   }
00695 
00696   void OverlayDiagnosticDisplay::setPosition(int x, int y)
00697   {
00698     top_property_->setValue(y);
00699     left_property_->setValue(x);
00700   }
00701 
00702   void OverlayDiagnosticDisplay::updateType()
00703   {
00704     type_ = type_property_->getOptionInt();
00705   }
00706 }
00707 
00708 #include <pluginlib/class_list_macros.h>
00709 PLUGINLIB_EXPORT_CLASS( jsk_rviz_plugins::OverlayDiagnosticDisplay, rviz::Display)


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Wed May 1 2019 02:40:22