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/point_drawing_plugin.h>
00031
00032 #include <vector>
00033 #include <list>
00034
00035 #include <QDialog>
00036 #include <QGLWidget>
00037 #include <QPalette>
00038 #include <QPainter>
00039
00040 #include <opencv2/core/core.hpp>
00041
00042 #include <swri_image_util/geometry_util.h>
00043 #include <swri_transform_util/transform_util.h>
00044
00045 namespace mapviz_plugins
00046 {
00047 PointDrawingPlugin::PointDrawingPlugin()
00048 : arrow_size_(25),
00049 draw_style_(LINES),
00050 position_tolerance_(0.0),
00051 buffer_size_(0),
00052 covariance_checked_(false),
00053 new_lap_(true),
00054 lap_checked_(false),
00055 buffer_holder_(false),
00056 scale_(1.0),
00057 static_arrow_sizes_(false),
00058 got_begin_(false)
00059 {
00060 }
00061
00062 void PointDrawingPlugin::ClearHistory()
00063 {
00064 points_.clear();
00065 }
00066
00067 void PointDrawingPlugin::DrawIcon()
00068 {
00069 if (icon_)
00070 {
00071 QPixmap icon(16, 16);
00072 icon.fill(Qt::transparent);
00073
00074 QPainter painter(&icon);
00075 painter.setRenderHint(QPainter::Antialiasing, true);
00076
00077 QPen pen(color_);
00078
00079 if (draw_style_ == POINTS)
00080 {
00081 pen.setWidth(7);
00082 pen.setCapStyle(Qt::RoundCap);
00083 painter.setPen(pen);
00084 painter.drawPoint(8, 8);
00085 }
00086 else if (draw_style_ == LINES)
00087 {
00088 pen.setWidth(3);
00089 pen.setCapStyle(Qt::FlatCap);
00090 painter.setPen(pen);
00091 painter.drawLine(1, 14, 14, 1);
00092 }
00093 else if (draw_style_ == ARROWS)
00094 {
00095 pen.setWidth(2);
00096 pen.setCapStyle(Qt::SquareCap);
00097 painter.setPen(pen);
00098 painter.drawLine(2, 13, 13, 2);
00099 painter.drawLine(13, 2, 13, 8);
00100 painter.drawLine(13, 2, 7, 2);
00101 }
00102
00103 icon_->SetPixmap(icon);
00104 }
00105 }
00106
00107 void PointDrawingPlugin::SetArrowSize(int arrowSize)
00108 {
00109 arrow_size_ = arrowSize;
00110 }
00111
00112 void PointDrawingPlugin::SetDrawStyle(QString style)
00113 {
00114 if (style == "lines")
00115 {
00116 draw_style_ = LINES;
00117 }
00118 else if (style == "points")
00119 {
00120 draw_style_ = POINTS;
00121 }
00122 else if (style == "arrows")
00123 {
00124 draw_style_ = ARROWS;
00125 }
00126
00127 DrawIcon();
00128 }
00129
00130 void PointDrawingPlugin::SetStaticArrowSizes(bool isChecked)
00131 {
00132 static_arrow_sizes_ = isChecked;
00133 }
00134
00135 void PointDrawingPlugin::PositionToleranceChanged(double value)
00136 {
00137 position_tolerance_ = value;
00138 }
00139
00140 void PointDrawingPlugin::BufferSizeChanged(int value)
00141 {
00142 buffer_size_ = value;
00143
00144 if (buffer_size_ > 0)
00145 {
00146 while (static_cast<int>(points_.size()) > buffer_size_)
00147 {
00148 points_.pop_front();
00149 }
00150 }
00151 }
00152
00153 bool PointDrawingPlugin::DrawPoints(double scale)
00154 {
00155 scale_ = scale;
00156 bool transformed = true;
00157 if (lap_checked_)
00158 {
00159 CollectLaps();
00160
00161 if (draw_style_ == ARROWS)
00162 {
00163 transformed &= DrawLapsArrows();
00164 }
00165 else
00166 {
00167 transformed &= DrawLaps();
00168 }
00169 }
00170 else if (buffer_size_ == INT_MAX)
00171 {
00172 buffer_size_ = buffer_holder_;
00173 laps_.clear();
00174 got_begin_ = false;
00175 }
00176 if (draw_style_ == ARROWS)
00177 {
00178 transformed &= DrawArrows();
00179 }
00180 else
00181 {
00182 transformed &= DrawLines();
00183 }
00184
00185 return transformed;
00186 }
00187
00188 void PointDrawingPlugin::CollectLaps()
00189 {
00190 if (!got_begin_)
00191 {
00192 begin_ = cur_point_.point;
00193 points_.clear();
00194 buffer_holder_ = buffer_size_;
00195 buffer_size_ = INT_MAX;
00196 got_begin_ = true;
00197 }
00198 tf::Point check = begin_ - cur_point_.point;
00199 if (((std::fabs(check.x()) <= 3) && (std::fabs(check.y()) <= 3)) &&
00200 !new_lap_)
00201 {
00202 new_lap_ = true;
00203 if (points_.size() > 0)
00204 {
00205 laps_.push_back(points_);
00206 laps_[0].pop_back();
00207 points_.clear();
00208 points_.push_back(cur_point_);
00209 }
00210 }
00211
00212 if (((std::fabs(check.x()) > 25) && (std::fabs(check.y()) > 25)) &&
00213 new_lap_)
00214 {
00215 new_lap_ = false;
00216 }
00217 }
00218
00219 bool PointDrawingPlugin::DrawLines()
00220 {
00221 bool success = cur_point_.transformed;
00222 glColor4d(color_.redF(), color_.greenF(), color_.blueF(), 1.0);
00223 if (draw_style_ == LINES)
00224 {
00225 glLineWidth(3);
00226 glBegin(GL_LINE_STRIP);
00227 }
00228 else
00229 {
00230 glPointSize(6);
00231 glBegin(GL_POINTS);
00232 }
00233
00234 std::list<StampedPoint>::iterator it = points_.begin();
00235 for (; it != points_.end(); ++it)
00236 {
00237 success &= it->transformed;
00238 if (it->transformed)
00239 {
00240 glVertex2d(it->transformed_point.getX(), it->transformed_point.getY());
00241 }
00242 }
00243
00244 if (cur_point_.transformed)
00245 {
00246 glVertex2d(cur_point_.transformed_point.getX(),
00247 cur_point_.transformed_point.getY());
00248 }
00249
00250 glEnd();
00251
00252 return success;
00253 }
00254
00255 bool PointDrawingPlugin::DrawArrow(const StampedPoint& it)
00256 {
00257 if (it.transformed)
00258 {
00259 glVertex2d(it.transformed_point.getX(),
00260 it.transformed_point.getY());
00261
00262 glVertex2d(it.transformed_arrow_point.getX(),
00263 it.transformed_arrow_point.getY());
00264
00265 glVertex2d(it.transformed_arrow_point.getX(),
00266 it.transformed_arrow_point.getY());
00267 glVertex2d(it.transformed_arrow_left.getX(),
00268 it.transformed_arrow_left.getY());
00269
00270 glVertex2d(it.transformed_arrow_point.getX(),
00271 it.transformed_arrow_point.getY());
00272 glVertex2d(it.transformed_arrow_right.getX(),
00273 it.transformed_arrow_right.getY());
00274 return true;
00275 }
00276 return false;
00277 }
00278
00279 bool PointDrawingPlugin::DrawArrows()
00280 {
00281 bool success = true;
00282 glLineWidth(2);
00283 glBegin(GL_LINES);
00284 glColor4d(color_.redF(), color_.greenF(), color_.blueF(), 0.5);
00285 std::list<StampedPoint>::iterator it = points_.begin();
00286 for (; it != points_.end(); ++it)
00287 {
00288 success &= DrawArrow(*it);
00289 }
00290
00291 success &= DrawArrow(cur_point_);
00292
00293 glEnd();
00294
00295 return success;
00296 }
00297
00298 void PointDrawingPlugin::SetColor(const QColor& color)
00299 {
00300 if (color != color_)
00301 {
00302 color_ = color;
00303 DrawIcon();
00304 }
00305 }
00306
00307 bool PointDrawingPlugin::TransformPoint(StampedPoint& point)
00308 {
00309 swri_transform_util::Transform transform;
00310 if (GetTransform(point.source_frame, point.stamp, transform))
00311 {
00312 point.transformed_point = transform * point.point;
00313
00314 tf::Transform orientation(tf::Transform(transform.GetOrientation()) *
00315 point.orientation);
00316
00317 double size = static_cast<double>(arrow_size_);
00318 if (static_arrow_sizes_)
00319 {
00320 size *= scale_;
00321 }
00322 else
00323 {
00324 size /= 10.0;
00325 }
00326 double arrow_width = size / 5.0;
00327 double head_length = size * 0.75;
00328
00329 point.transformed_arrow_point =
00330 point.transformed_point + orientation * tf::Point(size, 0.0, 0.0);
00331 point.transformed_arrow_left =
00332 point.transformed_point + orientation * tf::Point(head_length, -arrow_width, 0.0);
00333 point.transformed_arrow_right =
00334 point.transformed_point + orientation * tf::Point(head_length, arrow_width, 0.0);
00335
00336 if (covariance_checked_)
00337 {
00338 for (uint32_t i = 0; i < point.cov_points.size(); i++)
00339 {
00340 point.transformed_cov_points[i] = transform * point.cov_points[i];
00341 }
00342 }
00343
00344 point.transformed = true;
00345 return true;
00346 }
00347
00348 point.transformed = false;
00349 return false;
00350 }
00351
00352 void PointDrawingPlugin::Transform()
00353 {
00354 bool transformed = false;
00355
00356 std::list<StampedPoint>::iterator points_it = points_.begin();
00357 for (; points_it != points_.end(); ++points_it)
00358 {
00359 transformed = transformed | TransformPoint(*points_it);
00360 }
00361
00362 transformed = transformed | TransformPoint(cur_point_);
00363 if (laps_.size() > 0)
00364 {
00365 for (size_t i = 0; i < laps_.size(); i++)
00366 {
00367 std::list<StampedPoint>::iterator lap_it = laps_[i].begin();
00368 for (; lap_it != laps_[i].end(); ++lap_it)
00369 {
00370 transformed = transformed | TransformPoint(*lap_it);
00371 }
00372 }
00373 }
00374 if (!points_.empty() && !transformed)
00375 {
00376 PrintError("No transform between " + cur_point_.source_frame + " and " +
00377 target_frame_);
00378 }
00379 }
00380
00381 bool PointDrawingPlugin::DrawLaps()
00382 {
00383 bool transformed = points_.size() != 0;
00384 glColor4d(color_.redF(), color_.greenF(), color_.blueF(), 0.5);
00385 glLineWidth(3);
00386 QColor base_color = color_;
00387 if (laps_.size() != 0)
00388 {
00389 for (size_t i = 0; i < laps_.size(); i++)
00390 {
00391 UpdateColor(base_color, static_cast<int>(i));
00392 if (draw_style_ == LINES)
00393 {
00394 glLineWidth(3);
00395 glBegin(GL_LINE_STRIP);
00396 }
00397 else
00398 {
00399 glPointSize(6);
00400 glBegin(GL_POINTS);
00401 }
00402
00403 std::list<StampedPoint>::iterator it = laps_[i].begin();
00404 for (; it != laps_[i].end(); it++)
00405 {
00406 if (it->transformed)
00407 {
00408 glVertex2d(it->transformed_point.getX(),
00409 it->transformed_point.getY());
00410 }
00411 }
00412 glEnd();
00413 }
00414 }
00415
00416 if (draw_style_ == LINES)
00417 {
00418 glLineWidth(3);
00419 glBegin(GL_LINE_STRIP);
00420 }
00421 else
00422 {
00423 glPointSize(6);
00424 glBegin(GL_POINTS);
00425 }
00426
00427 glColor4d(base_color.redF(), base_color.greenF(), base_color.blueF(), 0.5);
00428
00429 if (points_.size() > 0)
00430 {
00431 std::list<StampedPoint>::iterator it = points_.begin();
00432 for (; it != points_.end(); ++it)
00433 {
00434 transformed &= it->transformed;
00435 if (it->transformed)
00436 {
00437 glVertex2d(it->transformed_point.getX(),
00438 it->transformed_point.getY());
00439 }
00440 }
00441 }
00442
00443 glEnd();
00444 return transformed;
00445 }
00446
00447 void PointDrawingPlugin::UpdateColor(QColor base_color, int i)
00448 {
00449 int hue = static_cast<int>(color_.hue() + (i + 1.0) * 10.0 * M_PI);
00450 if (hue > 360)
00451 {
00452 hue %= 360;
00453 }
00454 int sat = color_.saturation();
00455 int v = color_.value();
00456 base_color.setHsv(hue, sat, v);
00457 glColor4d(base_color.redF(), base_color.greenF(), base_color.blueF(),
00458 0.5);
00459 }
00460
00461 bool PointDrawingPlugin::DrawLapsArrows()
00462 {
00463 bool success = laps_.size() != 0 && points_.size() != 0;
00464 glColor4d(color_.redF(), color_.greenF(), color_.blueF(), 0.5);
00465 glLineWidth(2);
00466 QColor base_color = color_;
00467 if (laps_.size() != 0)
00468 {
00469 for (size_t i = 0; i < laps_.size(); i++)
00470 {
00471 UpdateColor(base_color, static_cast<int>(i));
00472 std::list<StampedPoint>::iterator it = laps_[i].begin();
00473 for (; it != laps_[i].end(); ++it)
00474 {
00475 glBegin(GL_LINE_STRIP);
00476 success &= DrawArrow(*it);
00477 glEnd();
00478 }
00479 }
00480 glEnd();
00481
00482 int hue = static_cast<int>(color_.hue() + laps_.size() * 10.0 * M_PI);
00483 int sat = color_.saturation();
00484 int v = color_.value();
00485 base_color.setHsv(hue, sat, v);
00486 glColor4d(base_color.redF(), base_color.greenF(), base_color.blueF(),
00487 0.5);
00488 }
00489
00490 if (points_.size() > 0)
00491 {
00492 std::list<StampedPoint>::iterator it = points_.begin();
00493 for (; it != points_.end(); ++it)
00494 {
00495 glBegin(GL_LINE_STRIP);
00496 success &= DrawArrow(*it);
00497 glEnd();
00498 }
00499 }
00500
00501 return success;
00502 }
00503 }