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