def can_collect_ball_before_opponent(our_robots_to_check=None, their_robots_to_check=None, our_robots_to_dodge=None, their_robots_to_dodge=None, valid_error_percent=0.05): if our_robots_to_check is None: our_robots_to_check = main.our_robots() if their_robots_to_check is None: their_robots_to_check = main.their_robots() if our_robots_to_dodge is None: our_robots_to_dodge = main.our_robots() if their_robots_to_dodge is None: their_robots_to_dodge = main.their_robots() shortest_opp_time = float("inf") shortest_our_time = float("inf") dodge_dist = constants.Robot.Radius closest_robot = None # TODO: Do some sort of prediction as the ball moves target_pos = main.ball().pos # TODO: Take velocity and acceleration into account # Find closest opponent robot for bot in their_robots_to_check: dist = estimate_path_length(bot.pos, target_pos, our_robots_to_dodge, dodge_dist) target_dir = (target_pos - bot.pos).normalized() time = robocup.get_trapezoidal_time( dist, dist, 2.2, 1, target_dir.dot(bot.vel) / target_dir.mag(), 0) if (time < shortest_opp_time): shortest_opp_time = time # Find closest robot on our team for bot in our_robots_to_check: dist = estimate_path_length(bot.pos, target_pos, their_robots_to_dodge, dodge_dist) target_dir = (target_pos - bot.pos).normalized() time = robocup.get_trapezoidal_time( dist, dist, 2.2, 1, target_dir.dot(bot.vel) / target_dir.mag(), 0) if (time < shortest_our_time): shortest_our_time = time closest_robot = bot # Greater than 1 when we are further away print(shortest_our_time) print(shortest_opp_time) return shortest_our_time < shortest_opp_time * ( 1 + valid_error_percent), closest_robot
def role_assignment_cost(robot): # Estimate the time it takes to intercept the ball # Use straight line distance to closest point along line # Then movement down the line # Represents ball movement line ball_move_line = robocup.Line(main.ball().pos, main.ball().pos + main.ball().vel * 10) # Closest point to robot on ball movement line ball_line_intercept = ball_move_line.nearest_point(robot.pos) ball_to_robot = robot.pos - main.ball().pos ball_to_intercept = ball_line_intercept - main.ball().pos robot_to_intercept = ball_line_intercept - robot.pos # If we are actually in front of the ball angle wise # OR close enough that it could be a bounce off the robot due to noisy vision in_front = ball_move_line.delta().angle_between(ball_to_robot) < math.pi/2 or \ ball_to_robot.mag() < 1.5*(constants.Robot.Radius + constants.Ball.Radius) # Calculate how much further the ball will move before we reach the point max_speed = robocup.MotionConstraints.MaxRobotSpeed.value max_acc = robocup.MotionConstraints.MaxRobotAccel.value # How long it will take the robot/ball to reach that intercept point ball_secs = main.ball().estimate_seconds_to(ball_line_intercept) robot_secs = robocup.get_trapezoidal_time(robot_to_intercept.mag(), robot_to_intercept.mag(), max_speed, max_acc, 0, 0) time_to_hit = robot_secs # If we aren't in front of the ball, we need to get time to catch up if (not in_front): # Difference in speed between us and ball delta_speed = max_speed - main.ball().vel.mag() # if we are slower than the ball, don't even try and just exclude it automatically if (delta_speed < 0): time_to_hit += 100 # If we are fast, figure out how much more time we need else: delta_time = robocup.get_trapezoidal_time( ball_to_intercept.mag(), ball_to_intercept.mag(), delta_speed, max_acc, 0, 0) time_to_hit += delta_time #main.debug_drawer().draw_text(str(time_to_hit), robot.pos + robocup.Point(0.1,0.1), (255,255,255), "test") return time_to_hit * Capture.SETTLE_COST_MULTIPLIER
def can_collect_ball_before_opponent(our_robots_to_check=None, their_robots_to_check=None, our_robots_to_dodge=None, their_robots_to_dodge=None, valid_error_percent=0.05): if our_robots_to_check is None: our_robots_to_check = main.our_robots() if their_robots_to_check is None: their_robots_to_check = main.their_robots() if our_robots_to_dodge is None: our_robots_to_dodge = main.our_robots() if their_robots_to_dodge is None: their_robots_to_dodge = main.their_robots() shortest_opp_time = float("inf") shortest_our_time = float("inf") dodge_dist = constants.Robot.Radius closest_robot = None # TODO: Do some sort of prediction as the ball moves target_pos = main.ball().pos # TODO: Take velocity and acceleration into account # Find closest opponent robot for bot in their_robots_to_check: dist = estimate_path_length(bot.pos, target_pos, our_robots_to_dodge, dodge_dist) target_dir = (target_pos - bot.pos).normalized() time = robocup.get_trapezoidal_time(dist, dist, 2.2, 1, target_dir.dot(bot.vel) / target_dir.mag(), 0) if (time < shortest_opp_time): shortest_opp_time = time # Find closest robot on our team for bot in our_robots_to_check: dist = estimate_path_length(bot.pos, target_pos, their_robots_to_dodge, dodge_dist) target_dir = (target_pos - bot.pos).normalized() time = robocup.get_trapezoidal_time(dist, dist, 2.2, 1, target_dir.dot(bot.vel) / target_dir.mag(), 0) if (time < shortest_our_time): shortest_our_time = time closest_robot = bot return shortest_our_time < shortest_opp_time * (1 + valid_error_percent ), closest_robot
def find_intercept_point(self): approach_vec = self.approach_vector() # sample every 5 cm in the -approach_vector direction from the ball pos = None for i in range(50): dist = i * 0.05 pos = main.ball().pos + approach_vec * dist # how long will it take the ball to get there ball_time = evaluation.ball.rev_predict(main.ball().vel, dist) robotDist = (pos - self.robot.pos).mag() * 0.6 bot_time = robocup.get_trapezoidal_time(robotDist, robotDist, 2.2, 1, self.robot.vel.mag(), 0) if bot_time < ball_time: break return pos
def find_intercept_point(self): approach_vec = self.approach_vector() # sample every 5 cm in the -approach_vector direction from the ball pos = None for i in range(50): dist = i * 0.05 pos = main.ball().pos + approach_vec * dist # how long will it take the ball to get there ball_time = evaluation.ball.rev_predict(main.ball().vel, dist) robotDist = (pos - self.robot.pos).mag() * 0.6 bot_time = robocup.get_trapezoidal_time(robotDist, robotDist, 2.2, 1, self.robot.vel.mag(), 0) if bot_time < ball_time: break return pos
def find_robot_capture_point(robot): if robot is None: return main.ball().pos approach_vec = approach_vector(robot) # sample every 5 cm in the -approach_vector direction from the ball pos = None for i in range(50): dist = i * 0.05 pos = main.ball().pos + approach_vec * dist # how long will it take the ball to get there ball_time = evaluation.ball.rev_predict(dist) robotDist = (pos - robot.pos).mag() * 0.6 bot_time = robocup.get_trapezoidal_time(robotDist, robotDist, 2.2, 1, robot.vel.mag(), 0) if bot_time < ball_time: break return pos