rcommander_auto_server.py
Go to the documentation of this file.
00001 import roslib; roslib.load_manifest('rcommander_pr2_gui')
00002 import rospy
00003 import actionlib
00004 
00005 from pr2_object_manipulation_msgs.srv import ActionInfo, ActionInfoResponse
00006 from pr2_object_manipulation_msgs.msg import *
00007 import rcommander.graph_model as gm
00008 
00009 from PyQt4 import QtCore, QtGui
00010 import sys
00011 import signal
00012 import os
00013 import os.path as pt
00014 import pdb
00015 
00016 class WatchDirectory(QtCore.QObject):
00017     def __init__(self, path, dir_changed_func=None, file_changed_func=None):
00018         self.path = path
00019         self.fs_watcher = QtCore.QFileSystemWatcher([path])
00020         self.fs_watcher.connect(self.fs_watcher, QtCore.SIGNAL('directoryChanged(QString)'), self.directory_changed)
00021         self.fs_watcher.connect(self.fs_watcher, QtCore.SIGNAL('fileChanged(QString)'), self.file_changed)
00022         self.file_changed_func = file_changed_func
00023         self.dir_changed_func = dir_changed_func
00024 
00025     def __del__(self):
00026         rospy.loginfo('Deleting watcher for ' + self.path)
00027         self.fs_watcher.disconnect(self.fs_watcher, 
00028                 QtCore.SIGNAL('directoryChanged(QString)'), self.directory_changed)
00029         self.fs_watcher.disconnect(self.fs_watcher, 
00030                 QtCore.SIGNAL('fileChanged(QString)'), self.file_changed)
00031 
00032     @QtCore.pyqtSlot(str)
00033     def directory_changed(self, path):
00034         if self.dir_changed_func != None:
00035             self.dir_changed_func(path)
00036     
00037     @QtCore.pyqtSlot(str)
00038     def file_changed(self, path):
00039         if self.file_changed_func != None:
00040             self.file_changed_func(path)
00041 
00042 class RCommanderAutoServer:
00043 
00044     def __init__(self, robot, path_to_rcommander_files):
00045         self.path_to_rcommander_files = path_to_rcommander_files
00046         self.robot = robot
00047         self.action_dict = {}
00048         self.main_dir_watcher = WatchDirectory(self.path_to_rcommander_files, self.main_directory_changed)
00049         self.main_directory_changed(self.path_to_rcommander_files)
00050 
00051         rospy.Service('list_rcommander_actions', ActionInfo, self.list_action_cb)
00052         self.actserv = actionlib.SimpleActionServer('run_rcommander_action', RunScriptAction, execute_cb=self.execute_cb, auto_start=False)
00053         self.actserv.start()
00054 
00055     def execute_cb(self, goal):
00056         rospy.loginfo('Requested: group ' + goal.group_name + ' action: ' + goal.action_name)
00057         self.action_dict[goal.action_name]['server'].execute(self.actserv)
00058 
00059     def _find_all_actions(self):
00060         dirs = [] 
00061         for d in os.listdir(self.path_to_rcommander_files):
00062             if os.path.isdir(os.path.join(self.path_to_rcommander_files, d)):
00063                 dirs.append(d)
00064         return dirs
00065 
00066     def _load(self, action):
00067         rospy.loginfo('Loading ' + action)
00068         action_path = os.path.join(self.path_to_rcommander_files, action)
00069         for i in range(3):
00070             try:
00071                 load_dict = {'server':  ScriptedActionServer(action, action_path, self.robot),
00072                              'watcher': WatchDirectory(action_path, self.action_directory_changed)}
00073                 rospy.loginfo('Successfully loaded ' + action)
00074                 return load_dict
00075             except IOError, e:
00076                 rospy.loginfo(str(e))
00077                 rospy.loginfo('IOError encountered, retrying.')
00078                 rospy.sleep(1)
00079 
00080     def action_directory_changed(self, action_path_name):
00081         action_path_name = str(action_path_name)
00082         action_name = pt.split(action_path_name)[1]
00083         rospy.loginfo('action_name ' + action_name)
00084         rospy.loginfo('action_directory_changed: ' + action_name)
00085         self.action_dict[action_name] = self._load(action_name)
00086 
00087     def main_directory_changed(self, main_path_name):
00088         rospy.loginfo('main_directory_changed: rescanning ' + main_path_name)
00089         ndict = {}
00090         actions = self._find_all_actions()
00091         for action in actions:
00092             if self.action_dict.has_key(action):
00093                 ndict[action] = self.action_dict[action]
00094             else:
00095                 loaded_action = self._load(action)
00096                 if loaded_action != None:
00097                     ndict[action] = loaded_action
00098                 else:
00099                     rospy.loginfo('Failed to load ' + action)
00100         self.action_dict = ndict
00101 
00102     def list_action_cb(self, req):
00103         actions = self.action_dict.keys()
00104         actions.sort()
00105         return ActionInfoResponse(actions)
00106 
00107 class ScriptedActionServer:
00108 
00109     def __init__(self, action_name, path_to_action, robot):
00110         self.action_name = action_name
00111         self.path_to_action = path_to_action
00112         self.robot = robot
00113         self.graph_model = gm.GraphModel.load(self.path_to_action)
00114 
00115     #def _state_machine_status_cb(self):
00116 
00117     def execute(self, actserver):
00118         r = rospy.Rate(30)
00119         #self.graph_model.register_status_cb(self._state_machine_status_cb)
00120         state_machine = self.graph_model.create_state_machine(self.robot)
00121         self.graph_model.run(self.action_name, state_machine=state_machine)
00122         state_machine_output = None
00123 
00124         #Check on execution status
00125         while True:
00126             if actserver.is_preempt_requested():
00127                 self.graph_model.preempt()
00128                 actserver.set_preempted()
00129                 success = False
00130                 break
00131 
00132             if not self.graph_model.is_running():
00133                 outcome = self.graph_model.get_last_outcome()
00134                 if outcome != None:
00135                     state_machine_output, end_time = outcome
00136                     success = True
00137                 else:
00138                     success = False
00139                 break
00140 
00141             r.sleep()
00142 
00143         if success:
00144             result = RunScriptResult(state_machine_output)
00145             rospy.loginfo("%s: succeeded with %s" % (self.action_name, state_machine_output))
00146             actserver.set_succeeded(result)
00147         else:
00148             actserver.set_aborted()
00149 
00150 def run(robot, path):
00151 #    from optparse import OptionParser
00152     #p = OptionParser()
00153     #options, args = p.parse_args()
00154     #print options.name, options.dir
00155     app = QtGui.QApplication(sys.argv)
00156     signal.signal(signal.SIGINT, signal.SIG_DFL)
00157     server = RCommanderAutoServer(robot, path)
00158     rospy.loginfo('RCommander server UP!')
00159     app.exec_()
00160 


rcommander_pr2_gui
Author(s): Hai Nguyen
autogenerated on Thu Dec 12 2013 12:09:58