def move_to_position(self, pos): shooting_angle = math.atan2(pos[1] - self.tank_pos[1], pos[0] - self.tank_pos[0]) self.current_angle = self.bzrc.get_mytanks()[self.tank_index].angle angvel = self.calculate_angvel(shooting_angle) * 1.3 should_shoot = False if abs(self.current_angle - shooting_angle) < 0.001: should_shoot = True command = Command(self.tank_index, 0, angvel, should_shoot) self.bzrc.do_commands([command])
def kalman(self, tank): target = self.get_target_loc(tank) if target != None: #calculate angle delta_x, delta_y, magnitude = self.calculate_objective_delta( tank.x, tank.y, target.x, target.y) turn_angle = math.atan2(delta_y, delta_x) relative_angle = self.normalize_angle(turn_angle - tank.angle) command = Command(tank.index, 0, 2 * relative_angle, True) self.commands.append(command)
def kalman(self, tank): sensor = self.get_target_loc() if sensor != None: X = np.matrix([[sensor.x], [sensor.y]]) P_k = self.get_Pk() K = self.get_K(P_k) self.mu = self.F * self.mu + K * (X - self.H * self.F * self.mu) self.SIGMA_T = (self.I - K * self.H) * P_k current_shot_dist = self.get_target_dist(tank.x, tank.y, sensor.x, sensor.y) iterations = 0 if current_shot_dist <= 350: #(current_shot_dist / self.shotspeed) = how many seconds it takes for the bullet to get to the current enemy location iterations = int((current_shot_dist / self.shotspeed) * self.iterations_per_second) #target_position = predicted location after (current_shot_dist / self.shotspeed) seconds target_position = self.predict_future_position(iterations) # how far away the tank will be after 'iterations' iterations future_shot_dist = self.get_target_dist(tank.x, tank.y, target_position[0, 0], target_position[2, 0]) #calculate angle delta_x, delta_y, magnitude = self.calculate_objective_delta( tank.x, tank.y, target_position[0, 0], target_position[3, 0]) turn_angle = math.atan2(delta_y, delta_x) relative_angle = self.normalize_angle(turn_angle - tank.angle) #if abs(relative_angle) < self.aimthreshold and abs(future_shot_dist - current_shot_dist) < 20: if abs(relative_angle) < self.aimthreshold: command = Command(tank.index, 0, 2 * relative_angle, True) else: command = Command(tank.index, 0, 2 * relative_angle, False) self.commands.append(command) else: self.victory_lap(tank)
def lock_on(self, targetTank): print str(targetTank.x) agentTank = self.mytanks[0] Zt = array([[targetTank.x], [targetTank.y]]) self._kalman.updateKalmanFilter(Zt) est = self._kalman.H.dot(self._kalman.mu) self.updates.append( ((int(est[0][0]), int(est[1][0])), self._kalman.sigmaT)) aimAngle, distance = self.take_aim((agentTank.x, agentTank.y), agentTank.angle) command = Command(0, 0, aimAngle * 2, True) if aimAngle < 1 and aimAngle > -1: if distance < 350: command = Command(0, 0, aimAngle * 2, True) else: command = Command(0, 0, aimAngle * 2, False) else: command = Command(0, 0, aimAngle * 2, False) self.commands.append(command) self.bzrc.do_commands(self.commands)
def sendCommand(self,totalY,totalX,tank): shoot = False theta = math.atan2(totalY,totalX) theta = self.normalize_angle(theta-tank.angle) speed = self.throttle*math.sqrt(totalY**2+totalX**2) self.commands = [] command = Command(tank.index,speed,.35*theta,shoot) self.commands.append(command) self.bzrc.do_commands(self.commands) self.commands = []
def goto_flags(self, tank): best_flag = None best_dist = 2 * float(self.constants['worldsize']) for flag in self.flags: dist = math.sqrt((flag.x - tank.x)**2 + (flag.y - tank.y)**2) if dist < best_dist: best_dist = dist best_flag = flag if best_flag is None: command = Command(tank.index, 0, 0, False) self.commands.append(command) else: self.move_to_position(tank, best_flag.x, best_flag.y)
def tick(self): if self.angvel_increasing: self.angvel += 0.01 if self.angvel > 5.5: self.angvel_increasing = False else: self.angvel -= 0.01 if self.angvel < -5.5: self.angvel_increasing = True command = Command(self.tank_index, self.velocity, self.angvel, False) self.bzrc.do_commands([command]) return
def tick(self, time_diff): '''Some time has passed; decide what to do next''' # Get information from the BZRC server mytanks, othertanks, flags, shots = self.bzrc.get_lots_o_stuff() self.mytanks = mytanks self.othertanks = othertanks self.flags = flags self.shots = shots self.enemies = [tank for tank in othertanks if tank.color != self.constants['team']] # Reset my set of commands (we don't want to run old commands) self.commands = [] print time_diff # Decide what to do with each of my tanks i = 0; #for bot in mytanks: #if tankSeconds are negative then it is turning #if tankSeconds are positive then it is moving for bot in mytanks: initialSec = self.tankSeconds[i] pos = (bot.x, bot.y) if self.tankSeconds[i]<0: # print 'INCREMENT'+str(initialSec) self.tankSeconds.pop(i) self.tankSeconds.insert(i,initialSec+1) # print 'INCREMENT RESULT'+str(self.tankSeconds[i]) elif self.tankSeconds[i]>0: # print 'DECREMENT '+str(initialSec) self.tankSeconds.pop(i) self.tankSeconds.insert(i,initialSec-1) # print 'DECREMENT RESULT '+str(self.tankSeconds[i]) print "top of tank seconds is:{}\n".format(self.tankSeconds[i]) if initialSec == -1: # print 'GO' go = Command(bot.index,1,0,False) self.commands.append(go) self.tankSeconds.pop(i) self.tankSeconds.insert(i,randint(3,8)) i += 1 if math.ceil(time_diff)%2 == 0: # print 'SHOOT!' self.bzrc.shoot(bot.index) #shoot and turn # Send the commands to the server results = self.bzrc.do_commands(self.commands)
def move(self, x_force, y_force, tank): magnitude = math.sqrt(x_force ** 2 + y_force ** 2)/20 targetAngle = math.atan2(y_force, x_force) # randomly shoot should_shoot = False if random.random() < .05: should_shoot = True command = Command(self.tank_index, magnitude, self.calculate_angvel(tank, targetAngle), should_shoot) self.commands.append(command) if self.commands: self.bzrc.do_commands(self.commands)
def align_to_pot_vector(self, tank, vector): # Turn to face the angle proscribed by the vector vector_mag = ((vector[0]**2 + vector[1]**2)**0.5) / (2**0.5) vector_angle = math.atan2(vector[1], vector[0]) angle_diff = self.normalize_angle(vector_angle - tank.angle) if vector_mag == 0: angle_diff = 0 command = Command(tank.index, vector_mag, angle_diff, False) # Append the command self.commands.append(command)
def getTargetingCommand(self, time_diff): yDiff = self.targetY - self.tank.y xDiff = self.targetX - self.tank.x #print "cur angle: " + str(curAngle) +" tank at "+ str(self.tank.x)+ ", "+ str(self.tank.y) target_angle = atan2(yDiff, xDiff) relative_angle = normalize_angle(target_angle - self.tank.angle) #print "shots avail "+str(self.tank.shots_avail) #print str(self.tank.time_to_reload) + ", " + str(time_diff) shoot = False #abs(relative_angle) < abs(.0001) #shots_avail > 0 #time_to_reload angleVel = relative_angle * 2 #/time_diff return Command(self.tank.index, 0, angleVel, shoot)
def get_direction(self, tank): """ Get the moving direction based on the strongest attractive vector """ delta_x, delta_y = self.compute_attractive_vectors( tank ) # compute the strongest attractive vector and the target flag angle = math.atan2(delta_y, delta_x) relative_angle = self.normalize_angle(angle - tank.angle) #print "relative angle: %f" % relative_angle #print "delta_x: %f \t delta_y: %f" % (delta_x, delta_y) if tank.index == 1: print "delta_x: %f \t delta_y: %f \t angle: %f \t tank angle: %f \t relative angle: %f" % ( delta_x, delta_y, angle, tank.angle, relative_angle) command = Command(tank.index, self.speed, 2 * relative_angle, False) self.commands.append(command)
def attack_enemies(self, tank): """Find the closest enemy and chase it, shooting as you go.""" best_enemy = None best_dist = 2 * float(self.constants['worldsize']) for enemy in self.enemies: if enemy.status != 'alive': continue dist = math.sqrt((enemy.x - tank.x)**2 + (enemy.y - tank.y)**2) if dist < best_dist: best_dist = dist best_enemy = enemy if best_enemy is None: command = Command(tank.index, 0, 0, False) self.commands.append(command) else: self.move_to_position(tank, best_enemy.x, best_enemy.y)
def tick(self, time_diff): """Some time has passed;""" self.commands = [] if self.num_ticks % self.MAXTICKS == 0: magnitude = random.random() * 0.5 + 0.5 relative_angle = 0.5 command = Command(0, magnitude, 2 * relative_angle, False) self.commands.append(command) results = self.bzrc.do_commands(self.commands) self.num_ticks = self.num_ticks + 1
def get_desired_movement_command(self, time_diff, maxspeed): # PD Controller stuff to make movement smoother #delta_x = self.target[0] - self.x #delta_y = self.target[1] - self.y #print "Delta:", (delta_x, delta_y) #target_angle = math.atan2(delta_y, delta_x) target_angle = self.estimate_firing_angle() current_angle = normalize_angle(self.angle) error_angle = normalize_angle(target_angle - current_angle) #print "Error:", int(rad2deg(error_angle)), "Target:", int(rad2deg(target_angle)), "Current:", int(rad2deg(current_angle)) # clamp the speed to -1 to 1 (technically, 0 to 1) # Base the speed on the current angle as well #target_speed = math.cos(error_angle) * maxspeed #current_speed = math.sqrt(math.pow(self.vy, 2) + math.pow(self.vx, 2)) #error_speed = target_speed - current_speed; #print "Error:", int(error_speed), "Target:", int(target_speed), "Current:", int(current_speed) proportional_gain_angle = 2.25 #proportional_gain_speed = 1.0 derivative_gain_angle = 0.5 #derivative_gain_speed = 0.1 send_angvel = proportional_gain_angle * error_angle + derivative_gain_angle * ( (error_angle - self.previous_error_angle) / time_diff) #send_speed = proportional_gain_speed * error_speed + derivative_gain_speed * ((error_speed - self.previous_error_speed) / time_diff) self.previous_error_angle = error_angle #self.previous_error_speed = error_speed ''' magnitude = math.sqrt(delta_x**2 + delta_y**2) if magnitude == 0: magnitude = 1 direction = (delta_x / magnitude, delta_y / magnitude) #dist((self.vx, self.vy), (0, 0))/time_diff < 1 and math.fabs(error_angle) < math.pi/6: # Did we not move very far, and were we facing the right way? if average_grid(self.agent.bel_grid, (self.x + 5 * direction[0] + 400, self.y + 5 * direction[1] + 400), 10) > .8 or (self.x == self.prev_x and self.y == self.prev_y): # Are we reasonably sure we're running into an obstacle right now? # If we are hitting an obstacle, send the max angular velocity send_angvel = 1 send_speed = 1 # print "true" #else: # print "false" ''' #return Command(self.index, send_speed, send_angvel, 1) return Command(self.index, 0, send_angvel, 1)
def kalmanCommand(self, totalX, totalY, theta, shoot, tank): p = Point(tank.x, tank.y) for obstacle in self.obstacles: if (p.distance(obstacle) < 50): deltaX, deltaY = self.fields.getTangentialField2( self.tank, obstacle, 100, 40, "CW") totalX = deltaX totalY = deltaY theta = math.atan2(totalY, totalX) theta = self.normalize_angle(theta - tank.angle) speed = math.sqrt(totalY**2 + totalX**2) self.commands = [] command = Command(tank.index, .15 * speed, 1.15 * theta, True) self.commands.append(command) self.bzrc.do_commands(self.commands) self.commands = []
def tick(self, time_diff): """Some time has passed; decide what to do next.""" # don't need to know where the flags or shots are when exploring. Enemies are included in the 'othertanks' call # pos,partialGrid = self.bzrc.get_occgrid() # self.grid.updateGrid(pos,partialGrid) self._kalman.setDT(time_diff) self.mytanks = self.bzrc.get_mytanks() # self.othertanks = self.bzrc.get_othertanks() targetTank = self.bzrc.get_othertanks()[0] self.commands = [] if targetTank.status == 'alive': self.lock_on(targetTank) else: self.aliveTime = time.time() stopMoving = Command(0, 0, 0, False) self.commands.append(stopMoving) self.bzrc.do_commands(self.commands) self._kalman.resetArrays()
def kalman(self, tank): target = self.get_target_loc(tank) X = np.matrix([target.x, target.y]) if target != None: P_k = self.get_Pk() K = self.get_K(P_k) self.mu = self.F * self.mu + K * (X - self.H * self.F * self.mu) self.SIGMA_T = (self.I - K * self.H) * P_k #calculate angle delta_x, delta_y, magnitude = self.calculate_objective_delta( tank.x, tank.y, target.x, target.y) turn_angle = math.atan2(delta_y, delta_x) relative_angle = self.normalize_angle(turn_angle - tank.angle) command = Command(tank.index, 0, 2 * relative_angle, True) self.commands.append(command)
def tick(self, gameClock): """Some time has passed; decide what to do next.""" self.tickTime = gameClock - self.prevTime mytanks, othertanks, flags, shots = self.bzrc.get_lots_o_stuff() self.mytanks = mytanks self.othertanks = othertanks self.flags = flags self.shots = shots self.enemies = [ tank for tank in othertanks if tank.color != self.constants['team'] ] self.commands = [] self.timer -= gameClock self.gunTimer -= self.tickTime self.moveTimer -= self.tickTime if self.gunTimer <= 0: shouldShoot = True self.gunTimer = float(random.randrange(15, 25)) / 10 else: shouldShoot = False if self.moveTimer <= 0: #turn self.turnTimer -= self.tickTime speed = 0 angVel = 1 if self.turnTimer <= 0: self.moveTimer = random.randrange(3, 9) self.turnTimer = 1.5 else: #keep moving forward speed = 1 angVel = 0 for i in range(2): command = Command(i, speed, angVel, shouldShoot) self.commands.append(command) results = self.bzrc.do_commands(self.commands) self.prevTime = gameClock
def tick(self, time_diff, tick_time): '''Some time has passed; decide what to do next''' # Get information from the BZRC server #self.mytanks = self.bzrc.get_mytanks() # Reset my set of commands (we don't want to run old commands) #self.commands = [] # Decide what to do with each of my tanks #self.do_dumb_stuff(tick_time) # Send the commands to the server #results = self.bzrc.do_commands(self.commands) # Just tell the tank to start moving in whatever direction its facing self.mytanks = self.bzrc.get_mytanks() for bot in self.mytanks: self.commands.append(Command(bot.index, 1, 0, 0)) self.bzrc.do_commands(self.commands)
def move_to_position(self, tank, target_x, target_y): """Set command to move to given coordinates.""" #target_x = tank.target_x #target_y = tank.target_y # calculate the fields that come as a result of the obstacles for obs in self.obstacles: # calculate the resulting force on the tank add that force to target_x and target_y delta_x, delta_y = self.get_obstacle_force(obs, tank) target_x += delta_x target_y += delta_y target_angle = math.atan2(target_y - tank.y, target_x - tank.x) relative_angle = self.normalize_angle(target_angle - tank.angle) command = Command(tank.index, 1, 2 * relative_angle, True) self.commands.append(command)
def move_to_position(self, tank, target_x, target_y): """Set command to move to given coordinates.""" #get deltas delta_xG, delta_yG, magnitude = self.calculate_objective_delta(tank.x, tank.y, target_x, target_y) delta_xO, delta_yO = self.calculate_obstacles_delta(tank.x, tank.y) #combine delta_x = delta_xG + delta_xO delta_y = delta_yG + delta_yO #calculate angle turn_angle = math.atan2(delta_y, delta_x) relative_angle = self.normalize_angle(turn_angle - tank.angle) #put lower bound on speed: no slower than 40% if magnitude < 0.4: magnitude = 0.4 command = Command(tank.index, magnitude, 2 * relative_angle, True) self.commands.append(command)
def pf_move(self, tank, pf, pfe): final_angle = 0 if pfe != None: #print self.constants['team'] + " tank: %d = pfe" % tank.index speedmod, angle = pfe.calc_vector(tank.x, tank.y) elif pf != None: #print self.constants['team'] + " tank: %d = pf" % tank.index speedmod, angle = pf.calc_vector(tank.x, tank.y) else: speedmod = -0.5 angle = (math.pi / 2.0) angle = self.normalize_angle(angle - tank.angle) if final_angle == 0: final_angle = angle else: final_angle = (float(final_angle) + float(angle)) / 2.0 command = Command(tank.index, speedmod, 2 * final_angle, True) self.commands.append(command)
def go_back(self, tank): """ go back to the base if tank has the flag """ d = math.sqrt((self.myflag.x - tank.x)**2 + (self.myflag.y - tank.y)**2) if d <= self.base_radius: command = Command(tank.index, 0, 0, False) self.commands.append(command) else: adx, ady = self.compute_attractive_x_and_y(self.myflag, 0, tank, \ self.base_radius) adx /= self.attractive_s ady /= self.attractive_s rdx, rdy = self.compute_repulsive_vectors(tank) tdx, tdy = self.compute_tangential_vectors(tank) delta_x, delta_y = self.combine_vectors([adx, rdx, tdx], \ [ady, rdy, tdy]) tank.goalx = self.myflag.y tank.goaly = self.myflag.x command = self.create_move_forward_command(tank, delta_x, delta_y) self.commands.append(command)
def get_desired_movement_command(self, movement_vector, time_diff, has_flag): delta_x, delta_y = movement_vector target_angle = math.atan2(delta_y, delta_x) # clamp the speed to -1 to 1 (technically, 0 to 1) target_speed = math.sqrt(math.pow(delta_x, 2) + math.pow(delta_y, 2)) current_angle = normalize_angle(self.angle); current_speed = math.sqrt(math.pow(self.vy, 2) + math.pow(self.vx, 2)) error_angle = normalize_angle(target_angle - current_angle); error_speed = target_speed - current_speed; proportional_gain_angle = 1.25 proportional_gain_speed = 0.1 derivative_gain_angle = 0.1 derivative_gain_speed = 0.1 send_angvel = proportional_gain_angle * error_angle + derivative_gain_angle * ((error_angle - self.previous_error_angle) / time_diff) send_speed = proportional_gain_speed * error_speed + derivative_gain_speed * ((error_speed - self.previous_error_speed) / time_diff) self.previous_error_angle = error_angle self.previous_error_speed = error_speed # Ignore the PD Controller for now - make sure fields are working first return Command(self.index, send_speed, send_angvel, 1 if self.shots_avail and (random.random() * 100 < 3 or has_flag) else 0) # Shoot sporadically
def kalman(self, tank): sensor = self.get_target_loc() if sensor != None: X = np.matrix([[sensor.x],[sensor.y]]) P_k = self.get_Pk() K = self.get_K(P_k) self.mu = self.F * self.mu + K * (X - self.H * self.F * self.mu) self.SIGMA_T = (self.I - K * self.H) * P_k target_position = self.predict_future_position() #mu_x = target_position[0,0] #mu_y = target_position[3,0] #calculate angle delta_x, delta_y, magnitude = self.calculate_objective_delta(tank.x, tank.y, target_position[0,0], target_position[3,0]) turn_angle = math.atan2(delta_y, delta_x) relative_angle = self.normalize_angle(turn_angle - tank.angle) command = Command(tank.index, 0, 2 * relative_angle, True) self.commands.append(command) else: self.victory_lap(tank)
def getTargetingCommand(self): yDiff = self.targetY - self.tank.y xDiff = self.targetX - self.tank.x target_angle = atan2(yDiff, xDiff) curTankAngle = self.getCurrentDirectionInPolar() angleDiff = target_angle - curTankAngle if abs(angleDiff + 2 * pi) < abs(angleDiff): angleDiff = angleDiff + 2 * pi elif abs(angleDiff - 2 * pi) < abs(angleDiff): angleDiff = angleDiff - 2 * pi angleVel = angleDiff #TODO depending on how we get the angle and speed, convert these to a command if 1 < angleVel: angleVel = 1 elif angleVel < -1: angleVel = -1 elif angleVel == 'nan': angleVel = 0 """ index, speed, angle, shoot""" return Command(self.tank.index, .5, angleVel, True)
def stop_tank(self, tank): command = Command(tank.index, 0, 0, False) self.commands.append(command)
def move_to_position(self, tank, target_x, target_y): """Set command to move to given coordinates.""" target_angle = math.atan2(target_y - tank.y, target_x - tank.x) relative_angle = self.normalize_angle(target_angle - tank.angle) command = Command(tank.index, 1, 2 * relative_angle, True) self.commands.append(command)
def tick(self): command = Command(self.tank_index, 4, 0, False) self.bzrc.do_commands([command]) return