segwayrmp_gui.cc
Go to the documentation of this file.
1 #include "segwayrmp/segwayrmp.h"
3 #include "ui_segwayrmp_gui.h"
5 
6 #include <QtCore/QtConcurrentRun>
7 #include <QtGui/QErrorMessage>
8 #include <QtCore/QTimer>
9 
10 #define JOY_DEADBAND 3200
11 #define JOY_MAX_VALUE 32768
12 
13 MainWindow::MainWindow(QWidget *parent) :
14  QMainWindow(parent),
15  ui(new Ui::MainWindow),
16  connected_(false),
17  interface_type_(segwayrmp::usb),
18  rmp_type_(segwayrmp::rmp200),
19  joystick_(0),
20  running_(true)
21 {
22  // Init UI
23  ui->setupUi(this);
24  this->usb_devices_.push_back("No devices detected.");
25  this->updateUSBList();
26  // Init SDL
27  SDL_Init(SDL_INIT_JOYSTICK);
28  SDL_JoystickEventState(SDL_ENABLE);
29  this->updateJoysticks();
30  QTimer * timer = new QTimer(this);
31 
32  // Connection related signals and slots
33  connect(ui->connect_button, SIGNAL(clicked()), this, SLOT(onConnectClicked()));
34 
35  connect(ui->connection_type, SIGNAL(currentIndexChanged(QString)), this, SLOT(connectionTypeChanged(QString)));
36 
37  connect(ui->rmp_type, SIGNAL(currentIndexChanged(QString)), this, SLOT(rmpTypeChanged(QString)));
38 
39  connect(ui->refresh_button, SIGNAL(clicked()), this, SLOT(updateUSBList()));
40  connect(this, SIGNAL(USBUpdateComplete()), this, SLOT(USBListUpdated()));
41 
42  // Logging connections
43  connect(this, SIGNAL(segwayLog(QString)), this, SLOT(handleSegwayLog(QString)));
44 
45  // Segway Status connection
46  connect(this, SIGNAL(segwayStatus(QString)), this, SLOT(handleSegwayStatus(QString)));
47 
48  // Command button connections
49  connect(ui->reset_integrators_button, SIGNAL(clicked()), this, SLOT(onResetIntegrators()));
50  connect(ui->disable_motors_button, SIGNAL(clicked()), this, SLOT(onDisableMotors()));
51  connect(ui->tractor_button, SIGNAL(clicked()), this, SLOT(onRequestTractor()));
52  connect(ui->balance_button, SIGNAL(clicked()), this, SLOT(onRequestBalance()));
53  connect(ui->power_down_button, SIGNAL(clicked()), this, SLOT(onRequestPowerDown()));
54  connect(ui->balance_lockout_button, SIGNAL(clicked()), this, SLOT(onBalanceLockout()));
55  connect(ui->balance_unlock_button, SIGNAL(clicked()), this, SLOT(onBalanceUnlock()));
56  connect(ui->send_config_button, SIGNAL(clicked()), this, SLOT(onSendConfig()));
57 
58  // joystick stuff
59  connect(ui->joy_list_cb, SIGNAL(activated(int)), this, SLOT(onJoystickChanged(int)));
60  connect(timer, SIGNAL(timeout()), this, SLOT(commandPoll()));
61  timer->start(1000.0/25.0);
62  this->onJoystickChanged(0);
63 }
64 
66 {
67  delete ui;
68 }
69 
70 void MainWindow::closeEvent(QCloseEvent * e) {
71  this->running_ = false;
72 }
73 
75  this->joy_mutex_.lock();
76  // If the joystick isn't there do nothing
77  if (!this->joystick_) {
78  this->joy_mutex_.unlock();
79  return;
80  }
81  SDL_JoystickUpdate();
82  int lv_i = SDL_JoystickGetAxis(this->joystick_, ui->lv_axis_cb->currentIndex());
83  int av_i = SDL_JoystickGetAxis(this->joystick_, ui->av_axis_cb->currentIndex());
84  this->joy_mutex_.unlock();
85  // Deadband
86  if (lv_i > -JOY_DEADBAND && lv_i < JOY_DEADBAND) {
87  lv_i = 0;
88  }
89  if (av_i > -JOY_DEADBAND && av_i < JOY_DEADBAND) {
90  av_i = 0;
91  }
92  // Normalize
93  double lv = float(lv_i)/float(JOY_MAX_VALUE);
94  lv *= -1; // Invert X
95  double av = float(av_i)/float(JOY_MAX_VALUE);
96  // Show in progress bars
97  ui->lv_pb->setValue(int(lv*100));
98  ui->av_pb->setValue(int(av*100));
99  if (ui->send_chb->checkState() == Qt::Checked && this->rmp_) {
100  try {
101  double lv_s = ui->lv_scale_slider->value() / 100.0f;
102  double av_s = ui->av_scale_slider->value() / 100.0f;
103  av_s *= -1.0; // Invert turning for segway
104  this->rmp_->moveCounts((short int)(lv*1176*lv_s), (short int)(av*1024*av_s));
105  } catch (const std::exception &e) {
106  qDebug() << "Error commanding base: " << e.what();
107  }
108  }
109 }
110 
112  this->joy_mutex_.lock();
113  if (this->joystick_) {
114  SDL_JoystickClose(this->joystick_);
115  this->joystick_ = 0;
116  }
117  if (SDL_NumJoysticks() > 0) {
118  this->joystick_ = SDL_JoystickOpen(index);
119  size_t num_axes = SDL_JoystickNumAxes(this->joystick_);
120  ui->lv_axis_cb->clear();
121  ui->lv_axis_cb->setEnabled(true);
122  ui->av_axis_cb->clear();
123  ui->av_axis_cb->setEnabled(true);
124  ui->send_chb->setEnabled(true);
125  if (num_axes == 0) {
126  ui->lv_axis_cb->addItem("No axes.");
127  ui->av_axis_cb->addItem("No axes.");
128  }
129  for (size_t i = 0; i < num_axes; ++i) {
130  ui->lv_axis_cb->addItem(QString("Axis %1").arg(QString::number(i)));
131  ui->av_axis_cb->addItem(QString("Axis %1").arg(QString::number(i)));
132  }
133  if (num_axes >= 2) {
134  ui->lv_axis_cb->setCurrentIndex(1);
135  ui->av_axis_cb->setCurrentIndex(0);
136  }
137  } else {
138  ui->lv_axis_cb->clear();
139  ui->lv_axis_cb->setEnabled(false);
140  ui->av_axis_cb->clear();
141  ui->av_axis_cb->setEnabled(false);
142  ui->send_chb->setEnabled(false);
143  }
144  this->joy_mutex_.unlock();
145 }
146 
148  size_t num_joysticks = SDL_NumJoysticks();
149  ui->joy_list_cb->clear();
150  if (num_joysticks == 0) {
151  ui->joy_list_cb->addItem("No Joysticks Detected.");
152  }
153  for (size_t i = 0; i < num_joysticks; ++i) {
154  ui->joy_list_cb->addItem(QString::fromAscii(SDL_JoystickName(i)));
155  }
156 }
157 
159  if (this->connected_ and this->rmp_) {
160  rmp_->resetAllIntegrators();
161  }
162 }
163 
165  if (this->connected_ and this->rmp_) {
166  rmp_->shutdown();
167  }
168 }
169 
171  if (this->connected_ and this->rmp_) {
172  rmp_->setOperationalMode(segwayrmp::tractor);
173  }
174 }
175 
177  if (this->connected_ and this->rmp_) {
178  rmp_->setOperationalMode(segwayrmp::balanced);
179  }
180 }
181 
183  if (this->connected_ and this->rmp_) {
184  rmp_->setOperationalMode(segwayrmp::power_down);
185  }
186 }
187 
189  if (this->connected_ and this->rmp_) {
190  rmp_->setBalanceModeLocking(true);
191  }
192 }
193 
195  if (this->connected_ and this->rmp_) {
196  rmp_->setBalanceModeLocking(false);
197  }
198 }
199 
201  if (this->connected_ and this->rmp_) {
202  rmp_->setMaxVelocityScaleFactor(ui->max_vel_sb->value());
203  rmp_->setMaxAccelerationScaleFactor(ui->max_accel_sb->value());
204  rmp_->setMaxTurnScaleFactor(ui->max_turn_rate_sb->value());
205  rmp_->setCurrentLimitScaleFactor(ui->current_limit_sb->value());
206  QString gain_schedule = ui->gain_schedule_cb->currentText();
207  if (gain_schedule == "Light") {
208  rmp_->setControllerGainSchedule(segwayrmp::light);
209  }
210  if (gain_schedule == "Tall") {
211  rmp_->setControllerGainSchedule(segwayrmp::tall);
212  }
213  if (gain_schedule == "Heavy") {
214  rmp_->setControllerGainSchedule(segwayrmp::heavy);
215  }
216  ui->statusbar->showMessage("Configurations sent to the Segway RMP", 3000);
217  }
218 }
219 
220 void MainWindow::onSegwayLog(QString log_type, const std::string &msg) {
221  emit segwayLog(QString("%1: %2").arg(log_type, QString::fromStdString(msg)));
222 }
223 
224 void MainWindow::handleSegwayLog(QString log) {
225  qDebug() << log;
226  ui->statusbar->showMessage(log, 3000);
227 }
228 
230  QString qss = QString::fromStdString(ss->str());
231  emit segwayStatus(QString("Time Stamp:\n%1").arg(qss));
232 }
233 
235  ui->status_label->setText(ss);
236 }
237 
239  if (!this->connected_) {
240  try {
242  if (this->interface_type_ == segwayrmp::usb) {
243  rmp_->configureUSBByIndex(ui->connection_id->currentIndex());
244  } else if (this->interface_type_ == segwayrmp::serial) {
245  rmp_->configureSerial(ui->connection_id->currentText().toStdString());
246  }
247  rmp_->setLogMsgCallback("error", boost::bind(&MainWindow::onSegwayLog, this, "Error", _1));
248  rmp_->setLogMsgCallback("info", boost::bind(&MainWindow::onSegwayLog, this, "Info", _1));
249  rmp_->setLogMsgCallback("debug", boost::bind(&MainWindow::onSegwayLog, this, "Debug", _1));
250  rmp_->setStatusCallback(boost::bind(&MainWindow::onSegwayStatus, this, _1));
251  rmp_->connect();
252  this->connected_ = true;
253  ui->connect_button->setText("Disconnect");
254  ui->connection_id->setEnabled(false);
255  ui->connection_type->setEnabled(false);
256  ui->rmp_type->setEnabled(false);
257  ui->refresh_button->setEnabled(false);
258  } catch (const std::exception &e) {
259  QString error = QString::fromAscii(e.what());
260  QErrorMessage error_msg;
261  QString error_string = QString("Error connecting: %1").arg(error);
262  qDebug() << "Error: " << error_string;
263  error_msg.showMessage(error_string);
264  error_msg.exec();
265  delete rmp_;
266  rmp_ = NULL;
267  this->connected_ = false;
268  }
269  } else {
270  delete rmp_;
271  rmp_ = NULL;
272  this->connected_ = false;
273  ui->connect_button->setText("Connect");
274  ui->connection_id->setEnabled(true);
275  ui->connection_type->setEnabled(true);
276  ui->rmp_type->setEnabled(true);
277  ui->refresh_button->setEnabled(true);
278  }
279 }
280 
282  if (mode == "USB") {
283  ui->refresh_button->setEnabled(true);
284  ui->connection_id->setEditable(false);
285  this->updateUSBList();
287  } else if (mode == "Serial") {
288  ui->refresh_button->setEnabled(false);
289  ui->connection_id->setEditable(true);
290  ui->connection_id->clear();
291  ui->connection_id->addItem(QString("/dev/ttyUSB0"));
293  }
294 }
295 
296 void MainWindow::rmpTypeChanged(QString type) {
297  if (type == "rmp50") {
298  this->rmp_type_ = segwayrmp::rmp50;
299  }
300  if (type == "rmp100") {
302  }
303  if (type == "rmp200") {
305  }
306  if (type == "rmp400") {
308  }
309 }
310 
312  ui->connection_id->clear();
313  foreach (QString entry, this->usb_devices_) {
314  ui->connection_id->addItem(entry);
315  }
316 }
317 
319  QtConcurrent::run(this, &MainWindow::updateUSBList_);
320 }
321 
323  std::vector<FT_DEVICE_LIST_INFO_NODE> devices = segwayrmp::enumerateUSBDevices();
324  std::vector<FT_DEVICE_LIST_INFO_NODE>::iterator it;
325  this->usb_devices_.clear();
326  int i = 0;
327  if (devices.size() == 0) {
328  this->usb_devices_.push_back("No devices detected.");
329  }
330  for (it = devices.begin(); it != devices.end(); it++) {
331  QString line = QString("%1 : %2 - %3").arg(QString::number(i), QString(it->Description), QString(it->SerialNumber));
332  this->usb_devices_.push_back(line);
333  }
334  emit USBUpdateComplete();
335 }
336 
bool connected_
Definition: segwayrmp_gui.h:56
timeout
QMutex joy_mutex_
Definition: segwayrmp_gui.h:62
void USBListUpdated()
void configureUSBByIndex(int device_index, int baudrate=460800)
Definition: segwayrmp.cc:320
segwayrmp::InterfaceType interface_type_
Definition: segwayrmp_gui.h:59
Ui::MainWindow * ui
Definition: segwayrmp_gui.h:55
void segwayLog(QString)
void setLogMsgCallback(std::string log_level, LogMsgCallback callback)
Definition: segwayrmp.cc:719
void onBalanceLockout()
boost::shared_ptr< SegwayStatus > Ptr
Definition: segwayrmp.h:325
void onSegwayLog(QString, const std::string &)
void connect(bool reset_integrators=true)
Definition: segwayrmp.cc:331
void onResetIntegrators()
void onJoystickChanged(int)
QVector< QString > usb_devices_
Definition: segwayrmp_gui.h:57
void closeEvent(QCloseEvent *)
void onRequestBalance()
void handleSegwayLog(QString)
void setStatusCallback(SegwayStatusCallback callback)
Definition: segwayrmp.cc:715
#define JOY_MAX_VALUE
void USBUpdateComplete()
void onBalanceUnlock()
void onConnectClicked()
void configureSerial(std::string port, int baudrate=460800)
Definition: segwayrmp.cc:281
MainWindow(QWidget *parent=0)
void updateJoysticks()
segwayrmp::SegwayRMP * rmp_
Definition: segwayrmp_gui.h:58
void onSendConfig()
void onSegwayStatus(segwayrmp::SegwayStatus::Ptr)
void updateUSBList_()
void segwayStatus(QString)
void connectionTypeChanged(QString)
segwayrmp::SegwayRMPType rmp_type_
Definition: segwayrmp_gui.h:60
void updateUSBList()
void handleSegwayStatus(QString)
void moveCounts(short int linear_counts, short int angular_counts)
Definition: segwayrmp.cc:367
SDL_Joystick * joystick_
Definition: segwayrmp_gui.h:61
void rmpTypeChanged(QString)
void onRequestPowerDown()
void onRequestTractor()
void commandPoll()
#define JOY_DEADBAND
void onDisableMotors()
std::vector< FT_DEVICE_LIST_INFO_NODE > enumerateUSBDevices()
Definition: rmp_ftd2xx.cc:78


libsegwayrmp
Author(s): William Woodall
autogenerated on Mon Jun 10 2019 13:46:49