Skip to content

Commit 76dc4ff

Browse files
authored
Obey ball not free (#638)
1 parent c089012 commit 76dc4ff

2 files changed

Lines changed: 90 additions & 7 deletions

File tree

yggdrasil/src/behavior/roles/striker.rs

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
use bevy::prelude::*;
2+
use bifrost::communication::{GameControllerMessage, SetPlay};
23
use nalgebra::{Point2, Point3};
34
use nidhogg::types::{FillExt, RightEye, color};
45

56
use crate::{
67
behavior::{
7-
behaviors::{RlStrikerSearchBehavior, Walk, WalkToBall},
8-
engine::{CommandsBehaviorExt, RoleState, Roles, in_role},
8+
behaviors::{RlStrikerSearchBehavior, StandLookAt, Walk, WalkTo, WalkToBall},
9+
engine::{BehaviorState, CommandsBehaviorExt, RoleState, Roles, in_role},
10+
primary_state::PrimaryState,
11+
},
12+
core::config::{
13+
layout::{FieldConfig, LayoutConfig},
14+
showtime::PlayerConfig,
915
},
10-
core::config::layout::{FieldConfig, LayoutConfig},
1116
localization::RobotPose,
12-
motion::walking_engine::step::Step,
17+
motion::{step_planner::Target, walking_engine::step::Step},
1318
nao::{NaoManager, Priority},
1419
vision::ball_detection::ball_tracker::BallTracker,
1520
};
@@ -22,9 +27,35 @@ pub struct StrikerRolePlugin;
2227

2328
impl Plugin for StrikerRolePlugin {
2429
fn build(&self, app: &mut App) {
25-
app.add_systems(Update, striker_role.run_if(in_role::<Striker>))
26-
.add_systems(OnExit(RoleState::Striker), reset_striker_role);
30+
app.add_systems(
31+
Update,
32+
(
33+
striker_role.run_if(in_role::<Striker>.and(not(in_set_play))),
34+
set_play.run_if(in_set_play),
35+
),
36+
)
37+
.add_systems(OnExit(RoleState::Striker), reset_striker_role);
38+
}
39+
}
40+
41+
fn in_set_play(
42+
gamecontroller_message: Option<Res<GameControllerMessage>>,
43+
primary_state: Res<PrimaryState>,
44+
player_config: Res<PlayerConfig>,
45+
) -> bool {
46+
if let Some(message) = gamecontroller_message {
47+
return match *primary_state {
48+
// return true if there is a set play OR we are in Playing state with a secondary time (Kick-Off)
49+
PrimaryState::Playing { .. } => {
50+
message.set_play != SetPlay::None
51+
|| (message.secondary_time != 0
52+
&& message.kicking_team != player_config.team_number)
53+
}
54+
_ => false,
55+
};
2756
}
57+
58+
false
2859
}
2960

3061
/// The `Striker` role has five substates, each indicated by the right eye LED color:
@@ -125,6 +156,52 @@ pub fn striker_role(
125156
}
126157
}
127158

159+
//TODO: Make this a separate stand-alone behavior
160+
fn set_play(
161+
mut commands: Commands,
162+
ball_tracker: Res<BallTracker>,
163+
pose: Res<RobotPose>,
164+
behavior_state: Res<State<BehaviorState>>,
165+
walk: Option<Res<Walk>>,
166+
) {
167+
let Some(relative_ball) = ball_tracker.stationary_ball() else {
168+
return;
169+
};
170+
let absolute_ball = pose.robot_to_world(&relative_ball);
171+
let ball_distance = relative_ball.coords.norm();
172+
let ball_target = Point3::new(absolute_ball.x, absolute_ball.y, 0.2);
173+
174+
if ball_distance > 1.2 {
175+
commands.set_behavior(WalkTo {
176+
target: Target {
177+
position: absolute_ball,
178+
rotation: None,
179+
},
180+
});
181+
return;
182+
}
183+
184+
if behavior_state.get() == &BehaviorState::Walk {
185+
if let Some(walk) = walk {
186+
if matches!(walk.step, Step::BACK) && ball_distance < 0.875 {
187+
return;
188+
}
189+
}
190+
}
191+
192+
if ball_distance < 0.75 {
193+
commands.set_behavior(Walk {
194+
step: Step::BACK,
195+
look_target: Some(ball_target),
196+
});
197+
return;
198+
}
199+
200+
commands.set_behavior(StandLookAt {
201+
target: absolute_ball,
202+
});
203+
}
204+
128205
pub fn goal_aligned(pose: &RobotPose, field_config: &FieldConfig) -> bool {
129206
if pose.inner.translation.x > 0.0 {
130207
// If on enemy side

yggdrasil/src/motion/walking_engine/step.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::kinematics::Kinematics;
99

1010
use super::{Side, feet::FootPositions};
1111

12-
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
12+
#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
1313
pub struct Step {
1414
/// Forward component of the step in meters.
1515
pub forward: f32,
@@ -53,6 +53,12 @@ impl Step {
5353
turn: 0.0,
5454
};
5555

56+
pub const BACK: Self = Self {
57+
forward: -0.06,
58+
left: 0.0,
59+
turn: 0.0,
60+
};
61+
5662
/// Clamp the step to the anatomic limits of the robot.
5763
#[must_use]
5864
pub fn clamp_anatomic(self, swing_foot: Side, max_inside_turn: f32) -> Self {

0 commit comments

Comments
 (0)