1516X Push Back 1.0
1516X's robot code for the 2025-2026 VEX Robotics Competition
Loading...
Searching...
No Matches
distanceReset.cpp
Go to the documentation of this file.
1#include "globals.h"
2#include "lemlib/util.hpp"
3#include "pros/distance.hpp"
4#include <numeric>
5
6const double MM_TO_IN = 0.0393701;
7const double FIELD_WIDTH = 3566.668 * MM_TO_IN;
8const double FIELD_HEIGHT = 3566.668 * MM_TO_IN;
9const double HALF_WIDTH = FIELD_WIDTH / 2.0;
10const double HALF_HEIGHT = FIELD_HEIGHT / 2.0;
11const double MAX_SENSOR_RANGE = 2000 * MM_TO_IN;
12const double MIN_SENSOR_RANGE = 0 * MM_TO_IN;
13
15
21
22
23const SensorConfig front_sensor_cfg = {4.067 + 0.2, 5.756, 0};
24const SensorConfig left_sensor_cfg = {-0.5, -6.039 + 0.69, 90};
25const SensorConfig right_sensor_cfg = {0.5, 6.039 - 1, -90};
26const SensorConfig back_sensor_cfg = {-2.691 + 2.7, 3.879, 180};
27
29 double dist_mm;
32};
33
35 double x;
36 double y;
39};
40
42 const SensorReadings& front_data,
43 const SensorReadings& left_data,
44 const SensorReadings& right_data,
45 const SensorReadings& back_data,
46 double heading_deg)
47{
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);
53
54 bool using_odom_x = true;
55 bool using_odom_y = true;
56
57 struct SensorData { SensorConfig cfg; double dist_in; int confidence;};
58 const SensorData sensors[] = {
59 {front_sensor_cfg, front_data.dist_mm * MM_TO_IN, frontDistance.get_confidence()},
60 {left_sensor_cfg, left_data.dist_mm * MM_TO_IN, leftDistance.get_confidence()},
61 {right_sensor_cfg, right_data.dist_mm * MM_TO_IN, rightDistance.get_confidence()},
62 {back_sensor_cfg, back_data.dist_mm * MM_TO_IN, backDistance.get_confidence()}
63 };
64
65 auto is_valid = [&](int i) {
66 return (sensors[i].dist_in < MAX_SENSOR_RANGE &&
67 sensors[i].dist_in >= MIN_SENSOR_RANGE);
68 };
69
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;
73
74 std::vector<double> x_cands;
75 std::vector<double> y_cands;
76
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);
80 double global_offset_x = (cfg.forward_offset * sin_h) + (cfg.strafe_offset * cos_h);
81 double global_offset_y = (cfg.forward_offset * cos_h) - (cfg.strafe_offset * sin_h);
82 return std::make_pair(global_offset_x, global_offset_y);
83 };
84
85
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);
94
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);
99
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); }
104 }
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);
108
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);
113
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);
118
119
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); }
124 }
125
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);
129
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);
134
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);
139
140
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); }
145 }
146
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);
150
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);
155
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);
160
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); }
165 }
166
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;
170 }
171
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;
175 }
176
177
178 distancePose pose;
179 pose.x = est_x;
180 pose.y = est_y;
181 pose.using_odom_x = using_odom_x;
182 pose.using_odom_y = using_odom_y;
183 return pose;
184}
185
186
187distancePose distanceReset(bool setPose = false, bool filter = true, float filter_range = 3.5) {
188 double heading_deg = chassis.getPose().theta;
189
190 const SensorReadings front_data = {(double)frontDistance.get_distance(), frontDistance.get_object_size(), frontDistance.get_confidence()};
191 const SensorReadings left_data = {(double)leftDistance.get_distance(), leftDistance.get_object_size(), leftDistance.get_confidence()};
192 const SensorReadings right_data = {(double)rightDistance.get_distance(), rightDistance.get_object_size(), rightDistance.get_confidence()};
193 const SensorReadings back_data = {(double)backDistance.get_distance(), backDistance.get_object_size(), backDistance.get_confidence()};
194
195 distancePose pose = calculateGlobalPosition(front_data, left_data, right_data, back_data, heading_deg);
196 if(filter)
197 {
198 if(std::abs(pose.x - chassis.getPose().x) > filter_range)
199 {
200 pose.x = chassis.getPose().x;
201 pose.using_odom_x = true;
202 std::cout << "Filtered X" << std::endl;
203 }
204 if(std::abs(pose.y - chassis.getPose().y) > filter_range)
205 {
206 pose.y = chassis.getPose().y;
207 pose.using_odom_y = true;
208 std::cout << "Filtered Y" << std::endl;
209 }
210
211 }
212 if(setPose) {
213 chassis.setPose(pose.x, pose.y, chassis.getPose().theta);
214 pros::delay(2);
215 }
216
217 std::cout << "Distance Reset Pose: " << pose.x << ", " << pose.y << ", using_odom_x: " << pose.using_odom_x << ", using_odom_y: " << pose.using_odom_y << std::endl;
218 return pose;
219}
220
221distancePose distanceReset(bool left_use, bool right_use, bool front_use, bool back_use, bool setPose) {
222 double heading_deg = chassis.getPose().theta;
223
224 const int invalid_dist_mm = 10000;
225 const int invalid_confidence = 0;
226
227 // Direct readings based on boolean flags
228 SensorReadings front_data = front_use
229 ? SensorReadings{(double)frontDistance.get_distance(), frontDistance.get_object_size(), frontDistance.get_confidence()}
230 : SensorReadings{invalid_dist_mm, 0, invalid_confidence};
231
232 SensorReadings left_data = left_use
233 ? SensorReadings{(double)leftDistance.get_distance(), leftDistance.get_object_size(), leftDistance.get_confidence()}
234 : SensorReadings{invalid_dist_mm, 0, invalid_confidence};
235
236 SensorReadings right_data = right_use
237 ? SensorReadings{(double)rightDistance.get_distance(), rightDistance.get_object_size(), rightDistance.get_confidence()}
238 : SensorReadings{invalid_dist_mm, 0, invalid_confidence};
239
240 SensorReadings back_data = back_use
241 ? SensorReadings{(double)backDistance.get_distance(), backDistance.get_object_size(), backDistance.get_confidence()}
242 : SensorReadings{invalid_dist_mm, 0, invalid_confidence};
243
244 distancePose pose = calculateGlobalPosition(front_data, left_data, right_data, back_data, heading_deg);
245
246 if(setPose) {
247 chassis.setPose(pose.x, pose.y, chassis.getPose().theta);
248 }
249
250 return pose;
251}
const double MAX_SENSOR_RANGE
distancePose distanceReset(bool setPose=false, bool filter=true, float filter_range=3.5)
const double MM_TO_IN
const double FIELD_HEIGHT
bool controller_screen_avilable
const SensorConfig left_sensor_cfg
const SensorConfig back_sensor_cfg
distancePose calculateGlobalPosition(const SensorReadings &front_data, const SensorReadings &left_data, const SensorReadings &right_data, const SensorReadings &back_data, double heading_deg)
const SensorConfig right_sensor_cfg
const double HALF_WIDTH
const SensorConfig front_sensor_cfg
const double FIELD_WIDTH
const double HALF_HEIGHT
const double MIN_SENSOR_RANGE
pros::Distance backDistance(7)
Chassis chassis(drivebase, lateral_controller, angular_controller, sensors, &throttle_curve, &steer_curve)
pros::Distance leftDistance(5)
pros::Distance rightDistance(6)
pros::Distance frontDistance(8)
double mounting_angle
double forward_offset