|
4 | 4 | #include "software/ai/hl/stp/tactic/move_primitive.h" |
5 | 5 | #include "software/math/math_functions.h" |
6 | 6 |
|
| 7 | + |
7 | 8 | Point GoalieFSM::getGoaliePositionToBlock( |
8 | 9 | const Ball &ball, const Field &field, |
9 | 10 | TbotsProto::GoalieTacticConfig goalie_tactic_config) |
@@ -182,6 +183,55 @@ void GoalieFSM::panic(const Update &event) |
182 | 183 | Angle goalie_orientation = |
183 | 184 | (event.common.world_ptr->ball().position() - goalie_pos).orientation(); |
184 | 185 |
|
| 186 | + Point save_pos = goalie_pos; |
| 187 | + // First we are trying to determine how much time do we have to reach the ball |
| 188 | + Duration ball_intercept_time = Duration::fromSeconds( |
| 189 | + (event.common.world_ptr->ball().position() - save_pos).length() / |
| 190 | + (std::max(std::numeric_limits<double>::epsilon(), |
| 191 | + event.common.world_ptr->ball().velocity().length()))); |
| 192 | + |
| 193 | + if (event.common.robot.getTimeToPosition(goalie_pos) > ball_intercept_time) |
| 194 | + { |
| 195 | + Point new_destination = save_pos; |
| 196 | + double final_speed = GOALIE_STEP_SPEED_M_PER_S; |
| 197 | + bool finished = false; |
| 198 | + double max_speed = event.common.robot.robotConstants().robot_max_speed_m_per_s; |
| 199 | + double max_acc = |
| 200 | + event.common.robot.robotConstants().robot_max_acceleration_m_per_s_2; |
| 201 | + while (!finished) |
| 202 | + { |
| 203 | + Vector final_velocity = |
| 204 | + (new_destination - event.common.robot.position()).normalize(final_speed); |
| 205 | + |
| 206 | + // What's happening here is we are using v_o^2=2*d*a to determine the extra |
| 207 | + // distance the goalie will be forced to travel if they intercept the ball |
| 208 | + // with final_speed and then immediately decelerate |
| 209 | + double extra_length = (final_speed * final_speed) / (2.0 * max_acc); |
| 210 | + new_destination = save_pos + final_velocity.normalize(extra_length); |
| 211 | + if (event.common.world_ptr->field().pointInFriendlyDefenseArea( |
| 212 | + new_destination)) |
| 213 | + { |
| 214 | + goalie_pos = new_destination; |
| 215 | + if (event.common.robot.getTimeToPosition(save_pos, final_velocity) < |
| 216 | + ball_intercept_time) |
| 217 | + { |
| 218 | + // If we found that the robot can make it before the ball we consider |
| 219 | + // the while loop finished |
| 220 | + finished = true; |
| 221 | + } |
| 222 | + } |
| 223 | + else |
| 224 | + { |
| 225 | + finished = true; |
| 226 | + } |
| 227 | + final_speed += GOALIE_STEP_SPEED_M_PER_S; |
| 228 | + if (final_speed > max_speed) |
| 229 | + { |
| 230 | + finished = true; |
| 231 | + } |
| 232 | + } |
| 233 | + } |
| 234 | + |
185 | 235 | event.common.set_primitive(std::make_unique<MovePrimitive>( |
186 | 236 | event.common.robot, goalie_pos, goalie_orientation, max_allowed_speed_mode, |
187 | 237 | TbotsProto::ObstacleAvoidanceMode::AGGRESSIVE, TbotsProto::DribblerMode::OFF, |
|
0 commit comments