James Kuszmaul | 84083f4 | 2022-02-27 17:24:38 -0800 | [diff] [blame] | 1 | #include "y2022/control_loops/superstructure/turret/aiming.h" |
| 2 | |
| 3 | #include "y2022/constants.h" |
| 4 | #include "y2022/control_loops/drivetrain/drivetrain_base.h" |
| 5 | |
| 6 | namespace y2022 { |
| 7 | namespace control_loops { |
| 8 | namespace superstructure { |
| 9 | namespace turret { |
| 10 | |
| 11 | using frc971::control_loops::Pose; |
| 12 | using frc971::control_loops::aiming::ShotConfig; |
| 13 | using frc971::control_loops::aiming::RobotState; |
| 14 | |
| 15 | namespace { |
| 16 | // Average speed-over-ground of the ball on its way to the target. Our current |
| 17 | // model assumes constant ball velocity regardless of shot distance. |
James Kuszmaul | 7b27aab | 2022-03-28 19:57:28 -0700 | [diff] [blame] | 18 | constexpr double kBallSpeedOverGround = 2.0; // m/s |
James Kuszmaul | 84083f4 | 2022-02-27 17:24:38 -0800 | [diff] [blame] | 19 | |
| 20 | // If the turret is at zero, then it will be at this angle at which the shot |
| 21 | // will leave the robot. I.e., if the turret is at zero, then the shot will go |
| 22 | // straight out the back of the robot. |
| 23 | constexpr double kTurretZeroOffset = M_PI; |
| 24 | |
James Kuszmaul | e3fc87f | 2022-03-12 21:00:50 -0800 | [diff] [blame] | 25 | constexpr double kMaxProfiledVelocity = 10.0; |
| 26 | constexpr double kMaxProfiledAccel = 20.0; |
| 27 | |
James Kuszmaul | 84083f4 | 2022-02-27 17:24:38 -0800 | [diff] [blame] | 28 | flatbuffers::DetachedBuffer MakePrefilledGoal() { |
| 29 | flatbuffers::FlatBufferBuilder fbb; |
| 30 | fbb.ForceDefaults(true); |
James Kuszmaul | e3fc87f | 2022-03-12 21:00:50 -0800 | [diff] [blame] | 31 | frc971::ProfileParameters::Builder profile_builder(fbb); |
| 32 | profile_builder.add_max_velocity(kMaxProfiledVelocity); |
| 33 | profile_builder.add_max_acceleration(kMaxProfiledAccel); |
| 34 | const flatbuffers::Offset<frc971::ProfileParameters> profile_offset = |
| 35 | profile_builder.Finish(); |
James Kuszmaul | 84083f4 | 2022-02-27 17:24:38 -0800 | [diff] [blame] | 36 | Aimer::Goal::Builder builder(fbb); |
| 37 | builder.add_unsafe_goal(0); |
| 38 | builder.add_goal_velocity(0); |
James Kuszmaul | e3fc87f | 2022-03-12 21:00:50 -0800 | [diff] [blame] | 39 | builder.add_ignore_profile(false); |
| 40 | builder.add_profile_params(profile_offset); |
James Kuszmaul | 84083f4 | 2022-02-27 17:24:38 -0800 | [diff] [blame] | 41 | fbb.Finish(builder.Finish()); |
| 42 | return fbb.Release(); |
| 43 | } |
| 44 | } // namespace |
| 45 | |
| 46 | Aimer::Aimer() : goal_(MakePrefilledGoal()) {} |
| 47 | |
| 48 | void Aimer::Update(const Status *status, ShotMode shot_mode) { |
| 49 | const Pose robot_pose({status->x(), status->y(), 0}, status->theta()); |
| 50 | const Pose goal({0.0, 0.0, 0.0}, 0.0); |
| 51 | |
| 52 | const Eigen::Vector2d linear_angular = |
| 53 | drivetrain::GetDrivetrainConfig().Tlr_to_la() * |
| 54 | Eigen::Vector2d(status->estimated_left_velocity(), |
| 55 | status->estimated_right_velocity()); |
| 56 | const double xdot = linear_angular(0) * std::cos(status->theta()); |
| 57 | const double ydot = linear_angular(0) * std::sin(status->theta()); |
| 58 | |
| 59 | current_goal_ = |
| 60 | frc971::control_loops::aiming::AimerGoal( |
| 61 | ShotConfig{goal, shot_mode, constants::Values::kTurretRange(), |
| 62 | kBallSpeedOverGround, |
| 63 | /*wrap_mode=*/0.0, kTurretZeroOffset}, |
| 64 | RobotState{robot_pose, |
| 65 | {xdot, ydot}, |
| 66 | linear_angular(1), |
| 67 | goal_.message().unsafe_goal()}); |
| 68 | |
| 69 | goal_.mutable_message()->mutate_unsafe_goal(current_goal_.position); |
| 70 | goal_.mutable_message()->mutate_goal_velocity( |
Austin Schuh | 3be7f7a | 2022-03-13 20:35:13 -0700 | [diff] [blame] | 71 | std::clamp(current_goal_.velocity, 0.0, 0.0)); |
James Kuszmaul | 84083f4 | 2022-02-27 17:24:38 -0800 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | flatbuffers::Offset<AimerStatus> Aimer::PopulateStatus( |
| 75 | flatbuffers::FlatBufferBuilder *fbb) const { |
| 76 | AimerStatus::Builder builder(*fbb); |
| 77 | builder.add_turret_position(current_goal_.position); |
| 78 | builder.add_turret_velocity(current_goal_.velocity); |
| 79 | builder.add_target_distance(current_goal_.target_distance); |
| 80 | builder.add_shot_distance(DistanceToGoal()); |
| 81 | return builder.Finish(); |
| 82 | } |
| 83 | |
| 84 | } // namespace turret |
| 85 | } // namespace superstructure |
| 86 | } // namespace control_loops |
| 87 | } // namespace y2022 |