blob: 90c9cd185783952180014ffb99b283aa6bd2b665 [file] [log] [blame]
Austin Schuh4fae0fc2018-03-27 23:51:42 -07001#ifndef MOTORS_SEEMS_REASONABLE_SPRING_H_
2#define MOTORS_SEEMS_REASONABLE_SPRING_H_
3
4#include <cmath>
5
6namespace motors {
7namespace seems_reasonable {
8
9float NextGoal(float current_goal, float goal);
10float PreviousGoal(float current_goal, float goal);
11
12class Spring {
13 public:
14 Spring() = default;
15 Spring(const Spring &) = delete;
16 Spring &operator=(const Spring &) = delete;
17
18 // Iterates the loop.
19 // If unload is true, unload.
20 // If the encoder isn't valid, unload.
21 // If prime is true, go to primed state.
22 // If prime and fire are true, fire.
23 void Iterate(bool unload, bool prime, bool fire, bool force_reset,
Austin Schuhe666dc62018-08-08 21:09:12 -070024 bool force_move, bool encoder_valid, float angle);
Austin Schuh4fae0fc2018-03-27 23:51:42 -070025
26 enum class State {
27 UNINITIALIZED = 0,
28 STUCK_UNLOAD = 1,
29 UNLOAD = 2,
30 LOAD = 3,
31 PRIME = 4,
32 FIRE = 5,
Austin Schuh72656c42018-04-01 16:37:52 -070033 WAIT_FOR_LOAD = 6,
34 WAIT_FOR_LOAD_RELEASE = 7,
Austin Schuhe666dc62018-08-08 21:09:12 -070035 FORCE_MOVE = 8,
Austin Schuh4fae0fc2018-03-27 23:51:42 -070036 };
37
38 // Returns the current to output to the spring motors.
39 float output() const { return output_; }
40
41 // Returns true if the motor is near the goal.
42 bool Near() { return ::std::abs(angle_ - goal_) < 0.2f; }
43
44 State state() const { return state_; }
45
46 float angle() const { return angle_; }
47 float goal() const { return goal_; }
48
49 int timeout() const { return timeout_; }
50
51 private:
52 void Load() {
53 timeout_ = 5 * 200;
54 state_ = State::LOAD;
55 }
56
57 void Prime() {
58 timeout_ = 1 * 200;
59 state_ = State::PRIME;
60 }
61
Austin Schuhe666dc62018-08-08 21:09:12 -070062 void ForceMove() {
63 timeout_ = 0;
64 state_ = State::FORCE_MOVE;
65 }
66
Austin Schuh4fae0fc2018-03-27 23:51:42 -070067 void Unload() {
Austin Schuhe666dc62018-08-08 21:09:12 -070068 timeout_ = 14 * 200;
Austin Schuh4fae0fc2018-03-27 23:51:42 -070069 state_ = State::UNLOAD;
70 }
71
72 void StuckUnload() {
Austin Schuhe666dc62018-08-08 21:09:12 -070073 timeout_ = 14 * 200;
Austin Schuh4fae0fc2018-03-27 23:51:42 -070074 state_ = State::STUCK_UNLOAD;
75 }
76
77 void Fire() {
78 timeout_ = 100;
79 state_ = State::FIRE;
80 }
81
82 float NextGoal(float goal) {
83 return ::motors::seems_reasonable::NextGoal(goal_, goal);
84 }
85
86 float PreviousGoal(float goal) {
87 return ::motors::seems_reasonable::PreviousGoal(goal_, goal);
88 }
89
90 State state_ = State::UNINITIALIZED;
91
92 // Note, these need to be (-M_PI, M_PI]
Brian Silvermanc8edc952018-03-31 12:30:17 -070093 constexpr static float kLoadGoal = -0.345f;
94 constexpr static float kPrimeGoal = -0.269f;
Austin Schuhe666dc62018-08-08 21:09:12 -070095 constexpr static float kFireGoal = -0.063f;
Austin Schuh4fae0fc2018-03-27 23:51:42 -070096 constexpr static float kUnloadGoal = kFireGoal;
97
98 float angle_ = 0.0f;
99 float goal_ = 0.0f;
100
101 int timeout_ = 0;
102
103 float output_ = 0.0f;
104 float last_error_ = 0.0f;
105};
106
107} // namespace seems_reasonable
108} // namespace motors
109
110#endif // MOTORS_SEEMS_REASONABLE_SPRING_H_