48 lemlib::Pose current_pose =
chassis.getPose();
49 double est_x = current_pose.x;
50 double est_y = current_pose.y;
51 bool use_pos_x_wall = (est_x >= 0);
52 bool use_pos_y_wall = (est_y >= 0);
54 bool using_odom_x =
true;
55 bool using_odom_y =
true;
57 struct SensorData {
SensorConfig cfg;
double dist_in;
int confidence;};
58 const SensorData sensors[] = {
65 auto is_valid = [&](
int i) {
70 double norm_heading = std::fmod(heading_deg, 360.0);
71 if (norm_heading < 0) norm_heading += 360.0;
72 const double TOLERANCE = 40.0;
74 std::vector<double> x_cands;
75 std::vector<double> y_cands;
77 auto get_global_offsets = [&](
const SensorConfig& cfg,
double heading_rad) {
78 double cos_h = std::cos(heading_rad);
79 double sin_h = std::sin(heading_rad);
82 return std::make_pair(global_offset_x, global_offset_y);
86 if (norm_heading <= TOLERANCE || norm_heading >= 360.0 - TOLERANCE) {
87 double angle_off_rad = (norm_heading <= TOLERANCE) ?
88 lemlib::degToRad(norm_heading) : lemlib::degToRad(norm_heading - 360.0);
89 double heading_rad = angle_off_rad;
90 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
91 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
92 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
93 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
95 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
96 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
97 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
98 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
100 if (is_valid(0) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_0 - offset_0.second); }
101 if (is_valid(3) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_3 - offset_3.second); }
102 if (is_valid(1) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_1 - offset_1.first); }
103 if (is_valid(2) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_2 - offset_2.first); }
105 else if (std::fabs(norm_heading - 180.0) <= TOLERANCE) {
106 double angle_off_rad = lemlib::degToRad(norm_heading - 180.0);
107 double heading_rad = lemlib::degToRad(norm_heading);
109 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
110 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
111 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
112 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
114 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
115 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
116 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
117 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
120 if (is_valid(0) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_0 - offset_0.second); }
121 if (is_valid(3) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_3 - offset_3.second); }
122 if (is_valid(1) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_1 - offset_1.first); }
123 if (is_valid(2) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_2 - offset_2.first); }
126 else if (std::fabs(norm_heading - 90.0) <= TOLERANCE) {
127 double angle_off_rad = lemlib::degToRad(norm_heading - 90.0);
128 double heading_rad = lemlib::degToRad(norm_heading);
130 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
131 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
132 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
133 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
135 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
136 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
137 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
138 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
141 if (is_valid(0) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_0 - offset_0.first); }
142 if (is_valid(3) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_3 - offset_3.first); }
143 if (is_valid(1) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_1 - offset_1.second); }
144 if (is_valid(2) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_2 - offset_2.second); }
147 else if (std::fabs(norm_heading - 270.0) <= TOLERANCE) {
148 double angle_off_rad = lemlib::degToRad(norm_heading - 270.0);
149 double heading_rad = lemlib::degToRad(norm_heading);
151 double perp_dist_0 = sensors[0].dist_in * std::cos(angle_off_rad);
152 double perp_dist_3 = sensors[3].dist_in * std::cos(angle_off_rad);
153 double perp_dist_1 = sensors[1].dist_in * std::cos(angle_off_rad);
154 double perp_dist_2 = sensors[2].dist_in * std::cos(angle_off_rad);
156 auto offset_0 = get_global_offsets(sensors[0].cfg, heading_rad);
157 auto offset_1 = get_global_offsets(sensors[1].cfg, heading_rad);
158 auto offset_2 = get_global_offsets(sensors[2].cfg, heading_rad);
159 auto offset_3 = get_global_offsets(sensors[3].cfg, heading_rad);
161 if (is_valid(0) && !use_pos_x_wall) { x_cands.push_back(-
HALF_WIDTH + perp_dist_0 - offset_0.first); }
162 if (is_valid(3) && use_pos_x_wall) { x_cands.push_back(
HALF_WIDTH - perp_dist_3 - offset_3.first); }
163 if (is_valid(1) && !use_pos_y_wall) { y_cands.push_back(-
HALF_HEIGHT + perp_dist_1 - offset_1.second); }
164 if (is_valid(2) && use_pos_y_wall) { y_cands.push_back(
HALF_HEIGHT - perp_dist_2 - offset_2.second); }
167 if (!x_cands.empty()) {
168 est_x = std::accumulate(x_cands.begin(), x_cands.end(), 0.0) / x_cands.size();
169 using_odom_x =
false;
172 if (!y_cands.empty()) {
173 est_y = std::accumulate(y_cands.begin(), y_cands.end(), 0.0) / y_cands.size();
174 using_odom_y =
false;