-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdemo_ball_placement.py
More file actions
146 lines (130 loc) · 4.96 KB
/
Copy pathdemo_ball_placement.py
File metadata and controls
146 lines (130 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""demo_ball_placement.py — Entry point for the ball placement feature.
Run:
pixi run python demo_ball_placement.py
# RSim window opens; open http://localhost:8080 in a browser
What this sets up
-----------------
- Exhibition Road field (4 m × 3 m, ``GREAT_EXHIBITION_FIELD_DIMS``)
- 2v2 format: two yellow robots (your team) vs two blue robots that
deliberately push the ball out once per side, then attack the yellow goal
- CustomReferee pre-configured with:
- Goal detection enabled (issues PREPARE_KICKOFF → NORMAL_START cycle)
- Out-of-bounds enabled (issues STOP → BALL_PLACEMENT_YELLOW → DIRECT_FREE)
- Defense area and keep-out rules OFF (less noise during development)
- Auto-advance fully enabled so state transitions fire automatically —
you can watch the full placement → free-kick → restart cycle without
touching the GUI
- Browser GUI at http://localhost:8080 — use "Manual Commands" to fire
BALL_PLACEMENT_YELLOW at any time and set the target position
Workflow
--------
1. Run this script and open http://localhost:8080.
2. Let the blue robots push the ball out of bounds, or use the GUI "Manual
Commands" panel to issue BALL_PLACEMENT_YELLOW.
3. Watch one of your robots (yellow) drive to the ball, capture it with the
dribbler, and carry it to the target circle shown in the GUI.
4. After the referee advances to NORMAL_START, yellow kicks once toward the
configured blue robot target.
"""
from utama_core.config.field_params import GREAT_EXHIBITION_FIELD_DIMS
from utama_core.custom_referee import CustomReferee
from utama_core.custom_referee.profiles.profile_loader import (
AutoAdvanceConfig,
DefenseAreaConfig,
GameConfig,
GoalDetectionConfig,
KeepOutConfig,
OutOfBoundsConfig,
RefereeProfile,
RulesConfig,
)
from utama_core.run import StrategyRunner
from utama_core.strategy.examples.ball_placement_and_kick_strategy import (
BallPlacementAndKickStrategy,
)
from utama_core.strategy.examples.deliberate_out_of_bounds_strategy import (
DeliberateOutOfBoundsStrategy,
)
# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
GUI_PORT = 8080
N_ROBOTS = 2
MY_TEAM_IS_YELLOW = True
MY_TEAM_IS_RIGHT = True
# ---------------------------------------------------------------------------
# Referee profile
#
# Out-of-bounds is the primary trigger for ball placement in a real game.
# Defense area and keep-out rules are disabled to reduce noise while you're
# developing the placement skill itself.
# ---------------------------------------------------------------------------
_BALL_PLACEMENT_PROFILE = RefereeProfile(
profile_name="ball_placement_dev",
rules=RulesConfig(
goal_detection=GoalDetectionConfig(
enabled=True,
cooldown_seconds=1.0,
),
out_of_bounds=OutOfBoundsConfig(
enabled=True,
free_kick_assigner="last_touch",
),
defense_area=DefenseAreaConfig(
enabled=False,
max_defenders=1,
attacker_infringement=False,
),
keep_out=KeepOutConfig(
enabled=False,
radius_meters=0.3,
violation_persistence_frames=30,
),
),
game=GameConfig(
half_duration_seconds=300.0,
kickoff_team="yellow",
force_start_after_goal=False,
stop_duration_seconds=2.0,
prepare_duration_seconds=3.0,
kickoff_timeout_seconds=10.0,
auto_advance=AutoAdvanceConfig(
# All auto-advance enabled: state machine drives itself so you can
# observe the full placement → free-kick → normal-start cycle.
stop_to_next_command=True,
prepare_kickoff_to_normal=True,
prepare_penalty_to_normal=True,
direct_free_to_normal=True,
ball_placement_to_next=True,
normal_start_to_force=True,
),
),
)
# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------
def main() -> None:
referee = CustomReferee(
_BALL_PLACEMENT_PROFILE,
n_robots_yellow=N_ROBOTS,
n_robots_blue=N_ROBOTS,
enable_gui=True,
gui_port=GUI_PORT,
)
runner = StrategyRunner(
strategy=BallPlacementAndKickStrategy(),
# Opponents create one out-of-bounds event per side, then attack yellow's goal.
opp_strategy=DeliberateOutOfBoundsStrategy(field_dims=GREAT_EXHIBITION_FIELD_DIMS),
my_team_is_yellow=MY_TEAM_IS_YELLOW,
my_team_is_right=MY_TEAM_IS_RIGHT,
mode="rsim",
control_scheme="pid",
exp_friendly=N_ROBOTS,
exp_enemy=N_ROBOTS,
full_field_dims=GREAT_EXHIBITION_FIELD_DIMS,
referee=referee,
show_live_status=True,
)
runner.run()
if __name__ == "__main__":
main()