blob: 0847b3c60df2419e2dced09117091493bee52d13 [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
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -08006namespace motors::seems_reasonable {
Austin Schuh4fae0fc2018-03-27 23:51:42 -07007
8float NextGoal(float current_goal, float goal);
9float PreviousGoal(float current_goal, float goal);
10
11class Spring {
12 public:
13 Spring() = default;
14 Spring(const Spring &) = delete;
15 Spring &operator=(const Spring &) = delete;
16
17 // Iterates the loop.
18 // If unload is true, unload.
19 // If the encoder isn't valid, unload.
20 // If prime is true, go to primed state.
21 // If prime and fire are true, fire.
22 void Iterate(bool unload, bool prime, bool fire, bool force_reset,
Austin Schuhe666dc62018-08-08 21:09:12 -070023 bool force_move, bool encoder_valid, float angle);
Austin Schuh4fae0fc2018-03-27 23:51:42 -070024
25 enum class State {
26 UNINITIALIZED = 0,
27 STUCK_UNLOAD = 1,
28 UNLOAD = 2,
29 LOAD = 3,
30 PRIME = 4,
31 FIRE = 5,
Austin Schuh72656c42018-04-01 16:37:52 -070032 WAIT_FOR_LOAD = 6,
33 WAIT_FOR_LOAD_RELEASE = 7,
Austin Schuhe666dc62018-08-08 21:09:12 -070034 FORCE_MOVE = 8,
Austin Schuh4fae0fc2018-03-27 23:51:42 -070035 };
36
37 // Returns the current to output to the spring motors.
38 float output() const { return output_; }
39
40 // Returns true if the motor is near the goal.
41 bool Near() { return ::std::abs(angle_ - goal_) < 0.2f; }
42
43 State state() const { return state_; }
44
45 float angle() const { return angle_; }
46 float goal() const { return goal_; }
47
48 int timeout() const { return timeout_; }
49
50 private:
51 void Load() {
52 timeout_ = 5 * 200;
53 state_ = State::LOAD;
54 }
55
56 void Prime() {
57 timeout_ = 1 * 200;
58 state_ = State::PRIME;
59 }
60
Austin Schuhe666dc62018-08-08 21:09:12 -070061 void ForceMove() {
62 timeout_ = 0;
63 state_ = State::FORCE_MOVE;
64 }
65
Austin Schuh4fae0fc2018-03-27 23:51:42 -070066 void Unload() {
Austin Schuhe666dc62018-08-08 21:09:12 -070067 timeout_ = 14 * 200;
Austin Schuh4fae0fc2018-03-27 23:51:42 -070068 state_ = State::UNLOAD;
69 }
70
71 void StuckUnload() {
Austin Schuhe666dc62018-08-08 21:09:12 -070072 timeout_ = 14 * 200;
Austin Schuh4fae0fc2018-03-27 23:51:42 -070073 state_ = State::STUCK_UNLOAD;
74 }
75
76 void Fire() {
77 timeout_ = 100;
78 state_ = State::FIRE;
79 }
80
81 float NextGoal(float goal) {
82 return ::motors::seems_reasonable::NextGoal(goal_, goal);
83 }
84
85 float PreviousGoal(float goal) {
86 return ::motors::seems_reasonable::PreviousGoal(goal_, goal);
87 }
88
89 State state_ = State::UNINITIALIZED;
90
91 // Note, these need to be (-M_PI, M_PI]
Brian Silvermanc8edc952018-03-31 12:30:17 -070092 constexpr static float kLoadGoal = -0.345f;
93 constexpr static float kPrimeGoal = -0.269f;
Austin Schuhe666dc62018-08-08 21:09:12 -070094 constexpr static float kFireGoal = -0.063f;
Austin Schuh4fae0fc2018-03-27 23:51:42 -070095 constexpr static float kUnloadGoal = kFireGoal;
96
97 float angle_ = 0.0f;
98 float goal_ = 0.0f;
99
100 int timeout_ = 0;
101
102 float output_ = 0.0f;
103 float last_error_ = 0.0f;
104};
105
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800106} // namespace motors::seems_reasonable
Austin Schuh4fae0fc2018-03-27 23:51:42 -0700107
108#endif // MOTORS_SEEMS_REASONABLE_SPRING_H_