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 /* Author: Kayman Jung */
18 
19 /*****************************************************************************
20  ** Includes
21  *****************************************************************************/
22 
23 #include <QtGui>
24 #include <QMessageBox>
25 #include <iostream>
26 #include "../include/thormang3_demo/main_window.hpp"
27 
28 /*****************************************************************************
29  ** Namespaces
30  *****************************************************************************/
31 
32 namespace thormang3_demo
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  qnode_thor3_(argc, argv),
44  is_updating_(false)
45 {
46  // code to DEBUG
47  debug_print_ = false;
48  demo_mode_ = false;
49 
50  if (argc >= 2)
51  {
52  std::string args_code(argv[1]);
53  if (args_code == "debug")
54  debug_print_ = true;
55  else
56  debug_print_ = false;
57 
58  if (args_code == "demo")
59  demo_mode_ = true;
60  else
61  demo_mode_ = false;
62  }
63 
64  ui_.setupUi(this); // Calling this incidentally connects all ui's triggers to on_...() callbacks in this class.
65  QObject::connect(ui_.actionAbout_Qt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt())); // qApp is a global variable for the application
66 
67  readSettings();
68  setWindowIcon(QIcon(":/images/icon.png"));
69 
70  ui_.tab_manager->setCurrentIndex(0); // ensure the first tab is showing - qt-designer should have this already hardwired, but often loses it (settings?).
71  QObject::connect(&qnode_thor3_, SIGNAL(rosShutdown()), this, SLOT(close()));
72 
73  qRegisterMetaType<std::vector<int> >("std::vector<int>");
74  QObject::connect(&qnode_thor3_, SIGNAL(updatePresentJointControlModules(std::vector<int>)), this,
75  SLOT(updatePresentJointModule(std::vector<int>)));
76  QObject::connect(&qnode_thor3_, SIGNAL(updateHeadJointsAngle(double,double)), this,
77  SLOT(updateHeadJointsAngle(double,double)));
78 
79  QObject::connect(ui_.head_pan_slider, SIGNAL(valueChanged(int)), this, SLOT(setHeadJointsAngle()));
80  QObject::connect(ui_.head_tilt_slider, SIGNAL(valueChanged(int)), this, SLOT(setHeadJointsAngle()));
81 
82  QObject::connect(&qnode_thor3_, SIGNAL(updateCurrJoint(double)), this, SLOT(updateCurrJointSpinbox(double)));
83  QObject::connect(&qnode_thor3_, SIGNAL(updateCurrPos(double , double , double)), this,
84  SLOT(updateCurrPosSpinbox(double , double , double)));
85  QObject::connect(&qnode_thor3_, SIGNAL(updateCurrOri(double , double , double, double)), this,
86  SLOT(updateCurrOriSpinbox(double , double , double , double)));
87 
88  QObject::connect(ui_.tabWidget_control, SIGNAL(currentChanged(int)), &qnode_thor3_, SLOT(setCurrentControlUI(int)));
89 
90  qRegisterMetaType<geometry_msgs::Point>("geometry_msgs::Point");
91  qRegisterMetaType<geometry_msgs::Pose>("geometry_msgs::Pose");
92  connect(&qnode_thor3_, SIGNAL(updateDemoPoint(geometry_msgs::Point)), this,
93  SLOT(updatePointPanel(geometry_msgs::Point)));
94  connect(&qnode_thor3_, SIGNAL(updateDemoPose(geometry_msgs::Pose)), this, SLOT(updatePosePanel(geometry_msgs::Pose)));
95 
96  /*********************
97  ** Logging
98  **********************/
99  ui_.view_logging->setModel(qnode_thor3_.loggingModel());
100  QObject::connect(&qnode_thor3_, SIGNAL(loggingUpdated()), this, SLOT(updateLoggingView()));
101 
102  /*********************
103  ** Init
104  **********************/
105  qnode_thor3_.init();
106  initModeUnit();
107  setUserShortcut();
108  updateModuleUI();
109 }
110 
112 {
113 }
114 
115 /*****************************************************************************
116  ** Implementation [Slots]
117  *****************************************************************************/
118 
120 {
122 }
124 {
126 }
128 {
130 }
131 
133 {
134  qnode_thor3_.initFTCommand("ft_air");
135 }
137 {
138  qnode_thor3_.initFTCommand("ft_gnd");
139 }
141 {
142  qnode_thor3_.initFTCommand("ft_send");
143  qnode_thor3_.log(QNodeThor3::Info, "Apply new FT config");
144 }
146 {
147  qnode_thor3_.initFTCommand("ft_save");
148  qnode_thor3_.log(QNodeThor3::Info, "Save FT config data.");
149 }
150 
152 {
153  if (demo_mode_ == false)
154  return;
155 
156  std::string tab_name = ui_.tabWidget_control->tabText(ui_.tabWidget_control->currentIndex()).toStdString();
157  if (tab_name != "Demo")
158  ui_.tabWidget_control->currentWidget()->setEnabled(false);
159 }
160 
161 // Manipulation
163 {
164  std_msgs::String msg;
165  msg.data = "ini_pose";
166 
168 }
169 
171 {
172  qnode_thor3_.getJointPose(ui_.joint_combobox->currentText().toStdString());
173 }
174 
176 {
177  thormang3_manipulation_module_msgs::JointPose msg;
178 
179  msg.name = ui_.joint_combobox->currentText().toStdString();
180  msg.value = deg2rad<double>(ui_.joint_spinbox->value());
181 
183 }
184 
186 {
187  double z_offset = 0.723;
188 
189  updateCurrPosSpinbox(ui_.dSpinBox_marker_pos_x->value(), ui_.dSpinBox_marker_pos_y->value(),
190  ui_.dSpinBox_marker_pos_z->value() + z_offset);
191 
192  updateCurrOriSpinbox(ui_.dSpinBox_marker_ori_r->value(), ui_.dSpinBox_marker_ori_p->value(),
193  ui_.dSpinBox_marker_ori_y->value());
194 }
195 
197 {
198  qnode_thor3_.getKinematicsPose(ui_.group_combobox->currentText().toStdString());
199 }
200 
202 {
203  thormang3_manipulation_module_msgs::KinematicsPose msg;
204 
205  msg.name = ui_.group_combobox->currentText().toStdString();
206 
207  msg.pose.position.x = ui_.pos_x_spinbox->value();
208  msg.pose.position.y = ui_.pos_y_spinbox->value();
209  msg.pose.position.z = ui_.pos_z_spinbox->value();
210 
211  // deg -> rad
212  double roll = deg2rad<double>(ui_.ori_roll_spinbox->value());
213  double pitch = deg2rad<double>(ui_.ori_pitch_spinbox->value());
214  double yaw = deg2rad<double>(ui_.ori_yaw_spinbox->value());
215 
216  Eigen::Quaterniond orientation = rpy2quaternion(roll, pitch, yaw);
217 
218  msg.pose.orientation.x = orientation.x();
219  msg.pose.orientation.y = orientation.y();
220  msg.pose.orientation.z = orientation.z();
221  msg.pose.orientation.w = orientation.w();
222 
223  qnode_thor3_.sendIkMsg(msg);
224 }
225 
227 {
228  setGripper(GRIPPER_ON_ANGLE, GRIPPER_TORQUE_LIMIT, ui_.gripper_comboBox->currentText().toStdString());
229 }
230 
232 {
233  setGripper(GRIPPER_OFF_ANGLE, GRIPPER_TORQUE_LIMIT, ui_.gripper_comboBox->currentText().toStdString());
234 }
235 
237 {
238  sendWalkingCommand("turn left");
239 }
240 
242 {
243  sendWalkingCommand("forward");
244 }
245 
247 {
248  sendWalkingCommand("turn right");
249 }
250 
252 {
253  sendWalkingCommand("left");
254 }
255 
257 {
258  sendWalkingCommand("stop");
259 }
260 
262 {
263  sendWalkingCommand("right");
264 }
265 
267 {
268 } // disable
269 
271 {
272  sendWalkingCommand("backward");
273 }
274 
276 {
277 } // disable
278 
280 {
282 }
283 
285 {
287 }
288 
290 {
292 }
293 
295 {
296  geometry_msgs::Pose target_pose;
297  target_pose.position.x = ui_.dSpinBox_marker_pos_x->value();
298  target_pose.position.y = ui_.dSpinBox_marker_pos_y->value();
299  target_pose.position.z = ui_.dSpinBox_marker_pos_z->value();
300 
301  double roll = deg2rad<double>(ui_.dSpinBox_marker_ori_r->value());
302  double pitch = deg2rad<double>(ui_.dSpinBox_marker_ori_p->value());
303  double yaw = deg2rad<double>(ui_.dSpinBox_marker_ori_y->value());
304 
305  Eigen::Quaterniond orientation = rpy2quaternion(roll, pitch, yaw);
306 
307  target_pose.orientation.x = orientation.x();
308  target_pose.orientation.y = orientation.y();
309  target_pose.orientation.z = orientation.z();
310  target_pose.orientation.w = orientation.w();
311 
312  // generate foot steps
314 
315  ui_.A1_button_clear_step->setEnabled(true);
316  ui_.A2_button_go_walking->setEnabled(true);
317 }
318 
320 {
322 
323  ui_.A1_button_clear_step->setEnabled(false);
324  ui_.A2_button_go_walking->setEnabled(false);
325 }
326 
328 {
330 
331  ui_.A1_button_clear_step->setEnabled(false);
332  ui_.A2_button_go_walking->setEnabled(false);
333 }
334 
336 {
337  qnode_thor3_.log(QNodeThor3::Info, "Go Head init position");
338  setHeadJointsAngle(0.0, 0.0);
339 }
340 
342 {
344 }
345 
347 {
349 }
350 
352 {
354 }
355 
357 {
359 }
360 
362 {
364 }
365 
367 {
369 }
370 
372 {
374 }
375 
377 {
379 }
380 
382 // Manupulation Demo
385 {
386  // init pose : base
388 }
389 
391 {
392  // manipulation mode
393  qnode_thor3_.enableControlModule("manipulation_module");
394  qnode_thor3_.enableControlModule("gripper_module");
395 }
396 
398 {
399  // manipulation init pose
401 }
402 
404 {
405  // head control mode
406  qnode_thor3_.enableControlModule("head_control_module");
407 
408  // wait for setting the module
409  usleep(10 * 1000);
410 
411  // scan
413 }
414 
416 {
417  // set interactive marker
418  geometry_msgs::Pose current_pose;
419  getPoseFromMarkerPanel(current_pose);
420 
421  // set default value
422  if (current_pose.position.x == 0 && current_pose.position.y == 0 && current_pose.position.z == 0)
423  {
424  current_pose.position.x = 0.305;
425  current_pose.position.y = (ui_.comboBox_arm_group->currentText().toStdString() == "Right Arm") ? -0.3 : 0.3;
426  current_pose.position.z = 0.108;
427 
428  updatePosePanel(current_pose);
429  }
430 
431  qnode_thor3_.makeInteractiveMarker(current_pose);
432 }
433 
435 {
436  // send pose
437  thormang3_manipulation_module_msgs::KinematicsPose msg;
438  double z_offset = 0.723;
439 
440  // arm group : left_arm_with_torso / right_arm_with_torso
441  std::string selected_arm = ui_.comboBox_arm_group->currentText().toStdString();
442  std::string arm_group = (selected_arm == "Right Arm") ? "right_arm_with_torso" : "left_arm_with_torso";
443  msg.name = arm_group;
444 
445  msg.pose.position.x = ui_.dSpinBox_marker_pos_x->value() + ui_.dSpinBox_offset_x->value();
446  msg.pose.position.y = ui_.dSpinBox_marker_pos_y->value() + ui_.dSpinBox_offset_y->value();
447  msg.pose.position.z = ui_.dSpinBox_marker_pos_z->value() + ui_.dSpinBox_offset_z->value() + z_offset;
448 
449  double roll = deg2rad<double>(ui_.dSpinBox_marker_ori_r->value());
450  double pitch = deg2rad<double>(ui_.dSpinBox_marker_ori_p->value());
451  double yaw = deg2rad<double>(ui_.dSpinBox_marker_ori_y->value());
452 
453  Eigen::Quaterniond orientation = rpy2quaternion(roll, pitch, yaw);
454 
455  msg.pose.orientation.x = orientation.x();
456  msg.pose.orientation.y = orientation.y();
457  msg.pose.orientation.z = orientation.z();
458  msg.pose.orientation.w = orientation.w();
459 
460  qnode_thor3_.sendIkMsg(msg);
461 
462  // clear marker and foot steps
465 }
466 
468 {
469  // grip on : l_arm_grip / r_arm_grip
470  std::string arm_group =
471  (ui_.comboBox_arm_group->currentText().toStdString() == "Right Arm") ? "r_arm_grip" : "l_arm_grip";
473 }
474 
476 {
477  // grip off : l_arm_grip / r_arm_grip
478  std::string arm_group =
479  (ui_.comboBox_arm_group->currentText().toStdString() == "Right Arm") ? "r_arm_grip" : "l_arm_grip";
481 }
482 
484 // Walking Demo
487 {
488  // init pose : base
490 }
491 
493 {
494  // head control mode
495  qnode_thor3_.enableControlModule("head_control_module");
496 
497  // wait for setting the module
498  usleep(10 * 1000);
499 
500  // scan
502 }
503 
505 {
506  // walking mode
507  qnode_thor3_.enableControlModule("walking_module");
508 
509  // wait for setting module
510  usleep(10 * 1000);
511 
512  // balance on
514 }
515 
517 {
518  // set interactive marker
520 }
521 
523 {
524  double y_offset = (ui_.comboBox_kick_foot->currentText().toStdString() == "Right Foot") ? 0.093 : -0.093;
525 
526  geometry_msgs::Pose target_pose;
527  target_pose.position.x = ui_.dSpinBox_marker_pos_x->value();
528  target_pose.position.y = ui_.dSpinBox_marker_pos_y->value() + y_offset;
529  target_pose.position.z = ui_.dSpinBox_marker_pos_z->value();
530 
531  double roll = deg2rad<double>(ui_.dSpinBox_marker_ori_r->value());
532  double pitch = deg2rad<double>(ui_.dSpinBox_marker_ori_p->value());
533  double yaw = deg2rad<double>(ui_.dSpinBox_marker_ori_y->value());
534 
535  Eigen::Quaterniond orientation = rpy2quaternion(roll, pitch, yaw);
536 
537  target_pose.orientation.x = orientation.x();
538  target_pose.orientation.y = orientation.y();
539  target_pose.orientation.z = orientation.z();
540  target_pose.orientation.w = orientation.w();
541 
542  // generate foot steps
544 }
545 
547 {
548  // start walking
550 
551  // clear marker and foot steps
554 }
555 
557 {
558  // head control mode
559  qnode_thor3_.enableControlModule("head_control_module");
560 
561  // wait for setting the module
562  usleep(10 * 1000);
563 
564  // scan
566 }
567 
569 {
570  // foot : right kick / left kick
571  std::string kick_command =
572  (ui_.comboBox_kick_foot->currentText().toStdString() == "Right Foot") ? "right kick" : "left kick";
573  qnode_thor3_.kickDemo(kick_command);
574 }
575 
577 // Action Demo
580 {
581  // init pose : base
583 }
584 
586 {
587  // action mode
588  qnode_thor3_.enableControlModule("action_module");
589 }
590 
591 /*****************************************************************************
592  ** Implemenation [Slots][manually connected]
593  *****************************************************************************/
594 
596 {
597  ui_.view_logging->scrollToBottom();
598 }
599 
600 // user shortcut
602 {
603  // Setup a signal mapper to avoid creating custom slots for each tab
604  QSignalMapper *sig_map = new QSignalMapper(this);
605 
606  // Setup the shortcut for the first tab : Mode
607  QShortcut *short_tab1 = new QShortcut(QKeySequence("F1"), this);
608  connect(short_tab1, SIGNAL(activated()), sig_map, SLOT(map()));
609  sig_map->setMapping(short_tab1, 0);
610 
611  // Setup the shortcut for the second tab : Manipulation
612  QShortcut *short_tab2 = new QShortcut(QKeySequence("F2"), this);
613  connect(short_tab2, SIGNAL(activated()), sig_map, SLOT(map()));
614  sig_map->setMapping(short_tab2, 1);
615 
616  // Setup the shortcut for the third tab : Walking
617  QShortcut *short_tab3 = new QShortcut(QKeySequence("F3"), this);
618  connect(short_tab3, SIGNAL(activated()), sig_map, SLOT(map()));
619  sig_map->setMapping(short_tab3, 2);
620 
621  // Setup the shortcut for the fouth tab : Head control
622  QShortcut *short_tab4 = new QShortcut(QKeySequence("F4"), this);
623  connect(short_tab4, SIGNAL(activated()), sig_map, SLOT(map()));
624  sig_map->setMapping(short_tab4, 3);
625 
626  // Setup the shortcut for the fifth tab : Motion
627  QShortcut *short_tab5 = new QShortcut(QKeySequence("F5"), this);
628  connect(short_tab5, SIGNAL(activated()), sig_map, SLOT(map()));
629  sig_map->setMapping(short_tab5, 4);
630 
631  // Demo tab
632  QShortcut *short_tab6 = new QShortcut(QKeySequence("F6"), this);
633  connect(short_tab6, SIGNAL(activated()), sig_map, SLOT(map()));
634  sig_map->setMapping(short_tab6, 5);
635 
636  // Wire the signal mapper to the tab widget index change slot
637  connect(sig_map, SIGNAL(mapped(int)), ui_.tabWidget_control, SLOT(setCurrentIndex(int)));
638 }
639 
640 void MainWindow::updatePresentJointModule(std::vector<int> mode)
641 {
642  QList<QComboBox *> combo_children = ui_.widget_mode->findChildren<QComboBox *>();
643 
644  for (int ix = 0; ix < combo_children.length(); ix++)
645  {
646  int control_index = mode.at(ix);
647  combo_children.at(ix)->setCurrentIndex(control_index);
648 
649  if (debug_print_)
650  {
651  std::stringstream log_stream;
652  std::string joint_name;
653  int id;
654 
655  std::string control_mode = combo_children.at(ix)->currentText().toStdString();
656 
657  bool result = qnode_thor3_.getIDJointNameFromIndex(ix, id, joint_name);
658  if (result == true)
659  log_stream << "[" << (id < 10 ? "0" : "") << id << "] " << joint_name << " : " << control_mode;
660  else
661  log_stream << "id " << ix << " : " << control_mode;
662 
663  qnode_thor3_.log(QNodeThor3::Info, log_stream.str());
664  }
665  }
666 
667  // set module UI
668  updateModuleUI();
669 }
670 
672 {
673  if (debug_print_)
674  return;
675 
676  for (int index = 0; index < qnode_thor3_.getModuleTableSize(); index++)
677  {
678  std::string mode = qnode_thor3_.getModuleName(index);
679  if (mode == "")
680  continue;
681 
682  std::map<std::string, QList<QWidget *> >::iterator module_iter = module_ui_table_.find(mode);
683  if (module_iter == module_ui_table_.end())
684  continue;
685 
686  QList<QWidget *> list = module_iter->second;
687  for (int ix = 0; ix < list.size(); ix++)
688  {
689  bool is_enable = qnode_thor3_.isUsingModule(mode);
690  list.at(ix)->setEnabled(is_enable);
691  }
692  }
693 }
694 
695 // head control
696 void MainWindow::updateHeadJointsAngle(double pan, double tilt)
697 {
698  if (ui_.head_pan_slider->underMouse() == true)
699  return;
700  if (ui_.head_pan_spinbox->underMouse() == true)
701  return;
702  if (ui_.head_tilt_slider->underMouse() == true)
703  return;
704  if (ui_.head_tilt_spinbox->underMouse() == true)
705  return;
706 
707  is_updating_ = true;
708 
709  ui_.head_pan_slider->setValue(rad2deg<double>(pan));
710  ui_.head_tilt_slider->setValue(rad2deg<double>(tilt));
711 
712  is_updating_ = false;
713 }
714 
716 {
717  if (is_updating_ == true)
718  return;
719  qnode_thor3_.setHeadJoint(deg2rad<double>(ui_.head_pan_slider->value()),
720  deg2rad<double>(ui_.head_tilt_slider->value()));
721 }
722 
723 void MainWindow::setHeadJointsAngle(double pan, double tilt)
724 {
725  qnode_thor3_.setHeadJoint(deg2rad<double>(pan), deg2rad<double>(tilt));
726 }
727 
728 void MainWindow::playMotion(int motion_index)
729 {
730  bool to_action_script = ui_.checkBox_action_script->isChecked();
731 
732  qnode_thor3_.playMotion(motion_index, to_action_script);
733 }
734 
735 // manipulation
737 {
738  ui_.joint_spinbox->setValue(rad2deg<double>(value));
739 }
740 
741 void MainWindow::updateCurrPosSpinbox(double x, double y, double z)
742 {
743  ui_.pos_x_spinbox->setValue(x);
744  ui_.pos_y_spinbox->setValue(y);
745  ui_.pos_z_spinbox->setValue(z);
746 }
747 
748 void MainWindow::updateCurrOriSpinbox(double x, double y, double z, double w)
749 {
750  Eigen::Quaterniond orientation(w, x, y, z);
751  Eigen::Vector3d euler = rad2deg<Eigen::Vector3d>(quaternion2rpy(orientation));
752 
753  ui_.ori_roll_spinbox->setValue(euler[0]);
754  ui_.ori_pitch_spinbox->setValue(euler[1]);
755  ui_.ori_yaw_spinbox->setValue(euler[2]);
756 }
757 
758 void MainWindow::updateCurrOriSpinbox(double r, double p, double y)
759 {
760  ui_.ori_roll_spinbox->setValue(r);
761  ui_.ori_pitch_spinbox->setValue(p);
762  ui_.ori_yaw_spinbox->setValue(y);
763 }
764 
765 void MainWindow::setGripper(const double angle_deg, const double torque_limit, const std::string &arm_type)
766 {
767  sensor_msgs::JointState gripper_joint;
768  gripper_joint.name.push_back(arm_type);
769  gripper_joint.position.push_back(deg2rad<double>(angle_deg));
770  gripper_joint.effort.push_back(torque_limit);
771 
772  qnode_thor3_.sendGripperPosition(gripper_joint);
773 }
774 
775 // walking
776 void MainWindow::sendWalkingCommand(const std::string &command)
777 {
778  thormang3_foot_step_generator::FootStepCommand msg;
779 
780  msg.command = command;
781  msg.step_num = ui_.A1_spinbox_step_num->value();
782  msg.step_time = ui_.AB1_spinbox_step_time->value();
783  msg.step_length = ui_.B1_spinbox_f_step_length->value();
784  msg.side_step_length = ui_.C1_spinbox_s_step_length->value();
785  msg.step_angle_rad = deg2rad<double>(ui_.D1_spinbox_r_angle->value());
786 
788 }
789 
790 // Update UI - position
791 void MainWindow::updatePointPanel(const geometry_msgs::Point point)
792 {
793  is_updating_ = true;
794 
795  setPointToMarkerPanel(point);
796 
797  ROS_INFO("Update Position Panel");
798  is_updating_ = false;
799 }
800 
801 // Update UI - pose
802 void MainWindow::updatePosePanel(const geometry_msgs::Pose pose)
803 {
804  is_updating_ = true;
805 
806  setPoseToMarkerPanel(pose);
807 
808  ROS_INFO("Update Pose Panel");
809  is_updating_ = false;
810 }
811 
812 void MainWindow::getPoseFromMarkerPanel(geometry_msgs::Pose &current)
813 {
814  // position
815  current.position.x = ui_.dSpinBox_marker_pos_x->value();
816  current.position.y = ui_.dSpinBox_marker_pos_y->value();
817  current.position.z = ui_.dSpinBox_marker_pos_z->value();
818 
819  // orientation
820  Eigen::Vector3d euler(ui_.dSpinBox_marker_ori_r->value(), ui_.dSpinBox_marker_ori_p->value(),
821  ui_.dSpinBox_marker_ori_y->value());
822  Eigen::Quaterniond orientation = rpy2quaternion(deg2rad<Eigen::Vector3d>(euler));
823 
824  tf::quaternionEigenToMsg(orientation, current.orientation);
825 }
826 
827 void MainWindow::setPoseToMarkerPanel(const geometry_msgs::Pose &current)
828 {
829  // position
830  ui_.dSpinBox_marker_pos_x->setValue(current.position.x);
831  ui_.dSpinBox_marker_pos_y->setValue(current.position.y);
832  ui_.dSpinBox_marker_pos_z->setValue(current.position.z);
833 
834  // orientation
835  Eigen::Vector3d euler = rad2deg<Eigen::Vector3d>(quaternion2rpy(current.orientation));
836 
837  ui_.dSpinBox_marker_ori_r->setValue(euler[0]);
838  ui_.dSpinBox_marker_ori_p->setValue(euler[1]);
839  ui_.dSpinBox_marker_ori_y->setValue(euler[2]);
840 }
841 
842 void MainWindow::getPointFromMarkerPanel(geometry_msgs::Point &current)
843 {
844  // position
845  current.x = ui_.dSpinBox_marker_pos_x->value();
846  current.y = ui_.dSpinBox_marker_pos_y->value();
847  current.z = ui_.dSpinBox_marker_pos_z->value();
848 }
849 
850 void MainWindow::setPointToMarkerPanel(const geometry_msgs::Point &current)
851 {
852  // position
853  ui_.dSpinBox_marker_pos_x->setValue(current.x);
854  ui_.dSpinBox_marker_pos_y->setValue(current.y);
855  ui_.dSpinBox_marker_pos_z->setValue(current.z);
856 
857  // orientation
858  ui_.dSpinBox_marker_ori_r->setValue(0.0);
859  ui_.dSpinBox_marker_ori_p->setValue(0.0);
860  ui_.dSpinBox_marker_ori_y->setValue(0.0);
861 }
862 
863 // make interactive marker
865 {
866  geometry_msgs::Pose current_pose;
867  getPoseFromMarkerPanel(current_pose);
868 
869  qnode_thor3_.makeInteractiveMarker(current_pose);
870 }
871 
872 // update interactive marker pose from ui
874 {
875  if (is_updating_ == true)
876  return;
877 
878  geometry_msgs::Pose current_pose;
879  getPoseFromMarkerPanel(current_pose);
880 
882 }
883 
885 {
886  geometry_msgs::Pose init_pose;
887  updatePosePanel(init_pose);
888 
889  ROS_INFO("Clear Panel");
890 
892 }
893 
894 /*****************************************************************************
895  ** Implementation [Menu]
896  *****************************************************************************/
897 
899 {
900  QMessageBox::about(this, tr("About ..."), tr("<h2>THORMANG3 Demo</h2><p>Copyright Robotis</p>"));
901 }
902 
903 /*****************************************************************************
904  ** Implementation [Configuration]
905  *****************************************************************************/
906 
908 {
909  int number_joint = qnode_thor3_.getJointTableSize();
910 
911  // preset module button
912  QHBoxLayout *preset_layout = new QHBoxLayout;
913  QSignalMapper *signalMapper = new QSignalMapper(this);
914 
915  // parse yaml : preset modules
916  for (std::map<int, std::string>::iterator iter = qnode_thor3_.module_table_.begin();
917  iter != qnode_thor3_.module_table_.end(); ++iter)
918  {
919  std::string preset_name = iter->second;
920  QPushButton *preset_button = new QPushButton(tr(preset_name.c_str()));
921  if (debug_print_)
922  std::cout << "name : " << preset_name << std::endl;
923 
924  preset_layout->addWidget(preset_button);
925 
926  signalMapper->setMapping(preset_button, preset_button->text());
927  QObject::connect(preset_button, SIGNAL(clicked()), signalMapper, SLOT(map()));
928  }
929 
930  QObject::connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(enableModule(QString)));
931 
932  ui_.widget_mode_preset->setLayout(preset_layout);
933 
934  // joints
935  QGridLayout *grid_mod = new QGridLayout;
936  for (int ix = 0; ix < number_joint; ix++)
937  {
938  std::stringstream stream;
939  std::string joint;
940  int id;
941 
942  bool result = false;
943  result = qnode_thor3_.getIDJointNameFromIndex(ix, id, joint);
944 
945  if (result == false)
946  continue;
947 
948  stream << "[" << (id < 10 ? "0" : "") << id << "] " << joint;
949  QLabel *label = new QLabel(tr(stream.str().c_str()));
950 
951  QStringList list;
952  for (int index = 0; index < qnode_thor3_.getModuleTableSize(); index++)
953  {
954  std::string mode = qnode_thor3_.getModuleName(index);
955  if (mode != "")
956  list << mode.c_str();
957  }
958 
959  QComboBox *combo = new QComboBox();
960  combo->setObjectName(tr(joint.c_str()));
961  combo->addItems(list);
962  combo->setEnabled(false); // not changable
963  int row = ix / 2 + 1;
964  int col = (ix % 2) * 3;
965  grid_mod->addWidget(label, row, col, 1, 1);
966  grid_mod->addWidget(combo, row, col + 1, 1, 2);
967  }
968 
969  // get buttons
970  QPushButton *get_mode_button = new QPushButton(tr("Get Mode"));
971  grid_mod->addWidget(get_mode_button, (number_joint / 2) + 2, 0, 1, 3);
972  QObject::connect(get_mode_button, SIGNAL(clicked(bool)), &qnode_thor3_, SLOT(getJointControlModule()));
973 
974  ui_.widget_mode->setLayout(grid_mod);
975 
976  // make module widget table
977  for (int index = 0; index < qnode_thor3_.getModuleTableSize(); index++)
978  {
979  std::string mode = qnode_thor3_.getModuleName(index);
980  if (mode == "")
981  continue;
982  std::string mode_reg = "*" + mode;
983 
984  QRegExp rx(QRegExp(tr(mode_reg.c_str())));
985  rx.setPatternSyntax(QRegExp::Wildcard);
986 
987  QList<QWidget *> list = ui_.centralwidget->findChildren<QWidget *>(rx);
988  module_ui_table_[mode] = list;
989 
990  if (debug_print_)
991  std::cout << "Module widget : " << mode << " [" << list.size() << "]" << std::endl;
992  }
993 
994  // make motion tab
995  if (qnode_thor3_.getModuleIndex("action_module") != -1)
996  initMotionUnit();
997 }
998 
1000 {
1001  // preset button
1002  QGridLayout *motion_layout = new QGridLayout;
1003  QGridLayout *demo_motion_layout = new QGridLayout;
1004  QSignalMapper *signalMapper = new QSignalMapper(this);
1005  QSignalMapper *demo_signalMapper = new QSignalMapper(this);
1006 
1007  // yaml preset
1008  int index = 0;
1009  for (std::map<int, std::string>::iterator iter = qnode_thor3_.motion_table_.begin();
1010  iter != qnode_thor3_.motion_table_.end(); ++iter)
1011  {
1012  int motion_index = iter->first;
1013  std::string motion_name = iter->second;
1014  QString q_motion_name = QString::fromStdString(motion_name);
1015  QPushButton *motion_button = new QPushButton(q_motion_name);
1016  QPushButton *demo_motion_button = new QPushButton(q_motion_name);
1017 
1018  int size = (motion_index < 0) ? 2 : 1;
1019  int row = index / 4;
1020  int col = index % 4;
1021  motion_layout->addWidget(motion_button, row, col, 1, size);
1022  demo_motion_layout->addWidget(demo_motion_button, row, col, 1, size);
1023 
1024  signalMapper->setMapping(motion_button, motion_index);
1025  QObject::connect(motion_button, SIGNAL(clicked()), signalMapper, SLOT(map()));
1026  demo_signalMapper->setMapping(demo_motion_button, motion_index);
1027  QObject::connect(demo_motion_button, SIGNAL(clicked()), demo_signalMapper, SLOT(map()));
1028 
1029  index += size;
1030  }
1031 
1032  int row = index / 4;
1033  row = (index % 4 == 0) ? row : row + 1;
1034  QSpacerItem *verticalSpacer = new QSpacerItem(20, 400, QSizePolicy::Minimum, QSizePolicy::Expanding);
1035  motion_layout->addItem(verticalSpacer, row, 0, 1, 4);
1036  QSpacerItem *demo_verticalSpacer = new QSpacerItem(20, 400, QSizePolicy::Minimum, QSizePolicy::Expanding);
1037  demo_motion_layout->addItem(demo_verticalSpacer, row, 0, 1, 4);
1038 
1039  QObject::connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(playMotion(int)));
1040  QObject::connect(demo_signalMapper, SIGNAL(mapped(int)), this, SLOT(playMotion(int)));
1041 
1042  ui_.scroll_widget_motion->setLayout(motion_layout);
1043  ui_.scroll_widget_demo_motion->setLayout(demo_motion_layout);
1044 }
1045 
1046 void MainWindow::enableModule(QString mode_name)
1047 {
1048  qnode_thor3_.enableControlModule(mode_name.toStdString());
1049 }
1050 
1052 {
1053  QSettings settings("Qt-Ros Package", "thormang3_demo");
1054  restoreGeometry(settings.value("geometry").toByteArray());
1055  restoreState(settings.value("windowState").toByteArray());
1056 }
1057 
1059 {
1060  QSettings settings("Qt-Ros Package", "thormang3_demo");
1061  settings.setValue("geometry", saveGeometry());
1062  settings.setValue("windowState", saveState());
1063 }
1064 
1065 void MainWindow::closeEvent(QCloseEvent *event)
1066 {
1067  writeSettings();
1068  QMainWindow::closeEvent(event);
1069 }
1070 
1071 /*****************************************************************************
1072  ** Implementation [Util]
1073  *****************************************************************************/
1074 // math : euler & quaternion & rotation mat
1075 Eigen::Vector3d MainWindow::rotation2rpy(const Eigen::MatrixXd &rotation)
1076 {
1077  Eigen::Vector3d rpy;
1078 
1079  rpy[0] = atan2(rotation.coeff(2, 1), rotation.coeff(2, 2));
1080  rpy[1] = atan2(-rotation.coeff(2, 0), sqrt(pow(rotation.coeff(2, 1), 2) + pow(rotation.coeff(2, 2), 2)));
1081  rpy[2] = atan2(rotation.coeff(1, 0), rotation.coeff(0, 0));
1082 
1083  return rpy;
1084 }
1085 
1086 Eigen::MatrixXd MainWindow::rpy2rotation(const double &roll, const double &pitch, const double &yaw)
1087 {
1088  Eigen::MatrixXd rotation = rotationZ(yaw) * rotationY(pitch) * rotationX(roll);
1089 
1090  return rotation;
1091 }
1092 
1093 Eigen::Quaterniond MainWindow::rpy2quaternion(const Eigen::Vector3d &euler)
1094 {
1095  return rpy2quaternion(euler[0], euler[1], euler[2]);
1096 }
1097 
1098 Eigen::Quaterniond MainWindow::rpy2quaternion(const double &roll, const double &pitch, const double &yaw)
1099 {
1100  Eigen::MatrixXd rotation = rpy2rotation(roll, pitch, yaw);
1101 
1102  Eigen::Matrix3d rotation3d;
1103  rotation3d = rotation.block(0, 0, 3, 3);
1104 
1105  Eigen::Quaterniond quaternion;
1106 
1107  quaternion = rotation3d;
1108 
1109  return quaternion;
1110 }
1111 
1112 Eigen::Quaterniond MainWindow::rotation2quaternion(const Eigen::MatrixXd &rotation)
1113 {
1114  Eigen::Matrix3d rotation3d;
1115 
1116  rotation3d = rotation.block(0, 0, 3, 3);
1117 
1118  Eigen::Quaterniond quaternion;
1119  quaternion = rotation3d;
1120 
1121  return quaternion;
1122 }
1123 
1124 Eigen::Vector3d MainWindow::quaternion2rpy(const Eigen::Quaterniond &quaternion)
1125 {
1126  Eigen::Vector3d rpy = rotation2rpy(quaternion.toRotationMatrix());
1127 
1128  return rpy;
1129 }
1130 
1131 Eigen::Vector3d MainWindow::quaternion2rpy(const geometry_msgs::Quaternion &quaternion)
1132 {
1133  Eigen::Quaterniond eigen_quaternion;
1134  tf::quaternionMsgToEigen(quaternion, eigen_quaternion);
1135 
1136  Eigen::Vector3d rpy = rotation2rpy(eigen_quaternion.toRotationMatrix());
1137 
1138  return rpy;
1139 }
1140 
1141 Eigen::MatrixXd MainWindow::quaternion2rotation(const Eigen::Quaterniond &quaternion)
1142 {
1143  Eigen::MatrixXd rotation = quaternion.toRotationMatrix();
1144 
1145  return rotation;
1146 }
1147 
1148 Eigen::MatrixXd MainWindow::rotationX(const double &angle)
1149 {
1150  Eigen::MatrixXd rotation(3, 3);
1151 
1152  rotation << 1.0, 0.0, 0.0, 0.0, cos(angle), -sin(angle), 0.0, sin(angle), cos(angle);
1153 
1154  return rotation;
1155 }
1156 
1157 Eigen::MatrixXd MainWindow::rotationY(const double &angle)
1158 {
1159  Eigen::MatrixXd rotation(3, 3);
1160 
1161  rotation << cos(angle), 0.0, sin(angle), 0.0, 1.0, 0.0, -sin(angle), 0.0, cos(angle);
1162 
1163  return rotation;
1164 }
1165 
1166 Eigen::MatrixXd MainWindow::rotationZ(const double &angle)
1167 {
1168  Eigen::MatrixXd rotation(3, 3);
1169 
1170  rotation << cos(angle), -sin(angle), 0.0, sin(angle), cos(angle), 0.0, 0.0, 0.0, 1.0;
1171 
1172  return rotation;
1173 }
1174 
1175 } // namespace thormang3_demo
void on_button_walking_demo_1_clicked(bool check)
bool getIDJointNameFromIndex(const int &index, int &id, std::string &joint_name)
Definition: qnode.cpp:288
void on_C2_button_br_clicked(bool check)
Eigen::Vector3d quaternion2rpy(const Eigen::Quaterniond &quaternion)
void on_dSpinBox_marker_ori_y_valueChanged(double value)
void sendInitPoseMsg(std_msgs::String msg)
Definition: qnode.cpp:560
void on_dSpinBox_marker_ori_p_valueChanged(double value)
void on_button_balance_off_clicked(bool check)
void on_button_grip_on_clicked(bool check)
void on_button_ft_calc_clicked(bool check)
Eigen::MatrixXd rpy2rotation(const double &roll, const double &pitch, const double &yaw)
void on_despos_button_clicked(bool check)
Eigen::MatrixXd rotationX(const double &angle)
void on_button_manipulation_demo_7_clicked(bool check)
void setGripper(const double angle_deg, const double torque_limit, const std::string &arm_type)
Eigen::Quaterniond rotation2quaternion(const Eigen::MatrixXd &rotation)
void quaternionEigenToMsg(const Eigen::Quaterniond &e, geometry_msgs::Quaternion &m)
std::map< std::string, QList< QWidget * > > module_ui_table_
void sendDestJointMsg(thormang3_manipulation_module_msgs::JointPose msg)
Definition: qnode.cpp:567
void updatePointPanel(const geometry_msgs::Point point)
void on_A1_button_f_clicked(bool check)
void on_button_feedback_gain_apply_clicked(bool check)
void on_button_manipulation_demo_6_clicked(bool check)
void updatePresentJointModule(std::vector< int > mode)
void on_A2_button_go_walking_clicked(bool check)
void on_A2_button_fr_clicked(bool check)
void on_button_clear_log_clicked(bool check)
static const double GRIPPER_TORQUE_LIMIT
bool isUsingModule(const std::string &module_name)
Definition: qnode.cpp:349
void updateCurrOriSpinbox(double x, double y, double z, double w)
void on_button_assemble_lidar_clicked(bool check)
void getKinematicsPose(std::string group_name)
Definition: qnode.cpp:638
void on_B2_button_r_clicked(bool check)
Eigen::MatrixXd rotationY(const double &angle)
void closeEvent(QCloseEvent *event)
void on_button_walking_demo_6_clicked(bool check)
void enableControlModule(const std::string &mode)
Definition: qnode.cpp:396
void on_button_ft_save_clicked(bool check)
void on_dSpinBox_marker_ori_r_valueChanged(double value)
void on_A0_button_fl_clicked(bool check)
void setWalkingBalance(bool on_command)
Definition: qnode.cpp:706
void updateCurrJointSpinbox(double value)
void on_currpos_button_clicked(bool check)
Ui::MainWindowDesign ui_
void on_button_manipulation_demo_2_clicked(bool check)
void kickDemo(const std::string &kick_foot)
Definition: qnode.cpp:1496
void on_button_motion_demo_1_clicked(bool check)
void playMotion(int motion_index, bool to_action_script=true)
Definition: qnode.cpp:1204
void on_dSpinBox_marker_pos_y_valueChanged(double value)
void sendGripperPosition(sensor_msgs::JointState msg)
Definition: qnode.cpp:598
void on_currjoint_button_clicked(bool check)
void enableModule(QString mode_name)
void sendWalkingCommand(const std::string &command)
void on_button_manipulation_demo_0_clicked(bool check)
static const double GRIPPER_OFF_ANGLE
void on_button_walking_demo_0_clicked(bool check)
void getPointFromMarkerPanel(geometry_msgs::Point &current)
void on_button_manipulation_demo_5_clicked(bool check)
void on_B1_button_stop_clicked(bool check)
#define ROS_INFO(...)
void on_button_manipulation_demo_3_clicked(bool check)
void on_C1_button_b_clicked(bool check)
void on_A1_button_clear_step_clicked(bool check)
void on_button_walking_demo_2_clicked(bool check)
void on_button_walking_demo_3_clicked(bool check)
void on_button_init_pose_clicked(bool check)
void playMotion(int motion_index)
void on_get_despos_button_clicked(bool check)
void setPointToMarkerPanel(const geometry_msgs::Point &current)
void getPoseFromMarkerPanel(geometry_msgs::Pose &current)
void on_button_walking_demo_4_clicked(bool check)
void updatePosePanel(const geometry_msgs::Pose pose)
void on_button_manipulation_demo_1_clicked(bool check)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
Eigen::Vector3d rotation2rpy(const Eigen::MatrixXd &rotation)
void on_B0_button_l_clicked(bool check)
void on_inipose_button_clicked(bool check)
void log(const LogLevel &level, const std::string &msg, std::string sender="Demo")
Definition: qnode.cpp:1559
void getJointPose(std::string joint_name)
Definition: qnode.cpp:604
void setWalkingCommand(thormang3_foot_step_generator::FootStepCommand msg)
Definition: qnode.cpp:692
MainWindow(int argc, char **argv, QWidget *parent=0)
Definition: main_window.cpp:41
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
void on_button_ft_air_clicked(bool check)
void on_dSpinBox_marker_pos_x_valueChanged(double value)
std::map< int, std::string > module_table_
Definition: qnode.hpp:163
void on_A0_button_get_step_clicked(bool check)
static const double GRIPPER_ON_ANGLE
void on_button_balance_on_clicked(bool check)
std::string getModuleName(const int &index)
Definition: qnode.cpp:307
void on_button_walking_demo_7_clicked(bool check)
void on_button_walking_demo_5_clicked(bool check)
std::map< int, std::string > motion_table_
Definition: qnode.hpp:164
void on_button_grip_off_clicked(bool check)
void initFTCommand(std::string command)
Definition: qnode.cpp:377
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
void updateHeadJointsAngle(double pan, double tilt)
void on_head_center_button_clicked(bool check)
void quaternionMsgToEigen(const geometry_msgs::Quaternion &m, Eigen::Quaterniond &e)
void on_desjoint_button_clicked(bool check)
void on_C0_button_bl_clicked(bool check)
void sendIkMsg(thormang3_manipulation_module_msgs::KinematicsPose msg)
Definition: qnode.cpp:580
void on_button_manipulation_demo_4_clicked(bool check)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
void updateCurrPosSpinbox(double x, double y, double z)
int getModuleIndex(const std::string &mode_name)
Definition: qnode.cpp:319
void on_button_ft_gnd_clicked(bool check)
void on_tabWidget_control_currentChanged(int index)
void makeInteractiveMarker(const geometry_msgs::Pose &marker_pose)
Definition: qnode.cpp:1309
Eigen::Quaterniond rpy2quaternion(const Eigen::Vector3d &euler)
QStringListModel * loggingModel()
Definition: qnode.hpp:110
Eigen::MatrixXd rotationZ(const double &angle)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Eigen::MatrixXd quaternion2rotation(const Eigen::Quaterniond &quaternion)
void on_dSpinBox_marker_pos_z_valueChanged(double value)
void on_button_motion_demo_0_clicked(bool check)
void updateInteractiveMarker(const geometry_msgs::Pose &pose)
Definition: qnode.cpp:1452
void setPoseToMarkerPanel(const geometry_msgs::Pose &current)
void setHeadJoint(double pan, double tilt)
Definition: qnode.cpp:546


thormang3_demo
Author(s): Kayman
autogenerated on Mon Jun 10 2019 15:38:34