controller_ghosts.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 import roslib; roslib.load_manifest('pacman_controller')
00003 import rospy
00004 import commands
00005 import string
00006 import sys
00007 import math
00008 import actionlib
00009 import random
00010 from collvoid_local_planner.srv import InitGuess
00011 from std_msgs.msg import String
00012 from geometry_msgs.msg import PoseWithCovarianceStamped,PoseStamped
00013 from socket import gethostname
00014 from collvoid_msgs.msg import PoseTwistWithCovariance
00015 from move_base_msgs.msg import *
00016 
00017 import tf
00018 
00019 from pacman_controller import game_engine as GE
00020 
00021 
00022 class ControllerGhosts():
00023 
00024     def __init__(self):
00025         self.initialize()
00026         
00027 
00028     def initialize(self):
00029         self.move_base_client = actionlib.SimpleActionClient('move_base', MoveBaseAction)
00030         self.move_base_client.wait_for_server()
00031         self.init_guess_srv = rospy.ServiceProxy("init_guess_pub", InitGuess)
00032 
00033         #self.pub_goal = rospy.Publisher("move_base/goal", MoveBaseActionGoal)
00034   
00035         self.ghostname = rospy.get_param("~ghostname")
00036         self.home = rospy.get_param("/%s/home"%self.ghostname)
00037         
00038         
00039         rospy.loginfo("Ghost: %s home %d",self.ghostname, self.home)
00040         self.gameEngine = GE.GameEngine()
00041         self.state = GE.State.STOPPED
00042         self.dead = False
00043         self.headingToWp = False
00044         self.current_wp = None
00045         self.old_wp = self.gameEngine.points[self.home]
00046         self.sleepTime = rospy.get_param('/%s/sleep_time'%self.ghostname)
00047   
00048 
00049         self.sub_state = rospy.Subscriber("/state", String, self.cb_state)
00050         self.sub_commands_robot = rospy.Subscriber("/commands_robot", String, self.cb_commands_robot)
00051 
00052    
00053     def update(self):
00054         if not self.gameEngine.initialized or not self.ghostname in self.gameEngine.ghosts or self.state == GE.State.SETUP:
00055             return
00056         me = self.gameEngine.ghosts[self.ghostname]
00057                           
00058         if self.state == GE.State.RUNNING and self.startTime + self.sleepTime > rospy.get_time():
00059             return
00060  
00061 
00062         if (self.state == GE.State.STOPPED or self.state == GE.State.PAUSED):
00063             self.move_base_client.cancel_all_goals()
00064             self.current_wp = None
00065             self.headingToWp = False
00066             #self.old_wp = self.gameEngin.points[self.home]
00067             return
00068   
00069         if (self.state in [GE.State.INIT, GE.State.GAME_OVER] or self.dead):
00070             new_wp,end = self.return_home();
00071             self.headingToWp = False
00072         elif (self.state == GE.State.FLEEING):
00073             if GE.dist(self.gameEngine.pacman, me) < self.gameEngine.pacman['radius'] + me['radius'] + 1.5*GE.THRESHOLD:
00074                 self.dead = True
00075                 new_wp,end = self.return_home();
00076                 self.headingToWp = False
00077             else:
00078                 new_wp,end = self.newBehavior()
00079                   
00080         elif self.headingToWp and GE.dist(me, self.gameEngine.points[self.current_wp]) < me['radius'] + GE.THRESHOLD:
00081             self.headingToWp = False
00082             return
00083         elif self.headingToWp:
00084             return
00085         else:
00086             new_wp,end = self.newBehavior()
00087         
00088         if not (new_wp == self.current_wp):
00089             self.current_wp = new_wp
00090             self.move_base_client.cancel_all_goals()
00091             self.send_goal(self.current_wp)
00092         else:
00093             nearestWP = self.gameEngine.findClosestWP(me)
00094             if self.state in [GE.State.RUNNING, GE.State.FLEEING] and nearestWP == self.current_wp and self.current_wp == end and GE.dist(me, self.gameEngine.points[self.current_wp]) < me['radius']:
00095                 self.headingToWp = True
00096                 
00097                 pm_wp = self.gameEngine.findClosestWP(self.gameEngine.pacman)
00098                 if (end == pm_wp):
00099                     pm_mp = self.gameEngine.findClosestMapPoint(self.gameEngine.pacman)
00100                     if pm_mp['neighbors'][0] == pm_wp:
00101                         self.current_wp = pm_mp['neighbors'][1]
00102                     else:
00103                         self.current_wp = pm_mp['neighbors'][0]
00104                     
00105                 else:
00106                     while self.current_wp == end:
00107                         print self.ghostname + str(self.current_wp)
00108                         self.current_wp = random.choice(self.gameEngine.points[nearestWP]['neighbors'])
00109                
00110                 self.move_base_client.cancel_all_goals()
00111                 self.send_goal(self.current_wp)
00112 
00113     def newBehavior(self):
00114         if (self.ghostname == "ghost_red"):
00115             return self.chase_pacman()
00116         if (self.ghostname == "ghost_pink"):
00117             return self.move_random(1.0)
00118         if (self.ghostname == "ghost_blue"):
00119             return self.move_random(0.2)
00120                     
00121     def send_goal(self,wp):
00122         goal = MoveBaseGoal()
00123         goal.target_pose.pose.position.x = self.gameEngine.points[wp]["x"]
00124         goal.target_pose.pose.position.y = self.gameEngine.points[wp]["y"]
00125         #q = tf.transformations.quaternion_from_euler(0,0, self.home["ang"], axes='sxyz')
00126         goal.target_pose.pose.orientation.x = 0
00127         goal.target_pose.pose.orientation.y = 0
00128         goal.target_pose.pose.orientation.z = 0
00129         goal.target_pose.pose.orientation.w = 1.0
00130         
00131 #        home.target_pose.header.stamp = rospy.get_time()
00132         goal.target_pose.header.frame_id = "/map"
00133        
00134         self.move_base_client.send_goal(goal)
00135         return
00136 
00137     def cb_state(self,msg):
00138         if self.state == GE.State.INIT and int(msg.data) == GE.State.RUNNING:
00139             self.startTime = rospy.get_time()
00140         if not self.state == GE.State.SETUP and int(msg.data) == GE.State.SETUP:
00141             self.move_base_client.cancel_all_goals()
00142 
00143         self.state = int(msg.data)
00144         
00145 
00146     def flee(self):
00147         my_position = self.gameEngine.ghosts[self.ghostname]
00148         pm_position = self.gameEngine.pacman
00149 
00150         my_wp = self.gameEngine.findClosestMapPoint(my_position)
00151         pm_wp = self.gameEngine.findClosestWP(pm_position)
00152         path = self.gameEngine.find_shortest_path(my_wp, pm_wp)
00153 
00154         if not (my_wp['neighbors'][0] == path[1]['id']):
00155             return my_wp['neighbors'][0]
00156         else:
00157             return my_wp['neighbors'][1]
00158 
00159         
00160     def move_random(self, percent):
00161         me = self.gameEngine.ghosts[self.ghostname]
00162         
00163         if GE.dist(me, self.old_wp) < me['radius'] + GE.THRESHOLD:
00164             if random.random() <= percent and not self.old_wp['id'] == self.home:
00165                 self.old_wp = random.choice(self.gameEngine.points)
00166             else:
00167                 self.old_wp = self.gameEngine.points[self.gameEngine.findClosestWP(self.gameEngine.pacman)]
00168             
00169         my_wp = self.gameEngine.findClosestMapPoint(me)
00170         path = self.gameEngine.find_shortest_path(my_wp, self.old_wp)
00171 
00172 
00173         if len(path) == 1:
00174             return path[0]['id'], path[len(path)-1]['id']
00175 
00176         index = 1
00177         
00178         while index < len(path)-1 and GE.dist(path[index], me) < me['radius'] + GE.THRESHOLD :
00179             index += 1;
00180 
00181         while index < len(path)-1 and GE.dist(path[index], self.gameEngine.ghosts[self.ghostname]) < 2 * self.gameEngine.ghosts[self.ghostname]['radius'] + 2.0 * GE.THRESHOLD and self.gameEngine.positionBlocked(path[index], self.gameEngine.ghosts[self.ghostname]):
00182             index +=1;
00183 
00184  
00185         return path[index]['id'], path[len(path)-1]['id']
00186 
00187                 
00188     def chase_pacman(self):
00189         my_position = self.gameEngine.ghosts[self.ghostname]
00190         pm_position = self.gameEngine.pacman
00191         
00192         my_wp = self.gameEngine.findClosestMapPoint(my_position)
00193         pm_wp = self.gameEngine.findClosestWP(pm_position)
00194         path = self.gameEngine.find_shortest_path(my_wp, self.gameEngine.points[pm_wp])
00195         
00196         if len(path) == 1:
00197             return path[0]['id'], path[len(path)-1]['id']
00198         
00199         index = 1
00200 
00201         while index < len(path)-1 and GE.dist(path[index], self.gameEngine.ghosts[self.ghostname]) < self.gameEngine.ghosts[self.ghostname]['radius'] + GE.THRESHOLD :
00202             index += 1;
00203 
00204  
00205         return path[index]['id'], path[len(path)-1]['id']
00206 
00207 
00208     def return_home(self):
00209         if GE.dist(self.gameEngine.points[self.home], self.gameEngine.ghosts[self.ghostname]) < self.gameEngine.ghosts[self.ghostname]['radius'] + GE.THRESHOLD:
00210             self.dead = False
00211         my_position = self.gameEngine.ghosts[self.ghostname]
00212         my_wp = self.gameEngine.findClosestMapPoint(my_position)
00213        
00214         path = self.gameEngine.find_shortest_path(my_wp,self.gameEngine.points[self.home])
00215         
00216         if len(path) == 1:
00217             return path[0]['id'], path[len(path)-1]['id']
00218 
00219         index = 1
00220         while index < len(path)-1 and GE.dist(path[index], self.gameEngine.ghosts[self.ghostname]) < self.gameEngine.ghosts[self.ghostname]['radius'] + 1.5 * GE.THRESHOLD :
00221             index += 1;
00222         
00223         while index < len(path)-1 and GE.dist(path[index], self.gameEngine.ghosts[self.ghostname]) < 2 * self.gameEngine.ghosts[self.ghostname]['radius'] + 2.0 * GE.THRESHOLD and self.gameEngine.positionBlocked(path[index], self.gameEngine.ghosts[self.ghostname]):
00224             index +=1;
00225  
00226         return path[index]['id'], path[len(path)-1]['id']
00227 
00228             
00229     def cb_commands_robot(self,msg):
00230         if (msg.data == "init Guess"):
00231             self.init_guess_srv(0.1)
00232   
00233 if __name__ == '__main__':
00234     #if not (len(sys.argv) == 2):
00235     #    print "usage: controllerWaypoints.py <ghostname>"
00236     #    sys.exit(-1)
00237 
00238     #ghostname = sys.argv[1]
00239     rospy.init_node('controller_ghosts')
00240     controller_ghosts = ControllerGhosts()
00241     r = rospy.Rate(10)
00242     while not rospy.is_shutdown():
00243         controller_ghosts.update()
00244         r.sleep()
00245     
00246 
00247 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


pacman_controller
Author(s): Daniel Claes
autogenerated on Sun Aug 25 2013 10:10:43