blob: fc5e917db4f3d8953576039f4d027632498802b5 [file] [log] [blame]
Austin Schuh3bb9a442014-02-02 16:01:45 -08001#ifndef FRC971_CONTROL_LOOPS_CLAW_CLAW_H_
2#define FRC971_CONTROL_LOOPS_CLAW_CLAW_H_
3
4#include <memory>
5
6#include "aos/common/control_loop/ControlLoop.h"
7#include "frc971/control_loops/state_feedback_loop.h"
8#include "frc971/control_loops/claw/claw.q.h"
9#include "frc971/control_loops/claw/top_claw_motor_plant.h"
10#include "frc971/control_loops/claw/bottom_claw_motor_plant.h"
11
Austin Schuh3bb9a442014-02-02 16:01:45 -080012namespace frc971 {
13namespace control_loops {
14namespace testing {
15class ClawTest_NoWindupPositive_Test;
16class ClawTest_NoWindupNegative_Test;
17};
18
Austin Schuh4b7b5d02014-02-10 21:20:34 -080019// Note: Everything in this file assumes that there is a 1 cycle delay between
20// power being requested and it showing up at the motor. It assumes that
21// X_hat(2, 1) is the voltage being applied as well. It will go unstable if
22// that isn't true.
23
24// This class implements the CapU function correctly given all the extra
25// information that we know about from the wrist motor.
26// It does not have any zeroing logic in it, only logic to deal with a delta U
27// controller.
28class ZeroedStateFeedbackLoop : public StateFeedbackLoop<3, 1, 1> {
Austin Schuh3bb9a442014-02-02 16:01:45 -080029 public:
Austin Schuh4b7b5d02014-02-10 21:20:34 -080030 ZeroedStateFeedbackLoop(StateFeedbackLoop<3, 1, 1> loop)
31 : StateFeedbackLoop<3, 1, 1>(loop),
32 voltage_(0.0),
33 last_voltage_(0.0),
34 uncapped_voltage_(0.0),
35 front_hall_effect_posedge_count_(0.0),
36 previous_front_hall_effect_posedge_count_(0.0),
37 front_hall_effect_negedge_count_(0.0),
38 previous_front_hall_effect_negedge_count_(0.0),
39 calibration_hall_effect_posedge_count_(0.0),
40 previous_calibration_hall_effect_posedge_count_(0.0),
41 calibration_hall_effect_negedge_count_(0.0),
42 previous_calibration_hall_effect_negedge_count_(0.0),
43 back_hall_effect_posedge_count_(0.0),
44 previous_back_hall_effect_posedge_count_(0.0),
45 back_hall_effect_negedge_count_(0.0),
46 previous_back_hall_effect_negedge_count_(0.0),
47 zeroing_state_(UNKNOWN_POSITION) {}
Austin Schuh3bb9a442014-02-02 16:01:45 -080048
Austin Schuh4b7b5d02014-02-10 21:20:34 -080049 const static int kZeroingMaxVoltage = 5;
Austin Schuh3bb9a442014-02-02 16:01:45 -080050
Austin Schuh4b7b5d02014-02-10 21:20:34 -080051 // Caps U, but this time respects the state of the wrist as well.
52 virtual void CapU();
Austin Schuh3bb9a442014-02-02 16:01:45 -080053
Austin Schuh4b7b5d02014-02-10 21:20:34 -080054 // Returns the accumulated voltage.
55 double voltage() const { return voltage_; }
Austin Schuh3bb9a442014-02-02 16:01:45 -080056
Austin Schuh4b7b5d02014-02-10 21:20:34 -080057 // Returns the uncapped voltage.
58 double uncapped_voltage() const { return uncapped_voltage_; }
59
60 // Zeros the accumulator.
61 void ZeroPower() { voltage_ = 0.0; }
62
63 enum JointZeroingState {
64 // We don't know where the joint is at all.
65 UNKNOWN_POSITION,
66 // We have an approximate position for where the claw is using.
67 APPROXIMATE_CALIBRATION,
68 // We observed the calibration edge while disabled. This is good enough for
69 // autonomous mode.
70 DISABLED_CALIBRATION,
71 // Ready for use during teleop.
72 CALIBRATED
73 };
74
75 void set_zeroing_state(JointZeroingState zeroing_state) {
76 zeroing_state_ = zeroing_state;
77 }
78 JointZeroingState zeroing_state() const { return zeroing_state_; }
79
80#define COUNT_SETTER_GETTER(variable) \
81 void set_##variable(int32_t value) { \
82 previous_##variable##_ = variable##_; \
83 variable##_ = value; \
84 } \
85 int32_t variable() const { return variable##_; } \
86 bool variable##_changed() const { \
87 return previous_##variable##_ != variable##_; \
88 }
89
90 COUNT_SETTER_GETTER(front_hall_effect_posedge_count);
91 COUNT_SETTER_GETTER(front_hall_effect_negedge_count);
92 COUNT_SETTER_GETTER(calibration_hall_effect_posedge_count);
93 COUNT_SETTER_GETTER(calibration_hall_effect_negedge_count);
94 COUNT_SETTER_GETTER(back_hall_effect_posedge_count);
95 COUNT_SETTER_GETTER(back_hall_effect_negedge_count);
96
97 bool any_hall_effect_changed() const {
98 return front_hall_effect_posedge_count_changed() ||
99 front_hall_effect_negedge_count_changed() ||
100 calibration_hall_effect_posedge_count_changed() ||
101 calibration_hall_effect_negedge_count_changed() ||
102 back_hall_effect_posedge_count_changed() ||
103 back_hall_effect_negedge_count_changed();
104 }
105
106#undef COUNT_SETTER_GETTER
107
108 private:
109 // The accumulated voltage to apply to the motor.
110 double voltage_;
111 double last_voltage_;
112 double uncapped_voltage_;
113
114 int32_t front_hall_effect_posedge_count_;
115 int32_t previous_front_hall_effect_posedge_count_;
116 int32_t front_hall_effect_negedge_count_;
117 int32_t previous_front_hall_effect_negedge_count_;
118 int32_t calibration_hall_effect_posedge_count_;
119 int32_t previous_calibration_hall_effect_posedge_count_;
120 int32_t calibration_hall_effect_negedge_count_;
121 int32_t previous_calibration_hall_effect_negedge_count_;
122 int32_t back_hall_effect_posedge_count_;
123 int32_t previous_back_hall_effect_posedge_count_;
124 int32_t back_hall_effect_negedge_count_;
125 int32_t previous_back_hall_effect_negedge_count_;
126
127 JointZeroingState zeroing_state_;
128};
129
130class ClawMotor
131 : public aos::control_loops::ControlLoop<control_loops::ClawGroup> {
132 public:
133 explicit ClawMotor(control_loops::ClawGroup *my_claw =
134 &control_loops::claw_queue_group);
Austin Schuh3bb9a442014-02-02 16:01:45 -0800135
136 // True if the state machine is ready.
Austin Schuh4b7b5d02014-02-10 21:20:34 -0800137 bool is_ready() const { return false; }
Austin Schuh3bb9a442014-02-02 16:01:45 -0800138
139 protected:
Austin Schuh4b7b5d02014-02-10 21:20:34 -0800140 virtual void RunIteration(const control_loops::ClawGroup::Goal *goal,
141 const control_loops::ClawGroup::Position *position,
142 control_loops::ClawGroup::Output *output,
143 ::aos::control_loops::Status *status);
144
145 double top_absolute_position() const { return top_claw_.X_hat(0, 0); }
146 double bottom_absolute_position() const { return bottom_claw_.X_hat(0, 0); }
Austin Schuh3bb9a442014-02-02 16:01:45 -0800147
148 private:
149 // Friend the test classes for acces to the internal state.
150 friend class testing::ClawTest_NoWindupPositive_Test;
151 friend class testing::ClawTest_NoWindupNegative_Test;
152
153 // The zeroed joint to use.
Austin Schuh4b7b5d02014-02-10 21:20:34 -0800154 bool has_top_claw_goal_;
155 double top_claw_goal_;
156 ZeroedStateFeedbackLoop top_claw_;
157
158 bool has_bottom_claw_goal_;
159 double bottom_claw_goal_;
160 ZeroedStateFeedbackLoop bottom_claw_;
161
162 bool was_enabled_;
Austin Schuh3bb9a442014-02-02 16:01:45 -0800163
164 DISALLOW_COPY_AND_ASSIGN(ClawMotor);
165};
166
167} // namespace control_loops
168} // namespace frc971
169
170#endif // FRC971_CONTROL_LOOPS_CLAW_CLAW_H_