blob: 1cdf201d213c705f24935139402477cc02f06b45 [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 Silverman38111502014-04-10 12:36:26 -07008#include "aos/common/controls/output_check.q.h"
Brian Silverman7d16c572014-01-03 20:27:57 -08009
10#include "bbb/sensor_reader.h"
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070011
12#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Brian Silverman6bf0d3c2014-03-08 12:52:54 -080013#include "frc971/queues/other_sensors.q.h"
Brian Silverman07ec88e2014-12-28 00:13:08 -080014#include "frc971/queues/gyro.q.h"
Brian Silverman6eb51f12013-11-02 14:39:01 -070015#include "frc971/constants.h"
Brian Silvermanb4a1f9f2014-02-14 17:59:55 -080016#include "frc971/queues/to_log.q.h"
Brian Silverman5b433df2014-02-17 11:57:37 -080017#include "frc971/control_loops/shooter/shooter.q.h"
18#include "frc971/control_loops/claw/claw.q.h"
Daniel Pettiaece37f2014-10-25 17:13:44 -070019#include "frc971/shifter_hall_effect.h"
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070020
21#ifndef M_PI
22#define M_PI 3.14159265358979323846
23#endif
24
25using ::frc971::control_loops::drivetrain;
Brian Silverman6bf0d3c2014-03-08 12:52:54 -080026using ::frc971::sensors::other_sensors;
27using ::frc971::sensors::gyro_reading;
Brian Silvermanf4937f62013-10-16 10:32:00 -070028using ::aos::util::WrappingCounter;
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070029
30namespace frc971 {
31namespace {
32
Brian Silverman5b433df2014-02-17 11:57:37 -080033struct State {
34 struct HallEffectCounters {
35 WrappingCounter posedges, negedges;
36 };
37
38 HallEffectCounters plunger, pusher_distal, pusher_proximal, latch;
39
40 struct SingleClawState {
41 HallEffectCounters front, calibration, back;
42 } top_claw, bottom_claw;
43};
44
Brian Silverman6eb51f12013-11-02 14:39:01 -070045double drivetrain_translate(int32_t in) {
Brian Silverman02b23c32014-02-17 17:26:48 -080046 return static_cast<double>(in)
47 / (256.0 /*cpr*/ * 4.0 /*quad*/)
48 * (18.0 / 50.0 /*output stage*/) * (56.0 / 30.0 /*encoder gears*/)
49 // * constants::GetValues().drivetrain_encoder_ratio
50 * (3.5 /*wheel diameter*/ * 2.54 / 100.0 * M_PI);
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070051}
52
Brian Silverman3c469b02014-03-30 13:31:40 -070053static const double kVcc = 5.15;
54
Brian Silverman74acd622013-10-26 14:47:14 -070055// Translates values from the ADC into voltage.
Brian Silverman6eb51f12013-11-02 14:39:01 -070056double adc_translate(uint16_t in) {
Brian Silverman051f1b82014-03-28 17:02:17 -070057 if (false) {
Brian Silverman3c469b02014-03-30 13:31:40 -070058 // This is the simple theoretical math.
59 static const uint16_t kMaximumValue = 0x3FF;
Brian Silverman051f1b82014-03-28 17:02:17 -070060 static const double kR1 = 5, kR2 = 6.65;
61 const double raw =
62 (kVcc * static_cast<double>(in) / static_cast<double>(kMaximumValue));
63 return (raw * (kR1 + kR2) - (kVcc / 2) * kR2) / kR1;
64 } else {
65 // This is from a linear regression calculated with some actual data points.
66 static const double kM = 0.012133, kB = -3.6813;
Brian Silverman3c469b02014-03-30 13:31:40 -070067 return static_cast<double>(in) * kM + kB;
Brian Silverman051f1b82014-03-28 17:02:17 -070068 }
Brian Silverman74acd622013-10-26 14:47:14 -070069}
70
Brian Silverman56658322014-03-22 16:57:22 -070071double battery_translate(uint16_t in_high, uint16_t in_low) {
72 const double high = adc_translate(in_high), low = adc_translate(in_low);
73 static const double kDividerBig = 5.55, kDividerSmall = 2.66;
Brian Silverman56658322014-03-22 16:57:22 -070074 return (high - low) * (kDividerBig + kDividerSmall) / kDividerSmall +
Brian Silverman3c469b02014-03-30 13:31:40 -070075 kDividerBig / kDividerSmall * kVcc;
76}
77
78double gyro_translate(int64_t in) {
79 return in / 16.0 / 1000.0 / (180.0 / M_PI);
Brian Silverman6eb51f12013-11-02 14:39:01 -070080}
81
Brian Silverman5a0a2ec2014-03-08 12:44:58 -080082double sonar_translate(uint32_t in) {
Brian Silverman0bca3ba2014-03-26 14:07:55 -070083 return static_cast<double>(in) * 10.0 /*us/tick*/ / 147.0 /*in/us*/ *
84 0.0254 /*m/in*/;
Brian Silverman5a0a2ec2014-03-08 12:44:58 -080085}
86
Austin Schuh809c2562014-03-02 11:50:19 -080087double hall_translate(const constants::ShifterHallEffect &k, uint16_t in_low,
88 uint16_t in_high) {
89 const double low_ratio =
90 0.5 * (in_low - static_cast<double>(k.low_gear_low)) /
91 static_cast<double>(k.low_gear_middle - k.low_gear_low);
92 const double high_ratio =
93 0.5 + 0.5 * (in_high - static_cast<double>(k.high_gear_middle)) /
94 static_cast<double>(k.high_gear_high - k.high_gear_middle);
95
96 // Return low when we are below 1/2, and high when we are above 1/2.
97 if (low_ratio + high_ratio < 1.0) {
98 return low_ratio;
99 } else {
100 return high_ratio;
101 }
Brian Silverman1ba46c72013-10-31 16:05:57 -0700102}
103
Brian Silverman258349f2014-02-17 21:38:53 -0800104double claw_translate(int32_t in) {
Brian Silverman02b23c32014-02-17 17:26:48 -0800105 return static_cast<double>(in)
106 / (256.0 /*cpr*/ * 4.0 /*quad*/)
Brian Silverman258349f2014-02-17 21:38:53 -0800107 / (18.0 / 48.0 /*encoder gears*/)
108 / (12.0 / 60.0 /*chain reduction*/)
Austin Schuh78d55462014-02-23 01:39:30 -0800109 * (M_PI / 180.0)
110 * 2.0 /*TODO(austin): Debug this, encoders read too little*/;
Brian Silverman5b433df2014-02-17 11:57:37 -0800111}
112
Brian Silverman258349f2014-02-17 21:38:53 -0800113double shooter_translate(int32_t in) {
Brian Silverman02b23c32014-02-17 17:26:48 -0800114 return static_cast<double>(in)
115 / (256.0 /*cpr*/ * 4.0 /*quad*/)
116 * 16 /*sprocket teeth*/ * 0.375 /*chain pitch*/
117 * (2.54 / 100.0 /*in to m*/);
Brian Silverman5b433df2014-02-17 11:57:37 -0800118}
119
Brian Silvermanfac5c292014-02-17 15:26:57 -0800120template<typename Structure>
121void CopyHallEffectEdges(Structure *output,
Brian Silverman5b433df2014-02-17 11:57:37 -0800122 const ::bbb::HallEffectEdges &input,
123 State::HallEffectCounters *state) {
124 output->posedge_count = state->posedges.Update(input.posedges);
125 output->negedge_count = state->negedges.Update(input.negedges);
126}
127
128void CopyClawPosition(control_loops::HalfClawPosition *output,
129 const ::bbb::SingleClawPosition &input,
Brian Silverman258349f2014-02-17 21:38:53 -0800130 State::SingleClawState *state,
131 bool reversed) {
Brian Silverman5b433df2014-02-17 11:57:37 -0800132 CopyHallEffectEdges(&output->front, input.front, &state->front);
Brian Silverman258349f2014-02-17 21:38:53 -0800133 output->front.current = input.bools.front;
Brian Silverman5b433df2014-02-17 11:57:37 -0800134 CopyHallEffectEdges(&output->calibration, input.calibration,
135 &state->calibration);
Brian Silverman258349f2014-02-17 21:38:53 -0800136 output->calibration.current = input.bools.calibration;
Brian Silverman5b433df2014-02-17 11:57:37 -0800137 CopyHallEffectEdges(&output->back, input.back, &state->back);
Brian Silverman258349f2014-02-17 21:38:53 -0800138 output->back.current = input.bools.back;
Brian Silverman5b433df2014-02-17 11:57:37 -0800139
Brian Silverman258349f2014-02-17 21:38:53 -0800140 const double multiplier = reversed ? -1.0 : 1.0;
141
142 output->position = multiplier * claw_translate(input.position);
143 output->posedge_value = multiplier * claw_translate(input.posedge_position);
144 output->negedge_value = multiplier * claw_translate(input.negedge_position);
Brian Silverman5b433df2014-02-17 11:57:37 -0800145}
146
Brian Silverman7d16c572014-01-03 20:27:57 -0800147void PacketReceived(const ::bbb::DataStruct *data,
Brian Silverman5b433df2014-02-17 11:57:37 -0800148 const ::aos::time::Time &cape_timestamp,
149 State *state) {
Brian Silvermanb407c672014-04-09 11:58:37 -0700150 ::aos::time::TimeFreezer time_freezer;
151
Brian Silverman258349f2014-02-17 21:38:53 -0800152 ::frc971::logging_structs::CapeReading reading_to_log(
Brian Silverman96e6d5a2014-03-24 15:55:40 -0700153 cape_timestamp, static_cast<uint16_t>(sizeof(*data)),
154 sonar_translate(data->main.ultrasonic_pulse_length),
Brian Silvermanfa577e42014-04-19 12:03:00 -0700155 adc_translate(data->main.auto_mode_selector),
Brian Silvermanf3780f62014-03-14 18:49:50 -0700156 data->main.low_left_drive_hall, data->main.high_left_drive_hall,
157 data->main.low_right_drive_hall, data->main.high_right_drive_hall);
Brian Silvermanb4a1f9f2014-02-14 17:59:55 -0800158 LOG_STRUCT(DEBUG, "cape reading", reading_to_log);
Brian Silverman7d16c572014-01-03 20:27:57 -0800159 bool bad_gyro;
Brian Silverman5a0a2ec2014-03-08 12:44:58 -0800160 // TODO(brians): Switch to LogInterval for these things.
Brian Silverman7d16c572014-01-03 20:27:57 -0800161 if (data->uninitialized_gyro) {
162 LOG(DEBUG, "uninitialized gyro\n");
163 bad_gyro = true;
164 } else if (data->zeroing_gyro) {
165 LOG(DEBUG, "zeroing gyro\n");
166 bad_gyro = true;
167 } else if (data->bad_gyro) {
168 LOG(ERROR, "bad gyro\n");
169 bad_gyro = true;
Brian Silverman7d16c572014-01-03 20:27:57 -0800170 } else if (data->old_gyro_reading) {
171 LOG(WARNING, "old/bad gyro reading\n");
172 bad_gyro = true;
173 } else {
174 bad_gyro = false;
175 }
Brian Silverman756f9ff2014-01-17 23:40:23 -0800176
177 if (!bad_gyro) {
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800178 gyro_reading.MakeWithBuilder()
179 .angle(gyro_translate(data->gyro_angle))
Brian Silverman756f9ff2014-01-17 23:40:23 -0800180 .Send();
Brian Silverman7d16c572014-01-03 20:27:57 -0800181 }
Brian Silverman756f9ff2014-01-17 23:40:23 -0800182
Brian Silvermanf482b4c2014-03-17 19:44:20 -0700183 if (data->analog_errors != 0) {
184 LOG(WARNING, "%" PRIu8 " analog errors\n", data->analog_errors);
185 }
186
Brian Silverman1b7fe842014-04-01 14:25:18 -0700187 if (data->main.output_check_pulse_length != 0) {
Brian Silverman38111502014-04-10 12:36:26 -0700188 auto message = ::aos::controls::output_check_received.MakeMessage();
Brian Silvermanb3adec12014-04-01 15:23:45 -0700189 // TODO(brians): Fix this math to match what the cRIO actually does.
190 // It's close but not quite right.
Brian Silverman1b7fe842014-04-01 14:25:18 -0700191 message->pulse_length =
Brian Silvermanb3adec12014-04-01 15:23:45 -0700192 static_cast<double>(data->main.output_check_pulse_length) / 10000.0;
Brian Silverman1b7fe842014-04-01 14:25:18 -0700193 if (message->pulse_length > 2.7) {
194 LOG(WARNING, "insane PWM pulse length %fms\n", message->pulse_length);
195 } else {
196 message->pwm_value = (message->pulse_length - 0.5) / 2.0 * 255.0 + 0.5;
197 LOG_STRUCT(DEBUG, "received", *message);
198 message.Send();
199 }
200 }
201
Brian Silvermand8f403a2014-12-13 19:12:04 -0500202 // Only send them out (approximately) every 10ms because the loops are now
203 // clocked off of this.
204 static int i = 0;
205 ++i;
206 if (i < 5) {
207 LOG(DEBUG, "skipping\n");
208 return;
209 } else {
210 i = 0;
211 }
212
Brian Silverman6bf0d3c2014-03-08 12:52:54 -0800213 other_sensors.MakeWithBuilder()
214 .sonar_distance(sonar_translate(data->main.ultrasonic_pulse_length))
215 .Send();
216
Brian Silverman45ceeb52014-04-17 15:15:18 -0700217 ::frc971::sensors::auto_mode.MakeWithBuilder()
218 .voltage(adc_translate(data->main.auto_mode_selector))
219 .Send();
220
Brian Silverman756f9ff2014-01-17 23:40:23 -0800221 drivetrain.position.MakeWithBuilder()
222 .right_encoder(drivetrain_translate(data->main.right_drive))
223 .left_encoder(-drivetrain_translate(data->main.left_drive))
224 .left_shifter_position(hall_translate(constants::GetValues().left_drive,
Austin Schuh809c2562014-03-02 11:50:19 -0800225 data->main.low_left_drive_hall,
226 data->main.high_left_drive_hall))
227 .right_shifter_position(hall_translate(constants::GetValues().right_drive,
228 data->main.low_right_drive_hall,
229 data->main.high_right_drive_hall))
Brian Silverman56658322014-03-22 16:57:22 -0700230 .battery_voltage(battery_translate(data->main.battery_voltage_high,
231 data->main.battery_voltage_low))
Brian Silverman756f9ff2014-01-17 23:40:23 -0800232 .Send();
Brian Silverman5b433df2014-02-17 11:57:37 -0800233
234 {
235 auto claw_position = control_loops::claw_queue_group.position.MakeMessage();
236 CopyClawPosition(&claw_position->top, data->main.top_claw,
Brian Silverman258349f2014-02-17 21:38:53 -0800237 &state->top_claw, false);
Brian Silverman5b433df2014-02-17 11:57:37 -0800238 CopyClawPosition(&claw_position->bottom, data->main.bottom_claw,
Brian Silverman258349f2014-02-17 21:38:53 -0800239 &state->bottom_claw, true);
Brian Silverman5b433df2014-02-17 11:57:37 -0800240 claw_position.Send();
241 }
242
243 {
244 auto shooter_position =
245 control_loops::shooter_queue_group.position.MakeMessage();
246
Brian Silvermanfac5c292014-02-17 15:26:57 -0800247 shooter_position->plunger = data->main.bools.plunger;
Brian Silverman5b433df2014-02-17 11:57:37 -0800248 CopyHallEffectEdges(&shooter_position->pusher_distal,
249 data->main.pusher_distal, &state->pusher_distal);
250 shooter_position->pusher_distal.current = data->main.bools.pusher_distal;
251 CopyHallEffectEdges(&shooter_position->pusher_proximal,
252 data->main.pusher_proximal, &state->pusher_proximal);
253 shooter_position->pusher_proximal.current =
254 data->main.bools.pusher_proximal;
Brian Silvermanfac5c292014-02-17 15:26:57 -0800255 shooter_position->latch = data->main.bools.latch;
Brian Silverman5b433df2014-02-17 11:57:37 -0800256
257 shooter_position->position = shooter_translate(data->main.shooter_position);
Brian Silvermanfac5c292014-02-17 15:26:57 -0800258 shooter_position->pusher_distal.posedge_value =
259 shooter_translate(data->main.pusher_distal_posedge_position);
260 shooter_position->pusher_proximal.posedge_value =
261 shooter_translate(data->main.pusher_proximal_posedge_position);
Brian Silverman5b433df2014-02-17 11:57:37 -0800262
263 shooter_position.Send();
264 }
Brian Silverman7d16c572014-01-03 20:27:57 -0800265}
266
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700267} // namespace
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700268} // namespace frc971
269
270int main() {
Brian Silverman7d16c572014-01-03 20:27:57 -0800271 ::aos::Init(::bbb::SensorReader::kRelativePriority);
Brian Silvermane364e382014-02-08 21:51:33 -0800272 ::bbb::SensorReader reader("comp");
Brian Silverman5b433df2014-02-17 11:57:37 -0800273 ::frc971::State state;
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700274 while (true) {
Brian Silverman5b433df2014-02-17 11:57:37 -0800275 ::frc971::PacketReceived(reader.ReadPacket(), reader.GetCapeTimestamp(),
276 &state);
Brian Silverman2e0dcfd2013-03-30 22:44:40 -0700277 }
278 ::aos::Cleanup();
279}