Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 1 | #include "y2014/control_loops/claw/claw.q.h" |
| 2 | #include "frc971/control_loops/control_loops.q.h" |
| 3 | |
John Park | 398c74a | 2018-10-20 21:17:39 -0700 | [diff] [blame] | 4 | #include "aos/init.h" |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 5 | #include "y2014/constants.h" |
| 6 | |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 7 | namespace y2014 { |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 8 | |
| 9 | typedef constants::Values::Claws Claws; |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 10 | using ::frc971::HallEffectStruct; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 11 | |
| 12 | class Sensor { |
| 13 | public: |
| 14 | Sensor(const double start_position, |
| 15 | const HallEffectStruct &initial_hall_effect) |
| 16 | : start_position_(start_position), |
| 17 | last_hall_effect_(initial_hall_effect), |
| 18 | last_posedge_count_(initial_hall_effect.posedge_count), |
| 19 | last_negedge_count_(initial_hall_effect.negedge_count) { |
| 20 | last_on_min_position_ = start_position; |
| 21 | last_on_max_position_ = start_position; |
| 22 | last_off_min_position_ = start_position; |
| 23 | last_off_max_position_ = start_position; |
| 24 | } |
| 25 | |
| 26 | bool DoGetPositionOfEdge( |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 27 | const ::y2014::control_loops::HalfClawPosition &claw_position, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 28 | const HallEffectStruct &hall_effect, Claws::AnglePair *limits) { |
| 29 | bool print = false; |
| 30 | |
| 31 | if (hall_effect.posedge_count != last_posedge_count_) { |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 32 | const double avg_off_position = |
| 33 | (last_off_min_position_ + last_off_max_position_) / 2.0; |
| 34 | if (hall_effect.posedge_value < avg_off_position) { |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 35 | printf("Posedge upper current %f posedge %f avg_off %f [%f, %f]\n", |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 36 | claw_position.position, hall_effect.posedge_value, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 37 | avg_off_position, last_off_min_position_, |
| 38 | last_off_max_position_); |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 39 | limits->upper_decreasing_angle = |
| 40 | hall_effect.posedge_value - start_position_; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 41 | } else { |
| 42 | printf("Posedge lower current %f posedge %f avg_off %f [%f, %f]\n", |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 43 | claw_position.position, hall_effect.posedge_value, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 44 | avg_off_position, last_off_min_position_, |
| 45 | last_off_max_position_); |
| 46 | limits->lower_angle = |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 47 | hall_effect.posedge_value - start_position_; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 48 | } |
| 49 | print = true; |
| 50 | } |
| 51 | if (hall_effect.negedge_count != last_negedge_count_) { |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 52 | const double avg_on_position = |
| 53 | (last_on_min_position_ + last_on_max_position_) / 2.0; |
| 54 | if (hall_effect.negedge_value > avg_on_position) { |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 55 | printf("Negedge upper current %f negedge %f last_on %f [%f, %f]\n", |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 56 | claw_position.position, hall_effect.negedge_value, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 57 | avg_on_position, last_on_min_position_, |
| 58 | last_on_max_position_); |
| 59 | limits->upper_angle = |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 60 | hall_effect.negedge_value - start_position_; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 61 | } else { |
| 62 | printf("Negedge lower current %f negedge %f last_on %f [%f, %f]\n", |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 63 | claw_position.position, hall_effect.negedge_value, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 64 | avg_on_position, last_on_min_position_, |
| 65 | last_on_max_position_); |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 66 | limits->lower_decreasing_angle = |
| 67 | hall_effect.negedge_value - start_position_; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 68 | } |
| 69 | print = true; |
| 70 | } |
| 71 | |
| 72 | if (hall_effect.current) { |
| 73 | if (!last_hall_effect_.current) { |
| 74 | last_on_min_position_ = last_on_max_position_ = claw_position.position; |
| 75 | } else { |
| 76 | last_on_min_position_ = |
| 77 | ::std::min(claw_position.position, last_on_min_position_); |
| 78 | last_on_max_position_ = |
| 79 | ::std::max(claw_position.position, last_on_max_position_); |
| 80 | } |
| 81 | } else { |
| 82 | if (last_hall_effect_.current) { |
Brian Silverman | d3efb18 | 2015-05-13 23:04:29 -0400 | [diff] [blame] | 83 | last_off_min_position_ = last_off_max_position_ = |
| 84 | claw_position.position; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 85 | } else { |
| 86 | last_off_min_position_ = |
| 87 | ::std::min(claw_position.position, last_off_min_position_); |
| 88 | last_off_max_position_ = |
| 89 | ::std::max(claw_position.position, last_off_max_position_); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | last_hall_effect_ = hall_effect; |
| 94 | last_posedge_count_ = hall_effect.posedge_count; |
| 95 | last_negedge_count_ = hall_effect.negedge_count; |
| 96 | |
| 97 | return print; |
| 98 | } |
| 99 | |
| 100 | private: |
| 101 | const double start_position_; |
| 102 | HallEffectStruct last_hall_effect_; |
| 103 | int32_t last_posedge_count_; |
| 104 | int32_t last_negedge_count_; |
| 105 | double last_on_min_position_; |
| 106 | double last_off_min_position_; |
| 107 | double last_on_max_position_; |
| 108 | double last_off_max_position_; |
| 109 | }; |
| 110 | |
| 111 | class ClawSensors { |
| 112 | public: |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 113 | ClawSensors( |
| 114 | const double start_position, |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 115 | const ::y2014::control_loops::HalfClawPosition &initial_claw_position) |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 116 | : start_position_(start_position), |
| 117 | front_(start_position, initial_claw_position.front), |
| 118 | calibration_(start_position, initial_claw_position.calibration), |
| 119 | back_(start_position, initial_claw_position.back) {} |
| 120 | |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 121 | bool GetPositionOfEdge( |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 122 | const ::y2014::control_loops::HalfClawPosition &claw_position, |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 123 | Claws::Claw *claw) { |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 124 | bool print = false; |
| 125 | if (front_.DoGetPositionOfEdge(claw_position, |
| 126 | claw_position.front, &claw->front)) { |
| 127 | print = true; |
| 128 | } else if (calibration_.DoGetPositionOfEdge(claw_position, |
| 129 | claw_position.calibration, |
| 130 | &claw->calibration)) { |
| 131 | print = true; |
| 132 | } else if (back_.DoGetPositionOfEdge(claw_position, |
| 133 | claw_position.back, &claw->back)) { |
| 134 | print = true; |
| 135 | } |
| 136 | |
| 137 | double position = claw_position.position - start_position_; |
| 138 | |
| 139 | if (position > claw->upper_limit) { |
| 140 | claw->upper_hard_limit = claw->upper_limit = position; |
| 141 | print = true; |
| 142 | } |
| 143 | if (position < claw->lower_limit) { |
| 144 | claw->lower_hard_limit = claw->lower_limit = position; |
| 145 | print = true; |
| 146 | } |
| 147 | return print; |
| 148 | } |
| 149 | |
| 150 | private: |
| 151 | const double start_position_; |
| 152 | Sensor front_; |
| 153 | Sensor calibration_; |
| 154 | Sensor back_; |
| 155 | }; |
| 156 | |
| 157 | int Main() { |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 158 | ::y2014::control_loops::claw_queue.position.FetchNextBlocking(); |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 159 | |
| 160 | const double top_start_position = |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 161 | ::y2014::control_loops::claw_queue.position->top.position; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 162 | const double bottom_start_position = |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 163 | ::y2014::control_loops::claw_queue.position->bottom.position; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 164 | |
| 165 | ClawSensors top(top_start_position, |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 166 | ::y2014::control_loops::claw_queue.position->top); |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 167 | ClawSensors bottom(bottom_start_position, |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 168 | ::y2014::control_loops::claw_queue.position->bottom); |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 169 | |
| 170 | Claws limits; |
| 171 | |
| 172 | limits.claw_zeroing_off_speed = 0.5; |
| 173 | limits.claw_zeroing_speed = 0.1; |
| 174 | limits.claw_zeroing_separation = 0.1; |
| 175 | |
| 176 | // claw separation that would be considered a collision |
| 177 | limits.claw_min_separation = 0.0; |
| 178 | limits.claw_max_separation = 0.0; |
| 179 | |
| 180 | // We should never get closer/farther than these. |
| 181 | limits.soft_min_separation = 0.0; |
| 182 | limits.soft_max_separation = 0.0; |
| 183 | |
| 184 | limits.upper_claw.lower_hard_limit = 0.0; |
| 185 | limits.upper_claw.upper_hard_limit = 0.0; |
| 186 | limits.upper_claw.lower_limit = 0.0; |
| 187 | limits.upper_claw.upper_limit = 0.0; |
| 188 | limits.upper_claw.front.lower_angle = 0.0; |
| 189 | limits.upper_claw.front.upper_angle = 0.0; |
| 190 | limits.upper_claw.front.lower_decreasing_angle = 0.0; |
| 191 | limits.upper_claw.front.upper_decreasing_angle = 0.0; |
| 192 | limits.upper_claw.calibration.lower_angle = 0.0; |
| 193 | limits.upper_claw.calibration.upper_angle = 0.0; |
| 194 | limits.upper_claw.calibration.lower_decreasing_angle = 0.0; |
| 195 | limits.upper_claw.calibration.upper_decreasing_angle = 0.0; |
| 196 | limits.upper_claw.back.lower_angle = 0.0; |
| 197 | limits.upper_claw.back.upper_angle = 0.0; |
| 198 | limits.upper_claw.back.lower_decreasing_angle = 0.0; |
| 199 | limits.upper_claw.back.upper_decreasing_angle = 0.0; |
| 200 | |
| 201 | limits.lower_claw.lower_hard_limit = 0.0; |
| 202 | limits.lower_claw.upper_hard_limit = 0.0; |
| 203 | limits.lower_claw.lower_limit = 0.0; |
| 204 | limits.lower_claw.upper_limit = 0.0; |
| 205 | limits.lower_claw.front.lower_angle = 0.0; |
| 206 | limits.lower_claw.front.upper_angle = 0.0; |
| 207 | limits.lower_claw.front.lower_decreasing_angle = 0.0; |
| 208 | limits.lower_claw.front.upper_decreasing_angle = 0.0; |
| 209 | limits.lower_claw.calibration.lower_angle = 0.0; |
| 210 | limits.lower_claw.calibration.upper_angle = 0.0; |
| 211 | limits.lower_claw.calibration.lower_decreasing_angle = 0.0; |
| 212 | limits.lower_claw.calibration.upper_decreasing_angle = 0.0; |
| 213 | limits.lower_claw.back.lower_angle = 0.0; |
| 214 | limits.lower_claw.back.upper_angle = 0.0; |
| 215 | limits.lower_claw.back.lower_decreasing_angle = 0.0; |
| 216 | limits.lower_claw.back.upper_decreasing_angle = 0.0; |
| 217 | |
| 218 | limits.claw_unimportant_epsilon = 0.01; |
| 219 | limits.start_fine_tune_pos = -0.2; |
| 220 | limits.max_zeroing_voltage = 4.0; |
| 221 | |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 222 | ::y2014::control_loops::ClawQueue::Position last_position = |
| 223 | *::y2014::control_loops::claw_queue.position; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 224 | |
| 225 | while (true) { |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 226 | ::y2014::control_loops::claw_queue.position.FetchNextBlocking(); |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 227 | bool print = false; |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 228 | if (top.GetPositionOfEdge(::y2014::control_loops::claw_queue.position->top, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 229 | &limits.upper_claw)) { |
| 230 | print = true; |
| 231 | printf("Got an edge on the upper claw\n"); |
| 232 | } |
| 233 | if (bottom.GetPositionOfEdge( |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 234 | ::y2014::control_loops::claw_queue.position->bottom, |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 235 | &limits.lower_claw)) { |
| 236 | print = true; |
| 237 | printf("Got an edge on the lower claw\n"); |
| 238 | } |
| 239 | const double top_position = |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 240 | ::y2014::control_loops::claw_queue.position->top.position - |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 241 | top_start_position; |
| 242 | const double bottom_position = |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 243 | ::y2014::control_loops::claw_queue.position->bottom.position - |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 244 | bottom_start_position; |
| 245 | const double separation = top_position - bottom_position; |
| 246 | if (separation > limits.claw_max_separation) { |
| 247 | limits.soft_max_separation = limits.claw_max_separation = separation; |
| 248 | print = true; |
| 249 | } |
| 250 | if (separation < limits.claw_min_separation) { |
| 251 | limits.soft_min_separation = limits.claw_min_separation = separation; |
| 252 | print = true; |
| 253 | } |
| 254 | |
| 255 | if (print) { |
| 256 | printf("{%f,\n", limits.claw_zeroing_off_speed); |
| 257 | printf("%f,\n", limits.claw_zeroing_speed); |
| 258 | printf("%f,\n", limits.claw_zeroing_separation); |
| 259 | printf("%f,\n", limits.claw_min_separation); |
| 260 | printf("%f,\n", limits.claw_max_separation); |
| 261 | printf("%f,\n", limits.soft_min_separation); |
| 262 | printf("%f,\n", limits.soft_max_separation); |
| 263 | printf( |
| 264 | "{%f, %f, %f, %f, {%f, %f, %f, %f}, {%f, %f, %f, %f}, {%f, %f, %f, " |
| 265 | "%f}},\n", |
| 266 | limits.upper_claw.lower_hard_limit, |
| 267 | limits.upper_claw.upper_hard_limit, limits.upper_claw.lower_limit, |
| 268 | limits.upper_claw.upper_limit, limits.upper_claw.front.lower_angle, |
| 269 | limits.upper_claw.front.upper_angle, |
| 270 | limits.upper_claw.front.lower_decreasing_angle, |
| 271 | limits.upper_claw.front.upper_decreasing_angle, |
| 272 | limits.upper_claw.calibration.lower_angle, |
| 273 | limits.upper_claw.calibration.upper_angle, |
| 274 | limits.upper_claw.calibration.lower_decreasing_angle, |
| 275 | limits.upper_claw.calibration.upper_decreasing_angle, |
| 276 | limits.upper_claw.back.lower_angle, |
| 277 | limits.upper_claw.back.upper_angle, |
| 278 | limits.upper_claw.back.lower_decreasing_angle, |
| 279 | limits.upper_claw.back.upper_decreasing_angle); |
| 280 | |
| 281 | printf( |
| 282 | "{%f, %f, %f, %f, {%f, %f, %f, %f}, {%f, %f, %f, %f}, {%f, %f, %f, " |
| 283 | "%f}},\n", |
| 284 | limits.lower_claw.lower_hard_limit, |
| 285 | limits.lower_claw.upper_hard_limit, limits.lower_claw.lower_limit, |
| 286 | limits.lower_claw.upper_limit, limits.lower_claw.front.lower_angle, |
| 287 | limits.lower_claw.front.upper_angle, |
| 288 | limits.lower_claw.front.lower_decreasing_angle, |
| 289 | limits.lower_claw.front.upper_decreasing_angle, |
| 290 | limits.lower_claw.calibration.lower_angle, |
| 291 | limits.lower_claw.calibration.upper_angle, |
| 292 | limits.lower_claw.calibration.lower_decreasing_angle, |
| 293 | limits.lower_claw.calibration.upper_decreasing_angle, |
| 294 | limits.lower_claw.back.lower_angle, |
| 295 | limits.lower_claw.back.upper_angle, |
| 296 | limits.lower_claw.back.lower_decreasing_angle, |
| 297 | limits.lower_claw.back.upper_decreasing_angle); |
| 298 | printf("%f, // claw_unimportant_epsilon\n", |
| 299 | limits.claw_unimportant_epsilon); |
| 300 | printf("%f, // start_fine_tune_pos\n", limits.start_fine_tune_pos); |
| 301 | printf("%f,\n", limits.max_zeroing_voltage); |
| 302 | printf("}\n"); |
| 303 | } |
| 304 | |
Brian Silverman | b601d89 | 2015-12-20 18:24:38 -0500 | [diff] [blame] | 305 | last_position = *::y2014::control_loops::claw_queue.position; |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 306 | } |
| 307 | return 0; |
| 308 | } |
| 309 | |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 310 | } // namespace y2014 |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 311 | |
| 312 | int main() { |
| 313 | ::aos::Init(); |
Austin Schuh | 2495710 | 2015-11-28 16:04:40 -0800 | [diff] [blame] | 314 | int returnvalue = ::y2014::Main(); |
Brian Silverman | 17f503e | 2015-08-02 18:17:18 -0700 | [diff] [blame] | 315 | ::aos::Cleanup(); |
| 316 | return returnvalue; |
| 317 | } |