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