jog_frame_panel.cpp
Go to the documentation of this file.
1 #include <boost/thread.hpp>
2 #include <rviz/config.h>
4 #include <ros/package.h>
6 #include <QVBoxLayout>
7 #include <QHBoxLayout>
8 #include <QSignalMapper>
9 #include <QTimer>
10 #include "jog_frame_panel.h"
11 #include "jog_msgs/JogFrame.h"
12 
13 namespace jog_controller
14 {
15 
17  : rviz::Panel(parent), jog_value_(0), ori_jog_value_(0)
18 {
19  ros::NodeHandle nh;
20  jog_frame_pub_ = nh.advertise<jog_msgs::JogFrame>( "jog_frame", 1);
21 
22  // Get groups parameter of jog_frame_node
23  nh.getParam("/jog_frame_node/group_names", group_names_);
24  for (int i=0; i<group_names_.size(); i++)
25  {
26  ROS_INFO_STREAM("group_names:" << group_names_[i]);
27  }
28  nh.getParam("/jog_frame_node/link_names", link_names_);
29  for (int i=0; i<link_names_.size(); i++)
30  {
31  ROS_INFO_STREAM("link_names:" << link_names_[i]);
32  }
33 
34  QHBoxLayout* enable_layout = new QHBoxLayout;
35  enable_layout->addWidget( new QLabel( "Jog Enable:" ), 1);
36  jog_button_ = new QPushButton("OFF");
37  jog_button_->setStyleSheet("QPushButton:checked { background-color: red; }\n");
38  jog_button_->setCheckable(true);
39  jog_button_->setChecked(false);
40  enable_layout->addWidget(jog_button_, 3);
41 
42  QHBoxLayout* group_layout = new QHBoxLayout;
43  group_layout->addWidget( new QLabel( "Group:" ), 1);
44  group_cbox_ = new QComboBox();
45  updateGroups();
46  group_layout->addWidget(group_cbox_, 3);
47 
48  QHBoxLayout* frame_layout = new QHBoxLayout;
49  frame_layout->addWidget( new QLabel( "Frame:" ), 1);
50  frame_cbox_ = new QComboBox();
51  frame_layout->addWidget(frame_cbox_, 3);
52 
53  QHBoxLayout* target_layout = new QHBoxLayout;
54  target_layout->addWidget( new QLabel( "Target:" ), 1);
55  target_link_cbox_ = new QComboBox();
56  target_layout->addWidget(target_link_cbox_, 3);
57 
58  QHBoxLayout* axis_layout = new QHBoxLayout;
59  axis_layout->addWidget( new QLabel( "Pos Axis:" ), 1);
60  axis_cbox_ = new QComboBox();
61  axis_layout->addWidget(axis_cbox_, 3);
62 
63  QHBoxLayout* pos_jog_layout = new QHBoxLayout;
64  pos_jog_layout->addWidget( new QLabel( "Pos Jog:" ), 1);
65  jog_slider_ = new QSlider(Qt::Horizontal);
66  jog_slider_->setTickPosition(QSlider::TicksBelow);
67  jog_slider_->setTickInterval(500);
68  jog_slider_->setMinimum(-1000);
69  jog_slider_->setMaximum( 1000);
70  jog_slider_->setTracking(true);
71  jog_slider_->setSingleStep(0);
72  jog_slider_->setPageStep(0);
73  // How can I change the slider style more properly??
74  jog_slider_->setStyleSheet("QSlider::handle {"
75  "background: white;"
76  "border: 3px solid black;"
77  "width: 60px;"
78  "margin: -30px 0;"
79  "} "
80  "QSlider::sub-page {"
81  "background: rgb(164, 192, 2);"
82  "} "
83  "QSlider::add-page {"
84  "background: rgb(223, 70, 70);"
85  "} ");
86  pos_jog_layout->addWidget(jog_slider_, 3);
87 
88  QHBoxLayout* pos_x_layout = new QHBoxLayout;
89  pos_x_layout->addWidget( new QLabel( "Pos X:" ), 1);
91  pos_x_layout->addWidget(pos_x_text_, 3);
92 
93  QHBoxLayout* pos_y_layout = new QHBoxLayout;
94  pos_y_layout->addWidget( new QLabel( "Pos Y:" ), 1);
96  pos_y_layout->addWidget(pos_y_text_, 3);
97 
98  QHBoxLayout* pos_z_layout = new QHBoxLayout;
99  pos_z_layout->addWidget( new QLabel( "Pos Z:" ), 1);
101  pos_z_layout->addWidget(pos_z_text_, 3);
102 
103  QHBoxLayout* ori_axis_layout = new QHBoxLayout;
104  ori_axis_layout->addWidget( new QLabel( "Rot Axis:" ), 1);
105  ori_axis_cbox_ = new QComboBox();
106  ori_axis_layout->addWidget(ori_axis_cbox_, 3);
107 
108  QHBoxLayout* ori_jog_layout = new QHBoxLayout;
109  ori_jog_layout->addWidget( new QLabel( "Rot Jog:" ), 1);
110  ori_jog_slider_ = new QSlider(Qt::Horizontal);
111  ori_jog_slider_->setTickPosition(QSlider::TicksBelow);
112  ori_jog_slider_->setTickInterval(500);
113  ori_jog_slider_->setMinimum(-1000);
114  ori_jog_slider_->setMaximum( 1000);
115  ori_jog_slider_->setTracking(true);
116  ori_jog_slider_->setSingleStep(0);
117  ori_jog_slider_->setPageStep(0);
118  // How can I change the slider style more properly??
119  ori_jog_slider_->setStyleSheet("QSlider::handle {"
120  "background: white;"
121  "border: 3px solid black;"
122  "width: 60px;"
123  "margin: -30px 0;"
124  "} "
125  "QSlider::sub-page {"
126  "background: rgb(164, 192, 2);"
127  "} "
128  "QSlider::add-page {"
129  "background: rgb(223, 70, 70);"
130  "} ");
131  ori_jog_layout->addWidget(ori_jog_slider_, 3);
132 
133  QHBoxLayout* rot_x_layout = new QHBoxLayout;
134  rot_x_layout->addWidget( new QLabel( "Roll:" ), 1);
136  rot_x_layout->addWidget(rot_x_text_, 3);
137 
138  QHBoxLayout* rot_y_layout = new QHBoxLayout;
139  rot_y_layout->addWidget( new QLabel( "Pitch:" ), 1);
141  rot_y_layout->addWidget(rot_y_text_, 3);
142 
143  QHBoxLayout* rot_z_layout = new QHBoxLayout;
144  rot_z_layout->addWidget( new QLabel( "Yaw:" ), 1);
146  rot_z_layout->addWidget(rot_z_text_, 3);
147 
148  QVBoxLayout* layout = new QVBoxLayout;
149  layout->addLayout(enable_layout);
150  layout->addLayout(group_layout);
151  layout->addLayout(frame_layout);
152  layout->addLayout(target_layout);
153  layout->addLayout(axis_layout);
154  layout->addLayout(pos_jog_layout);
155  layout->addLayout(ori_axis_layout);
156  layout->addLayout(ori_jog_layout);
157  layout->addLayout(pos_x_layout);
158  layout->addLayout(pos_y_layout);
159  layout->addLayout(pos_z_layout);
160  layout->addLayout(rot_x_layout);
161  layout->addLayout(rot_y_layout);
162  layout->addLayout(rot_z_layout);
163  setLayout(layout);
164 
165  connect(jog_button_, SIGNAL(toggled(bool)), this, SLOT(respondEnable(bool)));
166  connect(frame_cbox_, SIGNAL(activated(int)), this, SLOT(respondFrame(int)));
167  connect(target_link_cbox_, SIGNAL(activated(int)), this, SLOT(respondTargetLink(int)));
168  connect(axis_cbox_, SIGNAL(activated(int)), this, SLOT(respondAxis(int)));
169  connect(ori_axis_cbox_, SIGNAL(activated(int)), this, SLOT(respondOrientationAxis(int)));
170 
171  // Slider
172  connect(jog_slider_, SIGNAL(valueChanged(int)), this, SLOT(respondSliderChanged(int)));
173  connect(jog_slider_, SIGNAL(sliderReleased()), this, SLOT(respondSliderReleased()));
174  connect(ori_jog_slider_, SIGNAL(valueChanged(int)), this, SLOT(respondOrientationSliderChanged(int)));
175  connect(ori_jog_slider_, SIGNAL(sliderReleased()), this, SLOT(respondOrientationSliderReleased()));
176 
177  // Timer for update Frame ComboBox
178  QTimer* output_timer = new QTimer( this );
179  connect( output_timer, SIGNAL( timeout() ), this, SLOT( publish() ));
180  output_timer->start(100);
181 }
182 
184 {
185  connect( vis_manager_, SIGNAL( preUpdate() ), this, SLOT( update() ));
186  updateFrame();
190 }
191 
193 {
195  tf::StampedTransform transform;
196  try{
197  tf->lookupTransform(frame_id_, target_link_id_, ros::Time(0), transform);
198  }
199  catch (tf::TransformException ex){
200  ROS_ERROR("%s",ex.what());
201  }
202  fillNumericLabel(pos_x_text_, transform.getOrigin().x());
203  fillNumericLabel(pos_y_text_, transform.getOrigin().y());
204  fillNumericLabel(pos_z_text_, transform.getOrigin().z());
205 
206  // RPY
207  tf::Quaternion q = transform.getRotation();
208  tf::Matrix3x3 m(q);
209  double roll, pitch, yaw;
210  m.getRPY(roll, pitch, yaw);
214 }
215 
217 {
218  group_cbox_->clear();
219  for (auto it = group_names_.begin(); it != group_names_.end(); it++)
220  {
221  const std::string& group = *it;
222  if (group.empty())
223  {
224  continue;
225  }
226  group_cbox_->addItem(group.c_str());
227  }
228 }
229 
230 
232 {
233  typedef std::vector<std::string> V_string;
234  V_string frames;
236  std::sort(frames.begin(), frames.end());
237  frame_cbox_->clear();
238  for (V_string::iterator it = frames.begin(); it != frames.end(); ++it )
239  {
240  const std::string& frame = *it;
241  if (frame.empty())
242  {
243  continue;
244  }
245  frame_cbox_->addItem(it->c_str());
246  }
247  frame_cbox_->setCurrentIndex(0);
248  frame_id_ = frame_cbox_->currentText().toStdString();
249 }
250 
252 {
253  target_link_cbox_->clear();
254  for (int i=0; i<link_names_.size(); i++)
255  {
256  target_link_cbox_->addItem(link_names_[i].c_str());
257  }
258  target_link_cbox_->setCurrentIndex(0);
259  target_link_id_ = target_link_cbox_->currentText().toStdString();
260 }
261 
262 
264 {
265  boost::mutex::scoped_lock lock(mutex_);
266 
267  // publish
268  jog_msgs::JogFrame msg;
269  msg.header.stamp = ros::Time::now();
270  msg.header.frame_id = frame_id_;
271  msg.group_name = group_cbox_->currentText().toStdString();
272  msg.link_name = target_link_id_;
273 
274  if (axis_id_ == "x")
275  {
276  msg.linear_delta.x = jog_value_;
277  }
278  if (axis_id_ == "y")
279  {
280  msg.linear_delta.y = jog_value_;
281  }
282  if (axis_id_ == "z")
283  {
284  msg.linear_delta.z = jog_value_;
285  }
286  // Orientation jogging
287  if (ori_axis_id_ == "x")
288  {
289  msg.angular_delta.x = ori_jog_value_;
290  }
291  if (ori_axis_id_ == "y")
292  {
293  msg.angular_delta.y = ori_jog_value_;
294  }
295  if (ori_axis_id_ == "z")
296  {
297  msg.angular_delta.z = ori_jog_value_;
298  }
299 
300  // Publish if the button is enabled
301  if(jog_button_->isChecked())
302  {
303  // Publish only if the all command are not equal zero
304  // Not good, we need to compare slider value by some way...
305  if (msg.linear_delta.x != 0 || msg.linear_delta.y != 0 || msg.linear_delta.z != 0 ||
306  msg.angular_delta.x != 0 || msg.angular_delta.y != 0 || msg.angular_delta.z != 0)
307  {
308  jog_frame_pub_.publish(msg);
309  }
310  }
311 }
312 
314 {
315  if (checked)
316  {
317  jog_button_->setText("ON");
318  }
319  else
320  {
321  jog_button_->setText("OFF");
322  }
323 }
324 
326 {
327  boost::mutex::scoped_lock lock(mutex_);
328  frame_id_ = frame_cbox_->currentText().toStdString();
329  ROS_INFO_STREAM("respondFrame: " << frame_id_);
330 }
331 
333 {
334  boost::mutex::scoped_lock lock(mutex_);
335  target_link_id_ = target_link_cbox_->currentText().toStdString();
336  ROS_INFO_STREAM("respondTargetLink: " << target_link_id_);
337 }
338 
340 {
341  boost::mutex::scoped_lock lock(mutex_);
342  axis_id_ = axis_cbox_->currentText().toStdString();
343  ROS_INFO_STREAM("respondAxis: " << axis_id_);
344 }
345 
347 {
348  boost::mutex::scoped_lock lock(mutex_);
349  ori_axis_id_ = ori_axis_cbox_->currentText().toStdString();
350  ROS_INFO_STREAM("respondOrientationAxis: " << ori_axis_id_);
351 }
352 
354 {
355  boost::mutex::scoped_lock lock(mutex_);
356  jog_value_ = 0.05 * value / 1000.0;
357 }
358 
360 {
361  jog_slider_->setValue(0);
362 }
363 
365 {
366  boost::mutex::scoped_lock lock(mutex_);
367  ori_jog_value_ = 0.05 * value / 1000.0;
368 }
369 
371 {
372  ori_jog_slider_->setValue(0);
373 }
374 
376 {
377  rviz::Panel::save(config);
378 }
379 
381 {
382  rviz::Panel::load(config);
383 }
384 
386 {
387  axis_cbox_->addItem("x");
388  axis_cbox_->addItem("y");
389  axis_cbox_->addItem("z");
390  axis_cbox_->setCurrentIndex(0);
391  axis_id_ = axis_cbox_->currentText().toStdString();
392 }
393 
395 {
396  ori_axis_cbox_->addItem("x");
397  ori_axis_cbox_->addItem("y");
398  ori_axis_cbox_->addItem("z");
399  ori_axis_cbox_->setCurrentIndex(0);
400  ori_axis_id_ = ori_axis_cbox_->currentText().toStdString();
401 }
402 
404 {
405  QLineEdit* label = new QLineEdit;
406  label->setReadOnly( true );
407  return label;
408 }
409 
410 void JogFramePanel::fillNumericLabel( QLineEdit* label, double value )
411 {
412  label->setText( QString::number( value, 'f', 4 ));
413 }
414 
415 } // namespace jog_controller
416 
417 
msg
void getFrameStrings(std::vector< std::string > &ids) const
VisualizationManager * vis_manager_
void publish(const boost::shared_ptr< M > &message) const
std::vector< std::string > link_names_
tf::TransformListener * getTFClient() const
PLUGINLIB_EXPORT_CLASS(test_moveit_controller_manager::TestMoveItControllerManager, moveit_controller_manager::MoveItControllerManager)
TFSIMD_FORCE_INLINE const tfScalar & x() const
void respondOrientationSliderChanged(int value)
std::vector< std::string > V_string
virtual void save(rviz::Config config) const
TFSIMD_FORCE_INLINE const tfScalar & z() const
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
virtual void load(const rviz::Config &config)
std::vector< std::string > group_names_
TFSIMD_FORCE_INLINE const tfScalar & y() const
void fillNumericLabel(QLineEdit *label, double value)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
JogFramePanel(QWidget *parent=0)
#define ROS_INFO_STREAM(args)
Quaternion getRotation() const
bool getParam(const std::string &key, std::string &s) const
static Time now()
virtual void save(Config config) const
virtual void load(const Config &config)
#define ROS_ERROR(...)


jog_controller
Author(s): Ryosuke Tajima
autogenerated on Sun May 17 2020 03:25:01