blob: b336fd74a2e6774ca6b5c9b58231d3dd60b99b5e [file] [log] [blame]
Stephan Massaltd021f972020-01-05 20:41:23 -08001#include <inttypes.h>
2#include <stdio.h>
3#include <string.h>
4#include <unistd.h>
5
6#include <array>
7#include <chrono>
8#include <cmath>
9#include <functional>
10#include <mutex>
11#include <thread>
12
Stephan Massaltd021f972020-01-05 20:41:23 -080013#include "frc971/wpilib/ahal/AnalogInput.h"
14#include "frc971/wpilib/ahal/Counter.h"
15#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
16#include "frc971/wpilib/ahal/DriverStation.h"
17#include "frc971/wpilib/ahal/Encoder.h"
Alex Perryc4691f52020-02-17 19:20:01 -080018#include "frc971/wpilib/ahal/TalonFX.h"
Stephan Massaltd021f972020-01-05 20:41:23 -080019#include "frc971/wpilib/ahal/VictorSP.h"
20#undef ERROR
21
22#include "aos/commonmath.h"
23#include "aos/events/event_loop.h"
24#include "aos/events/shm_event_loop.h"
25#include "aos/init.h"
26#include "aos/logging/logging.h"
27#include "aos/make_unique.h"
Austin Schuh83873c32020-02-22 14:58:39 -080028#include "aos/network/team_number.h"
Stephan Massaltd021f972020-01-05 20:41:23 -080029#include "aos/realtime.h"
30#include "aos/robot_state/robot_state_generated.h"
31#include "aos/time/time.h"
32#include "aos/util/log_interval.h"
33#include "aos/util/phased_loop.h"
34#include "aos/util/wrapping_counter.h"
Alex Perryc4691f52020-02-17 19:20:01 -080035#include "ctre/phoenix/motorcontrol/can/TalonFX.h"
Stephan Massaltd021f972020-01-05 20:41:23 -080036#include "frc971/autonomous/auto_mode_generated.h"
37#include "frc971/control_loops/drivetrain/drivetrain_position_generated.h"
James Kuszmaula244a912020-01-18 13:50:50 -080038#include "frc971/wpilib/ADIS16470.h"
Stephan Massaltd021f972020-01-05 20:41:23 -080039#include "frc971/wpilib/buffered_pcm.h"
40#include "frc971/wpilib/buffered_solenoid.h"
41#include "frc971/wpilib/dma.h"
42#include "frc971/wpilib/drivetrain_writer.h"
43#include "frc971/wpilib/encoder_and_potentiometer.h"
44#include "frc971/wpilib/joystick_sender.h"
45#include "frc971/wpilib/logging_generated.h"
46#include "frc971/wpilib/loop_output_handler.h"
47#include "frc971/wpilib/pdp_fetcher.h"
48#include "frc971/wpilib/sensor_reader.h"
49#include "frc971/wpilib/wpilib_robot_base.h"
50#include "y2020/constants.h"
51#include "y2020/control_loops/superstructure/superstructure_output_generated.h"
52#include "y2020/control_loops/superstructure/superstructure_position_generated.h"
53
54using ::aos::monotonic_clock;
55using ::y2020::constants::Values;
56namespace superstructure = ::y2020::control_loops::superstructure;
57namespace chrono = ::std::chrono;
58using aos::make_unique;
59
60namespace y2020 {
61namespace wpilib {
62namespace {
63
64constexpr double kMaxBringupPower = 12.0;
65
66// TODO(Brian): Fix the interpretation of the result of GetRaw here and in the
67// DMA stuff and then removing the * 2.0 in *_translate.
68// The low bit is direction.
69
Stephan Massaltd021f972020-01-05 20:41:23 -080070double drivetrain_translate(int32_t in) {
71 return ((static_cast<double>(in) /
72 Values::kDrivetrainEncoderCountsPerRevolution()) *
73 (2.0 * M_PI)) *
74 Values::kDrivetrainEncoderRatio() *
75 control_loops::drivetrain::kWheelRadius;
76}
77
78double drivetrain_velocity_translate(double in) {
79 return (((1.0 / in) / Values::kDrivetrainCyclesPerRevolution()) *
80 (2.0 * M_PI)) *
81 Values::kDrivetrainEncoderRatio() *
82 control_loops::drivetrain::kWheelRadius;
83}
84
Alex Perryc4691f52020-02-17 19:20:01 -080085double turret_pot_translate(double voltage) {
86 return voltage * Values::kTurretPotRatio() *
87 (10.0 /*turns*/ / 5.0 /*volts*/) * (2 * M_PI /*radians*/);
88}
89
Stephan Massaltd021f972020-01-05 20:41:23 -080090constexpr double kMaxFastEncoderPulsesPerSecond =
Austin Schuh9dcd5202020-02-20 20:06:04 -080091 std::max({Values::kMaxControlPanelEncoderPulsesPerSecond(),
92 Values::kMaxFinisherEncoderPulsesPerSecond(),
93 Values::kMaxAcceleratorEncoderPulsesPerSecond()});
94static_assert(kMaxFastEncoderPulsesPerSecond <= 1000000.0,
Stephan Massaltd021f972020-01-05 20:41:23 -080095 "fast encoders are too fast");
Alex Perryc4691f52020-02-17 19:20:01 -080096constexpr double kMaxMediumEncoderPulsesPerSecond =
Austin Schuh9dcd5202020-02-20 20:06:04 -080097 std::max({Values::kMaxDrivetrainEncoderPulsesPerSecond(),
98 Values::kMaxHoodEncoderPulsesPerSecond(),
99 Values::kMaxIntakeEncoderPulsesPerSecond(),
100 Values::kMaxTurretEncoderPulsesPerSecond()});
Stephan Massaltd021f972020-01-05 20:41:23 -0800101
Austin Schuh9dcd5202020-02-20 20:06:04 -0800102static_assert(kMaxMediumEncoderPulsesPerSecond <= 400000.0,
Stephan Massaltd021f972020-01-05 20:41:23 -0800103 "medium encoders are too fast");
104
105} // namespace
106
107// Class to send position messages with sensor readings to our loops.
108class SensorReader : public ::frc971::wpilib::SensorReader {
109 public:
110 SensorReader(::aos::ShmEventLoop *event_loop)
111 : ::frc971::wpilib::SensorReader(event_loop),
112 auto_mode_sender_(
113 event_loop->MakeSender<::frc971::autonomous::AutonomousMode>(
114 "/autonomous")),
115 superstructure_position_sender_(
116 event_loop->MakeSender<superstructure::Position>(
117 "/superstructure")),
118 drivetrain_position_sender_(
119 event_loop
120 ->MakeSender<::frc971::control_loops::drivetrain::Position>(
121 "/drivetrain")) {
122 // Set to filter out anything shorter than 1/4 of the minimum pulse width
123 // we should ever see.
124 UpdateFastEncoderFilterHz(kMaxFastEncoderPulsesPerSecond);
125 UpdateMediumEncoderFilterHz(kMaxMediumEncoderPulsesPerSecond);
126 }
127
Alex Perryc4691f52020-02-17 19:20:01 -0800128 // Hood
129
130 void set_hood_encoder(::std::unique_ptr<frc::Encoder> encoder) {
131 medium_encoder_filter_.Add(encoder.get());
132 hood_encoder_.set_encoder(::std::move(encoder));
133 }
134
135 void set_hood_absolute_pwm(
136 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
137 hood_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
138 }
139
140 // Intake
141
142 void set_intake_encoder(::std::unique_ptr<frc::Encoder> encoder) {
143 medium_encoder_filter_.Add(encoder.get());
144 intake_joint_encoder_.set_encoder(::std::move(encoder));
145 }
146
147 void set_intake_absolute_pwm(
148 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
149 intake_joint_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
150 }
151
152 // Turret
153
154 void set_turret_encoder(::std::unique_ptr<frc::Encoder> encoder) {
155 medium_encoder_filter_.Add(encoder.get());
156 turret_encoder_.set_encoder(::std::move(encoder));
157 }
158
159 void set_turret_absolute_pwm(
160 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
161 turret_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
162 }
163
164 void set_turret_potentiometer(
165 ::std::unique_ptr<frc::AnalogInput> potentiometer) {
166 turret_encoder_.set_potentiometer(::std::move(potentiometer));
167 }
168
169 // Shooter
170
171 void set_flywheel_encoder(::std::unique_ptr<frc::Encoder> encoder) {
172 fast_encoder_filter_.Add(encoder.get());
173 flywheel_encoder_ = ::std::move(encoder);
174 }
175
176 void set_left_kicker_encoder(::std::unique_ptr<frc::Encoder> encoder) {
177 fast_encoder_filter_.Add(encoder.get());
178 left_kicker_encoder_ = ::std::move(encoder);
179 }
180
181 void set_right_kicker_encoder(::std::unique_ptr<frc::Encoder> encoder) {
182 fast_encoder_filter_.Add(encoder.get());
183 right_kicker_encoder_ = ::std::move(encoder);
184 }
185
186 // Control Panel
187
188 void set_control_panel_encoder(::std::unique_ptr<frc::Encoder> encoder) {
Austin Schuh9dcd5202020-02-20 20:06:04 -0800189 fast_encoder_filter_.Add(encoder.get());
Alex Perryc4691f52020-02-17 19:20:01 -0800190 control_panel_encoder_ = ::std::move(encoder);
191 }
192
Stephan Massaltd021f972020-01-05 20:41:23 -0800193 // Auto mode switches.
194 void set_autonomous_mode(int i, ::std::unique_ptr<frc::DigitalInput> sensor) {
Austin Schuh9dcd5202020-02-20 20:06:04 -0800195 medium_encoder_filter_.Add(sensor.get());
Stephan Massaltd021f972020-01-05 20:41:23 -0800196 autonomous_modes_.at(i) = ::std::move(sensor);
197 }
198
James Kuszmaula244a912020-01-18 13:50:50 -0800199 void set_imu(frc971::wpilib::ADIS16470 *imu) { imu_ = imu; }
200
Stephan Massaltd021f972020-01-05 20:41:23 -0800201 void RunIteration() override {
James Kuszmaula244a912020-01-18 13:50:50 -0800202 CHECK_NOTNULL(imu_)->DoReads();
203
Stephan Massaltd021f972020-01-05 20:41:23 -0800204 {
205 auto builder = drivetrain_position_sender_.MakeBuilder();
206 frc971::control_loops::drivetrain::Position::Builder drivetrain_builder =
207 builder.MakeBuilder<frc971::control_loops::drivetrain::Position>();
208 drivetrain_builder.add_left_encoder(
209 drivetrain_translate(drivetrain_left_encoder_->GetRaw()));
210 drivetrain_builder.add_left_speed(
211 drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod()));
212
213 drivetrain_builder.add_right_encoder(
214 -drivetrain_translate(drivetrain_right_encoder_->GetRaw()));
215 drivetrain_builder.add_right_speed(-drivetrain_velocity_translate(
216 drivetrain_right_encoder_->GetPeriod()));
217
218 builder.Send(drivetrain_builder.Finish());
219 }
Alex Perryc4691f52020-02-17 19:20:01 -0800220 const auto values = constants::GetValues();
Stephan Massaltd021f972020-01-05 20:41:23 -0800221
222 {
223 auto builder = superstructure_position_sender_.MakeBuilder();
224 superstructure::Position::Builder position_builder =
225 builder.MakeBuilder<superstructure::Position>();
Alex Perryc4691f52020-02-17 19:20:01 -0800226 // TODO(alex): check new absolute encoder api.
227 // Hood
228 frc971::AbsolutePositionT hood;
229 CopyPosition(hood_encoder_, &hood,
230 Values::kHoodEncoderCountsPerRevolution(),
231 Values::kHoodEncoderRatio(), false);
232 flatbuffers::Offset<frc971::AbsolutePosition> hood_offset =
233 frc971::AbsolutePosition::Pack(*builder.fbb(), &hood);
234
235 // Intake
236 frc971::AbsolutePositionT intake_joint;
237 CopyPosition(intake_joint_encoder_, &intake_joint,
238 Values::kIntakeEncoderCountsPerRevolution(),
239 Values::kIntakeEncoderRatio(), false);
240 flatbuffers::Offset<frc971::AbsolutePosition> intake_joint_offset =
241 frc971::AbsolutePosition::Pack(*builder.fbb(), &intake_joint);
242
243 // Turret
244 frc971::PotAndAbsolutePositionT turret;
245 CopyPosition(turret_encoder_, &turret,
246 Values::kTurretEncoderCountsPerRevolution(),
247 Values::kTurretEncoderRatio(), turret_pot_translate, false,
248 values.turret.potentiometer_offset);
249 flatbuffers::Offset<frc971::PotAndAbsolutePosition> turret_offset =
250 frc971::PotAndAbsolutePosition::Pack(*builder.fbb(), &turret);
251
252 // Shooter
253 y2020::control_loops::superstructure::ShooterPositionT shooter;
254 shooter.theta_finisher =
255 encoder_translate(flywheel_encoder_->GetRaw(),
256 Values::kFinisherEncoderCountsPerRevolution(),
257 Values::kFinisherEncoderRatio());
258 // TODO; check sign
259 shooter.theta_accelerator_left =
260 encoder_translate(left_kicker_encoder_->GetRaw(),
261 Values::kAcceleratorEncoderCountsPerRevolution(),
262 Values::kAcceleratorEncoderRatio());
263 shooter.theta_accelerator_right =
264 encoder_translate(right_kicker_encoder_->GetRaw(),
265 Values::kAcceleratorEncoderCountsPerRevolution(),
266 Values::kAcceleratorEncoderRatio());
267 flatbuffers::Offset<y2020::control_loops::superstructure::ShooterPosition>
268 shooter_offset =
269 y2020::control_loops::superstructure::ShooterPosition::Pack(
270 *builder.fbb(), &shooter);
271
272 // Control Panel
273 frc971::RelativePositionT control_panel;
274 CopyPosition(*control_panel_encoder_, &control_panel,
275 Values::kControlPanelEncoderCountsPerRevolution(),
276 Values::kControlPanelEncoderRatio(), false);
277 flatbuffers::Offset<frc971::RelativePosition> control_panel_offset =
278 frc971::RelativePosition::Pack(*builder.fbb(), &control_panel);
279
280 position_builder.add_hood(hood_offset);
281 position_builder.add_intake_joint(intake_joint_offset);
282 position_builder.add_turret(turret_offset);
283 position_builder.add_shooter(shooter_offset);
284 position_builder.add_control_panel(control_panel_offset);
285
Stephan Massaltd021f972020-01-05 20:41:23 -0800286 builder.Send(position_builder.Finish());
287 }
288
289 {
290 auto builder = auto_mode_sender_.MakeBuilder();
291
292 uint32_t mode = 0;
293 for (size_t i = 0; i < autonomous_modes_.size(); ++i) {
294 if (autonomous_modes_[i] && autonomous_modes_[i]->Get()) {
295 mode |= 1 << i;
296 }
297 }
298
299 auto auto_mode_builder =
300 builder.MakeBuilder<frc971::autonomous::AutonomousMode>();
301
302 auto_mode_builder.add_mode(mode);
303
304 builder.Send(auto_mode_builder.Finish());
305 }
306 }
307
308 private:
309 ::aos::Sender<::frc971::autonomous::AutonomousMode> auto_mode_sender_;
310 ::aos::Sender<superstructure::Position> superstructure_position_sender_;
311 ::aos::Sender<::frc971::control_loops::drivetrain::Position>
312 drivetrain_position_sender_;
313
Alex Perryc4691f52020-02-17 19:20:01 -0800314 ::frc971::wpilib::AbsoluteEncoderAndPotentiometer turret_encoder_;
315
316 ::frc971::wpilib::AbsoluteEncoder hood_encoder_, intake_joint_encoder_;
317
318 ::std::unique_ptr<::frc::Encoder> flywheel_encoder_, left_kicker_encoder_,
319 right_kicker_encoder_, control_panel_encoder_;
320
Stephan Massaltd021f972020-01-05 20:41:23 -0800321 ::std::array<::std::unique_ptr<frc::DigitalInput>, 2> autonomous_modes_;
James Kuszmaula244a912020-01-18 13:50:50 -0800322
323 frc971::wpilib::ADIS16470 *imu_ = nullptr;
Stephan Massaltd021f972020-01-05 20:41:23 -0800324};
325
326class SuperstructureWriter
327 : public ::frc971::wpilib::LoopOutputHandler<superstructure::Output> {
328 public:
329 SuperstructureWriter(::aos::EventLoop *event_loop)
330 : ::frc971::wpilib::LoopOutputHandler<superstructure::Output>(
331 event_loop, "/superstructure") {}
332
Alex Perryc4691f52020-02-17 19:20:01 -0800333 void set_hood_victor(::std::unique_ptr<::frc::VictorSP> t) {
334 hood_victor_ = ::std::move(t);
335 }
Stephan Massaltd021f972020-01-05 20:41:23 -0800336
Alex Perryc4691f52020-02-17 19:20:01 -0800337 void set_intake_joint_victor(::std::unique_ptr<::frc::VictorSP> t) {
338 intake_joint_victor_ = ::std::move(t);
339 }
340
341 void set_intake_roller_falcon(
342 ::std::unique_ptr<::ctre::phoenix::motorcontrol::can::TalonFX> t) {
343 intake_roller_falcon_ = ::std::move(t);
344 intake_roller_falcon_->ConfigSupplyCurrentLimit(
345 {true, Values::kIntakeRollerSupplyCurrentLimit(),
346 Values::kIntakeRollerSupplyCurrentLimit(), 0});
347 intake_roller_falcon_->ConfigStatorCurrentLimit(
348 {true, Values::kIntakeRollerStatorCurrentLimit(),
349 Values::kIntakeRollerStatorCurrentLimit(), 0});
350 }
351
352 void set_turret_victor(::std::unique_ptr<::frc::VictorSP> t) {
353 turret_victor_ = ::std::move(t);
354 }
355
356 void set_feeder_falcon(::std::unique_ptr<::frc::TalonFX> t) {
357 feeder_falcon_ = ::std::move(t);
358 }
359
360 void set_washing_machine_control_panel_victor(
361 ::std::unique_ptr<::frc::VictorSP> t) {
362 washing_machine_control_panel_victor_ = ::std::move(t);
363 }
364
365 void set_kicker_left_falcon(::std::unique_ptr<::frc::TalonFX> t) {
366 kicker_left_falcon_ = ::std::move(t);
367 }
368
369 void set_kicker_right_falcon(::std::unique_ptr<::frc::TalonFX> t) {
370 kicker_right_falcon_ = ::std::move(t);
371 }
372
373 void set_flywheel_falcon(::std::unique_ptr<::frc::TalonFX> t) {
374 flywheel_falcon_ = ::std::move(t);
375 }
376
377 void set_climber_falcon(
378 ::std::unique_ptr<::ctre::phoenix::motorcontrol::can::TalonFX> t) {
379 climber_falcon_ = ::std::move(t);
380 climber_falcon_->ConfigSupplyCurrentLimit(
381 {true, Values::kClimberSupplyCurrentLimit(),
382 Values::kClimberSupplyCurrentLimit(), 0});
383 }
384
385 private:
386 void Write(const superstructure::Output &output) override {
387 hood_victor_->SetSpeed(std::clamp(output.hood_voltage(), -kMaxBringupPower,
388 kMaxBringupPower) /
389 12.0);
390
391 intake_joint_victor_->SetSpeed(std::clamp(output.intake_joint_voltage(),
392 -kMaxBringupPower,
393 kMaxBringupPower) /
394 12.0);
395
396 intake_roller_falcon_->Set(
397 ctre::phoenix::motorcontrol::ControlMode::PercentOutput,
398 std::clamp(output.intake_roller_voltage(), -kMaxBringupPower,
399 kMaxBringupPower) /
400 12.0);
401
402 turret_victor_->SetSpeed(std::clamp(output.turret_voltage(),
403 -kMaxBringupPower, kMaxBringupPower) /
404 12.0);
405
406 feeder_falcon_->SetSpeed(std::clamp(output.feeder_voltage(),
407 -kMaxBringupPower, kMaxBringupPower) /
408 12.0);
409
410 washing_machine_control_panel_victor_->SetSpeed(
411 std::clamp(output.washing_machine_spinner_voltage(), -kMaxBringupPower,
412 kMaxBringupPower) /
413 12.0);
414
415 kicker_left_falcon_->SetSpeed(std::clamp(output.accelerator_left_voltage(),
416 -kMaxBringupPower,
417 kMaxBringupPower) /
418 12.0);
419
420 kicker_right_falcon_->SetSpeed(
421 std::clamp(output.accelerator_right_voltage(), -kMaxBringupPower,
422 kMaxBringupPower) /
423 12.0);
424
425 flywheel_falcon_->SetSpeed(std::clamp(output.finisher_voltage(),
426 -kMaxBringupPower,
427 kMaxBringupPower) /
428 12.0);
429
430 climber_falcon_->Set(
431 ctre::phoenix::motorcontrol::ControlMode::PercentOutput,
432 std::clamp(output.climber_voltage(), -kMaxBringupPower,
433 kMaxBringupPower) /
434 12.0);
435 }
436
437 void Stop() override {
438 AOS_LOG(WARNING, "Superstructure output too old.\n");
439 hood_victor_->SetDisabled();
440 intake_joint_victor_->SetDisabled();
441 turret_victor_->SetDisabled();
442 feeder_falcon_->SetDisabled();
443 washing_machine_control_panel_victor_->SetDisabled();
444 kicker_left_falcon_->SetDisabled();
445 kicker_right_falcon_->SetDisabled();
446 flywheel_falcon_->SetDisabled();
447 }
448
449 ::std::unique_ptr<::frc::VictorSP> hood_victor_, intake_joint_victor_,
450 turret_victor_, washing_machine_control_panel_victor_;
451
452 ::std::unique_ptr<::frc::TalonFX> feeder_falcon_, kicker_left_falcon_,
453 kicker_right_falcon_, flywheel_falcon_;
454
455 ::std::unique_ptr<::ctre::phoenix::motorcontrol::can::TalonFX>
456 intake_roller_falcon_, climber_falcon_;
Stephan Massaltd021f972020-01-05 20:41:23 -0800457};
458
459class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
460 public:
Alex Perryc4691f52020-02-17 19:20:01 -0800461 ::std::unique_ptr<frc::Encoder> make_encoder(
462 int index, frc::Encoder::EncodingType encodingType = frc::Encoder::k4X) {
Stephan Massaltd021f972020-01-05 20:41:23 -0800463 return make_unique<frc::Encoder>(10 + index * 2, 11 + index * 2, false,
Alex Perryc4691f52020-02-17 19:20:01 -0800464 encodingType);
Stephan Massaltd021f972020-01-05 20:41:23 -0800465 }
466
467 void Run() override {
468 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
469 aos::configuration::ReadConfig("config.json");
470
471 // Thread 1.
472 ::aos::ShmEventLoop joystick_sender_event_loop(&config.message());
473 ::frc971::wpilib::JoystickSender joystick_sender(
474 &joystick_sender_event_loop);
475 AddLoop(&joystick_sender_event_loop);
476
477 // Thread 2.
478 ::aos::ShmEventLoop pdp_fetcher_event_loop(&config.message());
479 ::frc971::wpilib::PDPFetcher pdp_fetcher(&pdp_fetcher_event_loop);
480 AddLoop(&pdp_fetcher_event_loop);
481
482 // Thread 3.
483 ::aos::ShmEventLoop sensor_reader_event_loop(&config.message());
484 SensorReader sensor_reader(&sensor_reader_event_loop);
485 sensor_reader.set_drivetrain_left_encoder(make_encoder(0));
486 sensor_reader.set_drivetrain_right_encoder(make_encoder(1));
487
Alex Perryc4691f52020-02-17 19:20:01 -0800488 // TODO: pin numbers
489 sensor_reader.set_hood_encoder(make_encoder(2));
490 sensor_reader.set_hood_absolute_pwm(make_unique<frc::DigitalInput>(2));
491
492 sensor_reader.set_intake_encoder(make_encoder(3));
493 sensor_reader.set_intake_absolute_pwm(make_unique<frc::DigitalInput>(3));
494
495 sensor_reader.set_turret_encoder(make_encoder(4));
496 sensor_reader.set_turret_absolute_pwm(make_unique<frc::DigitalInput>(4));
497 sensor_reader.set_turret_potentiometer(make_unique<frc::AnalogInput>(4));
498
499 sensor_reader.set_flywheel_encoder(make_encoder(5));
500 sensor_reader.set_left_kicker_encoder(make_encoder(6));
501 sensor_reader.set_right_kicker_encoder(make_encoder(7));
502
503 sensor_reader.set_control_panel_encoder(make_encoder(8, frc::Encoder::k2X));
504
James Kuszmaul022d40e2020-02-11 17:06:18 -0800505 // Note: If ADIS16470 is plugged in directly to the roboRIO SPI port without
506 // the Spartan Board, then trigger is on 26, reset 27, and chip select is
507 // CS0.
Austin Schuh83873c32020-02-22 14:58:39 -0800508 frc::SPI::Port spi_port = frc::SPI::Port::kOnboardCS2;
509 std::unique_ptr<frc::DigitalInput> imu_trigger;
510 std::unique_ptr<frc::DigitalOutput> imu_reset;
511 if (::aos::network::GetTeamNumber() ==
512 constants::Values::kCodingRobotTeamNumber) {
513 imu_trigger = make_unique<frc::DigitalInput>(26);
514 imu_reset = make_unique<frc::DigitalOutput>(27);
515 spi_port = frc::SPI::Port::kOnboardCS0;
516 } else {
517 imu_trigger = make_unique<frc::DigitalInput>(0);
518 imu_reset = make_unique<frc::DigitalOutput>(1);
519 }
520 auto spi = make_unique<frc::SPI>(spi_port);
James Kuszmaula244a912020-01-18 13:50:50 -0800521 frc971::wpilib::ADIS16470 imu(&sensor_reader_event_loop, spi.get(),
522 imu_trigger.get(), imu_reset.get());
523 sensor_reader.set_imu(&imu);
524
Stephan Massaltd021f972020-01-05 20:41:23 -0800525 AddLoop(&sensor_reader_event_loop);
526
527 // Thread 4.
528 ::aos::ShmEventLoop output_event_loop(&config.message());
James Kuszmaul57c2baa2020-01-19 14:52:52 -0800529 output_event_loop.set_name("output_writer");
Stephan Massaltd021f972020-01-05 20:41:23 -0800530 ::frc971::wpilib::DrivetrainWriter drivetrain_writer(&output_event_loop);
531 drivetrain_writer.set_left_controller0(
532 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(0)), true);
533 drivetrain_writer.set_right_controller0(
534 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(1)), false);
535
536 SuperstructureWriter superstructure_writer(&output_event_loop);
Alex Perryc4691f52020-02-17 19:20:01 -0800537 // TODO: check ports
538 superstructure_writer.set_hood_victor(make_unique<frc::VictorSP>(2));
539 superstructure_writer.set_intake_joint_victor(
540 make_unique<frc::VictorSP>(3));
541 superstructure_writer.set_intake_roller_falcon(
542 make_unique<::ctre::phoenix::motorcontrol::can::TalonFX>(4));
543 superstructure_writer.set_turret_victor(make_unique<frc::VictorSP>(5));
544 superstructure_writer.set_feeder_falcon(make_unique<frc::TalonFX>(6));
545 superstructure_writer.set_washing_machine_control_panel_victor(
546 make_unique<frc::VictorSP>(7));
547 superstructure_writer.set_kicker_left_falcon(
548 make_unique<::frc::TalonFX>(8));
549 superstructure_writer.set_kicker_right_falcon(
550 make_unique<::frc::TalonFX>(9));
551 superstructure_writer.set_flywheel_falcon(make_unique<::frc::TalonFX>(10));
552 superstructure_writer.set_climber_falcon(
553 make_unique<::ctre::phoenix::motorcontrol::can::TalonFX>(11));
Stephan Massaltd021f972020-01-05 20:41:23 -0800554
555 AddLoop(&output_event_loop);
556
557 RunLoops();
558 }
559};
560
561} // namespace wpilib
562} // namespace y2020
563
564AOS_ROBOT_CLASS(::y2020::wpilib::WPILibRobot);