A plugin for displaying std_msgs/Strings

Conflicts:
	mapviz_plugins/CMakeLists.txt
This commit is contained in:
P. J. Reed 2016-01-28 16:25:36 -06:00
parent e58181b613
commit e7cf17c54e
6 changed files with 1003 additions and 15 deletions

View File

@ -242,6 +242,19 @@ Projects an image loaded from file into the scene to represent the robot platfor
* Width: The physical width represented by the image
* Height: The physical height represented by the image
### String
Displays the most recent string from a std_msgs::String message at a fixed location on the scene.
**Parameters**
* Topic: The string topic
* Font: The font for rendering the string
* Color: The color for drawing the string
* Anchor: (top left | top center | top right | center left | center | center right | bottom left | bottom center | bottom right)
* Offset X: Horizontal offset from the anchor
* Offset Y: Vertical offset from the anchor
* Units: (pixels | percent of window)
### Textured Marker
Projects marti_visualization_msgs::TexturedMarker and marti_visualization_msgs::TexturedMarkerArray message data into the scene.

View File

@ -53,40 +53,50 @@ file (GLOB UI_FILES src/*.ui)
file (GLOB SRC_FILES
src/canvas_click_filter.cpp
src/multires_image_plugin.cpp
src/image_plugin.cpp
src/disparity_plugin.cpp
src/multires_view.cpp
src/odometry_plugin.cpp
src/marker_plugin.cpp
src/gps_plugin.cpp
src/grid_plugin.cpp
src/path_plugin.cpp
src/image_plugin.cpp
src/laserscan_plugin.cpp
src/pointcloud2_plugin.cpp
src/marker_plugin.cpp
src/multires_image_plugin.cpp
src/multires_view.cpp
src/navsat_plugin.cpp
src/odometry_plugin.cpp
src/path_plugin.cpp
src/point_click_publisher_plugin.cpp
src/pointcloud2_plugin.cpp
src/robot_image_plugin.cpp
src/string_plugin.cpp
src/textured_marker_plugin.cpp
src/tf_frame_plugin.cpp
src/robot_image_plugin.cpp
src/navsat_plugin.cpp)
src/navsat_plugin.cpp
)
QT4_WRAP_UI(SRC_FILES ${UI_FILES})
QT4_WRAP_CPP(SRC_FILES
include/mapviz_plugins/canvas_click_filter.h
include/mapviz_plugins/multires_image_plugin.h
include/mapviz_plugins/image_plugin.h
include/mapviz_plugins/disparity_plugin.h
include/mapviz_plugins/odometry_plugin.h
include/mapviz_plugins/marker_plugin.h
include/mapviz_plugins/gps_plugin.h
include/mapviz_plugins/grid_plugin.h
include/mapviz_plugins/path_plugin.h
include/mapviz_plugins/image_plugin.h
include/mapviz_plugins/laserscan_plugin.h
include/mapviz_plugins/pointcloud2_plugin.h
include/mapviz_plugins/marker_plugin.h
include/mapviz_plugins/multires_image_plugin.h
include/mapviz_plugins/navsat_plugin.h
include/mapviz_plugins/odometry_plugin.h
include/mapviz_plugins/path_plugin.h
include/mapviz_plugins/point_click_publisher_plugin.h
include/mapviz_plugins/pointcloud2_plugin.h
include/mapviz_plugins/robot_image_plugin.h
include/mapviz_plugins/string_plugin.h
include/mapviz_plugins/textured_marker_plugin.h
include/mapviz_plugins/tf_frame_plugin.h
include/mapviz_plugins/robot_image_plugin.h
include/mapviz_plugins/navsat_plugin.h)
include/mapviz_plugins/navsat_plugin.h
)
add_library(${PROJECT_NAME} ${SRC_FILES})
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARIES} ${GLU_LIBRARY} ${GLUT_LIBRARY} ${OpenCV_LIBRARIES} ${catkin_LIBRARIES})

View File

@ -0,0 +1,145 @@
// *****************************************************************************
//
// Copyright (c) 2015, Southwest Research Institute® (SwRI®)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Southwest Research Institute® (SwRI®) nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// *****************************************************************************
#ifndef MAPVIZ_PLUGINS_STRING_PLUGIN_H
#define MAPVIZ_PLUGINS_STRING_PLUGIN_H
#include <string>
#include <mapviz/mapviz_plugin.h>
#include <QObject>
#include <QString>
#include <QColor>
#include <QWidget>
#include <QGLWidget>
#include <QPainter>
#include <QFont>
#include <QStaticText>
#include <ros/ros.h>
#include <std_msgs/String.h>
// QT autogenerated files
#include "ui_string_config.h"
namespace mapviz_plugins
{
class StringPlugin : public mapviz::MapvizPlugin
{
Q_OBJECT
public:
enum Anchor {
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
CENTER_LEFT,
CENTER,
CENTER_RIGHT,
BOTTOM_LEFT,
BOTTOM_CENTER,
BOTTOM_RIGHT};
enum Units {PIXELS, PERCENT};
StringPlugin();
virtual ~StringPlugin();
bool Initialize(QGLWidget* canvas);
void Shutdown() {}
void Draw(double x, double y, double scale);
void Paint(QPainter* painter, double x, double y, double scale);
void Transform() {}
void LoadConfig(const YAML::Node& node, const std::string& path);
void SaveConfig(YAML::Emitter& emitter, const std::string& path);
QWidget* GetConfigWidget(QWidget* parent);
protected:
void PaintText(QPainter* painter);
void PrintError(const std::string& message);
void PrintInfo(const std::string& message);
void PrintWarning(const std::string& message);
protected Q_SLOTS:
void SelectColor();
void SelectFont();
void SelectTopic();
void TopicEdited();
void SetAnchor(QString anchor);
void SetUnits(QString units);
void SetOffsetX(int offset);
void SetOffsetY(int offset);
private:
Ui::string_config ui_;
QWidget* config_widget_;
std::string topic_;
Anchor anchor_;
Units units_;
int offset_x_;
int offset_y_;
int width_;
int height_;
int last_width_;
int last_height_;
ros::Subscriber string_sub_;
bool has_message_;
bool has_painted_;
QColor color_;
QFont font_;
QStaticText message_;
void stringCallback(const std_msgs::StringPtr& str);
std::string AnchorToString(Anchor anchor);
std::string UnitsToString(Units units);
static const char* ANCHOR_KEY;
static const char* COLOR_KEY;
static const char* FONT_KEY;
static const char* OFFSET_X_KEY;
static const char* OFFSET_Y_KEY;
static const char* TOPIC_KEY;
static const char* UNITS_KEY;
};
}
#endif //MAPVIZ_PLUGINS_STRING_PLUGIN_H

View File

@ -41,5 +41,8 @@
<class name="mapviz_plugins/point_click_publisher" type="mapviz_plugins::PointClickPublisherPlugin" base_class_type="mapviz::MapvizPlugin">
<description>Publishes a StampedPoint when a point on the map canvas is clicked.</description>
</class>
<class name="mapviz_plugins/string" type="mapviz_plugins::StringPlugin" base_class_type="mapviz::MapvizPlugin">
<description>Displays a std_msgs/String at a fixed point on the canvas.</description>
</class>
</library>

View File

@ -0,0 +1,339 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>string_config</class>
<widget class="QWidget" name="string_config">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="verticalSpacing">
<number>4</number>
</property>
<property name="margin">
<number>2</number>
</property>
<item row="11" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Status:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="selecttopic">
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="topic">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Topic:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="font_label">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Font:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="font_button">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Helvetica</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="color_label">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Color:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="mapviz::ColorButton" name="color">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="anchor">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
</font>
</property>
<item>
<property name="text">
<string>top left</string>
</property>
</item>
<item>
<property name="text">
<string>top center</string>
</property>
</item>
<item>
<property name="text">
<string>top right</string>
</property>
</item>
<item>
<property name="text">
<string>center left</string>
</property>
</item>
<item>
<property name="text">
<string>center</string>
</property>
</item>
<item>
<property name="text">
<string>center right</string>
</property>
</item>
<item>
<property name="text">
<string>bottom left</string>
</property>
</item>
<item>
<property name="text">
<string>bottom center</string>
</property>
</item>
<item>
<property name="text">
<string>bottom right</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Anchor:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Offset X:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="offsetx">
<property name="maximum">
<number>2000</number>
</property>
</widget>
</item>
<item row="11" column="1" colspan="2">
<widget class="QLabel" name="status">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>No topic</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Offset Y:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="offsety">
<property name="maximum">
<number>2000</number>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_8">
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Units:</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QComboBox" name="units">
<property name="maximumSize">
<size>
<width>16777213</width>
<height>25</height>
</size>
</property>
<property name="font">
<font>
<family>Sans Serif</family>
<pointsize>9</pointsize>
</font>
</property>
<item>
<property name="text">
<string>pixels</string>
</property>
</item>
<item>
<property name="text">
<string>percent</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>mapviz::ColorButton</class>
<extends>QPushButton</extends>
<header location="global">mapviz/color_button.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<slots>
<slot>SelectColor()</slot>
<slot>SelectTopic()</slot>
<slot>TopicEdited()</slot>
<slot>SelectFont()</slot>
<slot>PositionToleranceChanged(double)</slot>
<slot>AngleToleranceChanged(double)</slot>
</slots>
</ui>

View File

@ -0,0 +1,478 @@
// *****************************************************************************
//
// Copyright (c) 2015, Southwest Research Institute® (SwRI®)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Southwest Research Institute® (SwRI®) nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// *****************************************************************************
#include <mapviz_plugins/string_plugin.h>
#include <pluginlib/class_list_macros.h>
#include <mapviz/select_topic_dialog.h>
#include <QFontDialog>
PLUGINLIB_DECLARE_CLASS(
mapviz_plugins,
string,
mapviz_plugins::StringPlugin,
mapviz::MapvizPlugin)
namespace mapviz_plugins
{
const char* StringPlugin::COLOR_KEY = "color";
const char* StringPlugin::FONT_KEY = "font";
const char* StringPlugin::TOPIC_KEY = "topic";
const char* StringPlugin::ANCHOR_KEY = "anchor";
const char* StringPlugin::UNITS_KEY = "units";
const char* StringPlugin::OFFSET_X_KEY = "offset_x";
const char* StringPlugin::OFFSET_Y_KEY = "offset_y";
StringPlugin::StringPlugin() :
config_widget_(new QWidget()),
anchor_(TOP_LEFT),
units_(PIXELS),
offset_x_(0),
offset_y_(0),
has_message_(false),
has_painted_(false),
color_(Qt::black)
{
ui_.setupUi(config_widget_);
// Set background white
QPalette p(config_widget_->palette());
p.setColor(QPalette::Background, Qt::white);
config_widget_->setPalette(p);
// Set status text red
QPalette p3(ui_.status->palette());
p3.setColor(QPalette::Text, Qt::red);
ui_.status->setPalette(p3);
QObject::connect(ui_.selecttopic, SIGNAL(clicked()), this, SLOT(SelectTopic()));
QObject::connect(ui_.topic, SIGNAL(editingFinished()), this, SLOT(TopicEdited()));
QObject::connect(ui_.anchor, SIGNAL(activated(QString)), this, SLOT(SetAnchor(QString)));
QObject::connect(ui_.units, SIGNAL(activated(QString)), this, SLOT(SetUnits(QString)));
QObject::connect(ui_.offsetx, SIGNAL(valueChanged(int)), this, SLOT(SetOffsetX(int)));
QObject::connect(ui_.offsety, SIGNAL(valueChanged(int)), this, SLOT(SetOffsetY(int)));
QObject::connect(ui_.font_button, SIGNAL(clicked()), this, SLOT(SelectFont()));
QObject::connect(ui_.color, SIGNAL(colorEdited(const QColor &)), this, SLOT(SelectColor()));
font_.setFamily(tr("Helvetica"));
ui_.font_button->setFont(font_);
ui_.font_button->setText(font_.family());
ui_.color->setColor(color_);
}
StringPlugin::~StringPlugin()
{
}
bool StringPlugin::Initialize(QGLWidget* canvas)
{
canvas_ = canvas;
return true;
}
void StringPlugin::Draw(double x, double y, double scale)
{
// This plugin doesn't do any OpenGL drawing.
}
void StringPlugin::Paint(QPainter* painter, double x, double y, double scale)
{
if (has_message_)
{
painter->save();
painter->resetTransform();
painter->setFont(font_);
if (!has_painted_) {
// After the first time we get a new message, we do not know how wide it's
// going to be when rendered, so we can't accurately calculate the top left
// coordinate if it's offset from the right or bottom borders.
// The easiest workaround I've found for this is to draw it once using
// a completely transparent pen, which will cause the QStaticText class to
// know how wide it is; then we can recalculate the offsets and draw it
// again with a visible pen.
QPen invisPen(QBrush(Qt::transparent), 1);
painter->setPen(invisPen);
PaintText(painter);
has_painted_ = true;
}
QPen pen(QBrush(color_), 1);
painter->setPen(pen);
PaintText(painter);
painter->restore();
PrintInfo("OK");
}
else
{
PrintWarning("No messages received. :-(");
}
}
void StringPlugin::PaintText(QPainter* painter)
{
// Calculate the correct offsets and dimensions
int x_offset = offset_x_;
int y_offset = offset_y_;
if (units_ == PERCENT)
{
x_offset = (int)((float)(offset_x_ * canvas_->width()) / 100.0);
y_offset = (int)((float)(offset_y_ * canvas_->height()) / 100.0);
}
int right = (int)((float)canvas_->width() - message_.size().width()) - x_offset;
int bottom = (int)((float)canvas_->height() - message_.size().height()) - y_offset;
int yCenter = (int)((float)canvas_->height() / 2.0 - message_.size().height()/2.0);
int xCenter = (int)((float)canvas_->width() / 2.0 - message_.size().width()/2.0);
QPoint ulPoint;
switch (anchor_)
{
case TOP_LEFT:
ulPoint.setX(x_offset);
ulPoint.setY(y_offset);
break;
case TOP_CENTER:
ulPoint.setX(xCenter);
ulPoint.setY(y_offset);
break;
case TOP_RIGHT:
ulPoint.setX(right);
ulPoint.setY(y_offset);
break;
case CENTER_LEFT:
ulPoint.setX(x_offset);
ulPoint.setY(yCenter);
break;
case CENTER:
ulPoint.setX(xCenter);
ulPoint.setY(yCenter);
break;
case CENTER_RIGHT:
ulPoint.setX(right);
ulPoint.setY(yCenter);
break;
case BOTTOM_LEFT:
ulPoint.setX(x_offset);
ulPoint.setY(bottom);
break;
case BOTTOM_CENTER:
ulPoint.setX(xCenter);
ulPoint.setY(bottom);
break;
case BOTTOM_RIGHT:
ulPoint.setX(right);
ulPoint.setY(bottom);
break;
}
painter->drawStaticText(ulPoint, message_);
}
void StringPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
{
if (node[TOPIC_KEY])
{
ui_.topic->setText(QString(node[TOPIC_KEY].as<std::string>().c_str()));
TopicEdited();
}
if (node[FONT_KEY])
{
font_.fromString(QString(node[FONT_KEY].as<std::string>().c_str()));
ui_.font_button->setFont(font_);
ui_.font_button->setText(font_.family());
}
if (node[COLOR_KEY])
{
color_ = QColor(node[COLOR_KEY].as<std::string>().c_str());
ui_.color->setColor(QColor(color_.name().toStdString().c_str()));
}
if (node[ANCHOR_KEY])
{
std::string anchor = node[ANCHOR_KEY].as<std::string>();
ui_.anchor->setCurrentIndex(ui_.anchor->findText(anchor.c_str()));
SetAnchor(anchor.c_str());
}
if (node[UNITS_KEY])
{
std::string units = node[UNITS_KEY].as<std::string>();
ui_.units->setCurrentIndex(ui_.units->findText(units.c_str()));
SetUnits(units.c_str());
}
if (node[OFFSET_X_KEY])
{
offset_x_ = node[OFFSET_X_KEY].as<int>();
ui_.offsetx->setValue(offset_x_);
}
if (node[OFFSET_Y_KEY])
{
offset_y_ = node[OFFSET_Y_KEY].as<int>();
ui_.offsety->setValue(offset_y_);
}
}
void StringPlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
{
emitter << YAML::Key << FONT_KEY << YAML::Value << font_.toString().toStdString();
emitter << YAML::Key << COLOR_KEY << YAML::Value << color_.name().toStdString();
emitter << YAML::Key << TOPIC_KEY << YAML::Value << ui_.topic->text().toStdString();
emitter << YAML::Key << ANCHOR_KEY << YAML::Value << AnchorToString(anchor_);
emitter << YAML::Key << UNITS_KEY << YAML::Value << UnitsToString(units_);
emitter << YAML::Key << OFFSET_X_KEY << YAML::Value << offset_x_;
emitter << YAML::Key << OFFSET_Y_KEY << YAML::Value << offset_y_;
}
QWidget* StringPlugin::GetConfigWidget(QWidget* parent)
{
config_widget_->setParent(parent);
return config_widget_;
}
void StringPlugin::PrintError(const std::string& message)
{
if (message == ui_.status->text().toStdString())
return;
ROS_ERROR("Error: %s", message.c_str());
QPalette p(ui_.status->palette());
p.setColor(QPalette::Text, Qt::red);
ui_.status->setPalette(p);
ui_.status->setText(message.c_str());
}
void StringPlugin::PrintInfo(const std::string& message)
{
if (message == ui_.status->text().toStdString())
return;
ROS_INFO("%s", message.c_str());
QPalette p(ui_.status->palette());
p.setColor(QPalette::Text, Qt::green);
ui_.status->setPalette(p);
ui_.status->setText(message.c_str());
}
void StringPlugin::PrintWarning(const std::string& message)
{
if (message == ui_.status->text().toStdString())
return;
ROS_WARN("%s", message.c_str());
QPalette p(ui_.status->palette());
p.setColor(QPalette::Text, Qt::darkYellow);
ui_.status->setPalette(p);
ui_.status->setText(message.c_str());
}
void StringPlugin::SelectColor()
{
color_ = ui_.color->color();
}
void StringPlugin::SelectFont()
{
bool ok;
QFont font = QFontDialog::getFont(&ok, font_, canvas_);
if (ok)
{
font_ = font;
message_.prepare(QTransform(), font_);
ui_.font_button->setFont(font_);
ui_.font_button->setText(font_.family());
}
}
void StringPlugin::SelectTopic()
{
ros::master::TopicInfo topic = mapviz::SelectTopicDialog::selectTopic(
"std_msgs/String");
if (!topic.name.empty()) {
ui_.topic->setText(QString::fromStdString(topic.name));
TopicEdited();
}
}
void StringPlugin::TopicEdited()
{
if (ui_.topic->text().toStdString() != topic_)
{
initialized_ = false;
has_message_ = false;
topic_ = ui_.topic->text().toStdString();
PrintWarning("No messages received.");
string_sub_.shutdown();
string_sub_ = node_.subscribe(topic_, 1, &StringPlugin::stringCallback, this);
ROS_INFO("Subscribing to %s", topic_.c_str());
}
}
void StringPlugin::SetAnchor(QString anchor)
{
if (anchor == "top left")
{
anchor_ = TOP_LEFT;
}
else if (anchor == "top center")
{
anchor_ = TOP_CENTER;
}
else if (anchor == "top right")
{
anchor_ = TOP_RIGHT;
}
else if (anchor == "center left")
{
anchor_ = CENTER_LEFT;
}
else if (anchor == "center")
{
anchor_ = CENTER;
}
else if (anchor == "center right")
{
anchor_ = CENTER_RIGHT;
}
else if (anchor == "bottom left")
{
anchor_ = BOTTOM_LEFT;
}
else if (anchor == "bottom center")
{
anchor_ = BOTTOM_CENTER;
}
else if (anchor == "bottom right")
{
anchor_ = BOTTOM_RIGHT;
}
}
void StringPlugin::SetUnits(QString units)
{
if (units == "pixels")
{
units_ = PIXELS;
}
else if (units == "percent")
{
units_ = PERCENT;
}
}
void StringPlugin::SetOffsetX(int offset)
{
offset_x_ = offset;
}
void StringPlugin::SetOffsetY(int offset)
{
offset_y_ = offset;
}
void StringPlugin::stringCallback(const std_msgs::StringPtr& str)
{
message_.setText(QString(str->data.c_str()));
message_.prepare(QTransform(), font_);
has_message_ = true;
has_painted_ = false;
initialized_ = true;
}
std::string StringPlugin::AnchorToString(StringPlugin::Anchor anchor)
{
std::string anchor_string = "top left";
if (anchor == TOP_LEFT)
{
anchor_string = "top left";
}
else if (anchor == TOP_CENTER)
{
anchor_string = "top center";
}
else if (anchor == TOP_RIGHT)
{
anchor_string = "top right";
}
else if (anchor == CENTER_LEFT)
{
anchor_string = "center left";
}
else if (anchor == CENTER)
{
anchor_string = "center";
}
else if (anchor == CENTER_RIGHT)
{
anchor_string = "center right";
}
else if (anchor == BOTTOM_LEFT)
{
anchor_string = "bottom left";
}
else if (anchor == BOTTOM_CENTER)
{
anchor_string = "bottom center";
}
else if (anchor == BOTTOM_RIGHT)
{
anchor_string = "bottom right";
}
return anchor_string;
}
std::string StringPlugin::UnitsToString(StringPlugin::Units units)
{
std::string units_string = "pixels";
if (units == PIXELS)
{
units_string = "pixels";
}
else if (units == PERCENT)
{
units_string = "percent";
}
return units_string;
}
}