38 #include <OGRE/OgreMaterialManager.h>
39 #include <OGRE/OgreTextureManager.h>
40 #include <OGRE/OgreTexture.h>
41 #include <OGRE/OgreHardwarePixelBuffer.h>
42 #include <OGRE/OgreTechnique.h>
54 : previous_state_(STALL_STATE), Display()
57 "Topic",
"/diagnostics_agg",
58 ros::message_traits::datatype<diagnostic_msgs::DiagnosticArray>(),
59 "diagnostic_msgs::DiagnosticArray topic to subscribe to.",
60 this, SLOT( updateRosTopic() ));
62 "diagnostics namespace",
"/",
63 "diagnostics namespace to visualize diagnostics",
64 this, SLOT(updateDiagnosticsNamespace()));
66 "type",
"SAC",
"Type of visualization",
this, SLOT(updateType()));
67 type_property_->addOptionStd(
"SAC", 0);
68 type_property_->addOptionStd(
"EVA", 1);
80 this, SLOT(updateSize()));
81 size_property_->setMin(1);
89 "stall duration", 5.0,
90 "seconds to be regarded as stalled",
91 this, SLOT(updateStallDuration())
93 stall_duration_property_->setMin(0.0);
113 const diagnostic_msgs::DiagnosticArray::ConstPtr& msg)
117 std::set<std::string> new_namespaces;
118 for (
size_t i = 0; i <
msg->status.size(); i++) {
119 new_namespaces.insert(
msg->status[i].name);
122 std::set<std::string> difference_namespaces;
124 new_namespaces.begin(), new_namespaces.end(),
125 std::inserter(difference_namespaces,
126 difference_namespaces.end()));
127 if (difference_namespaces.size() != 0) {
132 difference_namespaces.clear();
133 std::set_difference(new_namespaces.begin(), new_namespaces.end(),
135 std::inserter(difference_namespaces,
136 difference_namespaces.end()));
137 if (difference_namespaces.size() != 0) {
147 for (
size_t i = 0; i <
msg->status.size(); i++) {
148 diagnostic_msgs::DiagnosticStatus
status =
msg->status[i];
150 #if ROS_VERSION_MINIMUM(1,12,0)
152 = std::make_shared<diagnostic_msgs::DiagnosticStatus>(
status);
155 = boost::make_shared<diagnostic_msgs::DiagnosticStatus>(
status);
169 static int count = 0;
171 ss <<
"OverlayDiagnosticDisplayObject" <<
count++;
172 overlay_.reset(
new OverlayObject(ss.str()));
277 if (
latest_status_->level == diagnostic_msgs::DiagnosticStatus::OK) {
280 else if (
latest_status_->level == diagnostic_msgs::DiagnosticStatus::WARN) {
283 else if (
latest_status_->level == diagnostic_msgs::DiagnosticStatus::ERROR) {
304 if (
latest_status_->level == diagnostic_msgs::DiagnosticStatus::OK) {
308 == diagnostic_msgs::DiagnosticStatus::WARN) {
312 == diagnostic_msgs::DiagnosticStatus::ERROR) {
330 QColor ok_color(25, 255, 240,
alpha_ * 255.0);
331 QColor warn_color(240, 173, 78,
alpha_ * 255.0);
332 QColor error_color(217, 83, 79,
alpha_ * 255.0);
333 QColor stall_color(151, 151, 151,
alpha_ * 255.0);
352 QColor ok_color(40, 40, 40,
alpha_ * 255.0);
353 QColor warn_color(255, 255, 255,
alpha_ * 255.0);
354 QColor error_color(240, 173, 78,
alpha_ * 255.0);
355 QColor stall_color(240, 173, 78,
alpha_ * 255.0);
375 QColor ret (
a.red() * a_rate +
b.red() * (1 - a_rate),
376 a.green() * a_rate +
b.green() * (1 - a_rate),
377 a.blue() * a_rate +
b.blue() * (1 - a_rate),
378 a.alpha() * a_rate +
b.alpha() * (1 - a_rate));
385 const double r =
size_ / 128.0;
386 QFont
font(
"Liberation Sans", font_size *
r, font_size *
r, QFont::Bold);
390 painter.setFont(
font);
392 QFontMetrics metrics(
font);
393 const int text_width = metrics.width(
text.c_str());
394 const int text_height = metrics.height();
402 const double r =
size_ / 128.0;
403 QFont
font(
"Liberation Sans", font_size *
r, font_size *
r, QFont::Bold);
407 painter.setFont(
font);
409 QFontMetrics metrics(
font);
410 const int text_height = metrics.height();
419 const double font_size,
420 const std::string
text)
422 const double r =
size_ / 128.0;
423 QFont
font(
"Liberation Sans", font_size *
r, font_size *
r,
false);
428 painter.setFont(
font);
432 const int text_width = metrics.width(
text.c_str());
433 const int text_height = metrics.height();
434 if (
overlay_->getTextureWidth() > text_width) {
435 path.addText((
overlay_->getTextureWidth() - text_width) / 2.0,
444 painter.drawPath(path);
449 const std::string&
text)
455 overlay_->getTextureHeight() / 3.0 + status_size,
471 + status_size + namespace_size,
480 QPainter painter( &Hud );
482 const int margin = 10;
483 const int inner_line_width = 20;
485 painter.setRenderHint(QPainter::Antialiasing,
true);
491 painter.setPen(QPen(
fg_color, inner_line_width, Qt::SolidLine));
494 const double draw_angle = 250;
495 const double inner_circle_start
496 =
line_width + margin + inner_line_width / 2.0;
509 painter.setPen(QPen(color, width, Qt::SolidLine));
510 QPainterPath large_rectangle_path;
511 large_rectangle_path.moveTo(
A, S - B);
512 large_rectangle_path.lineTo(
A, S);
513 large_rectangle_path.lineTo(S, B);
514 large_rectangle_path.lineTo(S, 0);
515 painter.setPen(Qt::NoPen);
516 painter.fillPath(large_rectangle_path, QBrush(color));
517 QPainterPath small_rectangle_path;
518 small_rectangle_path.moveTo(
A, S - B);
519 small_rectangle_path.lineTo(
A, S - B + C * B);
520 small_rectangle_path.lineTo(
A + (S -
A) * C, S - B + C * B - (S - B) * C);
521 small_rectangle_path.lineTo(
A + (S -
A) * C, S - B - (S - B) * C);
522 painter.setPen(Qt::NoPen);
523 painter.fillPath(small_rectangle_path, QBrush(small_color));
537 painter.setPen(QPen(color, width, Qt::SolidLine));
538 QPainterPath large_rectangle_path;
539 large_rectangle_path.moveTo(
A, S - B);
540 large_rectangle_path.lineTo(
A, S);
541 double r0 = (S -
A - D) / 2 / (S -
A);
542 large_rectangle_path.lineTo(
A + (S -
A - D) / 2, S - r0 * (S - B));
543 large_rectangle_path.lineTo(
A + (S -
A - D) / 2, S - r0 * (S - B) - B);
544 painter.setPen(Qt::NoPen);
545 painter.fillPath(large_rectangle_path, QBrush(color));
547 QPainterPath large_rectangle_path2;
548 large_rectangle_path2.moveTo(S - (S -
A - D) / 2, (S - B) * r0);
549 large_rectangle_path2.lineTo(S - (S -
A - D) / 2, (S - B) * r0 + B);
550 large_rectangle_path2.lineTo(S, B);
551 large_rectangle_path2.lineTo(S, 0);
552 painter.setPen(Qt::NoPen);
553 painter.fillPath(large_rectangle_path2, QBrush(color));
555 QPainterPath small_rectangle_path;
556 small_rectangle_path.moveTo(
A, S - B);
557 small_rectangle_path.lineTo(
A, S - B + C * B);
558 small_rectangle_path.lineTo(
A + (S -
A) * C, S - B + C * B - (S - B) * C);
559 small_rectangle_path.lineTo(
A + (S -
A) * C, S - B - (S - B) * C);
560 painter.setPen(Qt::NoPen);
561 painter.fillPath(small_rectangle_path, QBrush(small_color));
566 QColor line_color(240, 173, 78,
alpha_ * 255.0);
568 QColor small_rectangle_color(line_color);
569 QPainter painter(&Hud);
576 double max_gap = 0.05 * S;
577 painter.setRenderHint(QPainter::Antialiasing,
true);
578 painter.setPen(QPen(line_color,
line_width, Qt::SolidLine));
579 painter.drawLine(QPoint(0, 0), QPoint(0, S));
580 painter.drawLine(QPoint(0, S - B / 2), QPoint(
A, S - B / 2));
604 painter.setFont(QFont(
"Liberation Sans", 12, QFont::Bold));
605 double theta = atan2(S - B, S -
A) / M_PI * 180;
606 double text_box_height = cos(
theta*M_PI/180) * B;
607 double text_box_width = (S -
A) / cos(
theta*M_PI/180) - sin(
theta*M_PI/180) * B * 2;
610 painter.translate(
A, S - B);
611 painter.rotate(-
theta);
612 if (text_width > text_box_width) {
615 painter.drawText(QRectF(text_left, 0, text_width*2, text_box_height), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
619 painter.drawText(QRectF(0, 0, text_box_width, text_box_height), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
626 ScopedPixelBuffer buffer =
overlay_->getBuffer();
627 QColor transparent(0, 0, 0, 0.0);
628 QImage Hud = buffer.getQImage(*
overlay_, transparent);
632 else if (
type_ == 1) {
641 for (std::set<std::string>::iterator it =
namespaces_.begin();
689 return (top_ < y && top_ + size_ >
y &&
690 left_ < x && left_ + size_ >
x);