def defense(self): # Prepare to block the ball if self._is_ball_safe_to_kick() and self.game_state.ball.is_immobile(): self.next_state = self.clear if self._ball_going_toward_goal(): self.next_state = self.intercept return self.intercept() # no time to loose circle_radius = self.game_state.field.goal_width / 2 circle_center = self.game_state.field.our_goal - self.OFFSET_FROM_GOAL_LINE solutions = intersection_line_and_circle(circle_center, circle_radius, self.game_state.ball.position, self._best_target_into_goal()) # Their is one or two intersection on the circle, take the one on the field for solution in solutions: if solution.x < self.game_state.field.field_length / 2\ and self.game_state.ball.position.x < self.game_state.field.field_length / 2: orientation_to_ball = (self.game_state.ball.position - self.player.position).angle return MoveTo(Pose(solution, orientation_to_ball), cruise_speed=3, end_speed=0) return MoveTo(Pose(self.game_state.field.our_goal, np.pi), cruise_speed=3, end_speed=0)
def intercept(self): # Find the point where the ball will go if not self._ball_going_toward_goal( ) and not self.game_state.field.is_ball_in_our_goal_area(): self.next_state = self.defense elif self.game_state.field.is_ball_in_our_goal_area( ) and self.game_state.ball.is_immobile(): self.next_state = self.clear ball = self.game_state.ball where_ball_enter_goal = intersection_between_lines( self.GOAL_LINE.p1, self.GOAL_LINE.p2, ball.position, ball.position + ball.velocity) # This is where the ball is going to enter the goal where_ball_enter_goal = closest_point_on_segment( where_ball_enter_goal, self.GOAL_LINE.p1, self.GOAL_LINE.p2) enter_goal_to_ball = Line(where_ball_enter_goal, ball.position) # The goalkeeper can not enter goal since there a line blocking vision end_segment = enter_goal_to_ball.direction * ROBOT_RADIUS + where_ball_enter_goal intersect_pts = closest_point_on_segment(self.player.position, ball.position, end_segment) self.last_intersection = intersect_pts return MoveTo( Pose(intersect_pts, self.player.pose.orientation ), # It's a bit faster, to keep our orientation cruise_speed=3, end_speed=0, ball_collision=False)
def _generate_move_to(self): player_pose = self.player.pose ball_position = self.game_state.ball_position dest_position = self.get_behind_ball_position(ball_position) destination_pose = Pose(dest_position, player_pose.orientation) return MoveTo(destination_pose)
def main_state(self): if self.check_success(): self.current_position_index_to_go = random.randint(0, len(self.grid_of_positions) - 1) self.current_position_to_go = self.grid_of_positions[self.current_position_index_to_go] #self.current_angle_to_go = random.randint(-1, 1) * np.pi / 100. self.next_pose = Pose(self.current_position_to_go, self.current_angle_to_go) return MoveTo(self.next_pose, cruise_speed=2)
def main_state(self): self.compute_wall_arc() if self.game_state.field.is_ball_in_our_goal_area(): return Idle # We must not block the goalkeeper angle = self.angle_on_wall_arc() dest = Position(cos(angle), sin( angle)) * self.dist_from_ball + self.game_state.ball_position dest_orientation = (self.game_state.ball_position - dest).angle return MoveTo(Pose(dest, dest_orientation), cruise_speed=0.8)
def move_to_pass_position(self): destination_orientation = (self.game_state.ball_position - self.player.pose.position).angle if (time.time() - self.last_evaluation) > EVALUATION_INTERVAL: self.best_position = self._find_best_player_position() if self.auto_position else self.target self.last_evaluation = time.time() return MoveTo(Pose(self.best_position, destination_orientation), ball_collision=False, cruise_speed=2)
def grab_ball(self): if self._get_distance_from_ball() < 120: self.next_state = self.kick self.last_time = time.time() elif self._is_player_towards_ball_and_target(-0.9): self.next_state = self.grab_ball else: self.next_state = self.get_behind_ball return MoveTo( Pose(self.game_state.ball.position, self.player.pose.orientation))
def move_to_ball(self): ball_position = self.game_state.ball_position if (self.player.pose.position - ball_position).norm < POSITION_DEADZONE + ROBOT_RADIUS: self.status_flag = Flags.SUCCESS return Idle else: self.status_flag = Flags.WIP return MoveTo(ball_position)
def main_state(self): self.compute_wall_segment() if self.game_state.field.is_ball_in_our_goal_area(): return Idle # We must not block the goalkeeper elif self._should_ball_be_kick_by_wall() \ and self._is_closest_not_goaler(self.player) \ and self._no_enemy_around_ball(): self.next_state = self.go_kick dest = self.position_on_wall_segment() dest_orientation = (self.object_to_block.position - dest).angle return MoveTo(Pose(dest, dest_orientation), cruise_speed=self.cruise_speed)
def support_other_zone(self): enemy_positions = self.get_enemy_in_zone() if len(enemy_positions) == 0: self.next_state = self.support_other_zone else: self.next_state = self.cover_zone destination = stay_inside_square(self.game_state.ball_position, self.y_top, self.y_bottom, self.x_left, self.x_right) destination = self.game_state.game.field.stay_outside_goal_area( destination, our_goal=True) orientation = (self.game_state.ball_position - destination).angle return MoveTo(Pose(destination, orientation))
def push_ball(self): # self.debug.add_log(1, "Grab ball called") # self.debug.add_log(1, "vector player 2 ball : {} mm".format(self.vector_norm)) if (self.last_ball_position - self.player.pose.position).norm < 40: self.next_state = self.halt self.last_time = time.time() elif self._is_player_opposing_ball_and_target(-0.9): self.next_state = self.push_ball else: self.next_state = self.get_behind_ball # self.debug.add_log(1, "orientation go get ball {}".format(self.last_angle)) target = self.target.position player = self.player.pose.position player_to_target = target - player player_to_target = 0.5 * player_to_target / np.linalg.norm( player_to_target) speed_pose = Pose(Position.from_array(player_to_target)) return MoveTo(speed_pose)
def ProtectGoal(game_state: GameState, player: Player, is_right_goal: bool = True, minimum_distance: float = 150 / 2, maximum_distance: float = None): """ Calcul la pose que doit prendre le gardien en fonction de la position de la balle. :return: Un tuple (Pose, kick) où Pose est la destination du gardien et kick est nul (on ne botte pas) """ goalkeeper_position = player.pose.position ball_position = game_state.ball_position goal_x = game_state.field.our_goal_x goal_position = Position(goal_x, 0) # Calcul des deux positions extremums entre la balle et le centre du but inner_circle_position = stay_inside_circle(ball_position, goal_position, minimum_distance) outer_circle_position = stay_inside_circle(ball_position, goal_position, maximum_distance) destination_position = closest_point_on_segment(goalkeeper_position, inner_circle_position, outer_circle_position) # Vérification que destination_position respecte la distance maximale if maximum_distance is None: destination_position = game_state.game.field.stay_inside_goal_area( destination_position, our_goal=True) else: destination_position = stay_inside_circle(destination_position, goal_position, maximum_distance) # Calcul de l'orientation de la pose de destination destination_orientation = (ball_position - destination_position).angle destination_pose = Pose(destination_position, destination_orientation) return MoveTo(destination_pose)
def GoBehind(player: Player, position1: Position, position2: Optional[Position]=None, distance_behind: float=250, orientation: str= 'front'): """ Action GoBehind: Déplace le robot au point le plus proche sur la droite, derrière un objet dont la position est passée en paramètre, de sorte que cet objet se retrouve entre le robot et la seconde position passée en paramètre Méthodes : exec(self): Retourne la pose où se rendre Attributs (en plus de ceux de Action): player_id : L'identifiant du joueur position1 : La position de l'objet derrière lequel le robot doit se placer (exemple: le ballon) position2 : La position par rapport à laquelle le robot doit être "derrière" l'objet de la position 1 (exemple: le but) """ delta_x = position2.x - position1.x delta_y = position2.y - position1.y theta = math.atan2(delta_y, delta_x) x = position1.x - distance_behind * math.cos(theta) y = position1.y - distance_behind * math.sin(theta) player_x = player.pose.position.x player_y = player.pose.position.y norm_player_2_position2 = math.sqrt((player_x - position2.x) ** 2+(player_y - position2.y) ** 2) norm_position1_2_position2 = math.sqrt((position1.x - position2.x) ** 2 + (position1.y - position2.y) ** 2) if norm_player_2_position2 < norm_position1_2_position2: # on doit contourner l'objectif vecteur_position1_2_position2 = np.array([position1.x - position2.x, position1.y - position2.y, 0]) vecteur_vertical = np.array([0, 0, 1]) vecteur_player_2_position1 = np.array([position1.x - player_x, position1.y - player_y, 0]) vecteur_perp = np.cross(vecteur_position1_2_position2, vecteur_vertical) vecteur_perp /= np.linalg.norm(vecteur_perp) if np.dot(vecteur_perp, vecteur_player_2_position1) > 0: vecteur_perp = -vecteur_perp position_intermediaire_x = x + vecteur_perp[0] * RAYON_AVOID position_intermediaire_y = y + vecteur_perp[1] * RAYON_AVOID if math.sqrt((player_x-position_intermediaire_x)**2+(player_y-position_intermediaire_y)**2) < 50: position_intermediaire_x += vecteur_perp[0] * RAYON_AVOID * 2 position_intermediaire_y += vecteur_perp[1] * RAYON_AVOID * 2 destination_position = Position(position_intermediaire_x, position_intermediaire_y) else: if math.sqrt((player_x-x)**2+(player_y-y)**2) < 50: x -= math.cos(theta) * 2 y -= math.sin(theta) * 2 destination_position = Position(x, y) # Calcul de l'orientation de la pose de destination destination_orientation = 0 if orientation == 'front': destination_orientation = wrap_to_pi((position1 - destination_position).angle) elif orientation == 'back': destination_orientation = wrap_to_pi((position1 - destination_position).angle + np.pi) destination_pose = Pose(destination_position, destination_orientation) return MoveTo(destination_pose)
def defense_dumb(self): dest_y = self.game_state.ball.position.y \ * self.game_state.goal_width / 2 / self.game_state.field.top position = self.game_state.field.our_goal - Position( ROBOT_RADIUS + 10, -dest_y) return MoveTo(Pose(position, np.pi))
def stay_out_of_circle(self): position = stay_outside_circle(self.player.pose.position, self.game_state.ball_position, self.keepout_radius) return MoveTo(Pose(position, self.player.pose.orientation))