selectCtrl.cpp
Go to the documentation of this file.
1 
11 #include <gui/selectCtrl.hpp>
12 #include <gui/window.hpp>
13 #include <ctrl/file.hpp>
14 #include <ctrl/smoothPath.hpp>
15 #include <ctrl/goPID.hpp>
16 #include <ctrl/imitate.hpp>
17 #include <ctrl/PID.hpp>
18 #include <ctrl/analytic.hpp>
19 #include <gui/teleop.hpp>
20 #include <QMessageBox>
21 //#include <iostream>
22 
23 
24 // The name displayed when no save file is selected.
25 const char *QtCtrlSelect::default_save_name = "None";
26 
27 /* The dialog is build with a given parent and a time step
28  * for the future controller.
29  *
30  * Parameter parent the parent widget of the dialog,
31  * tm_stp the future controller's time step,
32  * motion the controller motion model.
33  */
34 QtCtrlSelect::QtCtrlSelect(QWidget* parent, const double tm_stp,
35  const MotionModel& motion)
36  : OkCancelDialog(parent, "ROS qt_ctrl Controller Selector",
37  "Which qt_ctrl controller do you want\n"
38  "to start, and in which ROS environment?"),
39  ROS_workspace( tr("ROS workspace") ), ctrl_id(-1),
40  save_file( tr(default_save_name) ), time_step(tm_stp),
41  motion_model(motion), controller(NULL), ctrl_wdgt(NULL) {
42  int index, idx2;
43  QWidget *ROS_line = new QWidget();
44  QHBoxLayout *ROS_layout = new QHBoxLayout(ROS_line);
45  // the center part of the dialog contains several group boxes:
46  // one for the ROS connection (containing a second one for the ROS
47  // workspace), one for the controller selection and one for output
48  // file.
49  QGroupBox
50  *ROS_connect = new QGroupBox(tr("Connection to ROS"), ROS_line),
51  *ctrl_line = new QGroupBox(tr("Controller Selection"), this),
52  *output_line = new QGroupBox(tr("Output File"), this);
53  // === ROS environment selection ===================================
54  QBoxLayout *ROS_layouts[ROS_choices]; // one layout for each group
55  QWidget *ROS_widget[ROS_choices] // the associated widget
56  = {ROS_connect, &ROS_workspace};
57  // Text of the ROS radio buttons & associated shortcuts
58  static const char *ROS_select[ROS_choices][ROS_choices]
59  = { {"ROS &already started", "&Start ROS with Gazebo"},
60  {"&Empty workspace", "&Default workspace"} },
61  ROS_shortcut[ROS_choices][ROS_choices]
62  = { {'A', 'S'}, {'E', 'D'} };
63  for(index = 0; index < ROS_choices; index++) {
64  ROS_layout->addWidget(ROS_widget[index]); // add group box to line
65  ROS_layouts[index] // defining the layout
66  = new QBoxLayout(QBoxLayout::LeftToRight, ROS_widget[index]);
67  for(idx2 = 0; idx2 < ROS_choices; idx2++) {
68  select_ROS[index][idx2].setText( tr(ROS_select[index][idx2]) );
69  select_ROS[index][idx2].setShortcut(ROS_shortcut[index][idx2]);
70  // changing the first two enables or disables the last two
71  if (index == 0)
72  connect( &select_ROS[index][idx2], SIGNAL( clicked() ),
73  this, SLOT( updateROSline() ) );
74  // was "index + idx2 == 1" for (0,1) and (1,0)
75  select_ROS[index][idx2].setChecked(idx2 == 0);
76  updateROSline(); // to disable the last two
77  ROS_layouts[index]->addWidget( &(select_ROS[index][idx2]) );
78  } } // end of for (all ROS buttons)
79  insertWidget(*ROS_line);
80  // === controller selection ========================================
81  QHBoxLayout *ctrl_layout = new QHBoxLayout(ctrl_line);
82  static const int ctrl_nb = 7;
83  static const char *ctrl_names[ctrl_nb]
84  = { "Keyboard Operating Controller", "File Operating Controller",
85  "PID Reaching Controller", "Analytic Reaching Controller",
86  "Copy Tracking Controller", "PID Tracking Controller",
87  "(Analytic Tracking Controller - not yet working)" };
88  ctrl_select.setParent(ctrl_line);
89  // fills the pop-up menu with the list of possible controllers
90  for(index = 0; index < ctrl_nb; index++)
91  ctrl_select.addItem( tr(ctrl_names[index]) );
92  // connects the pop-up selection to the related method
93  connect( &ctrl_select, SIGNAL( activated(int) ),
94  this, SLOT( updateCtrl(int) ) );
95  // connects the controller parameters button to the method
96  connect( &ctrl_param, SIGNAL( clicked() ),
97  this, SLOT( updateCtrl() ) );
98  // adds the pop-up menu and its associated button to the ctrl line
99  ctrl_layout->addWidget(&ctrl_select);
100  updateCtrl(0); // set the label text
101  ctrl_layout->addWidget(&ctrl_param);
102  insertWidget(*ctrl_line); // adds the ctrl line to the dialog
103  // === output file =================================================
104  QHBoxLayout *output_layout = new QHBoxLayout(output_line);
105  output_layout->addWidget( new QLabel( tr("Robot's motion"
106  " save file:") ) );
107  output_layout->addWidget(&save_file);
108  connect( &save_file, SIGNAL( clicked() ),
109  this, SLOT( updateFileName() ) );
110  insertWidget(*output_line);
111 } // end of QtCtrlSelect::QtCtrlSelect(QWidget*) ---------------------
112 
113 // Changes the selected controller.
114 // Parameter new_id the new controller number, in the selection list.
115 void QtCtrlSelect::updateCtrl(int new_id) {
116  const bool tracking = new_id > 3;
117  QString input_file; // for file and tracking controllers
118  State goal; // for reaching controllers
119  iSeeML::rob::OrPtConfig q; // for tracking controllers
120  static const int nb_coef = 6; // for PID controllers...
121  static const double h_coef = 1 / 0.35; // from [DP96]
122  const double time_coef = 1 / time_step;
123  double coef[nb_coef] =
124  { h_coef * h_coef, h_coef, 0,
125  time_coef * time_coef, time_coef, 0 };
126  // only the first controller do not need additional data
127  bool valid_change = (new_id == 0);
128  // an input file is needed for file operation or tracking
129  if ( (new_id == 1) || tracking ) {
130  const QString input_type = QString( tr("%1 File") )
131  .arg(new_id == 1 ? "Accelerations" : "Trajectory");
132  input_file = QFileDialog::getOpenFileName
133  ( this, input_type, "", tr("CSV File (*.csv *.txt)") );
134  valid_change = (! input_file.isNull() )
135  && (! input_file.isEmpty() );
136  } // end of if (input file needed)
137  if ( (new_id > 1) && (new_id < 4) ) // reaching -> state needed
138  valid_change = getState
139  (this, "State to reach",
140  "Enter the goal for the controller to reach", goal);
141  if (tracking && valid_change) // configuration needed
142  valid_change = getOrPtConfig(this, "Initial error setting",
143  "Set the initial error", q);
144  // PID parameters are needed for PID controllers
145  if ( ( (new_id == 2) || (new_id == 5) ) && valid_change ) {
146  static const char* name_coef[nb_coef]
147  = { "Prop_trans", "Integ_trans", "Deriv_trans",
148  "Prop_rot", "Integ_rot", "Deriv_rot" };
149  static const bool coef_Greek[nb_coef]
150  = {false, false, false, false, false, false};
151  valid_change = getDoubleArray
152  (this, "PID Parameters Setting", "Enter the PID parameters:",
153  2, nb_coef / 2, name_coef, coef_Greek, coef);
154  } // end of if (PID parameters needed)
155  if (valid_change) {
156  // updates the parameters button's state, if needed
157  if (ctrl_id != new_id) {
158  ctrl_id = new_id;
159  ctrl_param.setText( tr("Controller #%1's parameters")
160  .arg(ctrl_id) );
161  ctrl_param.setEnabled(ctrl_id != 0);
162  } // end of if (update of the parameters button's state needed)
163  // gets the parent as a QtCtrlGUI
164  QtCtrlGUI* ctrl_gui = qobject_cast<QtCtrlGUI*>( parent() );
165  // this string needs to remain allocated?
166  const std::string file_sname = input_file.toStdString();
167  // transforms the input file name from a QString to a char*
168  const char *file_name = file_sname.c_str();
169  //std::cout << "Input File: '" << file_name << "'\n";
170  if ( (*file_name != '\0') && (*file_name != '/') )
171  QMessageBox::warning( this, tr("Abnormal Input File Name"),
172  tr("Input file name '%1' seems invalid")
173  .arg(file_name) );
174  switch (ctrl_id) { // defining the new controller & widget
175  case 0: { // keyboard controller & associated widget
176  KbdCtrl* new_ctrl = new KbdCtrl(motion_model, time_step);
177  controller = new_ctrl;
178  ctrl_wdgt = new TeleopWidget(*ctrl_gui, *new_ctrl,
179  motion_model);
180  } break;
181  case 1: // file controller & associated widget
182  controller = new FileCtrl(motion_model, time_step, file_name);
183  break;
184  case 2: // PID reaching controller & associated widget
186  goal, coef);
187  break;
188  case 3: { // analytic reaching controller & associated widget
189  SmoothPathCtrl *new_ctrl =
191  controller = new_ctrl;
192  if (ctrl_gui) // if so, makes the connection
193  connect( new_ctrl, SIGNAL( pathChanged() ),
194  ctrl_gui, SLOT( updateTrajectory() ) );
195  } break;
196  default: { // tracking controllers & associated widget
197  TrackingCtrl *new_ctrl = // needed for trajectory()
198  ctrl_id == 6 ? (TrackingCtrl*)
199  new AnalyticCtrl(motion_model, time_step, file_name, q)
200  : ctrl_id == 5 ? (TrackingCtrl*)
201  new PIDCtrl(motion_model, time_step, file_name, q, coef)
202  : (TrackingCtrl*)
203  new ImitateCtrl(motion_model, time_step, file_name, q);
204  controller = new_ctrl;
205  if (ctrl_gui) // if so, reset the tracked trajectory
206  ctrl_gui->newTrajectory( new_ctrl->trajectory() ); }
207  } // end of switch (defining the new controller & widget)
208  //std::cout << "Input File: '" << file_name << "'\n";
209  if (ctrl_id != 0) // defines the new controller's widget
210  ctrl_wdgt = new ViewCtrlWdgt(*ctrl_gui, *controller,
211  motion_model);
212  } // end of if (if change is validated)
213  else // changes the pop-up menu back to the proper line
214  ctrl_select.setCurrentIndex(ctrl_id);
215 } // end of void QtCtrlSelect::updateCtrl() -------------------------
216 
217 // Updates the button displaying the save file.
219  save_file_name = QFileDialog::getSaveFileName
220  ( this, tr("Please select a save file"),
221  "", tr("CSV File (*.csv *.txt)") );
222  if ( save_file_name.isNull() || save_file_name.isEmpty() )
223  save_file.setText( tr(default_save_name) );
224  else {
225  QFileInfo file_info(save_file_name);
226  save_file.setText( file_info.baseName() );
227  } // end of else (file is defined)
228 } // end of void QtCtrlSelect::updateFileName() ----------------------
Qt based GUI for qt_ctrl package.
Oriented point reaching controller class using a smooth path generator.
PIDCtrl uses a PID to compute the trajectory&#39;s velocities.
Definition: PID.hpp:24
QString save_file_name
The save file name.
Definition: selectCtrl.hpp:59
This class defines a sub-class of dialog windows which lower part is a horizontal button panel with o...
Definition: inputDialog.hpp:27
KbdCtrl allows to control the robot with the keyboard.
Definition: keyboard.hpp:23
static const char * default_save_name
The name displayed when no save file is selected.
Definition: selectCtrl.hpp:56
File controller (teleoperation) class.
TrackingCtrl aims at following a trajectory with the robot.
Definition: track.hpp:23
QPushButton save_file
The button displaying and changing save file.
Definition: selectCtrl.hpp:62
QComboBox ctrl_select
The pop-up menu with the list of possible controllers.
Definition: selectCtrl.hpp:47
int ctrl_id
The identification number of the selected controller.
Definition: selectCtrl.hpp:50
This class is a Qt widget which allows to show the controller&#39;s behaviour (current and aimed velociti...
Definition: viewCtrl.hpp:24
Path following controller class, using a PID.
static bool getDoubleArray(QWidget *parent, const char *title, const char *msg, const int nb_lines, const int nb_col, const char *nameVal[], const bool isGreek[], double val[])
Asks in a dialog for a set of doubles, and returns it.
Definition: inputDialog.cpp:66
const double time_step
The controller&#39;s time step.
Definition: selectCtrl.hpp:65
void updateFileName()
Updates the button displaying the save file.
Definition: selectCtrl.cpp:218
void insertWidget(QWidget &widget)
Inserts the given widget (containing the inputs) in the dialog, between message and buttons...
Definition: inputDialog.hpp:92
void newTrajectory(const std::list< State * > &trajectory)
Adds a trajectory to the motion display.
Definition: window.hpp:144
QRadioButton select_ROS[ROS_choices][ROS_choices]
The radio buttons to select ROS environment.
Definition: selectCtrl.hpp:44
This class defines a state, i.e. a configuration and its (translation and rotation) velocities...
Definition: state.hpp:22
ControlWidget * ctrl_wdgt
The widget showing the controller&#39;s velocities.
Definition: selectCtrl.hpp:74
SmoothPathCtrl aims at reaching an oriented point with the robot, using a smooth path generator...
Definition: smoothPath.hpp:26
Qt based teleoperation widget for qt_ctrl.
const MotionModel & motion_model
The motion model of the controlled robot.
Definition: selectCtrl.hpp:68
Qt dialog window to select the control used by the qt_ctrl GUI.
This class defines a motion model, with the motion limits.
Definition: motion.hpp:28
FileCtrl allows to control the robot from a file.
Definition: file.hpp:25
QGroupBox ROS_workspace
The ROS workspace group box (may be desabled).
Definition: selectCtrl.hpp:41
void updateCtrl()
Updates the parameters of the current controller.
Definition: selectCtrl.hpp:122
PID controller reaching an oriented point.
ImitateCtrl copies the trajectory&#39;s velocities.
Definition: imitate.hpp:23
Path following controller class, copying the velocities.
This class is the Qt main window of qt_ctrl package.
Definition: window.hpp:41
QPushButton ctrl_param
The button to set the controller&#39;s parameters.
Definition: selectCtrl.hpp:53
PIDreachCtrl aims at reaching an oriented point with the robot, using a PID controller.
Definition: goPID.hpp:21
const std::list< State * > & trajectory() const
Gives the tracked trajectory.
Definition: track.hpp:75
QtCtrlSelect(QWidget *parent, const double tm_stp, const MotionModel &motion)
The dialog is build with a given parent and a time step for the future controller.
Definition: selectCtrl.cpp:34
static bool getOrPtConfig(QWidget *parent, const char *title, const char *msg, iSeeML::rob::OrPtConfig &q)
Asks in a dialog for an oriented point.
Path following controller class, with an analytic approach.
AnalyticCtrl compute the trajectory&#39;s velocities using analytic geometry and mecanic.
Definition: analytic.hpp:24
void updateROSline()
Enables or disables the ROS workspace group box.
Definition: selectCtrl.hpp:114
static const int ROS_choices
The number of ROS environments and sub-environments.
Definition: selectCtrl.hpp:38
int index
The index of additional widgets.
Definition: inputDialog.hpp:31
static bool getState(QWidget *parent, const char *title, const char *msg, State &state)
Asks in a dialog for a state.
This class is a Qt widget which allows to control the keyboard controller.
Definition: teleop.hpp:31
Controller * controller
The controller created by this dialog.
Definition: selectCtrl.hpp:71


qt_ctrl
Author(s): Alexis Scheuer
autogenerated on Wed Dec 16 2020 15:51:32