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
00031
00032
00033
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
00102
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
00117
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
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()) {
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
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
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
00476
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
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
00580 double r = animationRate();
00581 if (previous_state_ == close_state) {
00582 drawEVANonConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width, max_gap * r);
00583 }
00584 else if (getLatestState() == close_state) {
00585 drawEVANonConnectedRectangle(painter, rectangle_color, small_rectangle_color, line_width, max_gap * (1 - r));
00586 }
00587 else {
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
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)