def __init__(self, tank_index, target_color, state): self.state = state self.target_color = target_color self.tank_index = tank_index self.pdc = PDController() self.timer_id = Timer.add_task(self.update) self.kvis = KalmanVisualizer(800, 800) self.kfilter = KalmanFilter()
def __init__(self, tank_index, flag_index, state): self.tank_index = tank_index self.flag_index = flag_index self.state = state self.timer_id = Timer.add_task(self.potential_fields_move) self.pfc = self.setup_potential_fields() self.pdcontroller = PDController() self.attacking = True self.prev_x = 0 self.prev_y = 0 self.time_spent_stuck = 0 # stuck for more than 10 seconds, get a new random vector self.time_without_moving = 0 # consider ourselves stuck only after 5 seconds self.stuck_vector = [0, 0] self.stuck = False
def __init__(self, tank_index, bay_vis, bay_filter, state): self.tank_index = tank_index self.state = state self.bay_vis = bay_vis self.bay_filter = bay_filter # the tank should change goals periodically self.time_since_goal_change = 0 self.goal_x = 0 self.goal_y = 0 self.pdcontroller = PDController() self.pfc = self.setup_potential_fields() # these variables are used to check if we're stuck self.time_without_moving = 0 self.prev_x = 0 self.prev_y = 0 self.timer_id = Timer.add_task(self.bayesian_grid_search)
class PDFlagRetriever(Agent): def __init__(self, tank_index, flag_index, state): self.tank_index = tank_index self.flag_index = flag_index self.state = state self.timer_id = Timer.add_task(self.potential_fields_move) self.pfc = self.setup_potential_fields() self.pdcontroller = PDController() self.attacking = True self.prev_x = 0 self.prev_y = 0 self.time_spent_stuck = 0 # stuck for more than 10 seconds, get a new random vector self.time_without_moving = 0 # consider ourselves stuck only after 5 seconds self.stuck_vector = [0, 0] self.stuck = False def potential_fields_move(self): # set up tank tank = self.state.mytanks[self.tank_index] tank.shoot() # check if I'm stuck and respond appropriately if so self.check_stuck(tank) # check if I just picked up the enemy flag if tank.flag != '-' and self.attacking: self.return_to_base() # check if I just returned the enemy flag if tank.flag == '-' and not self.attacking: self.attack_enemy_flag() if not self.stuck: # get the vector suggested by the potential field pf_vec = self.pfc.potential_fields_calc(tank.x, tank.y) else: pf_vec = self.stuck_vector # give the vector to the pd controller for actionable speed and angvel next_action = self.pdcontroller.get_next_action(tank, pf_vec) # act upon the new speed and angvel tank.speed(next_action['speed']) tank.set_angvel(next_action['angvel']) self.state.update_mytanks() self.state.update_flags() self.prev_x = tank.x self.prev_y = tank.y def check_stuck(self, tank): # check if I've moved recently if tank.x == self.prev_x and tank.y == self.prev_y: self.time_without_moving += Timer.TIME_PER_TICK tank.shoot() # check if I'm stuck. Considered "stuck" if I haven't changed position in 5 seconds. if self.time_without_moving > .5: self.stuck = True # print "STUCK!" # if we just got stuck or we've been stuck for too long, get new random vector and shoot. if self.time_spent_stuck == 0: self.stuck_vector = [random.random() * 200 - 100, random.random() * 200 - 100] # print "Generated random vector ", self.stuck_vector # add to the stuck timer. If it's longer than 10 seconds, reset to 0. self.time_spent_stuck += Timer.TIME_PER_TICK if self.time_spent_stuck >= 2.5: self.time_spent_stuck = 0 elif self.stuck: # print "RESETTING!" self.time_without_moving = 0 self.stuck = False self.stuck_vector = [0, 0] def setup_potential_fields(self): flag = self.state.flags[self.flag_index] attractive = [] repulsive = [] tangential = [] # attractive. One flag that I chose at random. logging.debug("Tank %s is seeking flag %s", self.tank_index, str(flag)) attractive.append(AttractiveObject(x=flag.x, y=flag.y, radius=10, spread=20, alpha=1),) if len(self.state.obstacles) == 4: tangential.append(TangentialObject(x=121.2132034355, y=21.2132034356, radius=30, spread=60, alpha=1)) #LEFT tangential.append(TangentialObject(x=-78.78679656439999, y=21.2132034356, radius=30, spread=60, alpha=1, clockwise=False)) #TOP tangential.append(TangentialObject(x=21.2132034356, y=121.2132034355, radius=30, spread=60, alpha=1)) #BOTTOM tangential.append(TangentialObject(x=21.2132034356, y=-78.78679656439999, radius=30, spread=60, alpha=1)) else: # Top Left L tangential.append(TangentialObject(x=-90, y=120, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=-90, y=180, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=-150, y=120, radius=30, spread=100, alpha=1)) # Top Right L tangential.append(TangentialObject(x=150, y=120, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=150, y=180, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=210, y=120, radius=30, spread=100, alpha=1)) # Bottom Right L tangential.append(TangentialObject(x=150, y=-120, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=210, y=-120, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=150, y=-180, radius=30, spread=100, alpha=1)) # Bottom Left L tangential.append(TangentialObject(x=-90, y=-120, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=-90, y=-180, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=-150, y=-120, radius=30, spread=100, alpha=1)) # Top Left L tangential.append(TangentialObject(x=-90, y=120, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=-90, y=180, radius=30, spread=100, alpha=1)) tangential.append(TangentialObject(x=-150, y=120, radius=30, spread=100, alpha=1)) # Middle Rectangular Obstacle tangential.append(TangentialObject(x=0, y=10, radius=60, spread=100, alpha=1)) return PotentialFieldCalculator(attractive, repulsive, tangential) def return_to_base(self): self.attacking = False base_coords = self.state.me.base.get_centerpoint() attractive = [AttractiveObject(x=base_coords['x'], y=base_coords['y'], radius=10, spread=20, alpha=1)] self.pfc.update(attractive, self.pfc.repulsive, self.pfc.tangential) def attack_enemy_flag(self): self.attacking = True flag = self.state.flags[self.flag_index] attractive = [AttractiveObject(x=flag.x, y=flag.y, radius=10, spread=20, alpha=1)] self.pfc.update(attractive, self.pfc.repulsive, self.pfc.tangential)
class BayesianGridSearchAgent(Agent): def __init__(self, tank_index, bay_vis, bay_filter, state): self.tank_index = tank_index self.state = state self.bay_vis = bay_vis self.bay_filter = bay_filter # the tank should change goals periodically self.time_since_goal_change = 0 self.goal_x = 0 self.goal_y = 0 self.pdcontroller = PDController() self.pfc = self.setup_potential_fields() # these variables are used to check if we're stuck self.time_without_moving = 0 self.prev_x = 0 self.prev_y = 0 self.timer_id = Timer.add_task(self.bayesian_grid_search) def bayesian_grid_search(self): # set up tank tank = self.state.mytanks[self.tank_index] self.time_since_goal_change += Timer.time_passed print Timer.time_passed if self.time_since_goal_change.is_integer(): print self.time_since_goal_change self.check_new_direction(tank) # get the vector suggested by the potential field pf_vec = self.pfc.potential_fields_calc(tank.x, tank.y) # give the vector to the pd controller for actionable speed and angvel next_action = self.pdcontroller.get_next_action(tank, pf_vec) # act upon the new speed and angvel tank.speed(next_action['speed']) tank.set_angvel(next_action['angvel']) self.state.update_mytanks() self.state.update_flags() self.prev_x = tank.x self.prev_y = tank.y # ask the server for current position and update the Grid Filter self.update_grid() def check_new_direction(self, tank): # check if stuck if self.is_stuck(tank): print "Tank %s stuck, changing direction" % self.tank_index self.new_direction() # check if tank arrived at goal if abs(tank.x - self.goal_x) < 10 and abs(tank.y - self.goal_y) < 10: print "Tank %s arrived at goal, changing direction" % self.tank_index self.new_direction() # check if tank hasn't changed direction in a long time if self.time_since_goal_change > 60: print "Tank %s timeout, changing direction" % self.tank_index self.new_direction() def is_stuck(self, tank): # check if I've moved recently if tank.x == self.prev_x and tank.y == self.prev_y: self.time_without_moving += Timer.time_passed # check if I'm stuck. Considered "stuck" if I haven't changed position in 1 second. if self.time_without_moving > 1: tank.shoot() self.time_without_moving = 0 return True def new_direction(self): found_goal = False for i in range (0, 2): self.goal_x = random.randint(-400, 400) self.goal_y = random.randint(-400, 400) if not self.bay_filter.already_explored(self.goal_x, self.goal_y): break self.time_since_goal_change = 0 attractive = [AttractiveObject(x=self.goal_x, y=self.goal_y, radius=10, spread=1000000, alpha=1000)] self.pfc.update(attractive, self.pfc.repulsive, self.pfc.tangential) print "Tank %s new goal (%f,%f)" % (self.tank_index, self.goal_x, self.goal_y) def setup_potential_fields(self): attractive = [] repulsive = [] tangential = [] self.pfc = PotentialFieldCalculator(attractive, repulsive, tangential) self.new_direction() return self.pfc def update_grid(self): x, y, grid = self.state.update_occgrid(self.tank_index) # ask the server for the occgrid #self.bay_filter.test(grid, int(x), int(y)) # run it through the fake bayesian filter self.bay_filter.bayesian_grid(grid, int(x), int(y)) # run it through the bayesian filter self.bay_vis.update_and_draw_grid(self.bay_filter.model) # draw it
class KalmanAgent(Agents.Agent): def __init__(self, tank_index, target_color, state): self.state = state self.target_color = target_color self.tank_index = tank_index self.pdc = PDController() self.timer_id = Timer.add_task(self.update) self.kvis = KalmanVisualizer(800, 800) self.kfilter = KalmanFilter() def update(self): # update state self.state.update_mytanks() self.state.update_othertanks() tank = self.state.mytanks['0'] angvel = self.getAngvelToTarget(tank) tank.set_angvel(angvel) def getAngvelToTarget(self, tank): """ Calculates the vector that we should be facing to kill the target, then uses the PDController to find the angular velocity required to face the target. This calculation is performed like this: 1. Use the Kalman Filter to get the predicted location of the target. 2. Add to that vector the distance that the target will travel while the bullet fires. 3. Pass the vector into the PDController to find the angular velocity that we need to face the right way :return float: the angular velocity that we need in order to correctly face the target. """ # get newest data about target target = self.state.othertanks[self.target_color][0] # get the angle to the target # step 1: Kalman Filter ut, width, height = self.kfilter.update(npy.array([[target.x], [target.y]])) xpos, xvel, xacc, ypos, yvel, yacc = ut # step 2: bullet travel time t = math.sqrt((tank.x - target.x) ** 2 + (tank.y - target.y) ** 2) / 100 hitzone_x = xpos + xvel*t + 0.5 # * xacc * t**2 + 100 * math.cos(tank.x) * t hitzone_y = ypos + yvel*t + 0.5 # * yacc * t**2 + 100 * math.sin(tank.y) * t self.kvis.update(xpos, ypos, width, target.x, target.y, hitzone_x, hitzone_y) # step 3: PDController to find angular velocity ang = self.ang(hitzone_x, hitzone_y) # print ang if abs(math.pi + tank.angle - ang) < 0.1: tank.shoot() target_vec = [-math.cos(ang), -math.sin(ang)] next_action = self.pdc.get_next_action(self.state.mytanks[self.tank_index], target_vec) return next_action['angvel'] def ang(self, x, y): tank = self.state.mytanks['0'] angle = math.atan2(tank.y - y, tank.x - x) '''Make any angle be between +/- pi.''' angle -= 2 * math.pi * int(angle / (2 * math.pi)) if angle <= -math.pi: angle += 2 * math.pi elif angle > math.pi: angle -= 2 * math.pi return angle