soft_joystick.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # Software License Agreement (BSD License)
00003 #
00004 #  Copyright (c) 2011, UC Regents
00005 #  All rights reserved.
00006 #
00007 #  Redistribution and use in source and binary forms, with or without
00008 #  modification, are permitted provided that the following conditions
00009 #  are met:
00010 #
00011 #   * Redistributions of source code must retain the above copyright
00012 #     notice, this list of conditions and the following disclaimer.
00013 #   * Redistributions in binary form must reproduce the above
00014 #     copyright notice, this list of conditions and the following
00015 #     disclaimer in the documentation and/or other materials provided
00016 #     with the distribution.
00017 #   * Neither the name of the University of California nor the names of its
00018 #     contributors may be used to endorse or promote products derived
00019 #     from this software without specific prior written permission.
00020 #
00021 #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 #  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 #  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 #  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 #  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 #  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 #  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 #  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 #  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 #  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 #  POSSIBILITY OF SUCH DAMAGE.
00033 
00034 import roslib; roslib.load_manifest('starmac_gui')
00035 import rospy
00036 
00037 from std_msgs.msg import String
00038 
00039 from sensor_msgs.msg import Joy
00040 
00041 from PySide.QtCore import QThread 
00042 from PySide.QtGui import QApplication, QPushButton
00043 from PySide import QtGui, QtCore
00044 import sys
00045 import signal
00046 
00047 from starmac_gui.ui.joystick import Ui_MainWindow as joystick_Ui_MainWindow
00048 
00049 NUM_BUTTONS = 10
00050 NUM_AXES = 5
00051 
00052 def handle_sigint(*args):
00053     sys.stderr.write("\rSIGINT")
00054     QtGui.QApplication.quit()
00055 
00056 class SoftJoystick(QtCore.QThread):
00057     ui = None
00058     pub = None
00059     update_rate = 20.0
00060     def run(self):
00061         i = 0
00062         while not rospy.is_shutdown():
00063             self.send()
00064             self.msleep(1000.0/self.update_rate)
00065             i += 1
00066         print "is_shutdown true, returning from run()"
00067         
00068     def send(self):
00069         joy_msg = Joy()
00070         joy_msg.header.stamp = rospy.Time.now()
00071         buttons = (self.ui.button_0, self.ui.button_1, self.ui.button_2, self.ui.button_3, self.ui.button_4, 
00072                    self.ui.button_5, self.ui.button_6, self.ui.button_7, self.ui.button_8, self.ui.button_9, 
00073                    self.ui.button_10, self.ui.button_11)
00074         joy_msg.buttons = [b.isChecked() for b in buttons]
00075         joy_msg.axes = [mult*s.value()/100.0 for s, mult in 
00076                         zip((self.ui.rollSlider, self.ui.pitchSlider, self.ui.yawSlider, self.ui.altSlider), (-1.0, 1.0, -1.0, 1.0))]
00077         for label, value in zip((self.ui.rollLabel, self.ui.pitchLabel, self.ui.yawLabel, self.ui.altLabel), joy_msg.axes):
00078             label.setText('%0.2f' % value)
00079         
00080         self.pub.publish(joy_msg)
00081         #print self.ui.button_0.isChecked(), self.ui.button_1.isChecked()
00082 
00083 class UiForm(QtGui.QMainWindow):
00084     def __init__(self, parent=None):
00085         QtGui.QMainWindow.__init__(self, parent)
00086         self.ui = joystick_Ui_MainWindow()
00087         self.ui.setupUi(self)
00088 
00089 class GUI:
00090     finished = False
00091     
00092     def __init__(self, app):
00093         self.app = app
00094         self.form = UiForm()
00095         self.form.show()
00096         self.uibuttons = []
00097         
00098         
00099         self.soft_joystick = SoftJoystick()
00100         self.soft_joystick.ui = self.form.ui
00101         self.soft_joystick.update_rate = 20
00102         self.soft_joystick.finished.connect(self.thread_finished_callback)
00103         
00104         self.init_connections()
00105 
00106         # A publisher for messages
00107         self.pub = rospy.Publisher('joy', Joy)
00108         self.soft_joystick.pub = self.pub
00109 
00110         self.soft_joystick.start()
00111 
00112     def init_connections(self):
00113         sfu = self.form.ui
00114         buttons = (sfu.button_0, sfu.button_1, sfu.button_2, sfu.button_3, sfu.button_4, 
00115                    sfu.button_5, sfu.button_6, sfu.button_7, sfu.button_8, sfu.button_9, 
00116                    sfu.button_10, sfu.button_11)
00117         axes = (sfu.rollSlider, sfu.pitchSlider, sfu.yawSlider, sfu.altSlider)
00118         for b in buttons:
00119             b.clicked.connect(self.soft_joystick.send)
00120         for s in axes:
00121             s.valueChanged.connect(self.soft_joystick.send)
00122 
00123     def pub_callback(self):
00124         print "clicked"
00125         self.pub.publish('Thank You!')
00126 
00127     def sub_callback(self, msg):
00128         print 'Got message:', msg.data
00129         
00130     def thread_finished_callback(self): 
00131         print 'Thread finished'
00132         self.finished = True
00133         self.app.quit()
00134         
00135     def button_callback(self, btn):
00136         print 'Button %d pressed, state is %s' % (btn, str(self.uibuttons[btn].isChecked()))
00137 
00138 if __name__ == '__main__':
00139     # Initialize the node
00140     rospy.init_node('soft_joystick')
00141 
00142     # Initialize Qt
00143     app = QApplication(sys.argv)
00144     
00145     # Borrowed from rxlaunch:
00146     # Sets up signal handling so SIGINT closes the application,
00147     # following the solution given at [1].  Sets up a custom signal
00148     # handler, and ensures that the Python interpreter runs
00149     # occasionally so the signal is handled.  The email thread at [2]
00150     # explains why this is necessary.
00151     #
00152     # [1] http://stackoverflow.com/questions/4938723/#4939113
00153     # [2] http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg13757.html
00154     signal.signal(signal.SIGINT, handle_sigint)
00155     timer = QtCore.QTimer()
00156     timer.start(250)
00157     timer.timeout.connect(lambda: None)  # Forces the interpreter to run every 250ms
00158 
00159     gui = GUI(app)
00160 
00161     app.exec_()


starmac_gui
Author(s): bouffard
autogenerated on Sun Jan 5 2014 11:39:00