blob: 095ef1d97cb914454607d4950eac86ecfc859f89 [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"
James Kuszmaulec635d22023-08-12 18:39:24 -07009#include "frc971/zeroing/pot_and_absolute_encoder.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070010#include "frc971/zeroing/zeroing.h"
11#include "y2018/constants.h"
12#include "y2018/control_loops/superstructure/arm/generated_graph.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070013#include "y2018/control_loops/superstructure/superstructure_position_generated.h"
14#include "y2018/control_loops/superstructure/superstructure_status_generated.h"
Austin Schuhcb091712018-02-21 20:01:55 -080015
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -080016using frc971::control_loops::arm::EKF;
Philipp Schrader790cb542023-07-05 21:06:52 -070017using frc971::control_loops::arm::TrajectoryFollower;
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -080018
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080019namespace y2018::control_loops::superstructure::arm {
Austin Schuhcb091712018-02-21 20:01:55 -080020
Austin Schuhcb091712018-02-21 20:01:55 -080021class Arm {
22 public:
23 Arm();
24
Austin Schuh7a090402018-03-04 01:16:45 -080025 // If true, tune down all the constants for testing.
Austin Schuhb874fd32018-03-05 00:27:10 -080026 static constexpr bool kGrannyMode() { return false; }
Austin Schuh7a090402018-03-04 01:16:45 -080027
Austin Schuhcb091712018-02-21 20:01:55 -080028 // The operating voltage.
Austin Schuh7a090402018-03-04 01:16:45 -080029 static constexpr double kOperatingVoltage() {
Austin Schuh41c71e42018-04-04 20:11:20 -070030 return kGrannyMode() ? 5.0 : 12.0;
Austin Schuh7a090402018-03-04 01:16:45 -080031 }
Austin Schuhcb091712018-02-21 20:01:55 -080032 static constexpr double kDt() { return 0.00505; }
Austin Schuh41c71e42018-04-04 20:11:20 -070033 static constexpr double kAlpha0Max() { return kGrannyMode() ? 5.0 : 15.0; }
34 static constexpr double kAlpha1Max() { return kGrannyMode() ? 5.0 : 15.0; }
Austin Schuhb874fd32018-03-05 00:27:10 -080035
36 static constexpr double kVMax() { return kGrannyMode() ? 5.0 : 11.5; }
37 static constexpr double kPathlessVMax() { return 5.0; }
Austin Schuh41c71e42018-04-04 20:11:20 -070038 static constexpr double kGotoPathVMax() { return 6.0; }
Austin Schuhcb091712018-02-21 20:01:55 -080039
Alex Perrycb7da4b2019-08-28 19:35:56 -070040 flatbuffers::Offset<superstructure::ArmStatus> Iterate(
41 const ::aos::monotonic_clock::time_point monotonic_now,
42 const uint32_t *unsafe_goal, bool grab_box, bool open_claw,
43 bool close_claw, const superstructure::ArmPosition *position,
44 const bool claw_beambreak_triggered,
45 const bool box_back_beambreak_triggered, const bool intake_clear_of_box,
46 bool suicide, bool trajectory_override, double *proximal_output,
47 double *distal_output, bool *release_arm_brake, bool *claw_closed,
48 flatbuffers::FlatBufferBuilder *fbb);
Austin Schuhcb091712018-02-21 20:01:55 -080049
50 void Reset();
51
52 enum class State : int32_t {
53 UNINITIALIZED,
54 ZEROING,
Austin Schuh96341532018-03-09 21:17:24 -080055 DISABLED,
56 GOTO_PATH,
Austin Schuhcb091712018-02-21 20:01:55 -080057 RUNNING,
Austin Schuh17e484e2018-03-11 01:11:36 -080058 PREP_CLIMB,
Austin Schuhcb091712018-02-21 20:01:55 -080059 ESTOP,
60 };
61
Austin Schuh96341532018-03-09 21:17:24 -080062 enum class GrabState : int32_t {
Austin Schuhede47322018-07-08 16:04:36 -070063 NORMAL = 0,
64 WAIT_FOR_BOX = 1,
65 TALL_BOX = 2,
66 SHORT_BOX = 3,
67 CLAW_CLOSE = 4,
68 OPEN_INTAKE = 5,
Austin Schuh96341532018-03-09 21:17:24 -080069 };
70
Austin Schuhcb091712018-02-21 20:01:55 -080071 State state() const { return state_; }
Austin Schuh96341532018-03-09 21:17:24 -080072 GrabState grab_state() const { return grab_state_; }
73
Alex Perrycb7da4b2019-08-28 19:35:56 -070074 bool estopped() const { return state_ == State::ESTOP; }
75 bool zeroed() const {
76 return (proximal_zeroing_estimator_.zeroed() &&
77 distal_zeroing_estimator_.zeroed());
78 }
79
Austin Schuh96341532018-03-09 21:17:24 -080080 // Returns the maximum position for the intake. This is used to override the
81 // intake position to release the box when the state machine is lifting.
82 double max_intake_override() const { return max_intake_override_; }
Austin Schuhcb091712018-02-21 20:01:55 -080083
Austin Schuhd76546a2018-07-08 16:05:14 -070084 uint32_t current_node() const { return current_node_; }
85
86 double path_distance_to_go() { return follower_.path_distance_to_go(); }
87
Austin Schuhcb091712018-02-21 20:01:55 -080088 private:
Austin Schuh96341532018-03-09 21:17:24 -080089 bool AtState(uint32_t state) const { return current_node_ == state; }
Austin Schuh83cdd8a2018-03-21 20:49:02 -070090 bool NearEnd(double threshold = 0.03) const {
Austin Schuh96341532018-03-09 21:17:24 -080091 return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
92 ::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
93 follower_.path_distance_to_go() < 1e-3;
94 }
95
Austin Schuhcb091712018-02-21 20:01:55 -080096 State state_ = State::UNINITIALIZED;
97
Austin Schuh96341532018-03-09 21:17:24 -080098 GrabState grab_state_ = GrabState::NORMAL;
99
100 ::aos::monotonic_clock::time_point claw_close_start_time_ =
Austin Schuhcb091712018-02-21 20:01:55 -0800101 ::aos::monotonic_clock::min_time;
102
Austin Schuh72db9a12019-01-21 18:02:51 -0800103 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
104 proximal_zeroing_estimator_;
105 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
106 distal_zeroing_estimator_;
Austin Schuhcb091712018-02-21 20:01:55 -0800107
108 double proximal_offset_ = 0.0;
109 double distal_offset_ = 0.0;
110
Austin Schuh96341532018-03-09 21:17:24 -0800111 bool claw_closed_ = true;
112 double max_intake_override_ = 1000.0;
113
Austin Schuhcb091712018-02-21 20:01:55 -0800114 const ::Eigen::Matrix<double, 2, 2> alpha_unitizer_;
115
Austin Schuh41c71e42018-04-04 20:11:20 -0700116 double vmax_ = kVMax();
117
Maxwell Henderson8f0e07f2023-02-08 21:10:58 -0800118 frc971::control_loops::arm::Dynamics dynamics_;
119
Austin Schuh41c71e42018-04-04 20:11:20 -0700120 ::std::vector<TrajectoryAndParams> trajectories_;
Austin Schuhcb091712018-02-21 20:01:55 -0800121 SearchGraph search_graph_;
122
123 bool close_enough_for_full_power_ = false;
124
Austin Schuh17e484e2018-03-11 01:11:36 -0800125 int32_t climb_count_ = 0;
Austin Schuh7afcc232018-09-16 16:33:47 -0700126 int32_t brownout_count_ = 0;
Austin Schuh17e484e2018-03-11 01:11:36 -0800127
Austin Schuhcb091712018-02-21 20:01:55 -0800128 EKF arm_ekf_;
129 TrajectoryFollower follower_;
130
Austin Schuhb874fd32018-03-05 00:27:10 -0800131 const ::std::vector<::Eigen::Matrix<double, 2, 1>> points_;
132
Austin Schuhcb091712018-02-21 20:01:55 -0800133 // Start at the 0th index.
134 uint32_t current_node_ = 0;
135
Neil Balchba9cbba2018-04-06 22:26:38 -0700136 uint32_t claw_closed_count_ = 0;
137
Austin Schuhcb091712018-02-21 20:01:55 -0800138 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
139};
140
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800141} // namespace y2018::control_loops::superstructure::arm
Austin Schuhcb091712018-02-21 20:01:55 -0800142
143#endif // Y2018_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_