blob: a21c09d117d44dfdb1d70abcd07f5bc038d8cb9d [file] [log] [blame]
Niko Sohmersc4d2c502024-02-19 19:35:35 -08001#include "y2024/control_loops/superstructure/aiming.h"
2
3#include "frc971/control_loops/aiming/aiming.h"
4#include "frc971/control_loops/pose.h"
5
6using frc971::control_loops::aiming::RobotState;
7using frc971::control_loops::aiming::ShotConfig;
8using frc971::control_loops::aiming::ShotMode;
9using y2024::control_loops::superstructure::Aimer;
10
Maxwell Hendersoned8bf812024-02-24 16:41:44 -080011// When the turret is at 0 the note will be leaving the robot at PI.
James Kuszmaul4bd2b4b2024-03-16 11:51:55 -070012static constexpr double kTurretZeroOffset = M_PI - 0.22;
Maxwell Hendersoned8bf812024-02-24 16:41:44 -080013
Niko Sohmersc4d2c502024-02-19 19:35:35 -080014Aimer::Aimer(aos::EventLoop *event_loop,
15 const y2024::Constants *robot_constants)
16 : event_loop_(event_loop),
17 robot_constants_(CHECK_NOTNULL(robot_constants)),
18 drivetrain_config_(
19 frc971::control_loops::drivetrain::DrivetrainConfig<double>::
20 FromFlatbuffer(*robot_constants_->common()->drivetrain())),
21 interpolation_table_(
22 y2024::constants::Values::InterpolationTableFromFlatbuffer(
23 robot_constants_->common()->shooter_interpolation_table())),
24 joystick_state_fetcher_(
25 event_loop_->MakeFetcher<aos::JoystickState>("/aos")) {}
26
27void Aimer::Update(
28 const frc971::control_loops::drivetrain::Status *status,
29 frc971::control_loops::aiming::ShotMode shot_mode,
30 frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoalStatic
31 *turret_goal) {
James Kuszmaul4bd2b4b2024-03-16 11:51:55 -070032 if (status == nullptr) {
33 return;
34 }
Niko Sohmersc4d2c502024-02-19 19:35:35 -080035 const frc971::control_loops::Pose robot_pose({status->x(), status->y(), 0},
36 status->theta());
James Kuszmaul4bd2b4b2024-03-16 11:51:55 -070037 aos::Alliance alliance = aos::Alliance::kRed;
38 if (!joystick_state_fetcher_.Fetch() && !received_joystick_state_) {
39 received_joystick_state_ = false;
40 } else {
41 received_joystick_state_ = true;
Niko Sohmersc4d2c502024-02-19 19:35:35 -080042
James Kuszmaul4bd2b4b2024-03-16 11:51:55 -070043 CHECK_NOTNULL(joystick_state_fetcher_.get());
44 alliance = joystick_state_fetcher_->alliance();
45 }
Niko Sohmersc4d2c502024-02-19 19:35:35 -080046
47 const frc971::control_loops::Pose red_alliance_goal(
48 frc971::ToEigenOrDie<3, 1>(*robot_constants_->common()
49 ->shooter_targets()
50 ->red_alliance()
51 ->pos()),
52 robot_constants_->common()->shooter_targets()->red_alliance()->theta());
53
54 const frc971::control_loops::Pose blue_alliance_goal(
55 frc971::ToEigenOrDie<3, 1>(*robot_constants_->common()
56 ->shooter_targets()
57 ->blue_alliance()
58 ->pos()),
59 robot_constants_->common()->shooter_targets()->blue_alliance()->theta());
60
61 const frc971::control_loops::Pose goal =
62 alliance == aos::Alliance::kRed ? red_alliance_goal : blue_alliance_goal;
63
64 const Eigen::Vector2d linear_angular =
65 drivetrain_config_.Tlr_to_la() *
66 Eigen::Vector2d(status->estimated_left_velocity(),
67 status->estimated_right_velocity());
68 const double xdot = linear_angular(0) * std::cos(status->theta());
69 const double ydot = linear_angular(0) * std::sin(status->theta());
70
71 // Use the previous shot distance to estimate the speed-over-ground of the
72 // note.
73 current_goal_ = frc971::control_loops::aiming::AimerGoal(
74 ShotConfig{goal, shot_mode,
75 frc971::constants::Range::FromFlatbuffer(
76 robot_constants_->common()->turret()->range()),
77 interpolation_table_.Get(current_goal_.target_distance)
78 .shot_speed_over_ground,
James Kuszmaul4bd2b4b2024-03-16 11:51:55 -070079 /*wrap_mode=*/0.15, kTurretZeroOffset},
Niko Sohmersc4d2c502024-02-19 19:35:35 -080080 RobotState{
81 robot_pose, {xdot, ydot}, linear_angular(1), current_goal_.position});
82
83 turret_goal->set_unsafe_goal(current_goal_.position);
Niko Sohmersc4d2c502024-02-19 19:35:35 -080084}
85
86flatbuffers::Offset<AimerStatus> Aimer::PopulateStatus(
87 flatbuffers::FlatBufferBuilder *fbb) const {
88 AimerStatus::Builder builder(*fbb);
89 builder.add_turret_position(current_goal_.position);
90 builder.add_turret_velocity(current_goal_.velocity);
91 builder.add_target_distance(current_goal_.target_distance);
92 builder.add_shot_distance(DistanceToGoal());
93 return builder.Finish();
94}