Software
Strategy
Game strategy, behavior trees, dan decision making
Strategy
Modul strategy menentukan perilaku robot selama pertandingan: kapan mengejar bola, kapan menendang, kapan bertahan, dll.
Overview
┌─────────────────────────────────────────────────┐
│ Strategy Layer │
├─────────────────────────────────────────────────┤
│ │
│ Perception ──→ World Model ──→ Decision ──→ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Ball Position Robot State Action Selection │
│ Field Lines Team Status Motion Command │
│ Obstacles Game State │
│ │
└─────────────────────────────────────────────────┘Game Roles
KidSize (4 Robots)
| Role | Jumlah | Fungsi |
|---|---|---|
| Goalkeeper | 1 | Menjaga gawang |
| Striker | 1-2 | Menyerang, menendang |
| Defender | 1-2 | Bertahan, blocking |
Minimal 1 robot harus menjadi Goalkeeper. Role assignment bisa dinamis tergantung situasi.
Behavior Trees
Konsep
Behavior Tree adalah struktur hierarkis untuk decision making:
[Root]
│
┌──────┼──────┐
▼ ▼ ▼
[Selector] [Sequence] [Parallel]
│
┌────┼────┐
▼ ▼ ▼
[A] [B] [C] ← Actions/ConditionsNode Types
| Node | Symbol | Behavior |
|---|---|---|
| Selector | ? | Try children until one succeeds |
| Sequence | → | Execute all children in order |
| Parallel | ⇉ | Execute all children simultaneously |
| Action | ◆ | Perform an action |
| Condition | ◇ | Check a condition |
Example: Striker Behavior
[Striker Root]
│
[Selector ?]
┌───────────┼───────────┐
▼ ▼ ▼
[Ball Close?] [Ball Far?] [Search]
│ │
[Sequence →] [Sequence →]
│ │ │ │
[Aim][Kick] [Go to][Track]
Ball BallPseudocode
def striker_behavior():
if ball_distance < KICK_RANGE:
aim_at_goal()
kick()
elif ball_visible:
walk_to_ball()
else:
search_for_ball()State Machine
Alternative approach menggunakan Finite State Machine (FSM):
┌────────────────────────────────────────────────┐
│ │
│ ┌─────────┐ ball_seen ┌─────────────┐ │
│ │ SEARCH │ ──────────────→ │ APPROACH │ │
│ │ │ ←────────────── │ │ │
│ └─────────┘ ball_lost └──────┬──────┘ │
│ │ │
│ ball_close │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ KICK │ │
│ └─────────────┘ │
│ │
└────────────────────────────────────────────────┘Multi-Robot Coordination
Role Assignment
def assign_roles(robots, ball_position):
"""
Dynamically assign roles based on situation.
"""
# Find robot closest to ball
distances = [distance(r.position, ball_position) for r in robots]
striker_idx = argmin(distances)
for i, robot in enumerate(robots):
if i == 0: # First robot is always goalkeeper
robot.role = GOALKEEPER
elif i == striker_idx:
robot.role = STRIKER
else:
robot.role = DEFENDERCommunication
Robots dapat berkomunikasi via:
- Shared World Model - Central server menerima data dari semua robot
- Direct Messaging - Robot-to-robot communication (WiFi)
- Implicit Coordination - Rules-based, no direct communication
Dalam RoboCup, komunikasi antar robot dibatasi. Cek rulebook untuk batasan bandwidth.
Game States
Sesuai aturan RoboCup:
| State | Aksi Robot |
|---|---|
| INITIAL | Berdiri diam |
| READY | Pergi ke posisi awal |
| SET | Tunggu di posisi |
| PLAYING | Main! |
| FINISHED | Berhenti |
| PENALIZED | Keluar lapangan |
Game Controller
# Receive game state from GameController
ros2 topic echo /game_state
# States: 0=INITIAL, 1=READY, 2=SET, 3=PLAYING, 4=FINISHEDStrategy Parameters
Tunable Values
# strategy_params.yaml
kick_range: 0.3 # meters
aim_tolerance: 0.1 # radians
search_turn_speed: 0.5 # rad/s
approach_speed: 0.2 # m/s
defense_zone_x: -2.0 # meters from centerImplementation Tips
1. Start Simple
# Basic striker behavior
while True:
if see_ball():
if ball_close():
kick()
else:
walk_to_ball()
else:
turn_to_search()2. Add Complexity Gradually
# More sophisticated
if game_state == PLAYING:
if role == STRIKER:
striker_behavior()
elif role == GOALKEEPER:
goalkeeper_behavior()
else:
defender_behavior()3. Test in Simulation First
# Run Webots simulation
ros2 launch op3_webots_ros2 robot_launch.py
# Run strategy node
ros2 run strategy_node strategyCode Reference
Simple Striker
class StrikerNode(Node):
def __init__(self):
super().__init__('striker_node')
# Subscribers
self.ball_sub = self.create_subscription(
Point, '/ball_position', self.ball_callback, 10)
# Publishers
self.walk_pub = self.create_publisher(
Twist, '/cmd_vel', 10)
def ball_callback(self, msg):
ball_x, ball_y = msg.x, msg.y
if ball_x < KICK_DISTANCE:
self.kick()
else:
self.walk_to(ball_x, ball_y)
def walk_to(self, x, y):
cmd = Twist()
cmd.linear.x = 0.2 # forward speed
cmd.angular.z = atan2(y, x) * 0.5 # turn toward ball
self.walk_pub.publish(cmd)Testing Strategy
Unit Tests
def test_role_assignment():
robots = [Robot(0,0), Robot(1,1), Robot(2,2)]
ball = Point(1.5, 1.5)
assign_roles(robots, ball)
assert robots[0].role == GOALKEEPER
assert robots[1].role == STRIKER # closest to ballSimulation Tests
- Single robot vs ball
- Two robots cooperation
- Full team coordination
- Against opponent (if available)
Future Improvements
- Machine Learning untuk decision making
- Opponent modeling
- Dynamic formation
- Passing between robots
- Set plays (corner, free kick)