Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef TELEOPERATORINSTANCEWIDGET_H_
00030 #define TELEOPERATORINSTANCEWIDGET_H_
00031
00032 #include <iostream>
00033 #include <boost/bind.hpp>
00034 #include <boost/thread.hpp>
00035 #include <boost/foreach.hpp>
00036 #include <ros/ros.h>
00037 #include <std_msgs/Int32.h>
00038 #include <std_msgs/String.h>
00039
00040 #include <QtGui/QDockWidget>
00041
00042 #include <geometry_msgs/Twist.h>
00043 #include <mr_rqt/VelocityWidget.h>
00044 #include <mr_rqt/TeleoperatorInstance.h>
00045 #include <mr_rqt/KeyboardTeleop.h>
00046
00047 using namespace std;
00048
00049 class TeleoperatorInstanceWidget : public QWidget {
00050
00051 Q_OBJECT
00052
00053 public:
00054
00055 enum InputMethod {
00056 Joystick = 0, Keyboard = 1, Mouse = 2
00057 };
00058
00059 TeleoperatorInstanceWidget(
00060 ros::NodeHandle& nodeHandle, InputMethod inputMethod,
00061 int robotNumber, string velocityTopic, string feedbackVelocityFeedback)
00062 : _nodeHandle(nodeHandle) {
00063 _robotNumber = robotNumber;
00064 _linearVelocity = 0;
00065 _angularVelocity = 0;
00066 _inputMethod = inputMethod;
00067 _closed = false;
00068
00069 connect(this, SIGNAL(redrawSignal()), this, SLOT(redraw()),
00070 Qt::QueuedConnection);
00071
00072 initTopics(inputMethod, feedbackVelocityFeedback, velocityTopic);
00073
00074 _widget.setupUi(this);
00075 _velocityWidget = new mr_rqt::VelocityWidget(
00076 _widget.joystickContainer);
00077 _velocityWidget->setMinimumSize(200, 200);
00078 _velocityWidget->setMaximumSize(200, 200);
00079 _velocityWidget->setCallback(
00080 boost::bind(&TeleoperatorInstanceWidget::uiJoystickCallback, this,
00081 _1, _2));
00082 _widget.titleLabel->setText(
00083 QString::fromStdString(
00084 "Robot #" + boost::lexical_cast<string>(robotNumber)
00085 + " [" + inputMethodStr(inputMethod) + "]"));
00086
00087 _keyboardWidget = new mr_rqt::KeyboardTeleop();
00088 _keyboardWidget->setCallback(
00089 boost::bind(&TeleoperatorInstanceWidget::keyboardCallback, this,
00090 _1, _2));
00091 _widget.keyboardInput->installEventFilter(_keyboardWidget);
00092
00093 initJoystick(inputMethod);
00094
00095 }
00096
00097 virtual ~TeleoperatorInstanceWidget() {
00098
00099 _closed = true;
00100
00101 }
00102
00103 public slots:
00104
00108 void redraw() {
00109 _widget.lcdLinearVelocity->display(_linearVelocity);
00110 _widget.lcdAngularVelocity->display(_angularVelocity);
00111 }
00112
00113 signals:
00114
00115 void redrawSignal();
00116
00117 private:
00118
00119 int _robotNumber;
00120 InputMethod _inputMethod;
00121
00122 ros::NodeHandle& _nodeHandle;
00123
00124 ros::Publisher _publisher;
00125 ros::Subscriber _subscriber;
00126
00127 Ui_teleoperatorInstance _widget;
00128 mr_rqt::VelocityWidget* _velocityWidget;
00129 mr_rqt::KeyboardTeleop* _keyboardWidget;
00130
00131 double _linearVelocity;
00132 double _angularVelocity;
00133
00134 volatile bool _closed;
00135
00136
00137 void initJoystick(InputMethod method) {
00138 switch (method) {
00139 case TeleoperatorInstanceWidget::Joystick:
00140 _velocityWidget->disableMouseControl();
00141 _widget.keyboardInput->hide();
00142 break;
00143 case TeleoperatorInstanceWidget::Mouse:
00144 _velocityWidget->enableMouseControl();
00145 _widget.keyboardInput->hide();
00146 break;
00147 case TeleoperatorInstanceWidget::Keyboard:
00148 _velocityWidget->disableMouseControl();
00149 _widget.keyboardInput->show();
00150 break;
00151 }
00152 }
00153
00154 void initTopics(InputMethod method, string feedbackTopicName, string velocityTopic) {
00155 _publisher = _nodeHandle.advertise<geometry_msgs::Twist>(velocityTopic, 20,
00156 false);
00157 _subscriber = _nodeHandle.subscribe(feedbackTopicName, 50,
00158 &TeleoperatorInstanceWidget::onVelocityMessage, this);
00159 }
00160
00161 void uiJoystickCallback(double linearPercent, double angularPercent) {
00162
00163 if (_closed)
00164 return;
00165
00166 geometry_msgs::Twist cmdVel;
00167 cmdVel.linear.x = linearPercent / 50.0;
00168 cmdVel.angular.z = angularPercent / 50.0;
00169 _publisher.publish(cmdVel);
00170 }
00171
00172 void keyboardCallback(double linear, double angular) {
00173 if (_closed)
00174 return;
00175
00176 if (_inputMethod != TeleoperatorInstanceWidget::Keyboard)
00177 return;
00178
00179 geometry_msgs::Twist cmdVel;
00180 cmdVel.linear.x = linear;
00181 cmdVel.angular.z = angular;
00182 _publisher.publish(cmdVel);
00183 }
00184
00185 void onVelocityMessage(const geometry_msgs::Twist::Ptr velocityMessage) {
00186
00187 if (_closed)
00188 return;
00189
00190 double linear = velocityMessage->linear.x;
00191 double angular = velocityMessage->angular.z;
00192
00193 _velocityWidget->setVelocity(linear, angular);
00194
00195 _linearVelocity = linear;
00196 _angularVelocity = angular;
00197
00198 if (_inputMethod == TeleoperatorInstanceWidget::Joystick)
00199 _publisher.publish(velocityMessage);
00200
00201 emit redrawSignal();
00202 }
00203
00204 string inputMethodStr(InputMethod method) {
00205 switch (method) {
00206 case TeleoperatorInstanceWidget::Joystick:
00207 return "Joystick";
00208 case TeleoperatorInstanceWidget::Mouse:
00209 return "Mouse";
00210 case TeleoperatorInstanceWidget::Keyboard:
00211 return "Keyboard";
00212 default:
00213 return "None";
00214 }
00215 }
00216 };
00217
00218 #endif