ui_responder.py
Go to the documentation of this file.
00001 #! /usr/bin/python
00002 #***********************************************************
00003 #* Software License Agreement (BSD License)
00004 #*
00005 #*  Copyright (c) 2009, Willow Garage, Inc.
00006 #*  All rights reserved.
00007 #*
00008 #*  Redistribution and use in source and binary forms, with or without
00009 #*  modification, are permitted provided that the following conditions
00010 #*  are met:
00011 #*
00012 #*   * Redistributions of source code must retain the above copyright
00013 #*     notice, this list of conditions and the following disclaimer.
00014 #*   * Redistributions in binary form must reproduce the above
00015 #*     copyright notice, this list of conditions and the following
00016 #*     disclaimer in the documentation and/or other materials provided
00017 #*     with the distribution.
00018 #*   * Neither the name of Willow Garage, Inc. nor the names of its
00019 #*     contributors may be used to endorse or promote products derived
00020 #*     from this software without specific prior written permission.
00021 #*
00022 #*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 #*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 #*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 #*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 #*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 #*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 #*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 #*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 #*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 #*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 #*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 #*  POSSIBILITY OF SUCH DAMAGE.
00034 #* 
00035 #* Author: Eitan Marder-Eppstein
00036 #***********************************************************
00037 import roslib; roslib.load_manifest('ui_responder')
00038 import rospy
00039 
00040 from std_msgs.msg import Empty
00041 
00042 from PyQt4 import QtGui, QtCore
00043 
00044 import sys
00045 
00046 class UIResponder(QtGui.QMessageBox):
00047     preempted = QtCore.pyqtSignal()
00048     def __init__(self):
00049         QtGui.QMessageBox.__init__(self)
00050         self.timeout_seconds = rospy.get_param('~timeout', 60)
00051         self.name = rospy.get_param('~name', 'task')
00052         self.details = rospy.get_param('~details', 'Make sure it is safe to let the robot do something else.')
00053 
00054         self.pub = rospy.Publisher(rospy.remap_name('action_ns') + '/preempt_response', Empty)
00055         self.sub = rospy.Subscriber(rospy.remap_name('action_ns') + '/preempt_request', Empty, self.req_cb)
00056         self.preempted.connect(self.handle_preempt)
00057         self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
00058         self.end_now_button = self.addButton("Safe to end " + self.name, QtGui.QMessageBox.YesRole)
00059         self.defer_button = self.addButton("Remind me later", QtGui.QMessageBox.NoRole)
00060         self.setWindowTitle("Robot Task Preempt Request")
00061         self.setText("Another application or user needs to take control of the robot.")
00062         self.setInformativeText(self.details)
00063         self.setDefaultButton(self.defer_button)
00064         self.setIcon(self.Critical)
00065         self.defer_timer = QtCore.QTimer()
00066         self.defer_timer.timeout.connect(self.recenter)
00067         self.defer_timer.start( 1000 * self.timeout_seconds )
00068 
00069     def recenter(self):
00070         self.adjustSize()
00071         self.move(QtGui.QApplication.desktop().screen().rect().center() - self.rect().center())
00072 
00073     def handle_preempt(self):
00074         try:
00075             rospy.loginfo("Displaying ui_responder popup")
00076             self.exec_()
00077             while self.clickedButton() == self.defer_button:
00078                 print "defer!"
00079                 self.defer_timer.start( 1000 * self.timeout_seconds )
00080                 self.move(0,0)
00081                 self.exec_()
00082 
00083         except:
00084             pass
00085 
00086         rospy.loginfo("Exiting ui_responder")
00087         #TODO: Quit the application, and shutdown ROS
00088         rospy.signal_shutdown('quit')
00089         QtGui.qApp.quit()
00090         sys.exit()
00091 
00092     def req_cb(self, msg):
00093         self.preempted.emit()
00094 
00095 def main():
00096     rospy.init_node('ui_responder', None, False, 2, False, False, True)
00097     app = QtGui.QApplication(rospy.myargv(sys.argv))
00098     ui_r = UIResponder()
00099 
00100     # app.exec_() returns when UIResponder widget closes.  Since we
00101     # want our defer_timer to keep ticking, keep calling exec_().
00102     # Program ends when sys.exit() is called explicitly.
00103     while True:
00104         app.exec_()
00105 
00106 if __name__ == '__main__':
00107     main()


ui_responder
Author(s): Eitan Marder-Eppstein
autogenerated on Mon Dec 2 2013 12:01:01