Brian Silverman | 1ba46c7 | 2013-10-31 16:05:57 -0700 | [diff] [blame] | 1 | #include <inttypes.h> |
| 2 | |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 3 | #include "aos/atom_code/init.h" |
| 4 | #include "aos/common/logging/logging.h" |
Brian Silverman | f4937f6 | 2013-10-16 10:32:00 -0700 | [diff] [blame] | 5 | #include "aos/common/util/wrapping_counter.h" |
Brian Silverman | 7d16c57 | 2014-01-03 20:27:57 -0800 | [diff] [blame^] | 6 | #include "aos/common/time.h" |
| 7 | |
| 8 | #include "bbb/sensor_reader.h" |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 9 | |
| 10 | #include "frc971/control_loops/drivetrain/drivetrain.q.h" |
| 11 | #include "frc971/control_loops/wrist/wrist_motor.q.h" |
| 12 | #include "frc971/control_loops/angle_adjust/angle_adjust_motor.q.h" |
| 13 | #include "frc971/control_loops/index/index_motor.q.h" |
| 14 | #include "frc971/control_loops/shooter/shooter_motor.q.h" |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 15 | #include "frc971/queues/GyroAngle.q.h" |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 16 | #include "frc971/constants.h" |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 17 | |
| 18 | #ifndef M_PI |
| 19 | #define M_PI 3.14159265358979323846 |
| 20 | #endif |
| 21 | |
| 22 | using ::frc971::control_loops::drivetrain; |
| 23 | using ::frc971::control_loops::wrist; |
| 24 | using ::frc971::control_loops::angle_adjust; |
| 25 | using ::frc971::control_loops::shooter; |
| 26 | using ::frc971::control_loops::index_loop; |
| 27 | using ::frc971::sensors::gyro; |
Brian Silverman | f4937f6 | 2013-10-16 10:32:00 -0700 | [diff] [blame] | 28 | using ::aos::util::WrappingCounter; |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 29 | |
| 30 | namespace frc971 { |
| 31 | namespace { |
| 32 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 33 | double drivetrain_translate(int32_t in) { |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 34 | return static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) * |
Brian Silverman | 1a6590d | 2013-11-04 14:46:46 -0800 | [diff] [blame] | 35 | constants::GetValues().drivetrain_encoder_ratio * |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 36 | (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI); |
| 37 | } |
| 38 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 39 | double wrist_translate(int32_t in) { |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 40 | return static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) * |
| 41 | (14.0 / 50.0 * 20.0 / 84.0) /*gears*/ * (2 * M_PI); |
| 42 | } |
| 43 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 44 | double angle_adjust_translate(int32_t in) { |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 45 | static const double kCableDiameter = 0.060; |
| 46 | return -static_cast<double>(in) / (256.0 /*cpr*/ * 4.0 /*quad*/) * |
| 47 | ((0.75 + kCableDiameter) / (16.61125 + kCableDiameter)) /*pulleys*/ * |
| 48 | (2 * M_PI); |
| 49 | } |
| 50 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 51 | double shooter_translate(int32_t in) { |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 52 | return static_cast<double>(in) / (32.0 /*cpr*/ * 4.0 /*quad*/) * |
| 53 | (15.0 / 34.0) /*gears*/ * (2 * M_PI); |
| 54 | } |
| 55 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 56 | double index_translate(int32_t in) { |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 57 | return -static_cast<double>(in) / (128.0 /*cpr*/ * 4.0 /*quad*/) * |
| 58 | (1.0) /*gears*/ * (2 * M_PI); |
| 59 | } |
| 60 | |
Brian Silverman | 74acd62 | 2013-10-26 14:47:14 -0700 | [diff] [blame] | 61 | // Translates values from the ADC into voltage. |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 62 | double adc_translate(uint16_t in) { |
Brian Silverman | 74acd62 | 2013-10-26 14:47:14 -0700 | [diff] [blame] | 63 | static const double kVRefN = 0; |
| 64 | static const double kVRefP = 3.3; |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 65 | static const int kMaximumValue = 0xFFF; |
| 66 | static const double kDividerGnd = 31.6, kDividerOther = 28; |
| 67 | return (kVRefN + |
Brian Silverman | 74acd62 | 2013-10-26 14:47:14 -0700 | [diff] [blame] | 68 | (static_cast<double>(in) / static_cast<double>(kMaximumValue) * |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 69 | (kVRefP - kVRefN))) * (kDividerGnd + kDividerOther) / kDividerGnd; |
Brian Silverman | 74acd62 | 2013-10-26 14:47:14 -0700 | [diff] [blame] | 70 | } |
| 71 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 72 | double gyro_translate(int64_t in) { |
Brian Silverman | a280ae0 | 2013-10-28 18:21:15 -0700 | [diff] [blame] | 73 | return in / 16.0 / 1000.0 / (180.0 / M_PI); |
| 74 | } |
| 75 | |
Brian Silverman | 6eb51f1 | 2013-11-02 14:39:01 -0700 | [diff] [blame] | 76 | double battery_translate(uint16_t in) { |
| 77 | static const double kDividerBig = 98.9, kDividerSmall = 17.8; |
| 78 | return adc_translate(in) * kDividerBig / kDividerSmall; |
| 79 | } |
| 80 | |
| 81 | double hall_translate(const constants::ShifterHallEffect &k, uint16_t in) { |
| 82 | const double voltage = adc_translate(in); |
| 83 | return (voltage - k.low) / (k.high - k.low); |
Brian Silverman | 1ba46c7 | 2013-10-31 16:05:57 -0700 | [diff] [blame] | 84 | } |
| 85 | |
Brian Silverman | 7d16c57 | 2014-01-03 20:27:57 -0800 | [diff] [blame^] | 86 | WrappingCounter top_rise_; |
| 87 | WrappingCounter top_fall_; |
| 88 | WrappingCounter bottom_rise_; |
| 89 | WrappingCounter bottom_fall_delay_; |
| 90 | WrappingCounter bottom_fall_; |
| 91 | void ProcessData(const ::bbb::DataStruct *data, bool bad_gyro) { |
| 92 | if (!bad_gyro) { |
| 93 | gyro.MakeWithBuilder() |
| 94 | .angle(gyro_translate(data->gyro_angle)) |
| 95 | .Send(); |
| 96 | } |
| 97 | |
| 98 | drivetrain.position.MakeWithBuilder() |
| 99 | .right_encoder(drivetrain_translate(data->main.right_drive)) |
| 100 | .left_encoder(-drivetrain_translate(data->main.left_drive)) |
| 101 | .left_shifter_position(hall_translate(constants::GetValues().left_drive, |
| 102 | data->main.left_drive_hall)) |
| 103 | .right_shifter_position(hall_translate( |
| 104 | constants::GetValues().right_drive, data->main.right_drive_hall)) |
| 105 | .battery_voltage(battery_translate(data->main.battery_voltage)) |
| 106 | .Send(); |
| 107 | |
| 108 | wrist.position.MakeWithBuilder() |
| 109 | .pos(wrist_translate(data->main.wrist)) |
| 110 | .hall_effect(data->main.wrist_hall_effect) |
| 111 | .calibration(wrist_translate(data->main.capture_wrist_rise)) |
| 112 | .Send(); |
| 113 | |
| 114 | angle_adjust.position.MakeWithBuilder() |
| 115 | .angle(angle_adjust_translate(data->main.shooter_angle)) |
| 116 | .bottom_hall_effect(data->main.angle_adjust_bottom_hall_effect) |
| 117 | .middle_hall_effect(false) |
| 118 | .bottom_calibration(angle_adjust_translate( |
| 119 | data->main.capture_shooter_angle_rise)) |
| 120 | .middle_calibration(angle_adjust_translate( |
| 121 | 0)) |
| 122 | .Send(); |
| 123 | |
| 124 | shooter.position.MakeWithBuilder() |
| 125 | .position(shooter_translate(data->main.shooter)) |
| 126 | .Send(); |
| 127 | |
| 128 | index_loop.position.MakeWithBuilder() |
| 129 | .index_position(index_translate(data->main.indexer)) |
| 130 | .top_disc_detect(data->main.top_disc) |
| 131 | .top_disc_posedge_count(top_rise_.Update(data->main.top_rise_count)) |
| 132 | .top_disc_posedge_position( |
| 133 | index_translate(data->main.capture_top_rise)) |
| 134 | .top_disc_negedge_count(top_fall_.Update(data->main.top_fall_count)) |
| 135 | .top_disc_negedge_position( |
| 136 | index_translate(data->main.capture_top_fall)) |
| 137 | .bottom_disc_detect(data->main.bottom_disc) |
| 138 | .bottom_disc_posedge_count( |
| 139 | bottom_rise_.Update(data->main.bottom_rise_count)) |
| 140 | .bottom_disc_negedge_count( |
| 141 | bottom_fall_.Update(data->main.bottom_fall_count)) |
| 142 | .bottom_disc_negedge_wait_position(index_translate( |
| 143 | data->main.capture_bottom_fall_delay)) |
| 144 | .bottom_disc_negedge_wait_count( |
| 145 | bottom_fall_delay_.Update(data->main.bottom_fall_delay_count)) |
| 146 | .loader_top(data->main.loader_top) |
| 147 | .loader_bottom(data->main.loader_bottom) |
| 148 | .Send(); |
| 149 | } |
| 150 | |
| 151 | void PacketReceived(const ::bbb::DataStruct *data, |
| 152 | const ::aos::time::Time &cape_timestamp) { |
| 153 | LOG(DEBUG, "cape timestamp %010" PRId32 ".%09" PRId32 "s\n", |
| 154 | cape_timestamp.sec(), cape_timestamp.nsec()); |
| 155 | bool bad_gyro; |
| 156 | if (data->uninitialized_gyro) { |
| 157 | LOG(DEBUG, "uninitialized gyro\n"); |
| 158 | bad_gyro = true; |
| 159 | } else if (data->zeroing_gyro) { |
| 160 | LOG(DEBUG, "zeroing gyro\n"); |
| 161 | bad_gyro = true; |
| 162 | } else if (data->bad_gyro) { |
| 163 | LOG(ERROR, "bad gyro\n"); |
| 164 | bad_gyro = true; |
| 165 | gyro.MakeWithBuilder().angle(0).Send(); |
| 166 | } else if (data->old_gyro_reading) { |
| 167 | LOG(WARNING, "old/bad gyro reading\n"); |
| 168 | bad_gyro = true; |
| 169 | } else { |
| 170 | bad_gyro = false; |
| 171 | } |
| 172 | static int i = 0; |
| 173 | ++i; |
| 174 | if (i == 5) { |
| 175 | i = 0; |
| 176 | ProcessData(data, bad_gyro); |
| 177 | } |
| 178 | } |
| 179 | |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 180 | } // namespace |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 181 | } // namespace frc971 |
| 182 | |
| 183 | int main() { |
Brian Silverman | 7d16c57 | 2014-01-03 20:27:57 -0800 | [diff] [blame^] | 184 | ::aos::Init(::bbb::SensorReader::kRelativePriority); |
| 185 | ::bbb::SensorReader reader("main"); |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 186 | while (true) { |
Brian Silverman | 7d16c57 | 2014-01-03 20:27:57 -0800 | [diff] [blame^] | 187 | ::frc971::PacketReceived(reader.ReadPacket(), reader.GetCapeTimestamp()); |
Brian Silverman | 2e0dcfd | 2013-03-30 22:44:40 -0700 | [diff] [blame] | 188 | } |
| 189 | ::aos::Cleanup(); |
| 190 | } |