main_window.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright 2018 ROBOTIS CO., LTD.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16 
17 /* Authors: Kayman Jung, SCH */
18 
19 /*****************************************************************************
20  ** Includes
21  *****************************************************************************/
22 
23 #include <QtGui>
24 #include <QMessageBox>
25 #include <iostream>
26 #include "../include/thormang3_offset_tuner_client/main_window.hpp"
27 
28 /*****************************************************************************
29  ** Namespaces
30  *****************************************************************************/
31 
33 {
34 
35 using namespace Qt;
36 
37 /*****************************************************************************
38  ** Implementation [MainWindow]
39  *****************************************************************************/
40 
41 MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
42  : QMainWindow(parent),
43  offset_tuner_qnode_(argc, argv)
44 {
45  ui_.setupUi(this); // Calling this incidentally connects all ui's triggers to on_...() callbacks in this class.
46  QObject::connect(ui_.actionAbout_Qt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt())); // qApp is a global variable for the application
47 
48  setWindowIcon(QIcon(":/images/icon.png"));
49  ui_.tab_manager->setCurrentIndex(0); // ensure the first tab is showing - qt-designer should have this already hardwired, but often loses it (settings?).
50  QObject::connect(&offset_tuner_qnode_, SIGNAL(rosShutdown()), this, SLOT(close()));
51 
52  all_torque_on_ = false;
53 
54  spinBox_list_.push_back("goal");
55  spinBox_list_.push_back("offset");
56  spinBox_list_.push_back("mod");
57  spinBox_list_.push_back("present");
58  spinBox_list_.push_back("p_gain");
59  spinBox_list_.push_back("i_gain");
60  spinBox_list_.push_back("d_gain");
61 
62  /****************************
63  ** Connect
64  ****************************/
65 
66  qRegisterMetaType<thormang3_offset_tuner_msgs::JointOffsetPositionData>(
67  "thormang3_offset_tuner_msgs::JointOffsetPositionData");
68  QObject::connect(&offset_tuner_qnode_,
69  SIGNAL(update_present_joint_offset_data(thormang3_offset_tuner_msgs::JointOffsetPositionData)), this,
70  SLOT(update_joint_offset_data_spinbox(thormang3_offset_tuner_msgs::JointOffsetPositionData)));
71 
72  /*********************
73  ** Logging
74  **********************/
75  ui_.view_logging->setModel(offset_tuner_qnode_.loggingModel());
76  QObject::connect(&offset_tuner_qnode_, SIGNAL(loggingUpdated()), this, SLOT(updateLoggingView()));
77 
78  /****************************
79  ** Connect
80  ****************************/
81 
82  /*********************
83  ** Auto Start
84  **********************/
86 
87  // make ui
88  MakeUI();
89 }
90 
92 {
93 }
94 
95 /*****************************************************************************
96  ** Implementation [Slots]
97  *****************************************************************************/
98 
100 {
101  std_msgs::String msg;
102  msg.data = "save";
103 
105 }
106 
108 {
109  std_msgs::String msg;
110  msg.data = "ini_pose";
111 
113 }
114 
116 {
118 }
119 
120 void MainWindow::all_torque_on_button_clicked(QObject *button_group)
121 {
122  all_torque_on_ = true;
123 
124  QButtonGroup* torque_button_group = qobject_cast<QButtonGroup*>(button_group);
125  if (!torque_button_group) // this is just a safety check
126  return;
127 
128  QList<QAbstractButton *> torque_buttons = torque_button_group->buttons();
129  for (int ix = 0; ix < torque_buttons.size(); ix++)
130  {
131  if (torque_buttons[ix]->isChecked() == false)
132  torque_buttons[ix]->click();
133  }
134 
136 
137  all_torque_on_ = false;
138 }
139 
140 void MainWindow::all_torque_off_button_clicked(QObject *button_group)
141 {
142  QButtonGroup* torque_button_group = qobject_cast<QButtonGroup*>(button_group);
143  if (!torque_button_group) // this is just a safety check
144  return;
145 
146  QList<QAbstractButton *> torque_buttons = torque_button_group->buttons();
147  for (int ix = 0; ix < torque_buttons.size(); ix++)
148  {
149  if (torque_buttons[ix]->isChecked() == true)
150  torque_buttons[ix]->click();
151  }
152 }
153 
154 //void MainWindow::checkbox_clicked(QString joint_name)
156 {
157  QCheckBox* checkBox = qobject_cast<QCheckBox*>(widget);
158  if (!checkBox) // this is just a safety check
159  return;
160 
161  std::string joint_name = checkBox->text().toStdString();
162  bool _is_on = checkBox->isChecked();
163 
164  QList<QAbstractSpinBox *> spinbox_list = joint_spinbox_map_[joint_name];
165 
166  for (int ix = 0; ix < spinbox_list.size(); ix++)
167  {
168  spinbox_list[ix]->setEnabled(_is_on);
169  }
170 
171  publish_torque_msgs(joint_name, _is_on);
172 
173 }
174 
175 void MainWindow::publish_torque_msgs(std::string &joint_name, bool torque_on)
176 {
177  thormang3_offset_tuner_msgs::JointTorqueOnOffArray msg_array;
178  thormang3_offset_tuner_msgs::JointTorqueOnOff msg;
179 
180  msg.joint_name = joint_name;
181  msg.torque_enable = torque_on;
182 
183  msg_array.torque_enable_data.push_back(msg);
184 
186 
187  if (all_torque_on_ == false)
189 }
190 
191 void MainWindow::spinBox_valueChanged(QString joint_name)
192 {
193  if (offset_tuner_qnode_.is_refresh() == true)
194  return;
195 
196  thormang3_offset_tuner_msgs::JointOffsetData msg;
197  std::string current_joint_name = joint_name.toStdString();
198 
199  QList<QAbstractSpinBox *> spinbox_list = joint_spinbox_map_[current_joint_name];
200  QDoubleSpinBox *mod_spinBox;
201 
202  msg.joint_name = current_joint_name;
203 
204  for (int ix = 0; ix < spinbox_list.size(); ix++)
205  {
206  if (spinbox_list[ix]->whatsThis().toStdString() == "goal")
207  {
208  QDoubleSpinBox* spinbox = qobject_cast<QDoubleSpinBox*>(spinbox_list[ix]);
209  if (!spinbox) // this is just a safety check
210  continue;
211 
212  msg.goal_value = spinbox->value() * M_PI / 180.0;
213  }
214  else if (spinbox_list[ix]->whatsThis().toStdString() == "offset")
215  {
216  QDoubleSpinBox* spinbox = qobject_cast<QDoubleSpinBox*>(spinbox_list[ix]);
217  if (!spinbox) // this is just a safety check
218  continue;
219 
220  msg.offset_value = spinbox->value() * M_PI / 180.0;
221  }
222  else if (spinbox_list[ix]->whatsThis().toStdString() == "mod")
223  {
224  mod_spinBox = qobject_cast<QDoubleSpinBox*>(spinbox_list[ix]);
225  }
226  else if (spinbox_list[ix]->whatsThis().toStdString() == "p_gain")
227  {
228  QSpinBox* spinbox = qobject_cast<QSpinBox*>(spinbox_list[ix]);
229  if (!spinbox) // this is just a safety check
230  continue;
231 
232  msg.p_gain = spinbox->value();
233  }
234  else if (spinbox_list[ix]->whatsThis().toStdString() == "i_gain")
235  {
236  QSpinBox* spinbox = qobject_cast<QSpinBox*>(spinbox_list[ix]);
237  if (!spinbox) // this is just a safety check
238  continue;
239 
240  msg.i_gain = spinbox->value();
241  }
242  else if (spinbox_list[ix]->whatsThis().toStdString() == "d_gain")
243  {
244  QSpinBox* spinbox = qobject_cast<QSpinBox*>(spinbox_list[ix]);
245  if (!spinbox) // this is just a safety check
246  continue;
247 
248  msg.d_gain = spinbox->value();
249  }
250  }
251 
252  if (mod_spinBox) // this is just a safety check
253  mod_spinBox->setValue((msg.goal_value + msg.offset_value) * 180.0 / M_PI);
254 
256 }
257 
258 void MainWindow::update_joint_offset_data_spinbox(thormang3_offset_tuner_msgs::JointOffsetPositionData msg)
259 {
260  std::string joint_name = msg.joint_name;
261 
262  QList<QAbstractSpinBox *> spinbox_list = joint_spinbox_map_[joint_name];
263 
264  for (int ix = 0; ix < spinbox_list.size(); ix++)
265  {
266  if (spinbox_list[ix]->whatsThis().toStdString() == "goal")
267  {
268  QDoubleSpinBox* spinbox = qobject_cast<QDoubleSpinBox*>(spinbox_list[ix]);
269  if (!spinbox) // this is just a safety check
270  continue;
271 
272  spinbox->setValue(msg.goal_value * 180.0 / M_PI);
273  }
274  else if (spinbox_list[ix]->whatsThis().toStdString() == "offset")
275  {
276  QDoubleSpinBox* spinbox = qobject_cast<QDoubleSpinBox*>(spinbox_list[ix]);
277  if (!spinbox) // this is just a safety check
278  continue;
279 
280  spinbox->setValue(msg.offset_value * 180.0 / M_PI);
281  }
282  else if (spinbox_list[ix]->whatsThis().toStdString() == "present")
283  {
284  QDoubleSpinBox* spinbox = qobject_cast<QDoubleSpinBox*>(spinbox_list[ix]);
285  if (!spinbox) // this is just a safety check
286  continue;
287 
288  spinbox->setValue(msg.present_value * 180.0 / M_PI);
289  }
290  else if (spinbox_list[ix]->whatsThis().toStdString() == "p_gain")
291  {
292  QSpinBox* spinbox = qobject_cast<QSpinBox*>(spinbox_list[ix]);
293  if (!spinbox) // this is just a safety check
294  continue;
295 
296  spinbox->setValue(msg.p_gain);
297  }
298  else if (spinbox_list[ix]->whatsThis().toStdString() == "i_gain")
299  {
300  QSpinBox* spinbox = qobject_cast<QSpinBox*>(spinbox_list[ix]);
301  if (!spinbox) // this is just a safety check
302  continue;
303 
304  spinbox->setValue(msg.i_gain);
305  }
306  else if (spinbox_list[ix]->whatsThis().toStdString() == "d_gain")
307  {
308  QSpinBox* spinbox = qobject_cast<QSpinBox*>(spinbox_list[ix]);
309  if (!spinbox) // this is just a safety check
310  continue;
311 
312  spinbox->setValue(msg.d_gain);
313  }
314  }
315 }
316 
317 /*****************************************************************************
318  ** Implemenation [Slots][manually connected]
319  *****************************************************************************/
320 
327 {
328  ui_.view_logging->scrollToBottom();
329 }
330 
332 {
333  MakeTabUI(ui_.right_arm_group, ui_.right_arm_torque, right_arm_button_group_,
338 }
339 
340 void MainWindow::MakeTabUI(QGroupBox *joint_widget, QGroupBox *torque_widget, QButtonGroup *button_group,
341  std::map<int, std::string> &offset_group)
342 {
343  QSignalMapper *torque_checkbox_signalMapper = new QSignalMapper(this);
344 
345  QGridLayout *grid_layout = (QGridLayout *) joint_widget->layout();
346  QGridLayout *torque_layout = (QGridLayout *) torque_widget->layout();
347 
348  button_group = new QButtonGroup();
349  button_group->setExclusive(false);
350 
351  int row = 3;
352  int torque_checkbox_index = 0;
353  int torque_row = 1;
354  int torque_col = 0;
355  for (std::map<int, std::string>::iterator map_iter = offset_group.begin(); map_iter != offset_group.end(); ++map_iter)
356  {
357  QSignalMapper *spingox_signalMapper = new QSignalMapper(this);
358  QList<QAbstractSpinBox *> spinbox_list;
359 
360  // spin_box
361  int col = 0;
362  int size = 1;
363  std::string joint_name = map_iter->second;
364  QString q_joint_name = QString::fromStdString(joint_name);
365 
366  // label
367  QLabel *joint_label = new QLabel(q_joint_name);
368  grid_layout->addWidget(joint_label, row, col++, 1, size);
369 
370  // double spin box
371  for (int ix = 0; ix < 4; ix++)
372  {
373  QDoubleSpinBox *spin_box = new QDoubleSpinBox();
374  spin_box->setWhatsThis(tr(spinBox_list_[ix].c_str()));
375  spin_box->setMinimum(-360);
376  spin_box->setMaximum(360);
377  spin_box->setSingleStep(0.05);
378 
379  switch (ix)
380  {
381  case 2:
382  case 3:
383  spin_box->setReadOnly(true);
384  break;
385 
386  default:
387  spingox_signalMapper->setMapping(spin_box, q_joint_name);
388  QObject::connect(spin_box, SIGNAL(valueChanged(QString)), spingox_signalMapper, SLOT(map()));
389  break;
390  }
391 
392  grid_layout->addWidget(spin_box, row, col++, 1, size);
393 
394  spinbox_list.append(spin_box);
395  }
396 
397  // spin box
398  for (int ix = 0; ix < 3; ix++)
399  {
400  QSpinBox *spin_box = new QSpinBox();
401  spin_box->setWhatsThis(tr(spinBox_list_[ix + 4].c_str()));
402  spin_box->setMinimum(0);
403  spin_box->setMaximum(1000);
404  spin_box->setSingleStep(1);
405 
406  switch (ix)
407  {
408  case 0:
409  spin_box->setValue(32);
410 
411  spingox_signalMapper->setMapping(spin_box, q_joint_name);
412  QObject::connect(spin_box, SIGNAL(valueChanged(QString)), spingox_signalMapper, SLOT(map()));
413  break;
414 
415  default:
416  spin_box->setReadOnly(true);
417  break;
418  }
419 
420  grid_layout->addWidget(spin_box, row, col++, 1, size);
421 
422  spinbox_list.append(spin_box);
423  }
424 
425  // spinbox
426  joint_spinbox_map_[joint_name] = spinbox_list;
427  QObject::connect(spingox_signalMapper, SIGNAL(mapped(QString)), this, SLOT(spinBox_valueChanged(QString)));
428 
429  row += 1;
430 
431  // torque checkbox
432  torque_row = torque_checkbox_index / 6;
433  torque_col = torque_checkbox_index % 6;
434 
435  QCheckBox *check_box = new QCheckBox(q_joint_name);
436  check_box->setChecked(true);
437  torque_layout->addWidget(check_box, torque_row, torque_col, 1, size);
438  button_group->addButton(check_box);
439 
440  torque_checkbox_signalMapper->setMapping(check_box, check_box);
441  QObject::connect(check_box, SIGNAL(clicked()), torque_checkbox_signalMapper, SLOT(map()));
442 
443  torque_checkbox_index += 1;
444  }
445 
446  // all torque on
447  QSignalMapper *torque_on_signalMapper = new QSignalMapper(this);
448  QPushButton *on_button = new QPushButton(tr("All torque ON"));
449  torque_layout->addWidget(on_button, torque_row + 1, 4, 1, 1);
450  torque_on_signalMapper->setMapping(on_button, button_group);
451  QObject::connect(on_button, SIGNAL(clicked()), torque_on_signalMapper, SLOT(map()));
452  QObject::connect(torque_on_signalMapper, SIGNAL(mapped(QObject*)), this,
453  SLOT(all_torque_on_button_clicked(QObject*)));
454 
455  // all torque off
456  QSignalMapper *torque_off_signalMapper = new QSignalMapper(this);
457  QPushButton *off_button = new QPushButton(tr("All torque OFF"));
458  torque_layout->addWidget(off_button, torque_row + 1, 5, 1, 1);
459  torque_off_signalMapper->setMapping(off_button, button_group);
460  QObject::connect(off_button, SIGNAL(clicked()), torque_off_signalMapper, SLOT(map()));
461  QObject::connect(torque_off_signalMapper, SIGNAL(mapped(QObject*)), this,
462  SLOT(all_torque_off_button_clicked(QObject*)));
463 
464  QObject::connect(torque_checkbox_signalMapper, SIGNAL(mapped(QWidget*)), this,
465  SLOT(torque_checkbox_clicked(QWidget*)));
466 }
467 
468 /*****************************************************************************
469  ** Implementation [Menu]
470  *****************************************************************************/
471 
473 {
474  QMessageBox::about(this, tr("About ..."), tr("<h2>THORMANG3 Offset tuner client</h2><p>Copyright ROBOTIS</p>"));
475 }
476 
477 /*****************************************************************************
478  ** Implementation [Configuration]
479  *****************************************************************************/
480 
481 void MainWindow::closeEvent(QCloseEvent *event)
482 {
483  QMainWindow::closeEvent(event);
484 }
485 
486 } // namespace thormang3_offset_tuner_client
487 
void spinBox_valueChanged(QString joint_name)
void send_command_msg(std_msgs::String msg)
Definition: qnode.cpp:112
std::map< std::string, QList< QAbstractSpinBox * > > joint_spinbox_map_
Definition: main_window.hpp:98
std::map< int, std::string > right_arm_offset_group
Definition: qnode.hpp:91
void publish_torque_msgs(std::string &joint_name, bool torque_on)
void update_joint_offset_data_spinbox(thormang3_offset_tuner_msgs::JointOffsetPositionData msg)
std::vector< std::string > spinBox_list_
Definition: main_window.hpp:96
std::map< int, std::string > body_offset_group
Definition: qnode.hpp:94
void all_torque_off_button_clicked(QObject *button_group)
MainWindow(int argc, char **argv, QWidget *parent=0)
Definition: main_window.cpp:41
std::map< int, std::string > left_arm_offset_group
Definition: qnode.hpp:92
void send_torque_enable_msg(thormang3_offset_tuner_msgs::JointTorqueOnOffArray msg)
Definition: qnode.cpp:98
QStringListModel * loggingModel()
Definition: qnode.hpp:77
void send_joint_offset_data_msg(thormang3_offset_tuner_msgs::JointOffsetData msg)
Definition: qnode.cpp:105
std::map< int, std::string > legs_offset_group
Definition: qnode.hpp:93
void MakeTabUI(QGroupBox *joint_widget, QGroupBox *torque_widget, QButtonGroup *button_group, std::map< int, std::string > &offset_group)
void all_torque_on_button_clicked(QObject *button_group)
void torque_checkbox_clicked(QWidget *widget)


thormang3_offset_tuner_client
Author(s): Kayman
autogenerated on Mon Jun 10 2019 15:38:36