Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time to reach rework #1634

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open

Conversation

knoellle
Copy link
Contributor

@knoellle knoellle commented Feb 16, 2025

Why? What?

This PR refactors

  • Role assignment
  • Time to reach kick position calculation
  • Team ball handling

I still haven't been able to reproduce the exact bug related to time to reach that we found at RoboCup last year but this PR should hopefully fix it.

Fixes #

ToDo / Known Issues

There are still some todos left in the code

Ideas for Next Iterations (Not This PR)

  • Use network balls as percepts in the ball filter

How to Test

Best approach is probably to play around with robots, both in simulation and on real hardware.

@knoellle knoellle added the is:Refactoring No changes in functionality, only in coding style. label Feb 16, 2025
@knoellle knoellle self-assigned this Feb 16, 2025
@knoellle knoellle force-pushed the time-to-reach-rework branch from de2b39b to 570ca6c Compare February 16, 2025 19:47
@knoellle knoellle marked this pull request as ready for review February 16, 2025 21:23
Copy link
Member

@schmidma schmidma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not have a look at crates/control/src/role_assignment.rs yet. Nevertheless, here are already some questions and comments ;)

@@ -34,10 +35,17 @@ impl Default for HulkMessage {
pub struct StrikerMessage {
pub player_number: PlayerNumber,
pub pose: Pose2<Field>,
pub ball_position: Option<BallPosition<Field>>,
pub ball_position: BallPosition<Field>,
// TODO: make non-optional
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is blocking you from that? Is this something for a next iteration?

Comment on lines +65 to +73
let stand_up_back_estimated_remaining_duration = {
let last_cycle_duration = context.cycle_time.last_cycle_duration;
let condition_input = context.condition_input;

self.interpolator
.advance_by(last_cycle_duration, condition_input);
self.interpolator
.advance_by(last_cycle_duration, condition_input);

Some(self.interpolator.estimated_remaining_duration())
} else {
self.interpolator.reset();
None
};
self.interpolator.estimated_remaining_duration()
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look right?! You somehow miss the reset now?

Comment on lines +41 to +42
stand_up_back_estimated_remaining_duration:
CyclerState<Duration, "stand_up_back_estimated_remaining_duration">,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you think about this use of CyclerState twice? We should be very sure about behavior at edges. e.g. the duration being ZERO when the standup never happened yet? etc.

But there is definitely something incorrect in this module

time_to_turn,
]
.into_iter()
.fold(Duration::ZERO, Duration::saturating_add);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a fold and not a sum? Is the saturation property actually so important? Do we run into overflows?

Comment on lines +46 to +61
let walk_time = Duration::from_secs_f32(
dribble_path
.iter()
.map(|segment: &PathSegment| {
let length = segment.length();
match segment {
PathSegment::LineSegment(_) => {
length / context.configuration.path_planning.line_walking_speed
}
})
.sum()
})
.map(Duration::from_secs_f32);
let turning_angle = match context.motion_command {
MotionCommand::Walk {
orientation_mode: OrientationMode::Override(orientation),
..
} => Some(orientation.angle().abs()),
_ => {
let turning_angle_towards_path = match context.dribble_path {
Some(path) => match path.first() {
Some(PathSegment::LineSegment(line_segment)) => {
Some(line_segment.1.coords().angle(&Vector2::x_axis()).abs())
PathSegment::Arc(_) => {
length / context.configuration.path_planning.arc_walking_speed
}
_ => None,
},
}
})
.sum(),
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a little picky, but try to reduce some levels of indentation ;)

e.g.

        let secs = dribble_path
            .iter()
            .map(|segment: &PathSegment| {
                let length = segment.length();
                match segment {
                    PathSegment::LineSegment(_) => {
                        length / context.configuration.path_planning.line_walking_speed
                    }
                    PathSegment::Arc(_) => {
                        length / context.configuration.path_planning.arc_walking_speed
                    }
                }
            })
            .sum();
        let walk_time = Duration::from_secs_f32(secs);

Comment on lines +70 to +101
// === Team ball ===
// if let Some(game_controller_state) = filtered_game_controller_state {
// match game_controller_state.game_phase {
// GamePhase::PenaltyShootout {
// kicking_team: Team::Hulks,
// } => return (Role::Striker, false, None),
// GamePhase::PenaltyShootout {
// kicking_team: Team::Opponent,
// } => return (Role::Keeper, false, None),
// _ => {}
// };
// if let Some(SubState::PenaltyKick) = game_controller_state.sub_state {
// return (current_role, false, None);
// }
// }

// if primary_state != PrimaryState::Playing {
// match detected_own_team_ball {
// None => return (current_role, false, team_ball), Some(own_team_ball) => return (current_role, false, own_team_ball),
// }

// let team_ball_from_spl_message = Some(BallPosition {
// position: striker_event.ball_position.position,
// velocity: Vector::zeros(),
// last_seen: cycle_start_time - striker_event.ball_position.age,
// });

// === Obstacles ===
// let sender_position = ground_to_field.inverse() * spl_message.pose.position();
// if spl_message.player_number != *context.player_number {
// network_robot_obstacles.push(sender_position);
// }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here?

.filter_map(|message| Some((*time, (*message)?)))
})
.filter_map(|(time, message)| match message {
IncomingMessage::Spl(HulkMessage::Striker(message)) => Some((time, *message)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to handle Looser messages as well, do we?


let team_ball = self.get_best_received_ball(
context.cycle_time.start_time,
context.striker_trusts_team_ball.mul_f32(4.5),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be dependent on this other parameter?

Comment on lines +27 to +28
network_message_debug:
AdditionalOutput<Vec<(SystemTime, StrikerMessage)>, "network_message_debug">,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are not scoped, are they? This floats around in the top level now

Comment on lines +110 to +117
ball.filter(|ball| {
context
.cycle_time
.start_time
.duration_since(ball.last_seen)
.expect("time ran backwards")
< context.striker_trusts_team_ball.mul_f32(4.5)
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is duplication to the condition below, maybe extract this and refactor?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cat:Behavior GO25 is:Refactoring No changes in functionality, only in coding style.
Projects
Status: Request for Review
Development

Successfully merging this pull request may close these issues.

3 participants