TeleoperatorInstanceWidget.h
Go to the documentation of this file.
00001 /*
00002  * Filename: TeleoperatorInstanceWidget.h
00003  *   Author: Igor Makhtes
00004  *     Date: Dec 5, 2013
00005  *
00006  * The MIT License (MIT)
00007  *
00008  * Copyright (c) 2013 Cogniteam Ltd.
00009  *
00010  * Permission is hereby granted, free of charge, to any person obtaining a copy
00011  * of this software and associated documentation files (the "Software"), to deal
00012  * in the Software without restriction, including without limitation the rights
00013  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00014  * copies of the Software, and to permit persons to whom the Software is
00015  * furnished to do so, subject to the following conditions:
00016  *
00017  * The above copyright notice and this permission notice shall be included in
00018  * all copies or substantial portions of the Software.
00019  *
00020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00021  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00022  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00023  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00024  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00025  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00026  * THE SOFTWARE.
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 /* TELEOPERATORINSTANCEWIDGET_H_ */


mr_rqt
Author(s): Igor Makhtes
autogenerated on Fri Aug 28 2015 11:35:38