50 float heading_tolerance = 40.0)
52 lemlib::Pose current_pose =
chassis.getPose();
53 double est_x = current_pose.x;
54 double est_y = current_pose.y;
55 bool use_pos_x_wall = (est_x >= 0);
56 bool use_pos_y_wall = (est_y >= 0);
58 bool using_odom_x =
true;
59 bool using_odom_y =
true;
61 struct SensorData {
SensorConfig cfg;
double dist_in;
int confidence;};
62 const SensorData sensors[] = {
69 auto is_valid = [&](
int i) {
74 double norm_heading = std::fmod(heading_deg, 360.0);
75 if (norm_heading < 0) norm_heading += 360.0;
76 const double TOLERANCE = heading_tolerance;
78 std::vector<double> x_cands;
79 std::vector<double> y_cands;
81 auto get_global_offsets = [&](
const SensorConfig& cfg,
double heading_rad) {
82 double cos_h = std::cos(heading_rad);
83 double sin_h = std::sin(heading_rad);
86 return std::make_pair(global_offset_x, global_offset_y);
90 if (norm_heading <= TOLERANCE || norm_heading >= 360.0 - TOLERANCE) {
91 double angle_off_rad = (norm_heading <= TOLERANCE) ?
92 lemlib::degToRad(norm_heading) : lemlib::degToRad(norm_heading - 360.0);
93 double heading_rad = angle_off_rad;
94 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
95 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
96 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
97 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
99 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
100 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
101 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
102 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
104 if (is_valid(0) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_0 - offset_0.second); }
105 if (is_valid(3) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_3 - offset_3.second); }
106 if (is_valid(1) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_1 - offset_1.first); }
107 if (is_valid(2) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_2 - offset_2.first); }
109 else if (std::fabs(norm_heading - 180.0) <= TOLERANCE) {
110 double angle_off_rad = lemlib::degToRad(norm_heading - 180.0);
111 double heading_rad = lemlib::degToRad(norm_heading);
113 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
114 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
115 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
116 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
118 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
119 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
120 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
121 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
124 if (is_valid(0) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_0 - offset_0.second); }
125 if (is_valid(3) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_3 - offset_3.second); }
126 if (is_valid(1) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_1 - offset_1.first); }
127 if (is_valid(2) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_2 - offset_2.first); }
130 else if (std::fabs(norm_heading - 90.0) <= TOLERANCE) {
131 double angle_off_rad = lemlib::degToRad(norm_heading - 90.0);
132 double heading_rad = lemlib::degToRad(norm_heading);
134 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
135 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
136 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
137 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
139 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
140 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
141 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
142 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
145 if (is_valid(0) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_0 - offset_0.first); }
146 if (is_valid(3) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_3 - offset_3.first); }
147 if (is_valid(1) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_1 - offset_1.second); }
148 if (is_valid(2) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_2 - offset_2.second); }
151 else if (std::fabs(norm_heading - 270.0) <= TOLERANCE) {
152 double angle_off_rad = lemlib::degToRad(norm_heading - 270.0);
153 double heading_rad = lemlib::degToRad(norm_heading);
155 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
156 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
157 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
158 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
160 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
161 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
162 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
163 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
165 if (is_valid(0) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_0 - offset_0.first); }
166 if (is_valid(3) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_3 - offset_3.first); }
167 if (is_valid(1) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_1 - offset_1.second); }
168 if (is_valid(2) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_2 - offset_2.second); }
171 if (!x_cands.empty()) {
172 est_x = std::accumulate(x_cands.begin(), x_cands.end(), 0.0) / x_cands.size();
173 using_odom_x =
false;
176 if (!y_cands.empty()) {
177 est_y = std::accumulate(y_cands.begin(), y_cands.end(), 0.0) / y_cands.size();
178 using_odom_y =
false;