blob: 8bcb9b575a71fd6bdfd3cf3a256aa35566b6cd19 [file] [log] [blame]
Austin Schuh8347cb62017-04-08 14:37:34 -07001#include <inttypes.h>
Campbell Crowleyae6e8422017-02-05 12:38:50 -08002#include <stdio.h>
3#include <string.h>
4#include <unistd.h>
Campbell Crowleyae6e8422017-02-05 12:38:50 -08005
Campbell Crowleyae6e8422017-02-05 12:38:50 -08006#include <array>
Austin Schuh8347cb62017-04-08 14:37:34 -07007#include <chrono>
Brian Silverman50826c02017-02-18 14:40:25 -08008#include <cmath>
Austin Schuh8347cb62017-04-08 14:37:34 -07009#include <functional>
10#include <mutex>
11#include <thread>
Campbell Crowleyae6e8422017-02-05 12:38:50 -080012
Parker Schuhd3b7a8872018-02-19 16:42:27 -080013#include "frc971/wpilib/ahal/AnalogInput.h"
14#include "frc971/wpilib/ahal/Compressor.h"
15#include "frc971/wpilib/ahal/Counter.h"
16#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
17#include "frc971/wpilib/ahal/DriverStation.h"
18#include "frc971/wpilib/ahal/Encoder.h"
19#include "frc971/wpilib/ahal/Relay.h"
20#include "frc971/wpilib/ahal/Servo.h"
21#include "frc971/wpilib/ahal/VictorSP.h"
Campbell Crowleyae6e8422017-02-05 12:38:50 -080022#undef ERROR
23
John Park33858a32018-09-28 23:05:48 -070024#include "aos/commonmath.h"
Brian Silvermanf819b442019-01-20 16:51:04 -080025#include "aos/init.h"
John Park33858a32018-09-28 23:05:48 -070026#include "aos/logging/logging.h"
27#include "aos/logging/queue_logging.h"
Brian Silvermanf819b442019-01-20 16:51:04 -080028#include "aos/make_unique.h"
John Park33858a32018-09-28 23:05:48 -070029#include "aos/robot_state/robot_state.q.h"
30#include "aos/stl_mutex/stl_mutex.h"
31#include "aos/time/time.h"
32#include "aos/util/compiler_memory_barrier.h"
33#include "aos/util/log_interval.h"
34#include "aos/util/phased_loop.h"
35#include "aos/util/wrapping_counter.h"
Philipp Schrader996a2a22017-02-22 05:02:48 +000036#include "frc971/autonomous/auto.q.h"
Campbell Crowleyae6e8422017-02-05 12:38:50 -080037#include "frc971/control_loops/control_loops.q.h"
38#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuh8347cb62017-04-08 14:37:34 -070039#include "frc971/wpilib/ADIS16448.h"
40#include "frc971/wpilib/buffered_pcm.h"
41#include "frc971/wpilib/buffered_solenoid.h"
42#include "frc971/wpilib/dma.h"
43#include "frc971/wpilib/dma_edge_counting.h"
44#include "frc971/wpilib/encoder_and_potentiometer.h"
45#include "frc971/wpilib/interrupt_edge_counting.h"
46#include "frc971/wpilib/joystick_sender.h"
47#include "frc971/wpilib/logging.q.h"
48#include "frc971/wpilib/loop_output_handler.h"
49#include "frc971/wpilib/pdp_fetcher.h"
Austin Schuhbf29b6f2019-02-02 21:45:27 -080050#include "frc971/wpilib/sensor_reader.h"
Austin Schuh8347cb62017-04-08 14:37:34 -070051#include "frc971/wpilib/wpilib_robot_base.h"
Campbell Crowleyae6e8422017-02-05 12:38:50 -080052#include "y2017/constants.h"
Campbell Crowleyae6e8422017-02-05 12:38:50 -080053#include "y2017/control_loops/superstructure/superstructure.q.h"
Campbell Crowleyae6e8422017-02-05 12:38:50 -080054
Campbell Crowleyae6e8422017-02-05 12:38:50 -080055#ifndef M_PI
56#define M_PI 3.14159265358979323846
57#endif
58
59using ::frc971::control_loops::drivetrain_queue;
60using ::y2017::control_loops::superstructure_queue;
Brian Silverman052e69d2017-02-12 16:19:55 -080061using ::y2017::constants::Values;
Austin Schuh8347cb62017-04-08 14:37:34 -070062using ::aos::monotonic_clock;
63namespace chrono = ::std::chrono;
Parker Schuhd3b7a8872018-02-19 16:42:27 -080064using namespace frc;
Brian Silvermanf819b442019-01-20 16:51:04 -080065using aos::make_unique;
Campbell Crowleyae6e8422017-02-05 12:38:50 -080066
67namespace y2017 {
68namespace wpilib {
69namespace {
Brian Silverman052e69d2017-02-12 16:19:55 -080070
Campbell Crowleyae6e8422017-02-05 12:38:50 -080071constexpr double kMaxBringupPower = 12.0;
Campbell Crowleyae6e8422017-02-05 12:38:50 -080072
73// TODO(Brian): Fix the interpretation of the result of GetRaw here and in the
74// DMA stuff and then removing the * 2.0 in *_translate.
75// The low bit is direction.
76
Brian Silverman052e69d2017-02-12 16:19:55 -080077// TODO(brian): Use ::std::max instead once we have C++14 so that can be
78// constexpr.
79template <typename T>
80constexpr T max(T a, T b) {
81 return (a > b) ? a : b;
82}
83template <typename T, typename... Rest>
84constexpr T max(T a, T b, T c, Rest... rest) {
85 return max(max(a, b), c, rest...);
86}
Campbell Crowleyae6e8422017-02-05 12:38:50 -080087
Campbell Crowleyae6e8422017-02-05 12:38:50 -080088double drivetrain_translate(int32_t in) {
Brian Silverman052e69d2017-02-12 16:19:55 -080089 return static_cast<double>(in) /
90 Values::kDrivetrainEncoderCountsPerRevolution *
91 Values::kDrivetrainEncoderRatio * 2.0 * M_PI;
Campbell Crowleyae6e8422017-02-05 12:38:50 -080092}
93
94double drivetrain_velocity_translate(double in) {
Brian Silverman052e69d2017-02-12 16:19:55 -080095 return (1.0 / in) / Values::kDrivetrainCyclesPerRevolution *
96 Values::kDrivetrainEncoderRatio * 2.0 * M_PI;
Campbell Crowleyae6e8422017-02-05 12:38:50 -080097}
98
Brian Silverman50826c02017-02-18 14:40:25 -080099// TODO(Travis): Make sure the number of turns is right.
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800100double intake_pot_translate(double voltage) {
Brian Silverman50826c02017-02-18 14:40:25 -0800101 return voltage * Values::kIntakePotRatio * (3.0 /*turns*/ / 5.0 /*volts*/) *
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800102 (2 * M_PI /*radians*/);
103}
104
Brian Silverman052e69d2017-02-12 16:19:55 -0800105constexpr double kMaxFastEncoderPulsesPerSecond =
106 max(Values::kMaxDrivetrainEncoderPulsesPerSecond,
107 Values::kMaxShooterEncoderPulsesPerSecond);
108static_assert(kMaxFastEncoderPulsesPerSecond <= 1300000,
109 "fast encoders are too fast");
110constexpr double kMaxMediumEncoderPulsesPerSecond =
111 max(Values::kMaxIntakeEncoderPulsesPerSecond,
112 Values::kMaxTurretEncoderPulsesPerSecond,
113 Values::kMaxIndexerEncoderPulsesPerSecond);
114static_assert(kMaxMediumEncoderPulsesPerSecond <= 400000,
115 "medium encoders are too fast");
116constexpr double kMaxSlowEncoderPulsesPerSecond =
117 Values::kMaxHoodEncoderPulsesPerSecond;
118static_assert(kMaxSlowEncoderPulsesPerSecond <= 100000,
119 "slow encoders are too fast");
Brianef030df2017-03-05 15:06:04 -0800120static_assert(kMaxSlowEncoderPulsesPerSecond < kMaxMediumEncoderPulsesPerSecond,
121 "slow encoders are faster than medium?");
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800122
123// Class to send position messages with sensor readings to our loops.
Austin Schuhbf29b6f2019-02-02 21:45:27 -0800124class SensorReader : public ::frc971::wpilib::SensorReader {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800125 public:
126 SensorReader() {
Brian Silverman052e69d2017-02-12 16:19:55 -0800127 // Set to filter out anything shorter than 1/4 of the minimum pulse width
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800128 // we should ever see.
Austin Schuhbf29b6f2019-02-02 21:45:27 -0800129 UpdateFastEncoderFilterHz(kMaxFastEncoderPulsesPerSecond);
130 UpdateMediumEncoderFilterHz(kMaxMediumEncoderPulsesPerSecond);
Brianef030df2017-03-05 15:06:04 -0800131 hall_filter_.SetPeriodNanoSeconds(100000);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800132 }
133
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800134 void set_shooter_encoder(::std::unique_ptr<Encoder> encoder) {
Brian Silverman052e69d2017-02-12 16:19:55 -0800135 fast_encoder_filter_.Add(encoder.get());
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800136 shooter_encoder_ = ::std::move(encoder);
137 }
138
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800139 void set_intake_encoder(::std::unique_ptr<Encoder> encoder) {
Brian Silverman052e69d2017-02-12 16:19:55 -0800140 medium_encoder_filter_.Add(encoder.get());
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800141 intake_encoder_.set_encoder(::std::move(encoder));
142 }
143
144 void set_intake_potentiometer(::std::unique_ptr<AnalogInput> potentiometer) {
145 intake_encoder_.set_potentiometer(::std::move(potentiometer));
146 }
147
Brian Silverman50826c02017-02-18 14:40:25 -0800148 void set_intake_absolute(::std::unique_ptr<DigitalInput> input) {
149 intake_encoder_.set_absolute_pwm(::std::move(input));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800150 }
151
Brian Silverman052e69d2017-02-12 16:19:55 -0800152 void set_indexer_encoder(::std::unique_ptr<Encoder> encoder) {
153 medium_encoder_filter_.Add(encoder.get());
Brianef030df2017-03-05 15:06:04 -0800154 indexer_counter_.set_encoder(encoder.get());
Brian Silverman052e69d2017-02-12 16:19:55 -0800155 indexer_encoder_ = ::std::move(encoder);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800156 }
157
Brianef030df2017-03-05 15:06:04 -0800158 void set_indexer_hall(::std::unique_ptr<DigitalInput> input) {
159 hall_filter_.Add(input.get());
160 indexer_counter_.set_input(input.get());
161 indexer_hall_ = ::std::move(input);
162 }
163
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800164 void set_turret_encoder(::std::unique_ptr<Encoder> encoder) {
Brian Silverman052e69d2017-02-12 16:19:55 -0800165 medium_encoder_filter_.Add(encoder.get());
Brianef030df2017-03-05 15:06:04 -0800166 turret_counter_.set_encoder(encoder.get());
167 turret_encoder_ = ::std::move(encoder);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800168 }
169
Brianef030df2017-03-05 15:06:04 -0800170 void set_turret_hall(::std::unique_ptr<DigitalInput> input) {
171 hall_filter_.Add(input.get());
172 turret_counter_.set_input(input.get());
173 turret_hall_ = ::std::move(input);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800174 }
175
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800176 void set_hood_encoder(::std::unique_ptr<Encoder> encoder) {
Brianef030df2017-03-05 15:06:04 -0800177 medium_encoder_filter_.Add(encoder.get());
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800178 hood_encoder_.set_encoder(::std::move(encoder));
179 }
180
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800181 void set_hood_index(::std::unique_ptr<DigitalInput> index) {
Brianef030df2017-03-05 15:06:04 -0800182 medium_encoder_filter_.Add(index.get());
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800183 hood_encoder_.set_index(::std::move(index));
184 }
185
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800186 void set_autonomous_mode(int i, ::std::unique_ptr<DigitalInput> sensor) {
187 autonomous_modes_.at(i) = ::std::move(sensor);
188 }
189
Austin Schuhbf29b6f2019-02-02 21:45:27 -0800190 void Start() {
191 AddToDMA(&indexer_counter_);
192 AddToDMA(&hood_encoder_);
193 AddToDMA(&turret_counter_);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800194 }
195
196 void RunIteration() {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800197 {
198 auto drivetrain_message = drivetrain_queue.position.MakeMessage();
199 drivetrain_message->right_encoder =
200 drivetrain_translate(drivetrain_right_encoder_->GetRaw());
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800201 drivetrain_message->right_speed =
202 drivetrain_velocity_translate(drivetrain_right_encoder_->GetPeriod());
203
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800204 drivetrain_message->left_encoder =
205 -drivetrain_translate(drivetrain_left_encoder_->GetRaw());
206 drivetrain_message->left_speed =
207 drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod());
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800208
209 drivetrain_message.Send();
210 }
Austin Schuhbf29b6f2019-02-02 21:45:27 -0800211 }
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800212
Austin Schuhbf29b6f2019-02-02 21:45:27 -0800213 void RunDMAIteration() {
214 const auto values = constants::GetValues();
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800215
216 {
217 auto superstructure_message = superstructure_queue.position.MakeMessage();
Brian Silverman052e69d2017-02-12 16:19:55 -0800218 CopyPosition(intake_encoder_, &superstructure_message->intake,
Brian Silverman50826c02017-02-18 14:40:25 -0800219 Values::kIntakeEncoderCountsPerRevolution,
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800220 Values::kIntakeEncoderRatio, intake_pot_translate, true,
Brian Silverman052e69d2017-02-12 16:19:55 -0800221 values.intake.pot_offset);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800222
Brianef030df2017-03-05 15:06:04 -0800223 CopyPosition(indexer_counter_, &superstructure_message->column.indexer,
224 Values::kIndexerEncoderCountsPerRevolution,
Austin Schuh546a0382017-04-16 19:10:18 -0700225 Values::kIndexerEncoderRatio, true);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800226
Brian Silverman50826c02017-02-18 14:40:25 -0800227 superstructure_message->theta_shooter =
228 encoder_translate(shooter_encoder_->GetRaw(),
229 Values::kShooterEncoderCountsPerRevolution,
230 Values::kShooterEncoderRatio);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800231
Brian Silverman50826c02017-02-18 14:40:25 -0800232 CopyPosition(hood_encoder_, &superstructure_message->hood,
233 Values::kHoodEncoderCountsPerRevolution,
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800234 Values::kHoodEncoderRatio, true);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800235
Brianef030df2017-03-05 15:06:04 -0800236 CopyPosition(turret_counter_, &superstructure_message->column.turret,
Brian Silverman50826c02017-02-18 14:40:25 -0800237 Values::kTurretEncoderCountsPerRevolution,
Austin Schuhd5ccb862017-03-11 22:06:36 -0800238 Values::kTurretEncoderRatio, false);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800239
240 superstructure_message.Send();
241 }
242
243 {
Philipp Schrader996a2a22017-02-22 05:02:48 +0000244 auto auto_mode_message = ::frc971::autonomous::auto_mode.MakeMessage();
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800245 auto_mode_message->mode = 0;
246 for (size_t i = 0; i < autonomous_modes_.size(); ++i) {
Austin Schuh8347cb62017-04-08 14:37:34 -0700247 if (autonomous_modes_[i] && autonomous_modes_[i]->Get()) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800248 auto_mode_message->mode |= 1 << i;
249 }
250 }
251 LOG_STRUCT(DEBUG, "auto mode", *auto_mode_message);
252 auto_mode_message.Send();
253 }
254 }
255
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800256 private:
Austin Schuhbf29b6f2019-02-02 21:45:27 -0800257 DigitalGlitchFilter hall_filter_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800258
Austin Schuh2a3e0632018-02-19 16:24:49 -0800259 ::frc971::wpilib::AbsoluteEncoderAndPotentiometer intake_encoder_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800260
Brian Silverman052e69d2017-02-12 16:19:55 -0800261 ::std::unique_ptr<Encoder> indexer_encoder_;
Brianef030df2017-03-05 15:06:04 -0800262 ::std::unique_ptr<DigitalInput> indexer_hall_;
263 ::frc971::wpilib::DMAEdgeCounter indexer_counter_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800264
Brianef030df2017-03-05 15:06:04 -0800265 ::std::unique_ptr<Encoder> turret_encoder_;
266 ::std::unique_ptr<DigitalInput> turret_hall_;
267 ::frc971::wpilib::DMAEdgeCounter turret_counter_;
268
Brian Silverman7cce2d32017-02-19 21:48:48 -0800269 ::frc971::wpilib::DMAEncoder hood_encoder_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800270 ::std::unique_ptr<Encoder> shooter_encoder_;
271
272 ::std::array<::std::unique_ptr<DigitalInput>, 4> autonomous_modes_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800273};
274
Adam Snaidere0554ef2017-03-11 23:02:45 -0800275class SolenoidWriter {
276 public:
277 SolenoidWriter()
278 : superstructure_(".y2017.control_loops.superstructure_queue.output") {}
279
280 ::frc971::wpilib::BufferedPcm *pcm() { return &pcm_; }
281
Austin Schuh8347cb62017-04-08 14:37:34 -0700282 void set_lights(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
Adam Snaidere0554ef2017-03-11 23:02:45 -0800283 lights_ = ::std::move(s);
284 }
285
Austin Schuh8347cb62017-04-08 14:37:34 -0700286 void set_rgb_light(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
Austin Schuhc587c882017-03-29 21:33:10 -0700287 rgb_lights_ = ::std::move(s);
288 }
289
Adam Snaidere0554ef2017-03-11 23:02:45 -0800290 void operator()() {
291 ::aos::SetCurrentThreadName("Solenoids");
292 ::aos::SetCurrentThreadRealtimePriority(27);
293
294 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(20),
295 ::std::chrono::milliseconds(1));
296
297 while (run_) {
298 {
299 const int iterations = phased_loop.SleepUntilNext();
300 if (iterations != 1) {
301 LOG(DEBUG, "Solenoids skipped %d iterations\n", iterations - 1);
302 }
303 }
304
305 {
306 superstructure_.FetchLatest();
307 if (superstructure_.get()) {
308 LOG_STRUCT(DEBUG, "solenoids", *superstructure_);
309 lights_->Set(superstructure_->lights_on);
Austin Schuhc587c882017-03-29 21:33:10 -0700310 rgb_lights_->Set(superstructure_->red_light_on |
311 superstructure_->green_light_on |
312 superstructure_->blue_light_on);
Adam Snaidere0554ef2017-03-11 23:02:45 -0800313 }
314 }
315
316 pcm_.Flush();
317 }
318 }
319
320 void Quit() { run_ = false; }
321
322 private:
323 ::frc971::wpilib::BufferedPcm pcm_;
324
Austin Schuhc587c882017-03-29 21:33:10 -0700325 ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> lights_, rgb_lights_;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800326
Austin Schuh8347cb62017-04-08 14:37:34 -0700327 ::aos::Queue<::y2017::control_loops::SuperstructureQueue::Output>
Adam Snaidere0554ef2017-03-11 23:02:45 -0800328 superstructure_;
329
330 ::std::atomic<bool> run_{true};
331};
332
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800333class DrivetrainWriter : public ::frc971::wpilib::LoopOutputHandler {
334 public:
Austin Schuh8347cb62017-04-08 14:37:34 -0700335 void set_drivetrain_left_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800336 drivetrain_left_victor_ = ::std::move(t);
337 }
338
Austin Schuh8347cb62017-04-08 14:37:34 -0700339 void set_drivetrain_right_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800340 drivetrain_right_victor_ = ::std::move(t);
341 }
342
343 private:
344 virtual void Read() override {
345 ::frc971::control_loops::drivetrain_queue.output.FetchAnother();
346 }
347
348 virtual void Write() override {
349 auto &queue = ::frc971::control_loops::drivetrain_queue.output;
350 LOG_STRUCT(DEBUG, "will output", *queue);
Austin Schuh410e3812017-02-21 16:44:03 -0800351 drivetrain_left_victor_->SetSpeed(-queue->left_voltage / 12.0);
352 drivetrain_right_victor_->SetSpeed(queue->right_voltage / 12.0);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800353 }
354
355 virtual void Stop() override {
356 LOG(WARNING, "drivetrain output too old\n");
357 drivetrain_left_victor_->SetDisabled();
358 drivetrain_right_victor_->SetDisabled();
359 }
360
Austin Schuh8347cb62017-04-08 14:37:34 -0700361 ::std::unique_ptr<::frc::VictorSP> drivetrain_left_victor_,
362 drivetrain_right_victor_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800363};
364
365class SuperstructureWriter : public ::frc971::wpilib::LoopOutputHandler {
366 public:
Austin Schuh8347cb62017-04-08 14:37:34 -0700367 void set_intake_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800368 intake_victor_ = ::std::move(t);
369 }
Austin Schuh8347cb62017-04-08 14:37:34 -0700370 void set_intake_rollers_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800371 intake_rollers_victor_ = ::std::move(t);
372 }
373
Austin Schuh8347cb62017-04-08 14:37:34 -0700374 void set_indexer_victor(::std::unique_ptr<::frc::VictorSP> t) {
Brian Silverman052e69d2017-02-12 16:19:55 -0800375 indexer_victor_ = ::std::move(t);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800376 }
Austin Schuh8347cb62017-04-08 14:37:34 -0700377 void set_indexer_roller_victor(::std::unique_ptr<::frc::VictorSP> t) {
Brian Silverman052e69d2017-02-12 16:19:55 -0800378 indexer_roller_victor_ = ::std::move(t);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800379 }
380
Austin Schuh6a8131b2017-04-08 15:39:22 -0700381 void set_gear_servo(::std::unique_ptr<::frc::Servo> t) {
382 gear_servo_ = ::std::move(t);
383 }
Austin Schuh8347cb62017-04-08 14:37:34 -0700384 void set_shooter_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800385 shooter_victor_ = ::std::move(t);
386 }
Austin Schuh8347cb62017-04-08 14:37:34 -0700387 void set_turret_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800388 turret_victor_ = ::std::move(t);
389 }
Austin Schuh8347cb62017-04-08 14:37:34 -0700390 void set_hood_victor(::std::unique_ptr<::frc::VictorSP> t) {
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800391 hood_victor_ = ::std::move(t);
392 }
393
Austin Schuhc587c882017-03-29 21:33:10 -0700394 void set_red_light(::std::unique_ptr<DigitalOutput> t) {
395 red_light_ = ::std::move(t);
396 }
397 void set_green_light(::std::unique_ptr<DigitalOutput> t) {
398 green_light_ = ::std::move(t);
399 }
400 void set_blue_light(::std::unique_ptr<DigitalOutput> t) {
401 blue_light_ = ::std::move(t);
402 }
403
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800404 private:
405 virtual void Read() override {
406 ::y2017::control_loops::superstructure_queue.output.FetchAnother();
407 }
408
409 virtual void Write() override {
410 auto &queue = ::y2017::control_loops::superstructure_queue.output;
411 LOG_STRUCT(DEBUG, "will output", *queue);
412 intake_victor_->SetSpeed(::aos::Clip(queue->voltage_intake,
413 -kMaxBringupPower, kMaxBringupPower) /
414 12.0);
415 intake_rollers_victor_->SetSpeed(queue->voltage_intake_rollers / 12.0);
Austin Schuhd5ccb862017-03-11 22:06:36 -0800416 indexer_victor_->SetSpeed(-queue->voltage_indexer / 12.0);
417 indexer_roller_victor_->SetSpeed(queue->voltage_indexer_rollers / 12.0);
Austin Schuh410e3812017-02-21 16:44:03 -0800418 turret_victor_->SetSpeed(::aos::Clip(-queue->voltage_turret,
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800419 -kMaxBringupPower, kMaxBringupPower) /
420 12.0);
421 hood_victor_->SetSpeed(
422 ::aos::Clip(queue->voltage_hood, -kMaxBringupPower, kMaxBringupPower) /
423 12.0);
424 shooter_victor_->SetSpeed(queue->voltage_shooter / 12.0);
Austin Schuhc587c882017-03-29 21:33:10 -0700425
426 red_light_->Set(queue->red_light_on);
427 green_light_->Set(queue->green_light_on);
428 blue_light_->Set(queue->blue_light_on);
Austin Schuh6a8131b2017-04-08 15:39:22 -0700429
Parker Schuhd3b7a8872018-02-19 16:42:27 -0800430 gear_servo_->SetPosition(queue->gear_servo);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800431 }
432
433 virtual void Stop() override {
434 LOG(WARNING, "Superstructure output too old.\n");
435 intake_victor_->SetDisabled();
436 intake_rollers_victor_->SetDisabled();
Brian Silverman052e69d2017-02-12 16:19:55 -0800437 indexer_victor_->SetDisabled();
438 indexer_roller_victor_->SetDisabled();
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800439 turret_victor_->SetDisabled();
440 hood_victor_->SetDisabled();
441 shooter_victor_->SetDisabled();
Austin Schuhc587c882017-03-29 21:33:10 -0700442
Parker Schuhd3b7a8872018-02-19 16:42:27 -0800443 gear_servo_->SetRaw(0);
Austin Schuh6a8131b2017-04-08 15:39:22 -0700444
Austin Schuhc587c882017-03-29 21:33:10 -0700445 red_light_->Set(true);
446 green_light_->Set(true);
447 blue_light_->Set(true);
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800448 }
449
Austin Schuh8347cb62017-04-08 14:37:34 -0700450 ::std::unique_ptr<::frc::VictorSP> intake_victor_, intake_rollers_victor_,
451 indexer_victor_, indexer_roller_victor_, shooter_victor_, turret_victor_,
452 hood_victor_;
Austin Schuhc587c882017-03-29 21:33:10 -0700453
Austin Schuh6a8131b2017-04-08 15:39:22 -0700454 ::std::unique_ptr<::frc::Servo> gear_servo_;
455
Austin Schuhc587c882017-03-29 21:33:10 -0700456 ::std::unique_ptr<DigitalOutput> red_light_, green_light_, blue_light_;
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800457};
458
459class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
460 public:
461 ::std::unique_ptr<Encoder> make_encoder(int index) {
462 return make_unique<Encoder>(10 + index * 2, 11 + index * 2, false,
463 Encoder::k4X);
464 }
465
466 void Run() override {
467 ::aos::InitNRT();
468 ::aos::SetCurrentThreadName("StartCompetition");
469
470 ::frc971::wpilib::JoystickSender joystick_sender;
471 ::std::thread joystick_thread(::std::ref(joystick_sender));
472
473 ::frc971::wpilib::PDPFetcher pdp_fetcher;
474 ::std::thread pdp_fetcher_thread(::std::ref(pdp_fetcher));
475 SensorReader reader;
476
477 // TODO(campbell): Update port numbers
478 reader.set_drivetrain_left_encoder(make_encoder(0));
479 reader.set_drivetrain_right_encoder(make_encoder(1));
480
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800481 reader.set_intake_encoder(make_encoder(3));
Brian Silverman50826c02017-02-18 14:40:25 -0800482 reader.set_intake_absolute(make_unique<DigitalInput>(0));
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800483 reader.set_intake_potentiometer(make_unique<AnalogInput>(4));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800484
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800485 reader.set_indexer_encoder(make_encoder(5));
Brianef030df2017-03-05 15:06:04 -0800486 reader.set_indexer_hall(make_unique<DigitalInput>(4));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800487
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800488 reader.set_turret_encoder(make_encoder(6));
Brianef030df2017-03-05 15:06:04 -0800489 reader.set_turret_hall(make_unique<DigitalInput>(2));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800490
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800491 reader.set_hood_encoder(make_encoder(4));
492 reader.set_hood_index(make_unique<DigitalInput>(1));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800493
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800494 reader.set_shooter_encoder(make_encoder(2));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800495
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800496 reader.set_autonomous_mode(0, make_unique<DigitalInput>(9));
497 reader.set_autonomous_mode(1, make_unique<DigitalInput>(8));
Austin Schuh8347cb62017-04-08 14:37:34 -0700498
499 reader.set_pwm_trigger(make_unique<DigitalInput>(7));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800500
501 reader.set_dma(make_unique<DMA>());
502 ::std::thread reader_thread(::std::ref(reader));
503
Brian Silvermanb4439852017-02-24 19:49:09 -0800504 auto imu_trigger = make_unique<DigitalInput>(3);
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800505 ::frc971::wpilib::ADIS16448 imu(SPI::Port::kOnboardCS1, imu_trigger.get());
Brian Silvermana70994f2017-03-16 22:32:55 -0700506 imu.SetDummySPI(SPI::Port::kOnboardCS2);
507 auto imu_reset = make_unique<DigitalOutput>(6);
508 imu.set_reset(imu_reset.get());
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800509 ::std::thread imu_thread(::std::ref(imu));
510
511 DrivetrainWriter drivetrain_writer;
512 drivetrain_writer.set_drivetrain_left_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700513 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(7)));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800514 drivetrain_writer.set_drivetrain_right_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700515 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(3)));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800516 ::std::thread drivetrain_writer_thread(::std::ref(drivetrain_writer));
517
518 SuperstructureWriter superstructure_writer;
519 superstructure_writer.set_intake_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700520 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(1)));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800521 superstructure_writer.set_intake_rollers_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700522 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(4)));
Austin Schuh0fc1e6d2017-02-21 02:04:10 -0800523 superstructure_writer.set_indexer_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700524 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(6)));
Brian Silverman052e69d2017-02-12 16:19:55 -0800525 superstructure_writer.set_indexer_roller_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700526 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(5)));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800527 superstructure_writer.set_turret_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700528 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(9)));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800529 superstructure_writer.set_hood_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700530 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(2)));
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800531 superstructure_writer.set_shooter_victor(
Austin Schuh8347cb62017-04-08 14:37:34 -0700532 ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(8)));
Austin Schuhc587c882017-03-29 21:33:10 -0700533
Austin Schuh6a8131b2017-04-08 15:39:22 -0700534 superstructure_writer.set_gear_servo(
535 ::std::unique_ptr<Servo>(new Servo(0)));
536
Austin Schuhc587c882017-03-29 21:33:10 -0700537 superstructure_writer.set_red_light(
538 ::std::unique_ptr<DigitalOutput>(new DigitalOutput(5)));
539 superstructure_writer.set_green_light(
540 ::std::unique_ptr<DigitalOutput>(new DigitalOutput(24)));
541 superstructure_writer.set_blue_light(
542 ::std::unique_ptr<DigitalOutput>(new DigitalOutput(25)));
543
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800544 ::std::thread superstructure_writer_thread(
545 ::std::ref(superstructure_writer));
546
Adam Snaidere0554ef2017-03-11 23:02:45 -0800547 SolenoidWriter solenoid_writer;
548 solenoid_writer.set_lights(solenoid_writer.pcm()->MakeSolenoid(0));
Austin Schuhc587c882017-03-29 21:33:10 -0700549 solenoid_writer.set_rgb_light(solenoid_writer.pcm()->MakeSolenoid(1));
Adam Snaidere0554ef2017-03-11 23:02:45 -0800550
551 ::std::thread solenoid_thread(::std::ref(solenoid_writer));
552
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800553 // Wait forever. Not much else to do...
554 while (true) {
555 const int r = select(0, nullptr, nullptr, nullptr, nullptr);
556 if (r != 0) {
557 PLOG(WARNING, "infinite select failed");
558 } else {
559 PLOG(WARNING, "infinite select succeeded??\n");
560 }
561 }
562
563 LOG(ERROR, "Exiting WPILibRobot\n");
564
565 joystick_sender.Quit();
566 joystick_thread.join();
567 pdp_fetcher.Quit();
568 pdp_fetcher_thread.join();
569 reader.Quit();
570 reader_thread.join();
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800571 imu.Quit();
572 imu_thread.join();
573
574 drivetrain_writer.Quit();
575 drivetrain_writer_thread.join();
576 superstructure_writer.Quit();
577 superstructure_writer_thread.join();
578
579 ::aos::Cleanup();
580 }
581};
582
Brian Silverman052e69d2017-02-12 16:19:55 -0800583} // namespace
Campbell Crowleyae6e8422017-02-05 12:38:50 -0800584} // namespace wpilib
585} // namespace y2017
586
587AOS_ROBOT_CLASS(::y2017::wpilib::WPILibRobot);