blob: b241f508d6f52a96aba34dd5df02f01562e2d9f1 [file] [log] [blame]
Brian Silverman3204dd82013-03-12 18:42:01 -07001#include "frc971/input/sensor_packer.h"
2
3#include <arpa/inet.h>
4
5#include "aos/common/inttypes.h"
Brian Silvermanc6aa51a2013-03-15 17:06:27 -07006#include "aos/common/time.h"
7
8#include "frc971/control_loops/index/index.h"
Brian Silverman3204dd82013-03-12 18:42:01 -07009
Brian Silverman687f5242013-03-16 13:57:59 -070010using ::std::unique_ptr;
11namespace hardware = ::aos::crio::hardware;
Brian Silverman3204dd82013-03-12 18:42:01 -070012
13namespace frc971 {
14
Brian Silverman687f5242013-03-16 13:57:59 -070015SensorPacker::SensorPacker()
16 : drive_left_counter_(::hardware::Counter::Create(
17 unique_ptr< ::hardware::DigitalSource>(
18 new ::hardware::DigitalInput(3)),
19 unique_ptr< ::hardware::DigitalSource>(
20 new ::hardware::DigitalInput(4)),
21 ::CounterBase::EncodingType::k4X)),
22 drive_right_counter_(::hardware::Counter::Create(
23 unique_ptr< ::hardware::DigitalSource>(
24 new ::hardware::DigitalInput(1)),
25 unique_ptr< ::hardware::DigitalSource>(
26 new ::hardware::DigitalInput(2)),
27 ::CounterBase::EncodingType::k4X)),
28
29 wrist_counter_(::hardware::Counter::Create(
30 unique_ptr< ::hardware::DigitalSource>(
31 new ::hardware::DigitalInput(5)),
32 unique_ptr< ::hardware::DigitalSource>(
33 new ::hardware::DigitalInput(6)),
34 ::CounterBase::EncodingType::k4X)),
35 wrist_hall_effect_(new ::hardware::AnalogTriggerOutput(
36 unique_ptr< ::AnalogTrigger>(
37 new ::AnalogTrigger(1)),
38 ::AnalogTriggerOutput::Type::kState)),
39 wrist_notifier_(ReadEncoder, wrist_hall_effect_->source(),
40 new EncoderReadData(wrist_counter_.get(),
41 &wrist_edge_position_, &wrist_sync_)),
42
43 angle_adjust_counter_(::hardware::Counter::Create(
44 unique_ptr< ::hardware::DigitalSource>(
45 new ::hardware::DigitalInput(7)),
46 unique_ptr< ::hardware::DigitalSource>(
47 new ::hardware::DigitalInput(8)),
48 ::CounterBase::EncodingType::k2X)),
49 angle_adjust_middle_hall_effect_(new ::hardware::AnalogTriggerOutput(
50 unique_ptr< ::AnalogTrigger>(
51 new ::AnalogTrigger(5)),
52 ::AnalogTriggerOutput::Type::kState)),
53 angle_adjust_bottom_hall_effect_(new ::hardware::AnalogTriggerOutput(
54 unique_ptr< ::AnalogTrigger>(
55 new ::AnalogTrigger(3)),
56 ::AnalogTriggerOutput::Type::kState)),
57 angle_adjust_middle_notifier_(
58 ReadEncoder,
59 angle_adjust_middle_hall_effect_->source(),
60 new EncoderReadData(angle_adjust_counter_.get(),
61 &angle_adjust_middle_edge_position_,
62 &angle_adjust_sync_)),
63 angle_adjust_bottom_notifier_(
64 ReadEncoder,
65 angle_adjust_bottom_hall_effect_->source(),
66 new EncoderReadData(angle_adjust_counter_.get(),
67 &angle_adjust_bottom_edge_position_,
68 &angle_adjust_sync_)),
69
70 shooter_counter_(::hardware::Counter::Create(
71 unique_ptr< ::hardware::DigitalSource>(
72 new ::hardware::DigitalInput(9)),
73 unique_ptr< ::hardware::DigitalSource>(
74 new ::hardware::DigitalInput(10)),
75 ::CounterBase::EncodingType::k4X)),
76
77 index_counter_(new ::hardware::CounterCounter(
78 unique_ptr< ::hardware::DigitalSource>(
79 new ::hardware::DigitalInput(11)),
80 unique_ptr< ::hardware::DigitalSource>(
81 new ::hardware::DigitalInput(12)),
82 ::CounterBase::EncodingType::k2X)),
83 top_disc_edge_task_("TopDsc",
84 reinterpret_cast<FUNCPTR>(
85 StaticTopDiscEdgeReader),
86 96),
87 top_disc_(new ::AnalogTrigger(2)),
88 top_disc_posedge_output_(new ::hardware::AnalogTriggerOutput(
89 unique_ptr< ::AnalogTriggerOutput>(
90 top_disc_->CreateOutput(
91 ::AnalogTriggerOutput::Type::kState)))),
92 top_disc_negedge_output_(new ::hardware::AnalogTriggerOutput(
93 unique_ptr< ::AnalogTriggerOutput>(
94 top_disc_->CreateOutput(
95 ::AnalogTriggerOutput::Type::kState)))),
96 top_disc_posedge_count_(0),
97 top_disc_negedge_count_(0),
98 top_disc_posedge_position_(0),
99 top_disc_negedge_position_(0),
100 bottom_disc_edge_task_("BotDsc",
101 reinterpret_cast<FUNCPTR>(
102 StaticBottomDiscEdgeReader),
103 96),
104 bottom_disc_(new ::hardware::DigitalInput(13)),
105 bottom_disc_posedge_count_(0),
106 bottom_disc_negedge_count_(0),
107 bottom_disc_negedge_wait_count_(0),
108 bottom_disc_negedge_wait_position_(0) {
109 // 7, 8 = angle, down = -
110 // 5, 6 = wrist, down = +
111 // drive = flipped, l/r = flipped
112 // 9, 10 = angle adjust, out = -
113 // 11, 12 = indexing, up = -
114 // positive result should be up in the end
115 drive_left_counter_->counter_base()->Start();
116 drive_right_counter_->counter_base()->Start();
117
118 shooter_counter_->counter_base()->Start();
119
120 wrist_counter_->counter_base()->Start();
121 wrist_hall_effect_->source()->SetUpSourceEdge(true, true);
122 wrist_notifier_.Start();
123
124 angle_adjust_counter_->counter_base()->Start();
125 angle_adjust_middle_hall_effect_->source()->SetUpSourceEdge(true, true);
126 angle_adjust_bottom_hall_effect_->source()->SetUpSourceEdge(true, true);
127 angle_adjust_middle_notifier_.Start();
128 angle_adjust_bottom_notifier_.Start();
129
130 index_counter_->counter()->SetExternalDirectionMode();
131 index_counter_->counter_base()->Start();
132 top_disc_->SetLimitsVoltage(
133 ::hardware::AnalogTriggerOutput::kDefaultLowerVoltage,
134 ::hardware::AnalogTriggerOutput::kDefaultUpperVoltage);
135 top_disc_posedge_output_->source()->RequestInterrupts();
136 top_disc_posedge_output_->source()->SetUpSourceEdge(false, true);
137 top_disc_negedge_output_->source()->RequestInterrupts();
138 top_disc_negedge_output_->source()->SetUpSourceEdge(true, false);
139 top_disc_edge_task_.Start(reinterpret_cast<uintptr_t>(this));
140 // TODO(brians) change this to the correct constant
141 aos::time::SleepFor(aos::time::Time::InSeconds(0.25));
142 bottom_disc_->source()->RequestInterrupts();
143 bottom_disc_->source()->SetUpSourceEdge(true, true);
144 bottom_disc_edge_task_.Start(reinterpret_cast<uintptr_t>(this));
145 // TODO(brians) change this to the correct constant
146 aos::time::SleepFor(aos::time::Time::InSeconds(0.25));
Brian Silverman3204dd82013-03-12 18:42:01 -0700147
148 printf("frc971::SensorPacker started\n");
149}
150
Brian Silvermanc6aa51a2013-03-15 17:06:27 -0700151void SensorPacker::ReadEncoder(EncoderReadData *data) {
152 int32_t value = data->counter->Get();
153 {
154 ::aos::MutexLocker locker(data->sync);
155 *data->output = value;
156 }
157}
158
159void SensorPacker::TopDiscEdgeReader() {
160 while (true) {
161 top_disc_posedge_output_->source()->
162 WaitForInterrupt(kInterruptTimeout);
163 int32_t position = index_counter_->Get();
164 {
165 aos::MutexLocker locker(&top_disc_edge_sync_);
166 top_disc_posedge_position_ = position;
167 ++top_disc_posedge_count_;
168 }
169 top_disc_negedge_output_->source()->
170 WaitForInterrupt(kInterruptTimeout);
171 position = index_counter_->Get();
172 {
173 aos::MutexLocker locker(&top_disc_edge_sync_);
174 top_disc_negedge_position_ = position;
175 ++top_disc_negedge_count_;
176 }
177 }
178}
179
180void SensorPacker::BottomDiscEdgeReader() {
181 static const aos::time::Time kBottomDiscNegedgeSleep =
182 aos::time::Time::InSeconds(
183 control_loops::IndexMotor::kBottomDiscIndexDelay);
184 while (true) {
185 bottom_disc_->source()->WaitForInterrupt(kInterruptTimeout);
186 if (bottom_disc_->Get()) {
187 aos::time::Time start = aos::time::Time::Now();
188 {
189 aos::MutexLocker locker(&bottom_disc_edge_sync_);
190 ++bottom_disc_negedge_count_;
191 }
192 aos::time::SleepUntil(start + kBottomDiscNegedgeSleep);
193 int32_t position = index_counter_->Get();
194 {
195 aos::MutexLocker locker(&bottom_disc_edge_sync_);
196 bottom_disc_negedge_wait_position_ = position;
197 ++bottom_disc_negedge_wait_count_;
198 }
199 } else {
200 {
201 aos::MutexLocker locker(&bottom_disc_edge_sync_);
202 ++bottom_disc_posedge_count_;
203 }
204 }
205 }
206}
207
Brian Silverman3204dd82013-03-12 18:42:01 -0700208void SensorPacker::PackInto(sensor_values *values) {
Brian Silverman687f5242013-03-16 13:57:59 -0700209 values->shooter_encoder = shooter_counter_->Get();
210
211 values->drive_left_encoder = htonl(-drive_left_counter_->Get());
212 values->drive_right_encoder = -htonl(-drive_right_counter_->Get());
213
214 {
215 aos::MutexLocker locker(&wrist_sync_);
216 values->wrist_position = wrist_counter_->Get();
217 values->wrist_edge_position = wrist_edge_position_;
218 values->wrist_hall_effect = wrist_hall_effect_->Get();
219 }
220
221 {
222 aos::MutexLocker locker(&angle_adjust_sync_);
223 values->angle_adjust_position = angle_adjust_counter_->Get();
224 values->angle_adjust_middle_edge_position =
225 angle_adjust_middle_edge_position_;
226 values->angle_adjust_bottom_edge_position =
227 angle_adjust_bottom_edge_position_;
228 values->angle_adjust_middle_hall_effect =
229 angle_adjust_middle_hall_effect_->Get();
230 values->angle_adjust_bottom_hall_effect =
231 angle_adjust_bottom_hall_effect_->Get();
232 }
233
234 values->index_encoder = index_counter_->Get();
235 {
236 aos::MutexLocker locker(&top_disc_edge_sync_);
237 values->top_disc_posedge_count = top_disc_posedge_count_;
238 values->top_disc_negedge_count = top_disc_negedge_count_;
239 values->top_disc_posedge_position = top_disc_posedge_position_;
240 values->top_disc_negedge_position = top_disc_negedge_position_;
241 values->top_disc = top_disc_->GetTriggerState();
242 }
243 {
244 aos::MutexLocker locker(&bottom_disc_edge_sync_);
245 values->bottom_disc_negedge_wait_position =
246 bottom_disc_negedge_wait_position_;
247 values->bottom_disc_negedge_count = bottom_disc_negedge_count_;
248 values->bottom_disc_negedge_wait_count = bottom_disc_negedge_wait_count_;
249 values->bottom_disc_posedge_count = bottom_disc_posedge_count_;
250 values->bottom_disc = bottom_disc_->Get();
251 }
Brian Silverman3204dd82013-03-12 18:42:01 -0700252}
253
254} // namespace frc971