watchdog.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 import roslib
00004 roslib.load_manifest('collvoid_controller')
00005 import rospy
00006 roslib.load_manifest('stage')
00007 import string
00008 from stage.msg import Stall
00009 from nav_msgs.msg import Odometry
00010 from geometry_msgs.msg import Twist
00011 from std_msgs.msg import String
00012 from std_msgs.msg import Int32,Bool
00013 from geometry_msgs.msg import PoseWithCovarianceStamped,PoseStamped
00014 from std_srvs.srv import Empty
00015 from collvoid_msgs.msg import PoseTwistWithCovariance
00016 
00017 #from collvoid_controller import controller
00018 
00019 
00020 import re
00021 
00022 
00023 class Watchdog():
00024     
00025     STALL = 'stall'
00026     ODOM = 'base_pose_ground_truth'
00027     CMD_VEL = 'cmd_vel'
00028     X_MAX = 25
00029     X_MIN = - X_MAX
00030     Y_MAX = 25
00031     Y_MIN = - Y_MAX
00032 
00033     NUM_REPITITIONS = 50 #How many repititions in total?
00034     num_rep = 1
00035 
00036     WAIT_FOR_INIT = 5 #Wait time before sending start signal
00037     MAX_TIME = 60 #Max allowed time before timeout.
00038 
00039     AUTO_MODE = True
00040 
00041     resetting = False
00042     
00043     robots_in_collision = []
00044     robots_moving = []
00045 
00046     stall_count = 0 #total number of unresolved collisions 
00047     stall_count_resolved = 0 #total number of resolved collisions 
00048     exceeded = False
00049     
00050     wait_for_start = True
00051 
00052     INIT = True
00053 
00054     def __init__(self):
00055         rospy.loginfo('init watchdog')
00056         rospy.sleep(10) #wait 10 sec, so everything is started and all topics are there
00057         topics = rospy.get_published_topics()
00058         # stall topics
00059         stall_subs = []
00060         for (t,_) in topics:
00061             if re.match('/robot_[0123456789]+/' + self.STALL, t):
00062                 stall_subs.append(rospy.Subscriber(t, Stall, self.cb_stall))
00063         rospy.loginfo('subscribed to %d "stall" topics'%len(stall_subs))
00064         self.num_robots = len(stall_subs)
00065         # twist topics
00066         cmd_vel_subs = []
00067         for i in range(self.num_robots):
00068             self.robots_in_collision.append(False)
00069             self.robots_moving.append(True)
00070             cmd_vel_subs.append(rospy.Subscriber('robot_%d/'%i + self.CMD_VEL, Twist, self.cb_cmd_vel,i))
00071         # odom topics
00072         odom_subs = []
00073         for (t,_) in topics:
00074             if re.match('/robot_[0123456789]+/' + self.ODOM, t):
00075                 odom_subs.append(rospy.Subscriber(t, Odometry, self.cb_odom))
00076     
00077         commands_robots_subs = rospy.Subscriber("/commands_robot",String, self.cb_commands_robots)
00078         
00079         #publisher for collisions
00080         self.stall_pub = rospy.Publisher("/stall", Int32)
00081         self.stall_resolved_pub = rospy.Publisher("/stall_resolved", Int32)
00082         self.exceeded_pub = rospy.Publisher("/exceeded", Bool)
00083         self.num_run_pub = rospy.Publisher("/num_run", Int32)
00084         rospy.loginfo('subscribed to %d "odom" topics'%len(odom_subs))
00085 
00086 
00087         #app.wx.App()
00088         self.controller = controllerHeadless()
00089        
00090 
00091 
00092         if self.AUTO_MODE:
00093             rospy.sleep(5)
00094             self.start()
00095         self.INIT = False
00096 
00097     def start(self):
00098         self.num_run_pub.publish(Int32(self.num_rep))
00099         self.controller.all_init_guess(None)
00100         rospy.sleep(2)
00101         self.controller.all_init_guess(None)
00102         rospy.sleep(2)
00103         for i in range(1):
00104             self.controller.all_start(None)
00105 
00106     def reset(self):
00107         if (self.resetting):
00108             return
00109         self.resetting = True
00110         rospy.sleep(1)
00111         self.stall_pub.publish(Int32(self.stall_count))
00112         self.stall_resolved_pub.publish(Int32(self.stall_count_resolved))
00113         self.exceeded_pub.publish(Bool(self.exceeded))
00114         self.controller.reset(None)
00115         self.reset_vars()
00116         rospy.sleep(self.WAIT_FOR_INIT)
00117         self.num_rep += 1
00118         self.start()
00119         self.resetting = False
00120         self.exceeded = False
00121    
00122 
00123     def reset_vars(self):
00124         for i in range(self.num_robots):
00125             self.robots_in_collision[i] = False
00126             self.robots_moving[i] = True
00127         self.stall_count = 0
00128         self.stall_count_resolved = 0
00129 
00130 
00131     def cb_commands_robots(self, msg):
00132         if (msg.data == "all Start"):
00133             self.reset_vars()
00134             self.start_time = rospy.Time.now()
00135             rospy.sleep(1)
00136             self.wait_for_start = False
00137 
00138 
00139     def cb_stall(self, msg):
00140         if self.INIT:
00141             return
00142         robotId = int(msg.header.frame_id[7:msg.header.frame_id[1:].index('/')+1])
00143         if msg.stall and not self.robots_in_collision[robotId]:
00144             self.robots_in_collision[robotId] = True
00145             rospy.loginfo('robot %s is in collision'%msg.header.frame_id)
00146             self.stall_count+=1
00147         elif not msg.stall and self.robots_in_collision[robotId]:
00148             self.stall_count-=1
00149             self.stall_count_resolved+=1
00150             self.robots_in_collision[robotId] = False
00151         
00152     def cb_cmd_vel(self, msg, id):
00153         if self.wait_for_start or self.resetting:
00154             return
00155         #rospy.loginfo("Got a message")
00156         if msg.linear.x == 0.0 and msg.angular.z == 0.0:
00157             self.robots_moving[id] = False
00158             #rospy.loginfo("Robot %d stopped"%id)
00159         else:
00160             self.robots_moving[id] = True
00161         if max(self.robots_moving) == 0:
00162             rospy.loginfo("I think all robots reached their goal")
00163             if self.AUTO_MODE:
00164                 if self.num_rep < self.NUM_REPITITIONS:
00165                     self.wait_for_start = True
00166                     self.reset()
00167                 elif not self.resetting:
00168                     self.stall_pub.publish(Int32(self.stall_count))
00169                     self.stall_resolved_pub.publish(Int32(self.stall_count_resolved))
00170                     self.exceeded_pub.publish(Bool(self.exceeded))
00171                     rospy.logerr("!"*20 + "I AM DONE" + "!"*20)
00172 
00173         if (rospy.Time.now() - self.start_time).to_sec() > self.MAX_TIME and not self.exceeded:
00174             self.exceeded = True
00175             rospy.loginfo("max time exceeded, resetting")
00176             if self.num_rep < self.NUM_REPITITIONS:
00177                 self.wait_for_start = True
00178                 self.start_time = rospy.Time.now()
00179 
00180                 self.reset()
00181             elif not self.resetting:
00182                 self.stall_pub.publish(Int32(self.stall_count))
00183                 self.stall_resolved_pub.publish(Int32(self.stall_count_resolved))
00184                 self.exceeded_pub.publish(Bool(self.exceeded))
00185                 rospy.logerr("!"*20 + "I AM DONE" + "!"*20)
00186 
00187 
00188     def cb_odom(self, msg):
00189         x = msg.pose.pose.position.x
00190         y = msg.pose.pose.position.y
00191 
00192 
00193 class controllerHeadless():
00194 
00195     def __init__(self):
00196         self.pub = rospy.Publisher('/commands_robot', String)
00197         self.reset_srv = rospy.ServiceProxy('/stageros/reset', Empty)
00198     #    self.subCommonPositions = rospy.Subscriber("/position_share", PoseTwistWithCovariance, self.cbCommonPositions)
00199         self.initialized = True
00200 
00201     def cbCommonPositions(self,msg):
00202         if not self.initialized:
00203             return
00204         if self.robotList.count(msg.robot_id) == 0:
00205             rospy.loginfo("robot added")
00206             self.robotList.append(msg.robot_id)
00207     
00208     def all_start(self,event):
00209         string = "all Start"
00210         self.pub.publish(str(string))
00211 
00212     def all_init_guess(self,event):
00213         string = "all init Guess"
00214         self.pub.publish(str(string))
00215 
00216         
00217     def reset(self,event):
00218         self.pub.publish("all Stop")
00219         rospy.sleep(0.2)
00220         self.pub.publish("all Restart")
00221         #rospy.sleep(0.2)
00222         self.reset_srv()
00223 
00224 
00225 
00226 
00227 
00228 if __name__ == '__main__':
00229     rospy.init_node('watchdog')
00230     #app = wx.App()
00231     watchdog = Watchdog()
00232     #app.MainLoop()
00233     rospy.spin()
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


collvoid_controller
Author(s): Daniel Claes
autogenerated on Sun Aug 25 2013 10:10:35