blob: 7170a1d03c22cad12b9c67196406c43448835bb5 [file] [log] [blame]
milind-u086d7262022-01-19 20:44:18 -08001#include <unistd.h>
2
3#include <cmath>
4#include <cstdio>
5#include <cstring>
6
7#include "aos/actions/actions.h"
8#include "aos/init.h"
9#include "aos/logging/logging.h"
10#include "aos/network/team_number.h"
11#include "aos/util/log_interval.h"
12#include "frc971/autonomous/base_autonomous_actor.h"
Henry Speiser0b9b0052022-03-02 23:07:40 -080013#include "frc971/control_loops/drivetrain/localizer_generated.h"
Austin Schuh39f26f62022-02-24 21:34:46 -080014#include "frc971/control_loops/profiled_subsystem_generated.h"
milind-u086d7262022-01-19 20:44:18 -080015#include "frc971/input/action_joystick_input.h"
16#include "frc971/input/driver_station_data.h"
17#include "frc971/input/drivetrain_input.h"
18#include "frc971/input/joystick_input.h"
Henry Speiser0b9b0052022-03-02 23:07:40 -080019#include "frc971/zeroing/wrap.h"
20#include "y2022/constants.h"
milind-u086d7262022-01-19 20:44:18 -080021#include "y2022/control_loops/drivetrain/drivetrain_base.h"
22#include "y2022/control_loops/superstructure/superstructure_goal_generated.h"
23#include "y2022/control_loops/superstructure/superstructure_status_generated.h"
Henry Speiser0b9b0052022-03-02 23:07:40 -080024#include "y2022/setpoint_generated.h"
milind-u086d7262022-01-19 20:44:18 -080025
Henry Speiser0b9b0052022-03-02 23:07:40 -080026using frc971::CreateProfileParameters;
27using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
Austin Schuh39f26f62022-02-24 21:34:46 -080028using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
milind-u086d7262022-01-19 20:44:18 -080029using frc971::input::driver_station::ButtonLocation;
30using frc971::input::driver_station::ControlBit;
31using frc971::input::driver_station::JoystickAxis;
32using frc971::input::driver_station::POVLocation;
33
34namespace y2022 {
35namespace input {
36namespace joysticks {
37
38namespace superstructure = y2022::control_loops::superstructure;
39
Henry Speiser0b9b0052022-03-02 23:07:40 -080040// TODO(henry) put actually button locations here
41// TODO(milind): integrate with shooting statemachine and aimer
42const ButtonLocation kCatapultPos(3, 3);
43const ButtonLocation kFire(3, 2);
44const ButtonLocation kFixedTurret(3, 1);
45
46const ButtonLocation kIntakeFrontOut(4, 4);
47const ButtonLocation kIntakeBackOut(4, 3);
48
49const ButtonLocation kRedLocalizerReset(3, 13);
50const ButtonLocation kBlueLocalizerReset(3, 14);
51const ButtonLocation kLocalizerReset(3, 8);
52
53const ButtonLocation kClimberUpMidRung(10, 10);
54const ButtonLocation kClimberDown(11, 11);
55
milind-u086d7262022-01-19 20:44:18 -080056class Reader : public ::frc971::input::ActionJoystickInput {
57 public:
58 Reader(::aos::EventLoop *event_loop)
59 : ::frc971::input::ActionJoystickInput(
60 event_loop,
61 ::y2022::control_loops::drivetrain::GetDrivetrainConfig(),
62 ::frc971::input::DrivetrainInputReader::InputType::kPistol, {}),
63 superstructure_goal_sender_(
64 event_loop->MakeSender<superstructure::Goal>("/superstructure")),
Henry Speiser0b9b0052022-03-02 23:07:40 -080065 localizer_control_sender_(
66 event_loop->MakeSender<
67 ::frc971::control_loops::drivetrain::LocalizerControl>(
68 "/drivetrain")),
milind-u086d7262022-01-19 20:44:18 -080069 superstructure_status_fetcher_(
Henry Speiser0b9b0052022-03-02 23:07:40 -080070 event_loop->MakeFetcher<superstructure::Status>("/superstructure")),
71 setpoint_fetcher_(
72 event_loop->MakeFetcher<Setpoint>("/superstructure")) {}
73
74 void BlueResetLocalizer() {
75 auto builder = localizer_control_sender_.MakeBuilder();
76
77 frc971::control_loops::drivetrain::LocalizerControl::Builder
78 localizer_control_builder = builder.MakeBuilder<
79 frc971::control_loops::drivetrain::LocalizerControl>();
80 localizer_control_builder.add_x(7.4);
81 localizer_control_builder.add_y(-1.7);
82 localizer_control_builder.add_theta_uncertainty(10.0);
83 localizer_control_builder.add_theta(0.0);
84 localizer_control_builder.add_keep_current_theta(false);
85 if (builder.Send(localizer_control_builder.Finish()) !=
86 aos::RawSender::Error::kOk) {
87 AOS_LOG(ERROR, "Failed to reset blue localizer.\n");
88 }
89 }
90
91 void RedResetLocalizer() {
92 auto builder = localizer_control_sender_.MakeBuilder();
93
94 frc971::control_loops::drivetrain::LocalizerControl::Builder
95 localizer_control_builder = builder.MakeBuilder<
96 frc971::control_loops::drivetrain::LocalizerControl>();
97 localizer_control_builder.add_x(-7.4);
98 localizer_control_builder.add_y(1.7);
99 localizer_control_builder.add_theta_uncertainty(10.0);
100 localizer_control_builder.add_theta(M_PI);
101 localizer_control_builder.add_keep_current_theta(false);
102 if (builder.Send(localizer_control_builder.Finish()) !=
103 aos::RawSender::Error::kOk) {
104 AOS_LOG(ERROR, "Failed to reset red localizer.\n");
105 }
106 }
107
108 void ResetLocalizer() {
109 const frc971::control_loops::drivetrain::Status *drivetrain_status =
110 this->drivetrain_status();
111 if (drivetrain_status == nullptr) {
112 return;
113 }
114 // Get the current position
115 // Snap to heading.
116 auto builder = localizer_control_sender_.MakeBuilder();
117
118 // TODO<Henry> Put our starting location here.
119 frc971::control_loops::drivetrain::LocalizerControl::Builder
120 localizer_control_builder = builder.MakeBuilder<
121 frc971::control_loops::drivetrain::LocalizerControl>();
122 localizer_control_builder.add_x(drivetrain_status->x());
123 localizer_control_builder.add_y(drivetrain_status->y());
124 const double new_theta =
125 frc971::zeroing::Wrap(drivetrain_status->theta(), 0, M_PI);
126 localizer_control_builder.add_theta(new_theta);
127 localizer_control_builder.add_theta_uncertainty(10.0);
128 if (builder.Send(localizer_control_builder.Finish()) !=
129 aos::RawSender::Error::kOk) {
130 AOS_LOG(ERROR, "Failed to reset localizer.\n");
131 }
132 }
milind-u086d7262022-01-19 20:44:18 -0800133
134 void AutoEnded() override { AOS_LOG(INFO, "Auto ended.\n"); }
135
136 void HandleTeleop(
Austin Schuh39f26f62022-02-24 21:34:46 -0800137 const ::frc971::input::driver_station::Data &data) override {
milind-u086d7262022-01-19 20:44:18 -0800138 superstructure_status_fetcher_.Fetch();
139 if (!superstructure_status_fetcher_.get()) {
140 AOS_LOG(ERROR, "Got no superstructure status message.\n");
141 return;
142 }
Austin Schuh39f26f62022-02-24 21:34:46 -0800143
Henry Speiser0b9b0052022-03-02 23:07:40 -0800144 setpoint_fetcher_.Fetch();
Austin Schuh39f26f62022-02-24 21:34:46 -0800145
Henry Speiser0b9b0052022-03-02 23:07:40 -0800146 // Default to the intakes in
147 double intake_front_pos = constants::Values::kIntakeRange().lower;
148 double intake_back_pos = constants::Values::kIntakeRange().lower;
Austin Schuh39f26f62022-02-24 21:34:46 -0800149
Henry Speiser0b9b0052022-03-02 23:07:40 -0800150 double roller_front_speed = 0.0;
151 double roller_back_speed = 0.0;
152 bool roller_speed_compensation = false;
Austin Schuh39f26f62022-02-24 21:34:46 -0800153
Henry Speiser0b9b0052022-03-02 23:07:40 -0800154 double turret_pos = 0.0;
Austin Schuh39f26f62022-02-24 21:34:46 -0800155
Henry Speiser0b9b0052022-03-02 23:07:40 -0800156 double catapult_pos = 0.0;
157 double catapult_return_pos = 0.0;
158 double catapult_speed = 0.0;
159 bool fire = false;
Austin Schuh39f26f62022-02-24 21:34:46 -0800160
Henry Speiser0b9b0052022-03-02 23:07:40 -0800161 if (data.IsPressed(kFire)) {
162 fire = true;
163 }
164
165 // Use setpoints for shooting if present
166 if (setpoint_fetcher_.get()) {
167 turret_pos = setpoint_fetcher_->turret();
168
169 catapult_pos = setpoint_fetcher_->catapult_position();
170 catapult_speed = setpoint_fetcher_->catapult_velocity();
171 } else {
172 turret_pos = 0.0;
173
174 catapult_pos = constants::Values::kDefaultCatapultShotPosition();
175 catapult_speed = constants::Values::kDefaultCatapultShotVelocity();
176 }
177
178 // Keep the catapult return position at the shot one if kCatapultPos is
179 // pressed
180 if (data.IsPressed(kCatapultPos)) {
181 catapult_return_pos = catapult_pos;
182 } else {
183 catapult_return_pos = constants::Values::kCatapultReturnPosition();
184 }
185
186 // If either intake is out by enough, always spin the rollers
187 if (superstructure_status_fetcher_.get() &&
188 superstructure_status_fetcher_->intake_front()->zeroed() &&
189 superstructure_status_fetcher_->intake_front()->position() >
190 constants::Values::kIntakeSlightlyOutPosition()) {
191 roller_front_speed =
192 std::max(roller_front_speed,
193 constants::Values::kMinIntakeSlightlyOutRollerSpeed());
194 roller_speed_compensation = true;
195 }
196 if (superstructure_status_fetcher_.get() &&
197 superstructure_status_fetcher_->intake_back()->zeroed() &&
198 superstructure_status_fetcher_->intake_back()->position() >
199 constants::Values::kIntakeSlightlyOutPosition()) {
200 roller_back_speed =
201 std::max(roller_back_speed,
202 constants::Values::kMinIntakeSlightlyOutRollerSpeed());
203 roller_speed_compensation = true;
204 }
205
206 // Extend the intakes and spin the rollers
207 if (data.IsPressed(kIntakeFrontOut)) {
208 intake_front_pos = constants::Values::kIntakeOutPosition();
209 roller_front_speed = constants::Values::kIntakeOutRollerSpeed();
210 roller_speed_compensation = true;
211 }
212 if (data.IsPressed(kIntakeBackOut)) {
213 intake_back_pos = constants::Values::kIntakeOutPosition();
214 roller_back_speed = constants::Values::kIntakeOutRollerSpeed();
215 roller_speed_compensation = true;
216 }
217
218 // Position climber to climb on mid rung
219 if (data.IsPressed(kClimberUpMidRung)) {
220 climber_pos_ = constants::Values::kClimberMidRungHeight();
221 } else if (data.IsPressed(kClimberDown)) {
222 climber_pos_ = 0.0;
223 }
224
225 if (data.PosEdge(kLocalizerReset)) {
226 ResetLocalizer();
227 }
228
229 if (data.PosEdge(kRedLocalizerReset)) {
230 RedResetLocalizer();
231 }
232 if (data.PosEdge(kBlueLocalizerReset)) {
233 BlueResetLocalizer();
234 }
235
236 {
237 auto builder = superstructure_goal_sender_.MakeBuilder();
238
239 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
240 intake_front_offset =
241 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
242 *builder.fbb(), intake_front_pos,
243 CreateProfileParameters(*builder.fbb(), 20.0, 70.0));
244 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
245 intake_back_offset =
246 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
247 *builder.fbb(), intake_back_pos,
248 CreateProfileParameters(*builder.fbb(), 20.0, 70.0));
249
250 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
251 turret_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
252 *builder.fbb(), turret_pos,
253 CreateProfileParameters(*builder.fbb(), 6.0, 20.0));
254
255 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
256 climber_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
257 *builder.fbb(), climber_pos_,
258 CreateProfileParameters(*builder.fbb(), 6.0, 20.0));
259
260 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
261 catapult_return_offset =
262 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
263 *builder.fbb(), catapult_return_pos,
264 frc971::CreateProfileParameters(*builder.fbb(), 5.0, 30.0));
265
266 superstructure::CatapultGoal::Builder catapult_builder =
267 builder.MakeBuilder<superstructure::CatapultGoal>();
268 catapult_builder.add_return_position(catapult_return_offset);
269 catapult_builder.add_shot_position(catapult_pos);
270 catapult_builder.add_shot_velocity(catapult_speed);
271 flatbuffers::Offset<superstructure::CatapultGoal> catapult_offset =
272 catapult_builder.Finish();
273
274 superstructure::Goal::Builder superstructure_goal_builder =
275 builder.MakeBuilder<superstructure::Goal>();
276
277 superstructure_goal_builder.add_intake_front(intake_front_offset);
278 superstructure_goal_builder.add_intake_back(intake_back_offset);
279 superstructure_goal_builder.add_turret(turret_offset);
280 superstructure_goal_builder.add_climber(climber_offset);
281 superstructure_goal_builder.add_catapult(catapult_offset);
282 superstructure_goal_builder.add_fire(fire);
283
284 superstructure_goal_builder.add_roller_speed_front(roller_front_speed);
285 superstructure_goal_builder.add_roller_speed_back(roller_back_speed);
286 superstructure_goal_builder.add_roller_speed_compensation(
287 roller_speed_compensation ? 1.5 : 0.0f);
288
289 if (builder.Send(superstructure_goal_builder.Finish()) !=
290 aos::RawSender::Error::kOk) {
291 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
292 }
Austin Schuh39f26f62022-02-24 21:34:46 -0800293 }
milind-u086d7262022-01-19 20:44:18 -0800294 }
295
296 private:
Henry Speiser0b9b0052022-03-02 23:07:40 -0800297 double climber_pos_ = 0.0;
298
milind-u086d7262022-01-19 20:44:18 -0800299 ::aos::Sender<superstructure::Goal> superstructure_goal_sender_;
300
Henry Speiser0b9b0052022-03-02 23:07:40 -0800301 ::aos::Sender<frc971::control_loops::drivetrain::LocalizerControl>
302 localizer_control_sender_;
303
milind-u086d7262022-01-19 20:44:18 -0800304 ::aos::Fetcher<superstructure::Status> superstructure_status_fetcher_;
Henry Speiser0b9b0052022-03-02 23:07:40 -0800305
306 ::aos::Fetcher<Setpoint> setpoint_fetcher_;
milind-u086d7262022-01-19 20:44:18 -0800307};
308
309} // namespace joysticks
310} // namespace input
311} // namespace y2022
312
313int main(int argc, char **argv) {
314 ::aos::InitGoogle(&argc, &argv);
315
316 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
Austin Schuhc5fa6d92022-02-25 14:36:28 -0800317 aos::configuration::ReadConfig("aos_config.json");
milind-u086d7262022-01-19 20:44:18 -0800318
319 ::aos::ShmEventLoop event_loop(&config.message());
320 ::y2022::input::joysticks::Reader reader(&event_loop);
321
322 event_loop.Run();
323
324 return 0;
325}