coordinate_picker_plugin.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2018, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 
31 #include <mapviz/mapviz_plugin.h>
32 
33 #include <QClipboard>
34 #include <QMouseEvent>
35 #include <QTextStream>
36 
37 // ROS Libraries
38 #include <ros/ros.h>
39 
40 // Mapviz Libraries
42 
43 //
45 
48 
49 namespace mapviz_plugins
50 {
51 
52 CoordinatePickerPlugin::CoordinatePickerPlugin()
53  : config_widget_(new QWidget()),
54  map_canvas_(NULL),
55  copy_on_click_(false)
56 {
57  ui_.setupUi(config_widget_);
58 
59  QObject::connect(ui_.selectframe, SIGNAL(clicked()),
60  this, SLOT(SelectFrame()));
61  QObject::connect(ui_.frame, SIGNAL(editingFinished()),
62  this, SLOT(FrameEdited()));
63  QObject::connect(ui_.copyCheckBox, SIGNAL(stateChanged(int)),
64  this, SLOT(ToggleCopyOnClick(int)));
65  QObject::connect(ui_.clearListButton, SIGNAL(clicked()),
66  this, SLOT(ClearCoordList()));
67 }
68 
70 {
71  if (map_canvas_)
72  {
73  map_canvas_->removeEventFilter(this);
74  }
75 }
76 
77 QWidget* CoordinatePickerPlugin::GetConfigWidget(QWidget* parent)
78 {
79  config_widget_->setParent(parent);
80 
81  return config_widget_;
82 }
83 
84 bool CoordinatePickerPlugin::Initialize(QGLWidget* canvas)
85 {
86  map_canvas_ = static_cast< mapviz::MapCanvas* >(canvas);
87  map_canvas_->installEventFilter(this);
88 
89  initialized_ = true;
90  PrintInfo("OK");
91 
92  return true;
93 }
94 
95 bool CoordinatePickerPlugin::eventFilter(QObject* object, QEvent* event)
96 {
97  switch (event->type())
98  {
99  case QEvent::MouseButtonPress:
100  return handleMousePress(static_cast< QMouseEvent* >(event));
101  case QEvent::MouseButtonRelease:
102  return handleMouseRelease(static_cast< QMouseEvent* >(event));
103  case QEvent::MouseMove:
104  return handleMouseMove(static_cast< QMouseEvent* >(event));
105  default:
106  return false;
107  }
108 }
109 
111 {
112  QPointF point = event->localPos();
113  ROS_DEBUG("Map point: %f %f", point.x(), point.y());
114 
116  std::string frame = ui_.frame->text().toStdString();
117  if (frame.empty())
118  {
119  frame = target_frame_;
120  }
121 
122  // Frames get confusing. The `target_frame_` member is set by the "Fixed
123  // Frame" combobox in the GUI. When we transform the map coordinate to the
124  // fixed frame, we get it in the `target_frame_` frame.
125  //
126  // Then we translate from that frame into *our* target frame, `frame`.
127  if (tf_manager_.GetTransform(frame, target_frame_, transform))
128  {
129  ROS_DEBUG("Transforming from fixed frame '%s' to (plugin) target frame '%s'",
130  target_frame_.c_str(),
131  frame.c_str());
132  QPointF transformed = map_canvas_->MapGlCoordToFixedFrame(point);
133  ROS_DEBUG("Point in fixed frame: %f %f", transformed.x(), transformed.y());
134  tf::Vector3 position(transformed.x(), transformed.y(), 0.0);
135  position = transform * position;
136  point.setX(position.x());
137  point.setY(position.y());
138 
139  PrintInfo("OK");
140  }
141  else
142  {
143  QString warning;
144  QTextStream(&warning) << "No available transform from '" << QString::fromStdString(target_frame_) << "' to '" << QString::fromStdString(frame) << "'";
145  PrintWarning(warning.toStdString());
146  return false;
147  }
148 
149  ROS_DEBUG("Transformed point in frame '%s': %f %f", frame.c_str(), point.x(), point.y());
150  QString new_point;
151  QTextStream stream(&new_point);
152  stream.setRealNumberPrecision(9);
153  stream << point.x() << "," << point.y();
154 
155  if (copy_on_click_)
156  {
157  QClipboard* clipboard = QGuiApplication::clipboard();
158  clipboard->setText(new_point);
159  }
160 
161  stream << " (" << QString::fromStdString(frame) << ")\n";
162 
163  ui_.coordTextEdit->setPlainText(ui_.coordTextEdit->toPlainText().prepend(new_point));
164 
165  // Let other plugins process this event too
166  return false;
167 }
168 
170 {
171  // Let other plugins process this event too
172  return false;
173 }
174 
176 {
177  // Let other plugins process this event too
178  return false;
179 }
180 
182 {
183  std::string frame = mapviz::SelectFrameDialog::selectFrame(tf_);
184  if (!frame.empty())
185  {
186  ui_.frame->setText(QString::fromStdString(frame));
187  FrameEdited();
188  }
189 }
190 
192 {
193  ROS_INFO("Setting target frame to %s", ui_.frame->text().toStdString().c_str());
194 }
195 
197 {
198  switch(state)
199  {
200  case Qt::Checked:
201  copy_on_click_ = true;
202  break;
203  case Qt::PartiallyChecked:
204  case Qt::Unchecked:
205  default:
206  copy_on_click_ = false;
207  break;
208  }
209 }
210 
212 {
213  ui_.coordTextEdit->setPlainText(QString());
214 }
215 
216 void CoordinatePickerPlugin::Draw(double x, double y, double scale)
217 {
218 }
219 
220 void CoordinatePickerPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
221 {
222  if (node["frame"])
223  {
224  std::string frame;
225  node["frame"] >> frame;
226  ui_.frame->setText(QString::fromStdString(frame));
227  }
228 
229  if (node["copy"])
230  {
231  bool copy;
232  node["copy"] >> copy;
233  if (copy)
234  {
235  ui_.copyCheckBox->setCheckState(Qt::Checked);
236  }
237  else
238  {
239  ui_.copyCheckBox->setCheckState(Qt::Unchecked);
240  }
241  }
242 }
243 
244 void CoordinatePickerPlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
245 {
246  std::string frame = ui_.frame->text().toStdString();
247  emitter << YAML::Key << "frame" << YAML::Value << frame;
248 
249  bool copy_on_click = ui_.copyCheckBox->isChecked();
250  emitter << YAML::Key << "copy" << YAML::Value << copy_on_click;
251 }
252 
253 void CoordinatePickerPlugin::PrintError(const std::string& message)
254 {
255  PrintErrorHelper(ui_.status, message, 1.0);
256 }
257 
258 void CoordinatePickerPlugin::PrintInfo(const std::string& message)
259 {
260  PrintInfoHelper(ui_.status, message, 1.0);
261 }
262 
263 void CoordinatePickerPlugin::PrintWarning(const std::string& message)
264 {
265  PrintWarningHelper(ui_.status, message, 1.0);
266 }
267 
268 } // namespace mapviz_plugins
#define NULL
QPointF MapGlCoordToFixedFrame(const QPointF &point)
swri_transform_util::TransformManager tf_manager_
void transform(Route &route, const swri_transform_util::Transform &transform, const std::string &target_frame)
void PrintInfo(const std::string &message)
static void PrintWarningHelper(QLabel *status_label, const std::string &message, double throttle=0.0)
static void PrintErrorHelper(QLabel *status_label, const std::string &message, double throttle=0.0)
std::string target_frame_
static std::string selectFrame(boost::shared_ptr< tf::TransformListener > tf_listener, QWidget *parent=0)
bool eventFilter(QObject *object, QEvent *event)
static void PrintInfoHelper(QLabel *status_label, const std::string &message, double throttle=0.0)
void PrintError(const std::string &message)
void PrintWarning(const std::string &message)
#define ROS_INFO(...)
void Draw(double x, double y, double scale)
void LoadConfig(const YAML::Node &node, const std::string &path)
bool GetTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, Transform &transform) const
void SaveConfig(YAML::Emitter &emitter, const std::string &path)
boost::shared_ptr< tf::TransformListener > tf_
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
#define ROS_DEBUG(...)


mapviz_plugins
Author(s): Marc Alban
autogenerated on Thu Jun 6 2019 19:25:16