Skip to content

Commit

Permalink
Update Webots to R2022a
Browse files Browse the repository at this point in the history
* convert the world to ENU
* fix objects
* fix referee to deal with [x,y] instead of [x,z]
* fix compass to return angle 0 when the robot is
  facing opponent's goal
* closes #124

Signed-off-by: Adrian Matejov <[email protected]>
  • Loading branch information
Adman committed Jan 9, 2022
1 parent 7ab954a commit dba6c7d
Show file tree
Hide file tree
Showing 20 changed files with 893 additions and 774 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ as well as a sample simulated team of robots with some basic strategy.

1. Install Python 3.7 (or higher) 64 bit from the [official website](https://www.python.org/downloads/) (please make sure it is version 3.7 or higher for Windows, and 3.8 or higher if installing on MacOS or Linux). On Windows, please make sure your Python is referenced in Windows PATH by selecting the option "Add Python 3.x to PATH" during the installation. Check out this great [installation guide](https://realpython.com/installing-python/) if you need some help!

2. Download [Webots](https://www.cyberbotics.com/#download) from their official website. Currently, version R2021b is stable with the Soccer Simulator. You can find detailed installation procedure on the official [Webots Installation guide](https://cyberbotics.com/doc/guide/installation-procedure).
2. Download [Webots](https://www.cyberbotics.com/#download) from their official website. Currently, version R2022a is stable with the Soccer Simulator. You can find detailed installation procedure on the official [Webots Installation guide](https://cyberbotics.com/doc/guide/installation-procedure).

3. Clone the rcj-soccer-sim repository to your computer by downloading the ZIP file from [here](https://github.com/RoboCupJuniorTC/rcj-soccer-sim/archive/master.zip) or running

Expand Down
62 changes: 31 additions & 31 deletions controllers/rcj_soccer_referee_supervisor/referee/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@ class Team(Enum):

DEFAULT_MATCH_TIME = 10 * 60 # 10 minutes

GOAL_YELLOW_X_LIMIT = -0.745
GOAL_BLUE_X_LIMIT = 0.745
GOAL_Z_UPPER_LIMIT = 0.2
GOAL_Z_LOWER_LIMIT = -0.209
GOAL_YELLOW_BACK_WALL_X_LIMIT = -0.849
GOAL_BLUE_BACK_WALL_X_LIMIT = 0.849

FIELD_X_UPPER_LIMIT = 0.755
FIELD_X_LOWER_LIMIT = -0.755
FIELD_Z_UPPER_LIMIT = 0.655
FIELD_Z_LOWER_LIMIT = -0.655
GOAL_YELLOW_Y_LIMIT = -0.745
GOAL_BLUE_Y_LIMIT = 0.745
GOAL_X_UPPER_LIMIT = 0.2
GOAL_X_LOWER_LIMIT = -0.209
GOAL_YELLOW_BACK_WALL_Y_LIMIT = -0.849
GOAL_BLUE_BACK_WALL_Y_LIMIT = 0.849

FIELD_Y_UPPER_LIMIT = 0.755
FIELD_Y_LOWER_LIMIT = -0.755
FIELD_X_UPPER_LIMIT = 0.655
FIELD_X_LOWER_LIMIT = -0.655

TIME_STEP = 64
ROBOT_NAMES = ["B1", "B2", "B3", "Y1", "Y2", "Y3"]
N_ROBOTS = len(ROBOT_NAMES)

BALL_DEPTH = 0
BALL_INITIAL_TRANSLATION = [0, BALL_DEPTH, 0]
BALL_INITIAL_TRANSLATION = [0, 0, BALL_DEPTH]

CENTER_NS = "center_ns"
YELLOW_LEFT_NS = "yellow_left_ns"
Expand All @@ -37,42 +37,42 @@ class Team(Enum):
NEUTRAL_SPOTS = {
CENTER_NS: (0, 0),
YELLOW_LEFT_NS: (-0.3, -0.3),
YELLOW_MIDDLE_NS: (-0.2, 0),
YELLOW_RIGHT_NS: (-0.3, 0.3),
YELLOW_MIDDLE_NS: (0, -0.2),
YELLOW_RIGHT_NS: (0.3, -0.3),
BLUE_LEFT_NS: (0.3, 0.3),
BLUE_MIDDLE_NS: (0.2, 0),
BLUE_RIGHT_NS: (0.3, -0.3),
BLUE_MIDDLE_NS: (0, 0.2),
BLUE_RIGHT_NS: (-0.3, 0.3),
}

OBJECT_DEPTH = 0.042

ROBOT_INITIAL_TRANSLATION = {
"B1": [0.3, OBJECT_DEPTH, 0.3],
"B2": [0.3, OBJECT_DEPTH, -0.3],
"B3": [0.3, OBJECT_DEPTH, 0],
"Y1": [-0.3, OBJECT_DEPTH, -0.3],
"Y2": [-0.3, OBJECT_DEPTH, 0.3],
"Y3": [-0.3, OBJECT_DEPTH, 0],
"B1": [0.3, 0.3, OBJECT_DEPTH],
"B2": [-0.3, 0.3, OBJECT_DEPTH],
"B3": [0, 0.3, OBJECT_DEPTH],
"Y1": [-0.3, -0.3, OBJECT_DEPTH],
"Y2": [0.3, -0.3, OBJECT_DEPTH],
"Y3": [0, -0.3, OBJECT_DEPTH],
}

ROBOT_INITIAL_ROTATION = {
"B1": [0, 1, 0, -1.57],
"B2": [0, 1, 0, -1.57],
"B3": [0, 1, 0, -1.57],
"Y1": [0, 1, 0, 1.57],
"Y2": [0, 1, 0, 1.57],
"Y3": [0, 1, 0, 1.57],
"B1": [0, 0, 1, -1.57],
"B2": [0, 0, 1, -1.57],
"B3": [0, 0, 1, -1.57],
"Y1": [0, 0, 1, 1.57],
"Y2": [0, 0, 1, 1.57],
"Y3": [0, 0, 1, 1.57],
}

BLUE_KICKOFF_TRANSLATION = [0.1, OBJECT_DEPTH, 0]
YELLOW_KICKOFF_TRANSLATION = [-0.1, OBJECT_DEPTH, 0]
BLUE_KICKOFF_TRANSLATION = [0, 0.1, OBJECT_DEPTH]
YELLOW_KICKOFF_TRANSLATION = [0, -0.1, OBJECT_DEPTH]

KICKOFF_TRANSLATION = {
Team.BLUE.value: BLUE_KICKOFF_TRANSLATION,
Team.YELLOW.value: YELLOW_KICKOFF_TRANSLATION,
}

# (vertical boundary x, lower boundary z, upper boundary z)
# (vertical boundary y, lower boundary x, upper boundary x)
YELLOW_PENALTY_AREA = (-0.59, -0.35, 0.35)
BLUE_PENALTY_AREA = (0.59, -0.35, 0.35)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def reset(self):
self.time_entered_penalty = None
self.time_left_penalty = None

def is_in_yellow_penalty(self, x: float, z: float) -> bool:
return x < self.y_vertical and self.y_lower < z < self.y_upper
def is_in_yellow_penalty(self, x: float, y: float) -> bool:
return y < self.y_vertical and self.y_lower < x < self.y_upper

def is_in_blue_penalty(self, x: float, z: float) -> bool:
return x > self.b_vertical and self.b_lower < z < self.b_upper
def is_in_blue_penalty(self, x: float, y: float) -> bool:
return y > self.b_vertical and self.b_lower < x < self.b_upper

@property
def has_been_outside_penalty_for_longer(self) -> bool:
Expand All @@ -47,9 +47,9 @@ def track(self, position: List[float], time: int):
time (int): Current game time
"""
self.time = time
x, z = position[0], position[2]
x, y = position[0], position[1]

if self.is_in_blue_penalty(x, z) or self.is_in_yellow_penalty(x, z):
if self.is_in_blue_penalty(x, y) or self.is_in_yellow_penalty(x, y):
# the robot enters the penalty area for the first time
if not self.has_entered:
self.time_entered_penalty = self.time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def track(self, position: List[float]):

delta = math.sqrt(
(prev_position[0] - position[0]) ** 2
+ (prev_position[2] - position[2]) ** 2
+ (prev_position[1] - position[1]) ** 2
)

# store the currently computed delta sample
Expand Down
18 changes: 9 additions & 9 deletions controllers/rcj_soccer_referee_supervisor/referee/referee.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ def _add_initial_position_noise(
level = self.initial_position_noise
return [
translation[0] + (random.random() - 0.5) * level,
translation[1],
translation[2] + (random.random() - 0.5) * level,
translation[1] + (random.random() - 0.5) * level,
translation[2],
]

def add_event_subscriber(self, subscriber: EventHandler):
Expand Down Expand Up @@ -255,9 +255,9 @@ def check_progress(self):
pos = self.sv.get_robot_translation(robot)
self.progress_check[robot].track(pos)

x, z = pos[0], pos[2]
x, y = pos[0], pos[1]
if (
is_outside(x, z)
is_outside(x, y)
or not self.progress_check[robot].is_progress()
):
self.eventer.event(
Expand Down Expand Up @@ -285,9 +285,9 @@ def check_progress(self):

bpos = self.sv.get_ball_translation()
self.progress_check["ball"].track(bpos)
bx, bz = bpos[0], bpos[2]
bx, by = bpos[0], bpos[1]

if is_outside(bx, bz) or not self.progress_check["ball"].is_progress():
if is_outside(bx, by) or not self.progress_check["ball"].is_progress():
self.eventer.event(
referee=self,
type=GameEvents.LACK_OF_PROGRESS.value,
Expand Down Expand Up @@ -317,17 +317,17 @@ def check_goal(self):
team_kickoff = None

ball_translation = self.sv.get_ball_translation()
ball_x, ball_z = ball_translation[0], ball_translation[2]
ball_x, ball_y = ball_translation[0], ball_translation[1]

# ball in the blue goal
if is_in_blue_goal(ball_x, ball_z):
if is_in_blue_goal(ball_x, ball_y):
self.score_yellow += 1

team_goal = self.team_name_yellow
team_kickoff = Team.BLUE.value

# ball in the yellow goal
elif is_in_yellow_goal(ball_x, ball_z):
elif is_in_yellow_goal(ball_x, ball_y):
self.score_blue += 1

team_goal = self.team_name_blue
Expand Down
28 changes: 14 additions & 14 deletions controllers/rcj_soccer_referee_supervisor/referee/supervisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,26 @@ def reset_ball_velocity(self):
"""Reset the ball's velocity."""
self.ball.setVelocity([0, 0, 0, 0, 0, 0])

def is_neutral_spot_occupied(self, ns_x: float, ns_z: float) -> bool:
def is_neutral_spot_occupied(self, ns_x: float, ns_y: float) -> bool:
"""Check whether the specific neutral spot is occupied
Args:
ns_x (float): x position of the neutral spot
ns_z (float): z position of the neutral spot
ns_y (float): y position of the neutral spot
Returns:
bool: Whether the neutral spot is unoccupied
"""
# Check whether any of the robots is blocking the neutral spot
for _, pos in self.robot_translation.items():
rx, rz = pos[0], pos[2]
distance = math.sqrt((rx - ns_x) ** 2 + (rz - ns_z) ** 2)
rx, ry = pos[0], pos[1]
distance = math.sqrt((rx - ns_x) ** 2 + (ry - ns_y) ** 2)
if distance < DISTANCE_AROUND_UNOCCUPIED_NEUTRAL_SPOT:
return True

# Check whether the ball is blocking the neutral spot
bx, bz = self.ball_translation[0], self.ball_translation[2]
distance = math.sqrt((bx - ns_x) ** 2 + (bz - ns_z) ** 2)
bx, by = self.ball_translation[0], self.ball_translation[1]
distance = math.sqrt((bx - ns_x) ** 2 + (by - ns_y) ** 2)
if distance < DISTANCE_AROUND_UNOCCUPIED_NEUTRAL_SPOT:
return True

Expand All @@ -165,17 +165,17 @@ def get_unoccupied_neutral_spots_sorted(
"""
if object_name == "ball":
x = self.ball_translation[0]
z = self.ball_translation[2]
y = self.ball_translation[1]
else:
x = self.robot_translation[object_name][0]
z = self.robot_translation[object_name][2]
y = self.robot_translation[object_name][1]

spot_distance_pairs = []
for ns, ns_pos in NEUTRAL_SPOTS.items():
ns_x, ns_z = ns_pos
spot_distance = math.sqrt((x - ns_x) ** 2 + (z - ns_z) ** 2)
ns_x, ns_y = ns_pos
spot_distance = math.sqrt((x - ns_x) ** 2 + (y - ns_y) ** 2)

if not self.is_neutral_spot_occupied(ns_x, ns_z):
if not self.is_neutral_spot_occupied(ns_x, ns_y):
spot_distance_pairs.append((ns, spot_distance))

do_reverse = distance_type == NeutralSpotDistanceType.FURTHEST.value
Expand All @@ -196,11 +196,11 @@ def move_object_to_neutral_spot(self, object_name: str, neutral_spot: str):
object_name (str): Name of the object (Ball or robot's name)
neutral_spot (str): The spot the robot will be moved to
"""
x, z = NEUTRAL_SPOTS[neutral_spot]
x, y = NEUTRAL_SPOTS[neutral_spot]
if object_name == "ball":
self.set_ball_position([x, BALL_DEPTH, z])
self.set_ball_position([x, y, BALL_DEPTH])
else:
self.set_robot_position(object_name, [x, OBJECT_DEPTH, z])
self.set_robot_position(object_name, [x, y, OBJECT_DEPTH])
self.set_robot_rotation(
object_name, ROBOT_INITIAL_ROTATION[object_name]
)
Expand Down
42 changes: 21 additions & 21 deletions controllers/rcj_soccer_referee_supervisor/referee/utils.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from referee.consts import (
FIELD_X_LOWER_LIMIT,
FIELD_X_UPPER_LIMIT,
FIELD_Z_LOWER_LIMIT,
FIELD_Z_UPPER_LIMIT,
GOAL_BLUE_BACK_WALL_X_LIMIT,
GOAL_BLUE_X_LIMIT,
GOAL_YELLOW_BACK_WALL_X_LIMIT,
GOAL_YELLOW_X_LIMIT,
GOAL_Z_LOWER_LIMIT,
GOAL_Z_UPPER_LIMIT,
FIELD_Y_LOWER_LIMIT,
FIELD_Y_UPPER_LIMIT,
GOAL_BLUE_BACK_WALL_Y_LIMIT,
GOAL_BLUE_Y_LIMIT,
GOAL_X_LOWER_LIMIT,
GOAL_X_UPPER_LIMIT,
GOAL_YELLOW_BACK_WALL_Y_LIMIT,
GOAL_YELLOW_Y_LIMIT,
)


Expand All @@ -24,52 +24,52 @@ def time_to_string(time: int) -> str:
return "%02d:%02d" % (time // 60, time % 60)


def is_in_yellow_goal(x: int, z: int) -> bool:
def is_in_yellow_goal(x: int, y: int) -> bool:
"""Return whether object is located in the yellow goal.
Args:
x (int): X position
z (int): Z position
y (int): Y position
Returns:
bool: True if the object is located in the yellow goal
"""
if GOAL_Z_LOWER_LIMIT < z < GOAL_Z_UPPER_LIMIT:
if GOAL_YELLOW_BACK_WALL_X_LIMIT < x < GOAL_YELLOW_X_LIMIT:
if GOAL_X_LOWER_LIMIT < x < GOAL_X_UPPER_LIMIT:
if GOAL_YELLOW_BACK_WALL_Y_LIMIT < y < GOAL_YELLOW_Y_LIMIT:
return True
return False


def is_in_blue_goal(x: int, z: int) -> bool:
def is_in_blue_goal(x: int, y: int) -> bool:
"""Return whether object is located in the blue goal.
Args:
x (int): X position
z (int): Z position
y (int): Y position
Returns:
bool: True if the object is located in the blue goal
"""
if GOAL_Z_LOWER_LIMIT < z < GOAL_Z_UPPER_LIMIT:
if GOAL_BLUE_X_LIMIT < x < GOAL_BLUE_BACK_WALL_X_LIMIT:
if GOAL_X_LOWER_LIMIT < x < GOAL_X_UPPER_LIMIT:
if GOAL_BLUE_Y_LIMIT < y < GOAL_BLUE_BACK_WALL_Y_LIMIT:
return True
return False


def is_outside(x: int, z: int) -> bool:
def is_outside(x: int, y: int) -> bool:
"""Return whether object is located outside the field.
Args:
x (int): X position
z (int): Z position
y (int): Y position
Returns:
bool: True if the object is located outside
"""
if z > FIELD_Z_UPPER_LIMIT or z < FIELD_Z_LOWER_LIMIT:
if x > FIELD_X_UPPER_LIMIT or x < FIELD_X_LOWER_LIMIT:
return True

if x < FIELD_X_LOWER_LIMIT or x > FIELD_X_UPPER_LIMIT:
return not (is_in_blue_goal(x, z) or is_in_yellow_goal(x, z))
if y < FIELD_Y_LOWER_LIMIT or y > FIELD_Y_UPPER_LIMIT:
return not (is_in_blue_goal(x, y) or is_in_yellow_goal(x, y))

return False
11 changes: 3 additions & 8 deletions controllers/rcj_soccer_team_blue/rcj_soccer_robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def get_gps_coordinates(self) -> list:
List containing x and y values
"""
gps_values = self.gps.getValues()
return [gps_values[0], gps_values[2]]
return [gps_values[0], gps_values[1]]

def get_compass_heading(self) -> float:
"""Get compass heading in radians
Expand All @@ -171,16 +171,11 @@ def get_compass_heading(self) -> float:
"""
compass_values = self.compass.getValues()

# subtract math.pi/2 (90) so that the heading is 0 facing 'north'
# (given x going from left to right)
rad = math.atan2(compass_values[0], compass_values[2]) - (math.pi / 2)
# Add math.pi/2 (90) so that the heading 0 is facing opponent's goal
rad = math.atan2(compass_values[0], compass_values[1]) + (math.pi / 2)
if rad < -math.pi:
rad = rad + (2 * math.pi)

# This world is in NUE (not in EUN), so -1* has to be applied
# More info about coordinate system at
# https://cyberbotics.com/doc/reference/worldinfo
rad *= -1
return rad

def get_sonar_values(self) -> dict:
Expand Down
4 changes: 2 additions & 2 deletions controllers/rcj_soccer_team_blue/robot1.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def run(self):
# If the robot has the ball right in front of it, go forward,
# rotate otherwise
if direction == 0:
left_speed = -5
right_speed = -5
left_speed = 5
right_speed = 5
else:
left_speed = direction * 4
right_speed = direction * -4
Expand Down
Loading

0 comments on commit dba6c7d

Please sign in to comment.