blob: 0fa0f454ddfc76bc65bb96d828a29cae04d51c23 [file] [log] [blame]
Brian Silvermanc71537c2016-01-01 13:43:14 -08001#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <inttypes.h>
5
Austin Schuh8aec1ed2016-05-01 13:29:20 -07006#include <chrono>
Brian Silvermanc71537c2016-01-01 13:43:14 -08007#include <thread>
8#include <mutex>
9#include <functional>
10
Parker Schuhd3b7a8872018-02-19 16:42:27 -080011#include "frc971/wpilib/ahal/AnalogInput.h"
12#include "frc971/wpilib/ahal/Compressor.h"
13#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
14#include "frc971/wpilib/ahal/DriverStation.h"
15#include "frc971/wpilib/ahal/Encoder.h"
16#include "frc971/wpilib/ahal/PowerDistributionPanel.h"
17#include "frc971/wpilib/ahal/Relay.h"
18#include "frc971/wpilib/ahal/Talon.h"
Brian Silverman5090c432016-01-02 14:44:26 -080019#include "frc971/wpilib/wpilib_robot_base.h"
Brian Silvermanc71537c2016-01-01 13:43:14 -080020#undef ERROR
21
Brian Silvermanf819b442019-01-20 16:51:04 -080022#include "aos/init.h"
John Park33858a32018-09-28 23:05:48 -070023#include "aos/logging/logging.h"
24#include "aos/logging/queue_logging.h"
Brian Silvermanf819b442019-01-20 16:51:04 -080025#include "aos/make_unique.h"
26#include "aos/robot_state/robot_state.q.h"
27#include "aos/stl_mutex/stl_mutex.h"
John Park33858a32018-09-28 23:05:48 -070028#include "aos/time/time.h"
29#include "aos/util/log_interval.h"
30#include "aos/util/phased_loop.h"
31#include "aos/util/wrapping_counter.h"
Austin Schuh2a671df2016-11-26 15:00:06 -080032#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Brian Silvermanc71537c2016-01-01 13:43:14 -080033#include "frc971/wpilib/buffered_pcm.h"
Austin Schuh2a671df2016-11-26 15:00:06 -080034#include "frc971/wpilib/buffered_solenoid.h"
Brian Silvermanb5b46ca2016-03-13 01:14:17 -050035#include "frc971/wpilib/dma.h"
Austin Schuh2a671df2016-11-26 15:00:06 -080036#include "frc971/wpilib/dma_edge_counting.h"
Sabina Davise33f59a2019-02-03 01:17:45 -080037#include "frc971/wpilib/drivetrain_writer.h"
Austin Schuh2a671df2016-11-26 15:00:06 -080038#include "frc971/wpilib/encoder_and_potentiometer.h"
39#include "frc971/wpilib/gyro_sender.h"
40#include "frc971/wpilib/interrupt_edge_counting.h"
41#include "frc971/wpilib/joystick_sender.h"
42#include "frc971/wpilib/logging.q.h"
43#include "frc971/wpilib/loop_output_handler.h"
Austin Schuh45a549f2019-02-02 15:43:56 -080044#include "frc971/wpilib/sensor_reader.h"
Austin Schuh2a671df2016-11-26 15:00:06 -080045#include "y2012/control_loops/accessories/accessories.q.h"
Brian Silvermanc71537c2016-01-01 13:43:14 -080046
47#ifndef M_PI
48#define M_PI 3.14159265358979323846
49#endif
50
Austin Schuh2a671df2016-11-26 15:00:06 -080051using ::frc971::control_loops::drivetrain_queue;
Brian Silvermanc71537c2016-01-01 13:43:14 -080052using ::y2012::control_loops::accessories_queue;
Parker Schuhd3b7a8872018-02-19 16:42:27 -080053using namespace frc;
Brian Silvermanf819b442019-01-20 16:51:04 -080054using aos::make_unique;
Brian Silvermanc71537c2016-01-01 13:43:14 -080055
56namespace y2012 {
57namespace wpilib {
58
Brian Silvermanc71537c2016-01-01 13:43:14 -080059double drivetrain_translate(int32_t in) {
60 return -static_cast<double>(in) /
61 (256.0 /*cpr*/ * 4.0 /*4x*/) *
62 1 *
63 (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI) * 2.0 / 2.0;
64}
65
66double drivetrain_velocity_translate(double in) {
67 return (1.0 / in) / 256.0 /*cpr*/ *
68 1 *
69 (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI) * 2.0 / 2.0;
70}
71
Austin Schuh45a549f2019-02-02 15:43:56 -080072class SensorReader : public ::frc971::wpilib::SensorReader {
Brian Silvermanc71537c2016-01-01 13:43:14 -080073 public:
74 SensorReader() {}
75
Brian Silvermanc71537c2016-01-01 13:43:14 -080076 void RunIteration() {
Brian Silvermanc71537c2016-01-01 13:43:14 -080077 {
78 auto drivetrain_message = drivetrain_queue.position.MakeMessage();
79 drivetrain_message->right_encoder =
80 drivetrain_translate(drivetrain_right_encoder_->GetRaw());
81 drivetrain_message->left_encoder =
82 -drivetrain_translate(drivetrain_left_encoder_->GetRaw());
83 drivetrain_message->left_speed =
84 drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod());
85 drivetrain_message->right_speed =
86 drivetrain_velocity_translate(drivetrain_right_encoder_->GetPeriod());
87
88 drivetrain_message.Send();
89 }
90
91 accessories_queue.position.MakeMessage().Send();
92 }
Brian Silvermanc71537c2016-01-01 13:43:14 -080093};
94
95class SolenoidWriter {
96 public:
97 SolenoidWriter(const ::std::unique_ptr<::frc971::wpilib::BufferedPcm> &pcm)
98 : pcm_(pcm),
99 drivetrain_(".y2012.control_loops.drivetrain_queue.output"),
100 accessories_(".y2012.control_loops.accessories_queue.output") {}
101
102 void set_drivetrain_high(
103 ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
104 drivetrain_high_ = ::std::move(s);
105 }
106
107 void set_drivetrain_low(
108 ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
109 drivetrain_low_ = ::std::move(s);
110 }
111
112 void set_s1(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
113 s1_ = ::std::move(s);
114 }
115
116 void set_s2(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
117 s2_ = ::std::move(s);
118 }
119
120 void set_s3(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
121 s3_ = ::std::move(s);
122 }
123
124 void operator()() {
125 ::aos::SetCurrentThreadName("Solenoids");
Brian Silverman5090c432016-01-02 14:44:26 -0800126 ::aos::SetCurrentThreadRealtimePriority(27);
127
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700128 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(20),
129 ::std::chrono::milliseconds(1));
Brian Silvermanc71537c2016-01-01 13:43:14 -0800130
131 while (run_) {
Brian Silverman5090c432016-01-02 14:44:26 -0800132 {
133 const int iterations = phased_loop.SleepUntilNext();
134 if (iterations != 1) {
135 LOG(DEBUG, "Solenoids skipped %d iterations\n", iterations - 1);
136 }
137 }
Brian Silvermanc71537c2016-01-01 13:43:14 -0800138
139 {
140 accessories_.FetchLatest();
141 if (accessories_.get()) {
142 LOG_STRUCT(DEBUG, "solenoids", *accessories_);
143 s1_->Set(accessories_->solenoids[0]);
144 s2_->Set(accessories_->solenoids[1]);
145 s3_->Set(accessories_->solenoids[2]);
146 }
147 }
148
149 {
150 drivetrain_.FetchLatest();
151 if (drivetrain_.get()) {
152 LOG_STRUCT(DEBUG, "solenoids", *drivetrain_);
153 const bool high = drivetrain_->left_high || drivetrain_->right_high;
154 drivetrain_high_->Set(high);
155 drivetrain_low_->Set(!high);
156 }
157 }
158
159 {
160 ::frc971::wpilib::PneumaticsToLog to_log;
161 pcm_->Flush();
162 to_log.read_solenoids = pcm_->GetAll();
163 LOG_STRUCT(DEBUG, "pneumatics info", to_log);
164 }
165 }
166 }
167
168 void Quit() { run_ = false; }
169
170 private:
171 const ::std::unique_ptr<::frc971::wpilib::BufferedPcm> &pcm_;
172
173 ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> drivetrain_high_;
174 ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> drivetrain_low_;
175 ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s1_, s2_, s3_;
176
177 ::std::unique_ptr<Compressor> compressor_;
178
Austin Schuh2a671df2016-11-26 15:00:06 -0800179 ::aos::Queue<::frc971::control_loops::DrivetrainQueue::Output> drivetrain_;
Brian Silvermanc71537c2016-01-01 13:43:14 -0800180 ::aos::Queue<::y2012::control_loops::AccessoriesQueue::Message> accessories_;
181
182 ::std::atomic<bool> run_{true};
183};
184
Brian Silvermanc71537c2016-01-01 13:43:14 -0800185class AccessoriesWriter : public ::frc971::wpilib::LoopOutputHandler {
186 public:
187 void set_talon1(::std::unique_ptr<Talon> t) {
188 talon1_ = ::std::move(t);
189 }
190
191 void set_talon2(::std::unique_ptr<Talon> t) {
192 talon2_ = ::std::move(t);
193 }
194
195 private:
196 virtual void Read() override {
197 ::y2012::control_loops::accessories_queue.output.FetchAnother();
198 }
199
200 virtual void Write() override {
201 auto &queue = ::y2012::control_loops::accessories_queue.output;
Brian Silverman6eaa2d82017-02-04 20:48:30 -0800202 talon1_->SetSpeed(queue->sticks[0]);
203 talon2_->SetSpeed(queue->sticks[1]);
Brian Silvermanc71537c2016-01-01 13:43:14 -0800204 LOG_STRUCT(DEBUG, "will output", *queue);
205 }
206
207 virtual void Stop() override {
208 LOG(WARNING, "shooter output too old\n");
Brian Silverman6eaa2d82017-02-04 20:48:30 -0800209 talon1_->SetDisabled();
210 talon2_->SetDisabled();
Brian Silvermanc71537c2016-01-01 13:43:14 -0800211 }
212
213 ::std::unique_ptr<Talon> talon1_, talon2_;
214};
215
Brian Silverman5090c432016-01-02 14:44:26 -0800216class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
Brian Silvermanc71537c2016-01-01 13:43:14 -0800217 public:
218 ::std::unique_ptr<Encoder> make_encoder(int index) {
219 return make_unique<Encoder>(10 + index * 2, 11 + index * 2, false,
220 Encoder::k4X);
221 }
222
Brian Silverman5090c432016-01-02 14:44:26 -0800223 void Run() override {
Brian Silvermanc71537c2016-01-01 13:43:14 -0800224 ::aos::InitNRT();
225 ::aos::SetCurrentThreadName("StartCompetition");
226
227 ::frc971::wpilib::JoystickSender joystick_sender;
228 ::std::thread joystick_thread(::std::ref(joystick_sender));
229
230 SensorReader reader;
231
232 reader.set_drivetrain_left_encoder(make_encoder(0));
233 reader.set_drivetrain_right_encoder(make_encoder(1));
234
235 ::std::thread reader_thread(::std::ref(reader));
236
Sabina Davise33f59a2019-02-03 01:17:45 -0800237 ::frc971::wpilib::DrivetrainWriter drivetrain_writer;
238 drivetrain_writer.set_left_controller0(
239 ::std::unique_ptr<Talon>(new Talon(3)), true);
240 drivetrain_writer.set_right_controller0(
241 ::std::unique_ptr<Talon>(new Talon(4)), false);
Brian Silvermanc71537c2016-01-01 13:43:14 -0800242 ::std::thread drivetrain_writer_thread(::std::ref(drivetrain_writer));
243
244 ::y2012::wpilib::AccessoriesWriter accessories_writer;
245 accessories_writer.set_talon1(::std::unique_ptr<Talon>(new Talon(5)));
246 accessories_writer.set_talon2(::std::unique_ptr<Talon>(new Talon(6)));
247 ::std::thread accessories_writer_thread(::std::ref(accessories_writer));
248
249 ::std::unique_ptr<::frc971::wpilib::BufferedPcm> pcm(
250 new ::frc971::wpilib::BufferedPcm());
251 SolenoidWriter solenoid_writer(pcm);
252 solenoid_writer.set_drivetrain_high(pcm->MakeSolenoid(0));
253 solenoid_writer.set_drivetrain_low(pcm->MakeSolenoid(2));
254 solenoid_writer.set_s1(pcm->MakeSolenoid(1));
255 solenoid_writer.set_s2(pcm->MakeSolenoid(3));
256 solenoid_writer.set_s3(pcm->MakeSolenoid(4));
257
258 ::std::thread solenoid_thread(::std::ref(solenoid_writer));
259
260 // Wait forever. Not much else to do...
Brian Silverman5090c432016-01-02 14:44:26 -0800261 while (true) {
262 const int r = select(0, nullptr, nullptr, nullptr, nullptr);
263 if (r != 0) {
264 PLOG(WARNING, "infinite select failed");
265 } else {
266 PLOG(WARNING, "infinite select succeeded??\n");
267 }
268 }
Brian Silvermanc71537c2016-01-01 13:43:14 -0800269
270 LOG(ERROR, "Exiting WPILibRobot\n");
271
272 joystick_sender.Quit();
273 joystick_thread.join();
274 reader.Quit();
275 reader_thread.join();
276
277 drivetrain_writer.Quit();
278 drivetrain_writer_thread.join();
279 accessories_writer.Quit();
280 accessories_writer_thread.join();
281
282 ::aos::Cleanup();
283 }
284};
285
286} // namespace wpilib
287} // namespace y2012
288
289
Brian Silverman5090c432016-01-02 14:44:26 -0800290AOS_ROBOT_CLASS(::y2012::wpilib::WPILibRobot);