Go to the documentation of this file.00001
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
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
00034 num_rep = 1
00035
00036 WAIT_FOR_INIT = 5
00037 MAX_TIME = 60
00038
00039 AUTO_MODE = True
00040
00041 resetting = False
00042
00043 robots_in_collision = []
00044 robots_moving = []
00045
00046 stall_count = 0
00047 stall_count_resolved = 0
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)
00057 topics = rospy.get_published_topics()
00058
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
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
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
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
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
00156 if msg.linear.x == 0.0 and msg.angular.z == 0.0:
00157 self.robots_moving[id] = False
00158
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
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
00222 self.reset_srv()
00223
00224
00225
00226
00227
00228 if __name__ == '__main__':
00229 rospy.init_node('watchdog')
00230
00231 watchdog = Watchdog()
00232
00233 rospy.spin()