Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
data_association.cpp
Go to the documentation of this file.
1
3
4#include <float.h>
5
6#include <fstream>
7#include <iostream>
8#include <rclcpp/rclcpp.hpp>
9
11
12 : max_landmark_distance_(max_landmark_distance){};
13
17
18float MaxLikelihood::association_gate_ = 4.991f; // Default value, can be overridden
20MaxLikelihood::MaxLikelihood(float max_landmark_distance)
21 : DataAssociationModel(max_landmark_distance) {
22 if (max_landmark_distance < 1 || association_gate_ < 0 || new_landmark_gate_ < 0) {
23 throw std::invalid_argument("Invalid parameters for MaxLikelihood");
24 }
25};
26
28 const std::vector<common_lib::structures::Cone>& perception_map, Eigen::VectorXf& _x_vector_,
29 Eigen::MatrixXf& _p_matrix_, std::vector<int>& matched_ids,
30 std::vector<Eigen::Vector2f>& matched_cone_positions,
31 std::vector<Eigen::Vector2f>& new_features, ObservationModel* observation_model) const {
32 for (const common_lib::structures::Cone& cone : perception_map) {
33 Eigen::Vector2f landmark_absolute = observation_model->inverse_observation_model(
34 _x_vector_, ObservationData(cone.position.x, cone.position.y,
35 common_lib::competition_logic::Color::BLUE));
36
37 float distance_to_vehicle = (landmark_absolute - _x_vector_.segment<2>(0)).norm();
38
39 if (distance_to_vehicle > this->get_max_landmark_distance()) {
40 continue;
41 }
42
43 int j_best = 0;
44 float n_best = std::numeric_limits<int>::max();
45 float outer = std::numeric_limits<int>::max();
46 for (int j = 6; j < _x_vector_.size(); j += 2) {
47 Eigen::Vector2f z_hat = observation_model->observation_model(_x_vector_, j);
48
49 Eigen::MatrixXf h_matrix = observation_model->get_state_to_observation_matrix(
50 _x_vector_, j, static_cast<unsigned int>(_x_vector_.size()));
51 // get the observation noise covariance matrix
52 Eigen::MatrixXf q_matrix = observation_model->get_observation_noise_covariance_matrix();
53
54 Eigen::Vector2f innovation = Eigen::Vector2f(cone.position.x, cone.position.y) - z_hat;
55
56 Eigen::MatrixXf s_matrix = h_matrix * _p_matrix_ * h_matrix.transpose() + q_matrix;
57 // calculate nis, that means normalized innovation squared
58 float nis = innovation.transpose() * s_matrix.inverse() * innovation;
59
60 float nd = nis + log(s_matrix.determinant());
61
62 if (nis < this->association_gate_ && nd < n_best) { // 4.991
63 n_best = nd;
64 j_best = j;
65 } else if (nis < outer) {
66 outer = nis; // outer is the closest unmatched distanced
67 }
68 }
69 if (j_best != 0) {
70 matched_ids.push_back(j_best);
71 matched_cone_positions.push_back(Eigen::Vector2f(cone.position.x, cone.position.y));
72 } else if (outer > this->new_landmark_gate_) { // 20 TUNE
73 new_features.push_back(Eigen::Vector2f(cone.position.x, cone.position.y));
74 }
75 }
76 return 0;
77};
Data Association Method class, used to match observations to landmarks in the map.
DataAssociationModel()=default
float max_landmark_distance_
Check if the observed landmark is a valid match to the expected landmark It depends on external param...
float get_max_landmark_distance() const
MaxLikelihood(float max_landmark_distance)
Construct a new Max Likelihood object.
int associate_n_filter(const std::vector< common_lib::structures::Cone > &perception_map, Eigen::VectorXf &_x_vector_, Eigen::MatrixXf &_p_matrix_, std::vector< int > &matched_ids, std::vector< Eigen::Vector2f > &matched_cone_positions, std::vector< Eigen::Vector2f > &new_features, ObservationModel *observation_model) const override
normalized distance gate (closest unmatched landmark)
static float new_landmark_gate_
normalized innovation squared gate
static float association_gate_
Observation Model class compiled of functions for observation model.
Eigen::Vector2f observation_model(const Eigen::VectorXf &expected_state, const unsigned int landmark_index) const
Calculate expected observation from the state vector.
Eigen::Vector2f inverse_observation_model(const Eigen::VectorXf &expected_state, const ObservationData &observation_data) const
Calculate landmark position from observation.
Eigen::MatrixXf get_observation_noise_covariance_matrix() const
Get the observation noise covariance matrix (C or H)
Eigen::MatrixXf get_state_to_observation_matrix(const Eigen::VectorXf &expected_state, const unsigned int landmark_index, const unsigned int state_size) const
Get the state to observation matrix of the observation model (H in LaTeX documentation)
Struct containing observation data.