blob: 934daf8d89482a2ed00bd448fe7f3393948b91ae [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>
Austin Schuhf2a50ba2016-12-24 16:16:26 -08004#include <sys/stat.h>
5#include <sys/types.h>
6
7#include <chrono>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07008#include <cinttypes>
Brian Silverman07ec88e2014-12-28 00:13:08 -08009
Austin Schuh217a9782019-12-21 23:02:50 -080010#include "aos/events/shm_event_loop.h"
Austin Schuhdf6cbb12019-02-02 13:46:52 -080011#include "aos/init.h"
John Park33858a32018-09-28 23:05:48 -070012#include "aos/logging/logging.h"
John Park33858a32018-09-28 23:05:48 -070013#include "aos/time/time.h"
James Kuszmaul7077d342021-06-09 20:23:58 -070014#include "frc971/input/robot_state_generated.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070015#include "frc971/queues/gyro_generated.h"
Tyler Chatow24b5db12020-01-06 21:16:56 -080016#include "frc971/queues/gyro_uid_generated.h"
Philipp Schrader29d54f22016-04-02 22:14:48 +000017#include "frc971/zeroing/averager.h"
Brian Silverman07ec88e2014-12-28 00:13:08 -080018
Stephan Pleinesf63bde82024-01-13 15:59:33 -080019namespace frc971::wpilib {
Brian Silverman07ec88e2014-12-28 00:13:08 -080020
Austin Schuhf2a50ba2016-12-24 16:16:26 -080021namespace chrono = ::std::chrono;
22using ::aos::monotonic_clock;
Brian Silverman07ec88e2014-12-28 00:13:08 -080023
Austin Schuh217a9782019-12-21 23:02:50 -080024GyroSender::GyroSender(::aos::ShmEventLoop *event_loop)
Austin Schuhdf6cbb12019-02-02 13:46:52 -080025 : event_loop_(event_loop),
Alex Perrycb7da4b2019-08-28 19:35:56 -070026 joystick_state_fetcher_(
27 event_loop_->MakeFetcher<aos::RobotState>("/aos")),
28 uid_sender_(event_loop_->MakeSender<frc971::sensors::Uid>("/drivetrain")),
Austin Schuh1ea89bb2019-05-27 16:59:59 -070029 gyro_reading_sender_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 event_loop_->MakeSender<frc971::sensors::GyroReading>(
31 "/drivetrain")) {
James Kuszmaul7077d342021-06-09 20:23:58 -070032 AOS_PCHECK(system("busybox ps -ef | grep '\\[spi0\\]' | awk '{print $1}' | "
33 "xargs chrt -f -p "
34 "33") == 0);
Austin Schuh217a9782019-12-21 23:02:50 -080035 event_loop->set_name("Gyro");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070036 event_loop_->SetRuntimeRealtimePriority(33);
37
38 // TODO(austin): This should be synchronized with SensorReader... Pull out
39 // the sync logic and re-use it here.
40 event_loop_->AddPhasedLoop([this](int iterations) { Loop(iterations); },
41 ::aos::time::FromRate(kReadingRate),
42 chrono::milliseconds(4));
Austin Schuh268e13c2017-02-03 20:33:23 -080043}
44
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070045void GyroSender::Loop(const int iterations) {
46 switch (state_) {
47 case State::INITIALIZING: {
48 const monotonic_clock::time_point monotonic_now =
49 event_loop_->monotonic_now();
50 if (last_initialize_time_ + chrono::milliseconds(50) < monotonic_now) {
51 if (gyro_.InitializeGyro()) {
52 state_ = State::RUNNING;
Austin Schuhf257f3c2019-10-27 21:00:43 -070053 AOS_LOG(INFO, "gyro initialized successfully\n");
Brian Silverman07ec88e2014-12-28 00:13:08 -080054
Alex Perrycb7da4b2019-08-28 19:35:56 -070055 auto builder = uid_sender_.MakeBuilder();
milind1f1dca32021-07-03 13:50:07 -070056 builder.CheckOk(builder.Send(
57 frc971::sensors::CreateUid(*builder.fbb(), gyro_.ReadPartID())));
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070058 }
59 last_initialize_time_ = monotonic_now;
Brian Silverman07ec88e2014-12-28 00:13:08 -080060 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070061 } break;
62 case State::RUNNING: {
63 const uint32_t result = gyro_.GetReading();
64 if (result == 0) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070065 AOS_LOG(WARNING, "normal gyro read failed\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070066 return;
Brian Silverman07ec88e2014-12-28 00:13:08 -080067 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070068 switch (gyro_.ExtractStatus(result)) {
69 case 0:
Austin Schuhf257f3c2019-10-27 21:00:43 -070070 AOS_LOG(WARNING, "gyro says data is bad\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070071 return;
72 case 1:
73 break;
74 default:
Austin Schuhf257f3c2019-10-27 21:00:43 -070075 AOS_LOG(WARNING, "gyro gave weird status 0x%" PRIx8 "\n",
76 gyro_.ExtractStatus(result));
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070077 return;
Brian Silverman07ec88e2014-12-28 00:13:08 -080078 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070079 if (gyro_.ExtractErrors(result) != 0) {
80 const uint8_t errors = gyro_.ExtractErrors(result);
81 if (errors & (1 << 6)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070082 AOS_LOG(WARNING, "gyro gave PLL error\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070083 }
84 if (errors & (1 << 5)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070085 AOS_LOG(WARNING, "gyro gave quadrature error\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070086 }
87 if (errors & (1 << 4)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070088 AOS_LOG(WARNING, "gyro gave non-volatile memory error\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070089 }
90 if (errors & (1 << 3)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070091 AOS_LOG(WARNING, "gyro gave volatile memory error\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070092 }
93 if (errors & (1 << 2)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070094 AOS_LOG(WARNING, "gyro gave power error\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070095 }
96 if (errors & (1 << 1)) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070097 AOS_LOG(WARNING, "gyro gave continuous self-test error\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070098 }
99 if (errors & 1) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700100 AOS_LOG(WARNING, "gyro gave unexpected self-test mode\n");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700101 }
102 return;
Brian Silverman07ec88e2014-12-28 00:13:08 -0800103 }
Brian Silverman07ec88e2014-12-28 00:13:08 -0800104
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700105 if (startup_cycles_left_ > 0) {
106 --startup_cycles_left_;
107 return;
108 }
Brian Silverman07ec88e2014-12-28 00:13:08 -0800109
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700110 const double angle_rate = gyro_.ExtractAngle(result);
111 const double new_angle = angle_rate / static_cast<double>(kReadingRate);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700112 auto builder = gyro_reading_sender_.MakeBuilder();
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700113 if (zeroed_) {
114 angle_ += (new_angle + zero_offset_) * iterations;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700115 sensors::GyroReading::Builder gyro_builder =
116 builder.MakeBuilder<sensors::GyroReading>();
117 gyro_builder.add_angle(angle_);
118 gyro_builder.add_velocity(angle_rate + zero_offset_ * kReadingRate);
milind1f1dca32021-07-03 13:50:07 -0700119 builder.CheckOk(builder.Send(gyro_builder.Finish()));
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700120 } else {
121 // TODO(brian): Don't break without 6 seconds of standing still before
122 // enabling. Ideas:
123 // Don't allow driving until we have at least some data?
124 // Some kind of indicator light?
125 {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700126 sensors::GyroReading::Builder gyro_builder =
127 builder.MakeBuilder<sensors::GyroReading>();
128 gyro_builder.add_angle(0.0);
129 gyro_builder.add_velocity(0.0);
milind1f1dca32021-07-03 13:50:07 -0700130 builder.CheckOk(builder.Send(gyro_builder.Finish()));
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700131 }
132 zeroing_data_.AddData(new_angle);
Brian Silverman07ec88e2014-12-28 00:13:08 -0800133
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700134 joystick_state_fetcher_.Fetch();
Alex Perrycb7da4b2019-08-28 19:35:56 -0700135 if (joystick_state_fetcher_.get() &&
136 joystick_state_fetcher_->outputs_enabled() &&
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700137 zeroing_data_.full()) {
James Kuszmauld3f9eb22020-01-12 15:02:07 -0800138 zero_offset_ = -zeroing_data_.GetAverage()(0, 0);
Austin Schuhf257f3c2019-10-27 21:00:43 -0700139 AOS_LOG(INFO, "total zero offset %f\n", zero_offset_);
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700140 zeroed_ = true;
141 }
Brian Silverman07ec88e2014-12-28 00:13:08 -0800142 }
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700143 } break;
Brian Silverman07ec88e2014-12-28 00:13:08 -0800144 }
145}
146
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800147} // namespace frc971::wpilib