blob: 980efbaa9b0d3b8d441471a61ad7a63b3c1d4950 [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
11Aimer::Aimer(aos::EventLoop *event_loop,
12 const y2024::Constants *robot_constants)
13 : event_loop_(event_loop),
14 robot_constants_(CHECK_NOTNULL(robot_constants)),
15 drivetrain_config_(
16 frc971::control_loops::drivetrain::DrivetrainConfig<double>::
17 FromFlatbuffer(*robot_constants_->common()->drivetrain())),
18 interpolation_table_(
19 y2024::constants::Values::InterpolationTableFromFlatbuffer(
20 robot_constants_->common()->shooter_interpolation_table())),
21 joystick_state_fetcher_(
22 event_loop_->MakeFetcher<aos::JoystickState>("/aos")) {}
23
24void Aimer::Update(
25 const frc971::control_loops::drivetrain::Status *status,
26 frc971::control_loops::aiming::ShotMode shot_mode,
27 frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoalStatic
28 *turret_goal) {
29 const frc971::control_loops::Pose robot_pose({status->x(), status->y(), 0},
30 status->theta());
31 joystick_state_fetcher_.Fetch();
32 CHECK_NOTNULL(joystick_state_fetcher_.get());
33
34 aos::Alliance alliance = joystick_state_fetcher_->alliance();
35
36 const frc971::control_loops::Pose red_alliance_goal(
37 frc971::ToEigenOrDie<3, 1>(*robot_constants_->common()
38 ->shooter_targets()
39 ->red_alliance()
40 ->pos()),
41 robot_constants_->common()->shooter_targets()->red_alliance()->theta());
42
43 const frc971::control_loops::Pose blue_alliance_goal(
44 frc971::ToEigenOrDie<3, 1>(*robot_constants_->common()
45 ->shooter_targets()
46 ->blue_alliance()
47 ->pos()),
48 robot_constants_->common()->shooter_targets()->blue_alliance()->theta());
49
50 const frc971::control_loops::Pose goal =
51 alliance == aos::Alliance::kRed ? red_alliance_goal : blue_alliance_goal;
52
53 const Eigen::Vector2d linear_angular =
54 drivetrain_config_.Tlr_to_la() *
55 Eigen::Vector2d(status->estimated_left_velocity(),
56 status->estimated_right_velocity());
57 const double xdot = linear_angular(0) * std::cos(status->theta());
58 const double ydot = linear_angular(0) * std::sin(status->theta());
59
60 // Use the previous shot distance to estimate the speed-over-ground of the
61 // note.
62 current_goal_ = frc971::control_loops::aiming::AimerGoal(
63 ShotConfig{goal, shot_mode,
64 frc971::constants::Range::FromFlatbuffer(
65 robot_constants_->common()->turret()->range()),
66 interpolation_table_.Get(current_goal_.target_distance)
67 .shot_speed_over_ground,
68 /*wrap_mode=*/0.0, /*turret_zero_offset*/ 0.0},
69 RobotState{
70 robot_pose, {xdot, ydot}, linear_angular(1), current_goal_.position});
71
72 turret_goal->set_unsafe_goal(current_goal_.position);
73 turret_goal->set_goal_velocity(current_goal_.velocity);
74}
75
76flatbuffers::Offset<AimerStatus> Aimer::PopulateStatus(
77 flatbuffers::FlatBufferBuilder *fbb) const {
78 AimerStatus::Builder builder(*fbb);
79 builder.add_turret_position(current_goal_.position);
80 builder.add_turret_velocity(current_goal_.velocity);
81 builder.add_target_distance(current_goal_.target_distance);
82 builder.add_shot_distance(DistanceToGoal());
83 return builder.Finish();
84}