blob: b1edbd249efea0828eb40774f1ac099837de9b78 [file] [log] [blame]
Brian Silverman07ec88e2014-12-28 00:13:08 -08001#include "frc971/wpilib/gyro_sender.h"
2
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <fcntl.h>
Brian Silverman07ec88e2014-12-28 00:13:08 -08004#include <inttypes.h>
Austin Schuhf2a50ba2016-12-24 16:16:26 -08005#include <sys/stat.h>
6#include <sys/types.h>
7
8#include <chrono>
Brian Silverman07ec88e2014-12-28 00:13:08 -08009
Austin Schuhdf6cbb12019-02-02 13:46:52 -080010#include "aos/events/event-loop.h"
11#include "aos/init.h"
John Park33858a32018-09-28 23:05:48 -070012#include "aos/logging/logging.h"
13#include "aos/logging/queue_logging.h"
John Park33858a32018-09-28 23:05:48 -070014#include "aos/robot_state/robot_state.q.h"
15#include "aos/time/time.h"
Brian Silverman07ec88e2014-12-28 00:13:08 -080016
17#include "frc971/queues/gyro.q.h"
Philipp Schrader29d54f22016-04-02 22:14:48 +000018#include "frc971/zeroing/averager.h"
Brian Silverman07ec88e2014-12-28 00:13:08 -080019
20namespace frc971 {
21namespace wpilib {
22
Austin Schuhf2a50ba2016-12-24 16:16:26 -080023namespace chrono = ::std::chrono;
24using ::aos::monotonic_clock;
Brian Silverman07ec88e2014-12-28 00:13:08 -080025
Austin Schuhdf6cbb12019-02-02 13:46:52 -080026GyroSender::GyroSender(::aos::EventLoop *event_loop)
27 : event_loop_(event_loop),
28 joystick_state_fetcher_(event_loop_->MakeFetcher<::aos::JoystickState>(
Austin Schuhcc1010e2019-05-12 20:38:01 -070029 ".aos.joystick_state")),
30 uid_sender_(event_loop_->MakeSender<::frc971::sensors::Uid>(
Austin Schuh1ea89bb2019-05-27 16:59:59 -070031 ".frc971.sensors.gyro_part_id")),
32 gyro_reading_sender_(
33 event_loop_->MakeSender<::frc971::sensors::GyroReading>(
34 ".frc971.sensors.gyro_reading")) {
Austin Schuhdf6cbb12019-02-02 13:46:52 -080035 PCHECK(
36 system("ps -ef | grep '\\[spi0\\]' | awk '{print $1}' | xargs chrt -f -p "
Austin Schuh268e13c2017-02-03 20:33:23 -080037 "33") == 0);
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070038 event_loop_->set_name("Gyro");
39 event_loop_->SetRuntimeRealtimePriority(33);
40
41 // TODO(austin): This should be synchronized with SensorReader... Pull out
42 // the sync logic and re-use it here.
43 event_loop_->AddPhasedLoop([this](int iterations) { Loop(iterations); },
44 ::aos::time::FromRate(kReadingRate),
45 chrono::milliseconds(4));
Austin Schuh268e13c2017-02-03 20:33:23 -080046}
47
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070048void GyroSender::Loop(const int iterations) {
49 switch (state_) {
50 case State::INITIALIZING: {
51 const monotonic_clock::time_point monotonic_now =
52 event_loop_->monotonic_now();
53 if (last_initialize_time_ + chrono::milliseconds(50) < monotonic_now) {
54 if (gyro_.InitializeGyro()) {
55 state_ = State::RUNNING;
56 LOG(INFO, "gyro initialized successfully\n");
Brian Silverman07ec88e2014-12-28 00:13:08 -080057
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070058 {
59 auto message = uid_sender_.MakeMessage();
60 message->uid = gyro_.ReadPartID();
61 LOG_STRUCT(INFO, "gyro ID", *message);
62 message.Send();
63 }
64 }
65 last_initialize_time_ = monotonic_now;
Brian Silverman07ec88e2014-12-28 00:13:08 -080066 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070067 } break;
68 case State::RUNNING: {
69 const uint32_t result = gyro_.GetReading();
70 if (result == 0) {
71 LOG(WARNING, "normal gyro read failed\n");
72 return;
Brian Silverman07ec88e2014-12-28 00:13:08 -080073 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070074 switch (gyro_.ExtractStatus(result)) {
75 case 0:
76 LOG(WARNING, "gyro says data is bad\n");
77 return;
78 case 1:
79 break;
80 default:
81 LOG(WARNING, "gyro gave weird status 0x%" PRIx8 "\n",
82 gyro_.ExtractStatus(result));
83 return;
Brian Silverman07ec88e2014-12-28 00:13:08 -080084 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070085 if (gyro_.ExtractErrors(result) != 0) {
86 const uint8_t errors = gyro_.ExtractErrors(result);
87 if (errors & (1 << 6)) {
88 LOG(WARNING, "gyro gave PLL error\n");
89 }
90 if (errors & (1 << 5)) {
91 LOG(WARNING, "gyro gave quadrature error\n");
92 }
93 if (errors & (1 << 4)) {
94 LOG(WARNING, "gyro gave non-volatile memory error\n");
95 }
96 if (errors & (1 << 3)) {
97 LOG(WARNING, "gyro gave volatile memory error\n");
98 }
99 if (errors & (1 << 2)) {
100 LOG(WARNING, "gyro gave power error\n");
101 }
102 if (errors & (1 << 1)) {
103 LOG(WARNING, "gyro gave continuous self-test error\n");
104 }
105 if (errors & 1) {
106 LOG(WARNING, "gyro gave unexpected self-test mode\n");
107 }
108 return;
Brian Silverman07ec88e2014-12-28 00:13:08 -0800109 }
Brian Silverman07ec88e2014-12-28 00:13:08 -0800110
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700111 if (startup_cycles_left_ > 0) {
112 --startup_cycles_left_;
113 return;
114 }
Brian Silverman07ec88e2014-12-28 00:13:08 -0800115
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700116 const double angle_rate = gyro_.ExtractAngle(result);
117 const double new_angle = angle_rate / static_cast<double>(kReadingRate);
118 auto message = gyro_reading_sender_.MakeMessage();
119 if (zeroed_) {
120 angle_ += (new_angle + zero_offset_) * iterations;
121 message->angle = angle_;
122 message->velocity = angle_rate + zero_offset_ * kReadingRate;
123 LOG_STRUCT(DEBUG, "sending", *message);
Austin Schuh5125e082015-04-18 22:56:04 -0700124 message.Send();
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700125 } else {
126 // TODO(brian): Don't break without 6 seconds of standing still before
127 // enabling. Ideas:
128 // Don't allow driving until we have at least some data?
129 // Some kind of indicator light?
130 {
131 message->angle = new_angle;
132 message->velocity = angle_rate;
133 LOG_STRUCT(DEBUG, "collected while zeroing", *message);
134 message->angle = 0.0;
135 message->velocity = 0.0;
136 message.Send();
137 }
138 zeroing_data_.AddData(new_angle);
Brian Silverman07ec88e2014-12-28 00:13:08 -0800139
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700140 joystick_state_fetcher_.Fetch();
141 if (joystick_state_fetcher_.get() && joystick_state_fetcher_->enabled &&
142 zeroing_data_.full()) {
143 zero_offset_ = -zeroing_data_.GetAverage();
144 LOG(INFO, "total zero offset %f\n", zero_offset_);
145 zeroed_ = true;
146 }
Brian Silverman07ec88e2014-12-28 00:13:08 -0800147 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700148 } break;
Brian Silverman07ec88e2014-12-28 00:13:08 -0800149 }
150}
151
152} // namespace wpilib
153} // namespace frc971