blob: 9cda7fc7ff552a6f680774ab278e4f2c9f72e2c0 [file] [log] [blame]
milind-u37385182023-02-20 15:07:28 -08001#ifndef Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_
2#define Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_
3
4#include "aos/time/time.h"
5#include "frc971/control_loops/double_jointed_arm/dynamics.h"
6#include "frc971/control_loops/double_jointed_arm/ekf.h"
7#include "frc971/control_loops/double_jointed_arm/graph.h"
milind-u37385182023-02-20 15:07:28 -08008#include "frc971/zeroing/zeroing.h"
9#include "y2023/constants.h"
10#include "y2023/control_loops/superstructure/arm/generated_graph.h"
milind-u18a901d2023-02-17 21:51:55 -080011#include "y2023/control_loops/superstructure/arm/trajectory.h"
milind-u37385182023-02-20 15:07:28 -080012#include "y2023/control_loops/superstructure/superstructure_position_generated.h"
13#include "y2023/control_loops/superstructure/superstructure_status_generated.h"
14
15using frc971::control_loops::arm::EKF;
milind-u37385182023-02-20 15:07:28 -080016
17namespace y2023 {
18namespace control_loops {
19namespace superstructure {
20namespace arm {
21
22class Arm {
23 public:
24 Arm(std::shared_ptr<const constants::Values> values);
25
26 // if true, tune down all the constants for testing.
27 static constexpr bool kGrannyMode() { return false; }
milind-u01bbcf22023-02-20 18:00:28 -080028
milind-u37385182023-02-20 15:07:28 -080029 // the operating voltage.
30 static constexpr double kOperatingVoltage() {
31 return kGrannyMode() ? 5.0 : 12.0;
32 }
milind-u37385182023-02-20 15:07:28 -080033 static constexpr double kDt() { return 0.00505; }
milind-u18a901d2023-02-17 21:51:55 -080034 static constexpr std::chrono::nanoseconds kDtDuration() {
35 return std::chrono::duration_cast<std::chrono::nanoseconds>(
36 std::chrono::duration<double>(kDt()));
37 }
milind-u37385182023-02-20 15:07:28 -080038 static constexpr double kAlpha0Max() { return kGrannyMode() ? 5.0 : 15.0; }
39 static constexpr double kAlpha1Max() { return kGrannyMode() ? 5.0 : 15.0; }
milind-u18a901d2023-02-17 21:51:55 -080040 static constexpr double kAlpha2Max() { return kGrannyMode() ? 5.0 : 15.0; }
milind-u37385182023-02-20 15:07:28 -080041
42 static constexpr double kVMax() { return kGrannyMode() ? 5.0 : 11.5; }
milind-u37385182023-02-20 15:07:28 -080043 static constexpr double kPathlessVMax() { return 5.0; }
44 static constexpr double kGotoPathVMax() { return 6.0; }
45
46 flatbuffers::Offset<superstructure::ArmStatus> Iterate(
47 const ::aos::monotonic_clock::time_point /*monotonic_now*/,
48 const uint32_t *unsafe_goal, const superstructure::ArmPosition *position,
49 bool trajectory_override, double *proximal_output, double *distal_output,
milind-u18a901d2023-02-17 21:51:55 -080050 double *roll_joint_output, bool /*intake*/, bool /*spit*/,
51 flatbuffers::FlatBufferBuilder *fbb);
milind-u37385182023-02-20 15:07:28 -080052
53 void Reset();
54
55 ArmState state() const { return state_; }
milind-u37385182023-02-20 15:07:28 -080056
milind-u01bbcf22023-02-20 18:00:28 -080057 bool estopped() const { return state_ == ArmState::ESTOP; }
milind-u37385182023-02-20 15:07:28 -080058 bool zeroed() const {
59 return (proximal_zeroing_estimator_.zeroed() &&
milind-u18a901d2023-02-17 21:51:55 -080060 distal_zeroing_estimator_.zeroed() &&
61 roll_joint_zeroing_estimator_.zeroed());
milind-u37385182023-02-20 15:07:28 -080062 }
milind-u01bbcf22023-02-20 18:00:28 -080063
milind-u37385182023-02-20 15:07:28 -080064 uint32_t current_node() const { return current_node_; }
milind-u01bbcf22023-02-20 18:00:28 -080065
milind-u37385182023-02-20 15:07:28 -080066 double path_distance_to_go() { return follower_.path_distance_to_go(); }
67
68 private:
69 bool AtState(uint32_t state) const { return current_node_ == state; }
70 bool NearEnd(double threshold = 0.03) const {
71 return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
72 ::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
73 follower_.path_distance_to_go() < 1e-3;
74 }
75
76 std::shared_ptr<const constants::Values> values_;
milind-u01bbcf22023-02-20 18:00:28 -080077
milind-u37385182023-02-20 15:07:28 -080078 ArmState state_;
79
80 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
81 proximal_zeroing_estimator_;
82 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
83 distal_zeroing_estimator_;
milind-u18a901d2023-02-17 21:51:55 -080084 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
85 roll_joint_zeroing_estimator_;
milind-u37385182023-02-20 15:07:28 -080086
87 double proximal_offset_;
88 double distal_offset_;
milind-u18a901d2023-02-17 21:51:55 -080089 double roll_joint_offset_;
milind-u01bbcf22023-02-20 18:00:28 -080090
milind-u18a901d2023-02-17 21:51:55 -080091 const ::Eigen::DiagonalMatrix<double, 3> alpha_unitizer_;
milind-u01bbcf22023-02-20 18:00:28 -080092
milind-u37385182023-02-20 15:07:28 -080093 double vmax_ = kVMax();
94
95 frc971::control_loops::arm::Dynamics dynamics_;
96
97 ::std::vector<TrajectoryAndParams> trajectories_;
milind-u37385182023-02-20 15:07:28 -080098
99 bool close_enough_for_full_power_;
100
101 size_t brownout_count_;
102
milind-u18a901d2023-02-17 21:51:55 -0800103 StateFeedbackLoop<3, 1, 1, double, StateFeedbackPlant<3, 1, 1>,
104 StateFeedbackObserver<3, 1, 1>>
105 roll_joint_loop_;
106 const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>,
107 HybridKalman<3, 1, 1>>
108 hybrid_roll_joint_loop_;
milind-u37385182023-02-20 15:07:28 -0800109 EKF arm_ekf_;
milind-u18a901d2023-02-17 21:51:55 -0800110 SearchGraph search_graph_;
milind-u37385182023-02-20 15:07:28 -0800111 TrajectoryFollower follower_;
112
milind-u18a901d2023-02-17 21:51:55 -0800113 const ::std::vector<::Eigen::Matrix<double, 3, 1>> points_;
milind-u37385182023-02-20 15:07:28 -0800114
115 // Start at the 0th index.
116 uint32_t current_node_;
117
118 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
119};
milind-u01bbcf22023-02-20 18:00:28 -0800120
milind-u37385182023-02-20 15:07:28 -0800121} // namespace arm
122} // namespace superstructure
123} // namespace control_loops
124} // namespace y2023
125
126#endif // Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_