Stop using std::function in HybridEkf
Removes malloc's from the HybridEkf and localizer as a whole.
This solution feels a bit inelegant, but that's true of the entire
HybridEkf class (I may simplify some of this once we delete y2019).
Change-Id: I2deb5b1221ea17b08baad7e8bb46d6bbd1b987a6
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/y2020/control_loops/drivetrain/localizer.h b/y2020/control_loops/drivetrain/localizer.h
index 5458797..de57091 100644
--- a/y2020/control_loops/drivetrain/localizer.h
+++ b/y2020/control_loops/drivetrain/localizer.h
@@ -9,8 +9,8 @@
#include "aos/network/message_bridge_server_generated.h"
#include "frc971/control_loops/drivetrain/hybrid_ekf.h"
#include "frc971/control_loops/drivetrain/localizer.h"
-#include "y2020/control_loops/superstructure/superstructure_status_generated.h"
#include "y2020/control_loops/drivetrain/localizer_debug_generated.h"
+#include "y2020/control_loops/superstructure/superstructure_status_generated.h"
#include "y2020/vision/sift/sift_generated.h"
namespace y2020 {
@@ -95,6 +95,37 @@
std::array<int, kNumRejectionReasons> rejection_counts;
};
+ class Corrector : public HybridEkf::ExpectedObservationFunctor {
+ public:
+ Corrector(const Eigen::Matrix<float, 4, 4> &H_field_target,
+ const Pose &pose_robot_target, const State &state_at_capture,
+ const Eigen::Vector3f &Z,
+ std::optional<RejectionReason> *correction_rejection)
+ : H_field_target_(H_field_target),
+ pose_robot_target_(pose_robot_target),
+ state_at_capture_(state_at_capture),
+ Z_(Z),
+ correction_rejection_(correction_rejection) {
+ H_.setZero();
+ H_(0, StateIdx::kX) = 1;
+ H_(1, StateIdx::kY) = 1;
+ H_(2, StateIdx::kTheta) = 1;
+ }
+ Output H(const State &, const Input &) final;
+ Eigen::Matrix<float, HybridEkf::kNOutputs, HybridEkf::kNStates> DHDX(
+ const State &) final {
+ return H_;
+ }
+
+ private:
+ Eigen::Matrix<float, HybridEkf::kNOutputs, HybridEkf::kNStates> H_;
+ const Eigen::Matrix<float, 4, 4> H_field_target_;
+ Pose pose_robot_target_;
+ const State state_at_capture_;
+ const Eigen::Vector3f &Z_;
+ std::optional<RejectionReason> *correction_rejection_;
+ };
+
// Processes new image data from the given pi and updates the EKF.
aos::SizedArray<flatbuffers::Offset<ImageMatchDebug>, 5> HandleImageMatch(
size_t camera_index, std::string_view pi,
@@ -113,6 +144,7 @@
aos::EventLoop *const event_loop_;
const frc971::control_loops::drivetrain::DrivetrainConfig<double> dt_config_;
HybridEkf ekf_;
+ HybridEkf::ExpectedObservationAllocator<Corrector> observations_;
std::vector<aos::Fetcher<frc971::vision::sift::ImageMatchResult>>
image_fetchers_;