blob: 2160b3832c7a42f9ff4ba0494d5d7907f83621f1 [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"
James Kuszmaulec635d22023-08-12 18:39:24 -07008#include "frc971/zeroing/pot_and_absolute_encoder.h"
milind-u37385182023-02-20 15:07:28 -08009#include "frc971/zeroing/zeroing.h"
10#include "y2023/constants.h"
11#include "y2023/control_loops/superstructure/arm/generated_graph.h"
milind-u18a901d2023-02-17 21:51:55 -080012#include "y2023/control_loops/superstructure/arm/trajectory.h"
milind-u37385182023-02-20 15:07:28 -080013#include "y2023/control_loops/superstructure/superstructure_position_generated.h"
14#include "y2023/control_loops/superstructure/superstructure_status_generated.h"
15
16using frc971::control_loops::arm::EKF;
milind-u37385182023-02-20 15:07:28 -080017
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080018namespace y2023::control_loops::superstructure::arm {
milind-u37385182023-02-20 15:07:28 -080019
20class Arm {
21 public:
Maxwell Hendersonb392b742023-03-05 07:53:51 -080022 Arm(std::shared_ptr<const constants::Values> values,
23 const ArmTrajectories &arm_trajectories);
milind-u37385182023-02-20 15:07:28 -080024
milind-u37385182023-02-20 15:07:28 -080025 flatbuffers::Offset<superstructure::ArmStatus> Iterate(
26 const ::aos::monotonic_clock::time_point /*monotonic_now*/,
27 const uint32_t *unsafe_goal, const superstructure::ArmPosition *position,
28 bool trajectory_override, double *proximal_output, double *distal_output,
Maxwell Henderson5938a832023-02-23 09:33:15 -080029 double *roll_joint_output, flatbuffers::FlatBufferBuilder *fbb);
milind-u37385182023-02-20 15:07:28 -080030
31 void Reset();
32
33 ArmState state() const { return state_; }
milind-u37385182023-02-20 15:07:28 -080034
milind-u01bbcf22023-02-20 18:00:28 -080035 bool estopped() const { return state_ == ArmState::ESTOP; }
milind-u37385182023-02-20 15:07:28 -080036 bool zeroed() const {
37 return (proximal_zeroing_estimator_.zeroed() &&
milind-u18a901d2023-02-17 21:51:55 -080038 distal_zeroing_estimator_.zeroed() &&
39 roll_joint_zeroing_estimator_.zeroed());
milind-u37385182023-02-20 15:07:28 -080040 }
milind-u01bbcf22023-02-20 18:00:28 -080041
milind-u37385182023-02-20 15:07:28 -080042 uint32_t current_node() const { return current_node_; }
milind-u01bbcf22023-02-20 18:00:28 -080043
milind-u37385182023-02-20 15:07:28 -080044 double path_distance_to_go() { return follower_.path_distance_to_go(); }
45
46 private:
47 bool AtState(uint32_t state) const { return current_node_ == state; }
48 bool NearEnd(double threshold = 0.03) const {
49 return ::std::abs(arm_ekf_.X_hat(0) - follower_.theta(0)) <= threshold &&
50 ::std::abs(arm_ekf_.X_hat(2) - follower_.theta(1)) <= threshold &&
51 follower_.path_distance_to_go() < 1e-3;
52 }
53
Maxwell Hendersonb392b742023-03-05 07:53:51 -080054 static SearchGraph GetSearchGraph(const ArmTrajectories &arm_trajectories) {
55 // Creating edges from fbs
56 std::vector<SearchGraph::Edge> edges;
57
58 for (const auto *edge : *arm_trajectories.edges()) {
59 SearchGraph::Edge edge_data{
60 .start = static_cast<size_t>(edge->start()),
61 .end = static_cast<size_t>(edge->end()),
62 .cost = edge->cost(),
63 };
64
65 edges.emplace_back(edge_data);
66 }
67
68 return SearchGraph(edges.size(), std::move(edges));
69 }
70
milind-u37385182023-02-20 15:07:28 -080071 std::shared_ptr<const constants::Values> values_;
milind-u01bbcf22023-02-20 18:00:28 -080072
milind-u37385182023-02-20 15:07:28 -080073 ArmState state_;
74
75 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
76 proximal_zeroing_estimator_;
77 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
78 distal_zeroing_estimator_;
milind-u18a901d2023-02-17 21:51:55 -080079 ::frc971::zeroing::PotAndAbsoluteEncoderZeroingEstimator
80 roll_joint_zeroing_estimator_;
milind-u37385182023-02-20 15:07:28 -080081
82 double proximal_offset_;
83 double distal_offset_;
milind-u18a901d2023-02-17 21:51:55 -080084 double roll_joint_offset_;
milind-u01bbcf22023-02-20 18:00:28 -080085
milind-u18a901d2023-02-17 21:51:55 -080086 const ::Eigen::DiagonalMatrix<double, 3> alpha_unitizer_;
milind-u01bbcf22023-02-20 18:00:28 -080087
Maxwell Henderson5c47a462023-02-25 14:40:44 -080088 double vmax_ = constants::Values::kArmVMax();
milind-u37385182023-02-20 15:07:28 -080089
90 frc971::control_loops::arm::Dynamics dynamics_;
91
92 ::std::vector<TrajectoryAndParams> trajectories_;
milind-u37385182023-02-20 15:07:28 -080093
94 bool close_enough_for_full_power_;
95
96 size_t brownout_count_;
97
milind-u18a901d2023-02-17 21:51:55 -080098 StateFeedbackLoop<3, 1, 1, double, StateFeedbackPlant<3, 1, 1>,
99 StateFeedbackObserver<3, 1, 1>>
100 roll_joint_loop_;
101 const StateFeedbackLoop<3, 1, 1, double, StateFeedbackHybridPlant<3, 1, 1>,
102 HybridKalman<3, 1, 1>>
103 hybrid_roll_joint_loop_;
milind-u37385182023-02-20 15:07:28 -0800104 EKF arm_ekf_;
milind-u18a901d2023-02-17 21:51:55 -0800105 SearchGraph search_graph_;
milind-u37385182023-02-20 15:07:28 -0800106 TrajectoryFollower follower_;
107
milind-u18a901d2023-02-17 21:51:55 -0800108 const ::std::vector<::Eigen::Matrix<double, 3, 1>> points_;
milind-u37385182023-02-20 15:07:28 -0800109
110 // Start at the 0th index.
111 uint32_t current_node_;
112
113 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
114};
milind-u01bbcf22023-02-20 18:00:28 -0800115
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800116} // namespace y2023::control_loops::superstructure::arm
milind-u37385182023-02-20 15:07:28 -0800117
118#endif // Y2023_CONTROL_LOOPS_SUPERSTRUCTURE_ARM_ARM_H_