blob: 0b0a6a44fcc16e2dbe9797f8b7ce4431005eacba [file] [log] [blame]
Austin Schuhcb091712018-02-21 20:01:55 -08001#ifndef Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_
2#define Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_
3
Alex Perrycb7da4b2019-08-28 19:35:56 -07004#include "aos/time/time.h"
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -08005#include "frc971/control_loops/double_jointed_arm/dynamics.h"
6#include "frc971/control_loops/double_jointed_arm/ekf.h"
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -08007#include "frc971/control_loops/double_jointed_arm/graph.h"
8#include "frc971/control_loops/double_jointed_arm/trajectory.h"
Philipp Schrader790cb542023-07-05 21:06:52 -07009#include "frc971/zeroing/zeroing.h"
10#include "y2018/constants.h"
11#include "y2018/control_loops/superstructure/arm/generated_graph.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070012#include "y2018/control_loops/superstructure/superstructure_position_generated.h"
13#include "y2018/control_loops/superstructure/superstructure_status_generated.h"
Austin Schuhcb091712018-02-21 20:01:55 -080014
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -080015using frc971::control_loops::arm::EKF;
Philipp Schrader790cb542023-07-05 21:06:52 -070016using frc971::control_loops::arm::TrajectoryFollower;
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -080017
Austin Schuhcb091712018-02-21 20:01:55 -080018namespace y2018 {
19namespace control_loops {
20namespace superstructure {
21namespace arm {
22
Austin Schuhcb091712018-02-21 20:01:55 -080023class Arm {
24 public:
25 Arm();
26
Austin Schuh7a090402018-03-04 01:16:45 -080027 // If true, tune down all the constants for testing.
Austin Schuhb874fd32018-03-05 00:27:10 -080028 static constexpr bool kGrannyMode() { return false; }
Austin Schuh7a090402018-03-04 01:16:45 -080029
Austin Schuhcb091712018-02-21 20:01:55 -080030 // The operating voltage.
Austin Schuh7a090402018-03-04 01:16:45 -080031 static constexpr double kOperatingVoltage() {
Austin Schuh41c71e42018-04-04 20:11:20 -070032 return kGrannyMode() ? 5.0 : 12.0;
Austin Schuh7a090402018-03-04 01:16:45 -080033 }
Austin Schuhcb091712018-02-21 20:01:55 -080034 static constexpr double kDt() { return 0.00505; }
Austin Schuh41c71e42018-04-04 20:11:20 -070035 static constexpr double kAlpha0Max() { return kGrannyMode() ? 5.0 : 15.0; }
36 static constexpr double kAlpha1Max() { return kGrannyMode() ? 5.0 : 15.0; }
Austin Schuhb874fd32018-03-05 00:27:10 -080037
38 static constexpr double kVMax() { return kGrannyMode() ? 5.0 : 11.5; }
39 static constexpr double kPathlessVMax() { return 5.0; }
Austin Schuh41c71e42018-04-04 20:11:20 -070040 static constexpr double kGotoPathVMax() { return 6.0; }
Austin Schuhcb091712018-02-21 20:01:55 -080041
Alex Perrycb7da4b2019-08-28 19:35:56 -070042 flatbuffers::Offset<superstructure::ArmStatus> Iterate(
43 const ::aos::monotonic_clock::time_point monotonic_now,
44 const uint32_t *unsafe_goal, bool grab_box, bool open_claw,
45 bool close_claw, const superstructure::ArmPosition *position,
46 const bool claw_beambreak_triggered,
47 const bool box_back_beambreak_triggered, const bool intake_clear_of_box,
48 bool suicide, bool trajectory_override, double *proximal_output,
49 double *distal_output, bool *release_arm_brake, bool *claw_closed,
50 flatbuffers::FlatBufferBuilder *fbb);
Austin Schuhcb091712018-02-21 20:01:55 -080051
52 void Reset();
53
54 enum class State : int32_t {
55 UNINITIALIZED,
56 ZEROING,
Austin Schuh96341532018-03-09 21:17:24 -080057 DISABLED,
58 GOTO_PATH,
Austin Schuhcb091712018-02-21 20:01:55 -080059 RUNNING,
Austin Schuh17e484e2018-03-11 01:11:36 -080060 PREP_CLIMB,
Austin Schuhcb091712018-02-21 20:01:55 -080061 ESTOP,
62 };
63
Austin Schuh96341532018-03-09 21:17:24 -080064 enum class GrabState : int32_t {
Austin Schuhede47322018-07-08 16:04:36 -070065 NORMAL = 0,
66 WAIT_FOR_BOX = 1,
67 TALL_BOX = 2,
68 SHORT_BOX = 3,
69 CLAW_CLOSE = 4,
70 OPEN_INTAKE = 5,
Austin Schuh96341532018-03-09 21:17:24 -080071 };
72
Austin Schuhcb091712018-02-21 20:01:55 -080073 State state() const { return state_; }
Austin Schuh96341532018-03-09 21:17:24 -080074 GrabState grab_state() const { return grab_state_; }
75
Alex Perrycb7da4b2019-08-28 19:35:56 -070076 bool estopped() const { return state_ == State::ESTOP; }
77 bool zeroed() const {
78 return (proximal_zeroing_estimator_.zeroed() &&
79 distal_zeroing_estimator_.zeroed());
80 }
81
Austin Schuh96341532018-03-09 21:17:24 -080082 // Returns the maximum position for the intake. This is used to override the
83 // intake position to release the box when the state machine is lifting.
84 double max_intake_override() const { return max_intake_override_; }
Austin Schuhcb091712018-02-21 20:01:55 -080085
Austin Schuhd76546a2018-07-08 16:05:14 -070086 uint32_t current_node() const { return current_node_; }
87
88 double path_distance_to_go() { return follower_.path_distance_to_go(); }
89
Austin Schuhcb091712018-02-21 20:01:55 -080090 private:
Austin Schuh96341532018-03-09 21:17:24 -080091 bool AtState(uint32_t state) const { return current_node_ == state; }
Austin Schuh83cdd8a2018-03-21 20:49:02 -070092 bool NearEnd(double threshold = 0.03) const {
Austin Schuh96341532018-03-09 21:17:24 -080093 return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
94 ::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
95 follower_.path_distance_to_go() < 1e-3;
96 }
97
Austin Schuhcb091712018-02-21 20:01:55 -080098 State state_ = State::UNINITIALIZED;
99
Austin Schuh96341532018-03-09 21:17:24 -0800100 GrabState grab_state_ = GrabState::NORMAL;
101
102 ::aos::monotonic_clock::time_point claw_close_start_time_ =
Austin Schuhcb091712018-02-21 20:01:55 -0800103 ::aos::monotonic_clock::min_time;
104
Austin Schuh72db9a12019-01-21 18:02:51 -0800105 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
106 proximal_zeroing_estimator_;
107 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
108 distal_zeroing_estimator_;
Austin Schuhcb091712018-02-21 20:01:55 -0800109
110 double proximal_offset_ = 0.0;
111 double distal_offset_ = 0.0;
112
Austin Schuh96341532018-03-09 21:17:24 -0800113 bool claw_closed_ = true;
114 double max_intake_override_ = 1000.0;
115
Austin Schuhcb091712018-02-21 20:01:55 -0800116 const ::Eigen::Matrix<double, 2, 2> alpha_unitizer_;
117
Austin Schuh41c71e42018-04-04 20:11:20 -0700118 double vmax_ = kVMax();
119
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -0800120 frc971::control_loops::arm::Dynamics dynamics_;
121
Austin Schuh41c71e42018-04-04 20:11:20 -0700122 ::std::vector<TrajectoryAndParams> trajectories_;
Austin Schuhcb091712018-02-21 20:01:55 -0800123 SearchGraph search_graph_;
124
125 bool close_enough_for_full_power_ = false;
126
Austin Schuh17e484e2018-03-11 01:11:36 -0800127 int32_t climb_count_ = 0;
Austin Schuh7afcc232018-09-16 16:33:47 -0700128 int32_t brownout_count_ = 0;
Austin Schuh17e484e2018-03-11 01:11:36 -0800129
Austin Schuhcb091712018-02-21 20:01:55 -0800130 EKF arm_ekf_;
131 TrajectoryFollower follower_;
132
Austin Schuhb874fd32018-03-05 00:27:10 -0800133 const ::std::vector<::Eigen::Matrix<double, 2, 1>> points_;
134
Austin Schuhcb091712018-02-21 20:01:55 -0800135 // Start at the 0th index.
136 uint32_t current_node_ = 0;
137
Neil Balchba9cbba2018-04-06 22:26:38 -0700138 uint32_t claw_closed_count_ = 0;
139
Austin Schuhcb091712018-02-21 20:01:55 -0800140 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
141};
142
143} // namespace arm
144} // namespace superstructure
145} // namespace control_loops
146} // namespace y2018
147
148#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_