blob: 7648db8233c982e960ea8f2174f931ea6db29c09 [file] [log] [blame]
Brian Silverman1ba46c72013-10-31 16:05:57 -07001#include <inttypes.h>
2
Brian Silverman14fd0fb2014-01-14 21:42:01 -08003#include "aos/linux_code/init.h"
Brian Silverman2e0dcfd2013-03-30 22:44:40 -07004#include "aos/common/logging/logging.h"
Brian Silvermanf4937f62013-10-16 10:32:00 -07005#include "aos/common/util/wrapping_counter.h"
Brian Silverman7d16c572014-01-03 20:27:57 -08006#include "aos/common/time.h"
Brian Silvermanb4a1f9f2014-02-14 17:59:55 -08007#include "aos/common/logging/queue_logging.h"
Brian Silverman7d16c572014-01-03 20:27:57 -08008
9#include "bbb/sensor_reader.h"
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070010
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Brian Silverman6bf0d3c2014-03-08 12:52:54 -080012#include "frc971/queues/other_sensors.q.h"
Brian Silverman6eb51f12013-11-02 14:39:01 -070013#include "frc971/constants.h"
Brian Silvermanb4a1f9f2014-02-14 17:59:55 -080014#include "frc971/queues/to_log.q.h"
Brian Silverman5b433df2014-02-17 11:57:37 -080015#include "frc971/control_loops/shooter/shooter.q.h"
16#include "frc971/control_loops/claw/claw.q.h"
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070017
18#ifndef M_PI
19#define M_PI 3.14159265358979323846
20#endif
21
22using ::frc971::control_loops::drivetrain;
Brian Silverman6bf0d3c2014-03-08 12:52:54 -080023using ::frc971::sensors::other_sensors;
24using ::frc971::sensors::gyro_reading;
Brian Silvermanf4937f62013-10-16 10:32:00 -070025using ::aos::util::WrappingCounter;
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070026
27namespace frc971 {
28namespace {
29
Brian Silverman5b433df2014-02-17 11:57:37 -080030struct State {
31 struct HallEffectCounters {
32 WrappingCounter posedges, negedges;
33 };
34
35 HallEffectCounters plunger, pusher_distal, pusher_proximal, latch;
36
37 struct SingleClawState {
38 HallEffectCounters front, calibration, back;
39 } top_claw, bottom_claw;
40};
41
Brian Silverman6eb51f12013-11-02 14:39:01 -070042double drivetrain_translate(int32_t in) {
Brian Silverman02b23c32014-02-17 17:26:48 -080043 return static_cast<double>(in)
44 / (256.0 /*cpr*/ * 4.0 /*quad*/)
45 * (18.0 / 50.0 /*output stage*/) * (56.0 / 30.0 /*encoder gears*/)
46 // * constants::GetValues().drivetrain_encoder_ratio
47 * (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI);
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070048}
49
Brian Silverman74acd622013-10-26 14:47:14 -070050// Translates values from the ADC into voltage.
Brian Silverman56658322014-03-22 16:57:22 -070051// TODO(brian): Tune this to the actual hardware.
Brian Silverman6eb51f12013-11-02 14:39:01 -070052double adc_translate(uint16_t in) {
Brian Silvermanc8efb5e2014-02-18 21:03:24 -080053 static const double kVcc = 5;
Brian Silverman56658322014-03-22 16:57:22 -070054 static const double kR1 = 5, kR2 = 6.65;
Brian Silvermanc8efb5e2014-02-18 21:03:24 -080055 static const uint16_t kMaximumValue = 0x3FF;
Brian Silverman56658322014-03-22 16:57:22 -070056 const double raw =
57 (kVcc * static_cast<double>(in) / static_cast<double>(kMaximumValue));
58 return (raw * (kR1 + kR2) - (kVcc / 2) * kR2) / kR1;
Brian Silverman74acd622013-10-26 14:47:14 -070059}
60
Brian Silverman6eb51f12013-11-02 14:39:01 -070061double gyro_translate(int64_t in) {
Brian Silvermana280ae02013-10-28 18:21:15 -070062 return in / 16.0 / 1000.0 / (180.0 / M_PI);
63}
64
Brian Silverman56658322014-03-22 16:57:22 -070065double battery_translate(uint16_t in_high, uint16_t in_low) {
66 const double high = adc_translate(in_high), low = adc_translate(in_low);
67 static const double kDividerBig = 5.55, kDividerSmall = 2.66;
68 static const double kSensorVcc = 5.0;
69 return (high - low) * (kDividerBig + kDividerSmall) / kDividerSmall +
70 kDividerBig / kDividerSmall * kSensorVcc;
Brian Silverman6eb51f12013-11-02 14:39:01 -070071}
72
Brian Silverman5a0a2ec2014-03-08 12:44:58 -080073double sonar_translate(uint32_t in) {
Austin Schuh05a81662014-03-09 00:47:34 -080074 return static_cast<double>(in) / 1000.0 * 2.0;
Brian Silverman5a0a2ec2014-03-08 12:44:58 -080075}
76
Austin Schuh809c2562014-03-02 11:50:19 -080077double hall_translate(const constants::ShifterHallEffect &k, uint16_t in_low,
78 uint16_t in_high) {
79 const double low_ratio =
80 0.5 * (in_low - static_cast<double>(k.low_gear_low)) /
81 static_cast<double>(k.low_gear_middle - k.low_gear_low);
82 const double high_ratio =
83 0.5 + 0.5 * (in_high - static_cast<double>(k.high_gear_middle)) /
84 static_cast<double>(k.high_gear_high - k.high_gear_middle);
85
86 // Return low when we are below 1/2, and high when we are above 1/2.
87 if (low_ratio + high_ratio < 1.0) {
88 return low_ratio;
89 } else {
90 return high_ratio;
91 }
Brian Silverman1ba46c72013-10-31 16:05:57 -070092}
93
Brian Silverman258349f2014-02-17 21:38:53 -080094double claw_translate(int32_t in) {
Brian Silverman02b23c32014-02-17 17:26:48 -080095 return static_cast<double>(in)
96 / (256.0 /*cpr*/ * 4.0 /*quad*/)
Brian Silverman258349f2014-02-17 21:38:53 -080097 / (18.0 / 48.0 /*encoder gears*/)
98 / (12.0 / 60.0 /*chain reduction*/)
Austin Schuh78d55462014-02-23 01:39:30 -080099 * (M_PI / 180.0)
100 * 2.0 /*TODO(austin): Debug this, encoders read too little*/;
Brian Silverman5b433df2014-02-17 11:57:37 -0800101}
102
Brian Silverman258349f2014-02-17 21:38:53 -0800103double shooter_translate(int32_t in) {
Brian Silverman02b23c32014-02-17 17:26:48 -0800104 return static_cast<double>(in)
105 / (256.0 /*cpr*/ * 4.0 /*quad*/)
106 * 16 /*sprocket teeth*/ * 0.375 /*chain pitch*/
107 * (2.54 / 100.0 /*in to m*/);
Brian Silverman5b433df2014-02-17 11:57:37 -0800108}
109
Brian Silvermanfac5c292014-02-17 15:26:57 -0800110template<typename Structure>
111void CopyHallEffectEdges(Structure *output,
Brian Silverman5b433df2014-02-17 11:57:37 -0800112 const ::bbb::HallEffectEdges &input,
113 State::HallEffectCounters *state) {
114 output->posedge_count = state->posedges.Update(input.posedges);
115 output->negedge_count = state->negedges.Update(input.negedges);
116}
117
118void CopyClawPosition(control_loops::HalfClawPosition *output,
119 const ::bbb::SingleClawPosition &input,
Brian Silverman258349f2014-02-17 21:38:53 -0800120 State::SingleClawState *state,
121 bool reversed) {
Brian Silverman5b433df2014-02-17 11:57:37 -0800122 CopyHallEffectEdges(&output->front, input.front, &state->front);
Brian Silverman258349f2014-02-17 21:38:53 -0800123 output->front.current = input.bools.front;
Brian Silverman5b433df2014-02-17 11:57:37 -0800124 CopyHallEffectEdges(&output->calibration, input.calibration,
125 &state->calibration);
Brian Silverman258349f2014-02-17 21:38:53 -0800126 output->calibration.current = input.bools.calibration;
Brian Silverman5b433df2014-02-17 11:57:37 -0800127 CopyHallEffectEdges(&output->back, input.back, &state->back);
Brian Silverman258349f2014-02-17 21:38:53 -0800128 output->back.current = input.bools.back;
Brian Silverman5b433df2014-02-17 11:57:37 -0800129
Brian Silverman258349f2014-02-17 21:38:53 -0800130 const double multiplier = reversed ? -1.0 : 1.0;
131
132 output->position = multiplier * claw_translate(input.position);
133 output->posedge_value = multiplier * claw_translate(input.posedge_position);
134 output->negedge_value = multiplier * claw_translate(input.negedge_position);
Brian Silverman5b433df2014-02-17 11:57:37 -0800135}
136
Brian Silverman7d16c572014-01-03 20:27:57 -0800137void PacketReceived(const ::bbb::DataStruct *data,
Brian Silverman5b433df2014-02-17 11:57:37 -0800138 const ::aos::time::Time &cape_timestamp,
139 State *state) {
Brian Silverman258349f2014-02-17 21:38:53 -0800140 ::frc971::logging_structs::CapeReading reading_to_log(
141 cape_timestamp.sec(), cape_timestamp.nsec(),
Brian Silvermanf3780f62014-03-14 18:49:50 -0700142 sizeof(*data), sonar_translate(data->main.ultrasonic_pulse_length),
143 data->main.low_left_drive_hall, data->main.high_left_drive_hall,
144 data->main.low_right_drive_hall, data->main.high_right_drive_hall);
Brian Silvermanb4a1f9f2014-02-14 17:59:55 -0800145 LOG_STRUCT(DEBUG, "cape reading", reading_to_log);
Brian Silverman7d16c572014-01-03 20:27:57 -0800146 bool bad_gyro;
Brian Silverman5a0a2ec2014-03-08 12:44:58 -0800147 // TODO(brians): Switch to LogInterval for these things.
Brian Silverman7d16c572014-01-03 20:27:57 -0800148 if (data->uninitialized_gyro) {
149 LOG(DEBUG, "uninitialized gyro\n");
150 bad_gyro = true;
151 } else if (data->zeroing_gyro) {
152 LOG(DEBUG, "zeroing gyro\n");
153 bad_gyro = true;
154 } else if (data->bad_gyro) {
155 LOG(ERROR, "bad gyro\n");
156 bad_gyro = true;
Brian Silverman7d16c572014-01-03 20:27:57 -0800157 } else if (data->old_gyro_reading) {
158 LOG(WARNING, "old/bad gyro reading\n");
159 bad_gyro = true;
160 } else {
161 bad_gyro = false;
162 }
Brian Silverman756f9ff2014-01-17 23:40:23 -0800163
164 if (!bad_gyro) {
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800165 gyro_reading.MakeWithBuilder()
166 .angle(gyro_translate(data->gyro_angle))
Brian Silverman756f9ff2014-01-17 23:40:23 -0800167 .Send();
Brian Silverman7d16c572014-01-03 20:27:57 -0800168 }
Brian Silverman756f9ff2014-01-17 23:40:23 -0800169
Brian Silvermanf482b4c2014-03-17 19:44:20 -0700170 if (data->analog_errors != 0) {
171 LOG(WARNING, "%" PRIu8 " analog errors\n", data->analog_errors);
172 }
173
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800174 other_sensors.MakeWithBuilder()
175 .sonar_distance(sonar_translate(data->main.ultrasonic_pulse_length))
176 .Send();
177
Brian Silverman756f9ff2014-01-17 23:40:23 -0800178 drivetrain.position.MakeWithBuilder()
179 .right_encoder(drivetrain_translate(data->main.right_drive))
180 .left_encoder(-drivetrain_translate(data->main.left_drive))
181 .left_shifter_position(hall_translate(constants::GetValues().left_drive,
Austin Schuh809c2562014-03-02 11:50:19 -0800182 data->main.low_left_drive_hall,
183 data->main.high_left_drive_hall))
184 .right_shifter_position(hall_translate(constants::GetValues().right_drive,
185 data->main.low_right_drive_hall,
186 data->main.high_right_drive_hall))
Brian Silverman56658322014-03-22 16:57:22 -0700187 .battery_voltage(battery_translate(data->main.battery_voltage_high,
188 data->main.battery_voltage_low))
Brian Silverman756f9ff2014-01-17 23:40:23 -0800189 .Send();
Brian Silverman5b433df2014-02-17 11:57:37 -0800190
191 {
192 auto claw_position = control_loops::claw_queue_group.position.MakeMessage();
193 CopyClawPosition(&claw_position->top, data->main.top_claw,
Brian Silverman258349f2014-02-17 21:38:53 -0800194 &state->top_claw, false);
Brian Silverman5b433df2014-02-17 11:57:37 -0800195 CopyClawPosition(&claw_position->bottom, data->main.bottom_claw,
Brian Silverman258349f2014-02-17 21:38:53 -0800196 &state->bottom_claw, true);
Brian Silverman5b433df2014-02-17 11:57:37 -0800197 claw_position.Send();
198 }
199
200 {
201 auto shooter_position =
202 control_loops::shooter_queue_group.position.MakeMessage();
203
Brian Silvermanfac5c292014-02-17 15:26:57 -0800204 shooter_position->plunger = data->main.bools.plunger;
Brian Silverman5b433df2014-02-17 11:57:37 -0800205 CopyHallEffectEdges(&shooter_position->pusher_distal,
206 data->main.pusher_distal, &state->pusher_distal);
207 shooter_position->pusher_distal.current = data->main.bools.pusher_distal;
208 CopyHallEffectEdges(&shooter_position->pusher_proximal,
209 data->main.pusher_proximal, &state->pusher_proximal);
210 shooter_position->pusher_proximal.current =
211 data->main.bools.pusher_proximal;
Brian Silvermanfac5c292014-02-17 15:26:57 -0800212 shooter_position->latch = data->main.bools.latch;
Brian Silverman5b433df2014-02-17 11:57:37 -0800213
214 shooter_position->position = shooter_translate(data->main.shooter_position);
Brian Silvermanfac5c292014-02-17 15:26:57 -0800215 shooter_position->pusher_distal.posedge_value =
216 shooter_translate(data->main.pusher_distal_posedge_position);
217 shooter_position->pusher_proximal.posedge_value =
218 shooter_translate(data->main.pusher_proximal_posedge_position);
Brian Silverman5b433df2014-02-17 11:57:37 -0800219
220 shooter_position.Send();
221 }
Brian Silverman7d16c572014-01-03 20:27:57 -0800222}
223
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700224} // namespace
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700225} // namespace frc971
226
227int main() {
Brian Silverman7d16c572014-01-03 20:27:57 -0800228 ::aos::Init(::bbb::SensorReader::kRelativePriority);
Brian Silvermane364e382014-02-08 21:51:33 -0800229 ::bbb::SensorReader reader("comp");
Brian Silverman5b433df2014-02-17 11:57:37 -0800230 ::frc971::State state;
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700231 while (true) {
Brian Silverman5b433df2014-02-17 11:57:37 -0800232 ::frc971::PacketReceived(reader.ReadPacket(), reader.GetCapeTimestamp(),
233 &state);
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700234 }
235 ::aos::Cleanup();
236}