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 #include <mapviz_plugins/grid_plugin.h>
00031
00032
00033 #include <cstdio>
00034 #include <vector>
00035
00036
00037 #include <QGLWidget>
00038 #include <QPalette>
00039
00040 #include <mapviz/select_frame_dialog.h>
00041
00042
00043 #include <pluginlib/class_list_macros.h>
00044 PLUGINLIB_DECLARE_CLASS(
00045 mapviz_plugins,
00046 grid,
00047 mapviz_plugins::GridPlugin,
00048 mapviz::MapvizPlugin)
00049
00050 namespace mapviz_plugins
00051 {
00052 GridPlugin::GridPlugin() :
00053 config_widget_(new QWidget()),
00054 alpha_(1.0),
00055 top_left_(0, 0, 0),
00056 size_(1),
00057 rows_(1),
00058 columns_(1),
00059 transformed_(false)
00060 {
00061 ui_.setupUi(config_widget_);
00062
00063 ui_.color->setColor(Qt::red);
00064
00065
00066 QPalette p(config_widget_->palette());
00067 p.setColor(QPalette::Background, Qt::white);
00068 config_widget_->setPalette(p);
00069
00070
00071 QPalette p3(ui_.status->palette());
00072 p3.setColor(QPalette::Text, Qt::red);
00073 ui_.status->setPalette(p3);
00074
00075 QObject::connect(ui_.select_frame, SIGNAL(clicked()), this, SLOT(SelectFrame()));
00076 QObject::connect(ui_.frame, SIGNAL(textEdited(const QString&)), this, SLOT(FrameEdited()));
00077 QObject::connect(ui_.alpha, SIGNAL(valueChanged(double)), this, SLOT(SetAlpha(double)));
00078 QObject::connect(ui_.x, SIGNAL(valueChanged(double)), this, SLOT(SetX(double)));
00079 QObject::connect(ui_.y, SIGNAL(valueChanged(double)), this, SLOT(SetY(double)));
00080 QObject::connect(ui_.size, SIGNAL(valueChanged(double)), this, SLOT(SetSize(double)));
00081 QObject::connect(ui_.rows, SIGNAL(valueChanged(int)), this, SLOT(SetRows(int)));
00082 QObject::connect(ui_.columns, SIGNAL(valueChanged(int)), this, SLOT(SetColumns(int)));
00083 connect(ui_.color, SIGNAL(colorEdited(const QColor &)), this, SLOT(DrawIcon()));
00084 }
00085
00086 GridPlugin::~GridPlugin()
00087 {
00088 Shutdown();
00089 }
00090
00091 void GridPlugin::Shutdown()
00092 {
00093 }
00094
00095 void GridPlugin::DrawIcon()
00096 {
00097 if (icon_)
00098 {
00099 QPixmap icon(16, 16);
00100 icon.fill(Qt::transparent);
00101
00102 QPainter painter(&icon);
00103 painter.setRenderHint(QPainter::Antialiasing, true);
00104
00105 QPen pen(QColor(ui_.color->color()));
00106
00107 pen.setWidth(2);
00108 pen.setCapStyle(Qt::SquareCap);
00109 painter.setPen(pen);
00110
00111 painter.drawLine(2, 2, 14, 2);
00112 painter.drawLine(2, 2, 2, 14);
00113 painter.drawLine(14, 2, 14, 14);
00114 painter.drawLine(2, 14, 14, 14);
00115 painter.drawLine(8, 2, 8, 14);
00116 painter.drawLine(2, 8, 14, 8);
00117
00118 icon_->SetPixmap(icon);
00119 }
00120 }
00121
00122 void GridPlugin::SetAlpha(double alpha)
00123 {
00124 alpha_ = alpha;
00125 }
00126
00127 void GridPlugin::SetX(double x)
00128 {
00129 top_left_.setX(x);
00130
00131 RecalculateGrid();
00132 }
00133
00134 void GridPlugin::SetY(double y)
00135 {
00136 top_left_.setY(y);
00137
00138 RecalculateGrid();
00139 }
00140
00141 void GridPlugin::SetSize(double size)
00142 {
00143 size_ = size;
00144
00145 RecalculateGrid();
00146 }
00147
00148 void GridPlugin::SetRows(int rows)
00149 {
00150 rows_ = rows;
00151
00152 RecalculateGrid();
00153 }
00154
00155 void GridPlugin::SetColumns(int columns)
00156 {
00157 columns_ = columns;
00158
00159 RecalculateGrid();
00160 }
00161
00162 void GridPlugin::SelectFrame()
00163 {
00164 std::string frame = mapviz::SelectFrameDialog::selectFrame(tf_);
00165 if (!frame.empty())
00166 {
00167 ui_.frame->setText(QString::fromStdString(frame));
00168 FrameEdited();
00169 }
00170 }
00171
00172 void GridPlugin::FrameEdited()
00173 {
00174 source_frame_ = ui_.frame->text().toStdString();
00175
00176 initialized_ = true;
00177
00178 RecalculateGrid();
00179 }
00180
00181 void GridPlugin::PrintError(const std::string& message)
00182 {
00183 if (message == ui_.status->text().toStdString())
00184 {
00185 return;
00186 }
00187
00188 ROS_ERROR("Error: %s", message.c_str());
00189 QPalette p(ui_.status->palette());
00190 p.setColor(QPalette::Text, Qt::red);
00191 ui_.status->setPalette(p);
00192 ui_.status->setText(message.c_str());
00193 }
00194
00195 void GridPlugin::PrintInfo(const std::string& message)
00196 {
00197 if (message == ui_.status->text().toStdString())
00198 {
00199 return;
00200 }
00201
00202 ROS_INFO("%s", message.c_str());
00203 QPalette p(ui_.status->palette());
00204 p.setColor(QPalette::Text, Qt::green);
00205 ui_.status->setPalette(p);
00206 ui_.status->setText(message.c_str());
00207 }
00208
00209 void GridPlugin::PrintWarning(const std::string& message)
00210 {
00211 if (message == ui_.status->text().toStdString())
00212 {
00213 return;
00214 }
00215
00216 ROS_WARN("%s", message.c_str());
00217 QPalette p(ui_.status->palette());
00218 p.setColor(QPalette::Text, Qt::darkYellow);
00219 ui_.status->setPalette(p);
00220 ui_.status->setText(message.c_str());
00221 }
00222
00223 QWidget* GridPlugin::GetConfigWidget(QWidget* parent)
00224 {
00225 config_widget_->setParent(parent);
00226
00227 return config_widget_;
00228 }
00229
00230 bool GridPlugin::Initialize(QGLWidget* canvas)
00231 {
00232 canvas_ = canvas;
00233
00234 DrawIcon();
00235
00236 return true;
00237 }
00238
00239 void GridPlugin::Draw(double x, double y, double scale)
00240 {
00241 if (transformed_)
00242 {
00243 QColor color = ui_.color->color();
00244
00245 glLineWidth(3);
00246 glColor4d(color.redF(), color.greenF(), color.blueF(), alpha_);
00247 glBegin(GL_LINES);
00248
00249 std::list<tf::Point>::iterator transformed_left_it = transformed_left_points_.begin();
00250 std::list<tf::Point>::iterator transformed_right_it = transformed_right_points_.begin();
00251 for (; transformed_left_it != transformed_left_points_.end(); ++transformed_left_it)
00252 {
00253 glVertex2d(transformed_left_it->getX(), transformed_left_it->getY());
00254 glVertex2d(transformed_right_it->getX(), transformed_right_it->getY());
00255
00256 ++transformed_right_it;
00257 }
00258
00259 std::list<tf::Point>::iterator transformed_top_it = transformed_top_points_.begin();
00260 std::list<tf::Point>::iterator transformed_bottom_it = transformed_bottom_points_.begin();
00261 for (; transformed_top_it != transformed_top_points_.end(); ++transformed_top_it)
00262 {
00263 glVertex2d(transformed_top_it->getX(), transformed_top_it->getY());
00264 glVertex2d(transformed_bottom_it->getX(), transformed_bottom_it->getY());
00265
00266 ++transformed_bottom_it;
00267 }
00268
00269 glEnd();
00270
00271 PrintInfo("OK");
00272 }
00273 }
00274
00275 void GridPlugin::RecalculateGrid()
00276 {
00277 transformed_ = false;
00278
00279 left_points_.clear();
00280 right_points_.clear();
00281 top_points_.clear();
00282 bottom_points_.clear();
00283
00284 transformed_left_points_.clear();
00285 transformed_right_points_.clear();
00286 transformed_top_points_.clear();
00287 transformed_bottom_points_.clear();
00288
00289
00290 for (int c = 0; c <= columns_; c++)
00291 {
00292 tf::Point top_point(top_left_.getX() + c * size_, top_left_.getY(), 0);
00293 top_points_.push_back(top_point);
00294 transformed_top_points_.push_back(transform_ * top_point);
00295
00296 tf::Point bottom_point(top_left_.getX() + c * size_, top_left_.getY() + size_ * rows_, 0);
00297 bottom_points_.push_back(bottom_point);
00298 transformed_bottom_points_.push_back(transform_ * bottom_point);
00299 }
00300
00301
00302 for (int r = 0; r <= rows_; r++)
00303 {
00304 tf::Point left_point(top_left_.getX(), top_left_.getY() + r * size_, 0);
00305 left_points_.push_back(left_point);
00306 transformed_left_points_.push_back(transform_ * left_point);
00307
00308 tf::Point right_point(top_left_.getX() + size_ * columns_, top_left_.getY() + r * size_, 0);
00309 right_points_.push_back(right_point);
00310 transformed_right_points_.push_back(transform_ * right_point);
00311 }
00312 }
00313
00314 void GridPlugin::Transform()
00315 {
00316 transformed_ = false;
00317
00318 if (GetTransform(ros::Time(), transform_))
00319 {
00320 Transform(left_points_, transformed_left_points_);
00321 Transform(right_points_, transformed_right_points_);
00322 Transform(top_points_, transformed_top_points_);
00323 Transform(bottom_points_, transformed_bottom_points_);
00324
00325 transformed_ = true;
00326 }
00327 }
00328
00329 void GridPlugin::Transform(std::list<tf::Point>& src, std::list<tf::Point>& dst)
00330 {
00331 std::list<tf::Point>::iterator points_it = src.begin();
00332 std::list<tf::Point>::iterator transformed_it = dst.begin();
00333 for (; points_it != src.end() && transformed_it != dst.end(); ++points_it)
00334 {
00335 (*transformed_it) = transform_ * (*points_it);
00336
00337 ++transformed_it;
00338 }
00339 }
00340
00341 void GridPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
00342 {
00343 if (node["color"])
00344 {
00345 std::string color;
00346 node["color"] >> color;
00347 ui_.color->setColor(QColor(color.c_str()));
00348 }
00349
00350 if (node["frame"])
00351 {
00352 std::string frame;
00353 node["frame"] >> frame;
00354 ui_.frame->setText(QString::fromStdString(frame));
00355 }
00356
00357 if (node["x"])
00358 {
00359 float x = 0;
00360 node["x"] >> x;
00361 ui_.x->setValue(x);
00362 }
00363
00364 if (node["y"])
00365 {
00366 float y = 0;
00367 node["y"] >> y;
00368 ui_.y->setValue(y);
00369 }
00370
00371 if (node["alpha"])
00372 {
00373 node["alpha"] >> alpha_;
00374 ui_.alpha->setValue(alpha_);
00375 }
00376
00377 if (node["size"])
00378 {
00379 node["size"] >> size_;
00380 ui_.size->setValue(size_);
00381 }
00382
00383 if (node["rows"])
00384 {
00385 node["rows"] >> rows_;
00386 ui_.rows->setValue(rows_);
00387 }
00388
00389 if (node["columns"])
00390 {
00391 node["columns"] >> columns_;
00392 ui_.columns->setValue(columns_);
00393 }
00394
00395 FrameEdited();
00396 }
00397
00398 void GridPlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
00399 {
00400 emitter << YAML::Key << "color" << YAML::Value << ui_.color->color().name().toStdString();
00401
00402 emitter << YAML::Key << "alpha" << YAML::Value << alpha_;
00403
00404 std::string frame = ui_.frame->text().toStdString();
00405 emitter << YAML::Key << "frame" << YAML::Value << frame;
00406
00407 emitter << YAML::Key << "x" << YAML::Value << top_left_.getX();
00408 emitter << YAML::Key << "y" << YAML::Value << top_left_.getY();
00409 emitter << YAML::Key << "size" << YAML::Value << size_;
00410 emitter << YAML::Key << "rows" << YAML::Value << rows_;
00411 emitter << YAML::Key << "columns" << YAML::Value << columns_;
00412 }
00413 }
00414