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