1516X Push Back 1.0
1516X's robot code for the 2025-2026 VEX Robotics Competition
Loading...
Searching...
No Matches
MCL.cpp
Go to the documentation of this file.
1#include "globals.h"
2#include <cmath>
3#include "lemlib/chassis/trackingWheel.hpp"
4#include "lemlib/util.hpp"
5#include "MCL.h"
6
7using namespace std;
8
9namespace MCL {
10 double X = 0, Y = 0, theta = 0;
11
12 mt19937 Random(random_device {} ());
13
14 double Velo = 0;
15 double Deviation;
18
19 vector<Particle> Particles(num_particles);
20
21 vector<MCLDistanceSensor> Sensors = {
22 MCLDistanceSensor(frontDistance, Point(-3, -0.75), FRONT),
23 MCLDistanceSensor(rightDistance, Point(6.3, -0.5), RIGHT),
24 MCLDistanceSensor(leftDistance, Point(-6.4, -0.5), LEFT),
25 MCLDistanceSensor(backDistance, Point(-3, -10.5), BACK),
26 };
27
28 Field field_;
29 vector<MCLDistanceSensor> activeSensors;
30
31 pros::Mutex particle_mutex;
32
33 double getAvgVelocity(void) noexcept;
34 void StartMCL(double x_, double y_, double theta_);
35 void MonteCarlo(void);
36
37 const double LOOP_DELAY_MS = 20.0;
38 const double LOOP_DT_SEC = LOOP_DELAY_MS / 1000.0;
39
40 void StartMCL(double x_, double y_, double theta_) {
41 particle_mutex.take();
42
43 Particles.clear();
44 Particles.resize(num_particles);
45
46 uniform_real_distribution<double> start_dist_x(-start_std_pos[0], start_std_pos[0]);
47 uniform_real_distribution<double> start_dist_y(-start_std_pos[1], start_std_pos[1]);
48 uniform_real_distribution<double> start_dist_theta(-start_std_pos[2], start_std_pos[2]);
49
50 for (int i = 0; i < num_particles; ++i) {
51 Particles[i].x = x_ + start_dist_x(Random);
52 Particles[i].y = y_ + start_dist_y(Random);
53 Particles[i].theta = lemlib::radToDeg(theta_) + start_dist_theta(Random);
54 Particles[i].weight = 1.0;
55 }
56
57 particle_mutex.give();
58 }
59
60 vector<Particle> Resampled(num_particles);
61 vector<double> CDF(num_particles);
62
63 void MonteCarlo(void) {
64 while (true) {
65 uint32_t start_time = pros::millis();
66
68 double distance_step = Velo * LOOP_DT_SEC;
69 normal_distribution<double> dist_pos(0, std::abs(distance_step * 0.25));
70
71 lemlib::Pose odomPose = chassis.getPose(true);
72 const double theta_ = odomPose.theta;
73 const double rotated_theta = M_PI_2 - theta_;
74 const float cos_theta = cosf(rotated_theta);
75 const float sin_theta = sinf(rotated_theta);
76
77 particle_mutex.take();
78
79 for (auto& p : Particles) {
80 p.theta = theta_;
81 p.step = Point(cos_theta, sin_theta);
82 p.x += (distance_step * cos_theta) + dist_pos(Random);
83 p.y += (distance_step * sin_theta) + dist_pos(Random);
84 p.x = std::clamp(p.x, -field_.HalfSize, field_.HalfSize);
85 p.y = std::clamp(p.y, -field_.HalfSize, field_.HalfSize);
86 }
87
88 for (auto& sensor : Sensors) {
89 sensor.Measure();
90 }
91
92 activeSensors.clear();
93 for (auto& sensor : Sensors) {
94 if (sensor.measurement > -1) {
95 activeSensors.push_back(sensor);
96 }
97 }
98
99 weights_sum = 0;
100 if (!activeSensors.empty()) {
101 for (auto& P : Particles) {
102 double wt = 1.0;
103 for (auto& sensor : activeSensors) {
104 const double predicted = field_.get_sensor_distance(P, sensor);
105 if (predicted < 0) {
106 wt = 0;
107 break;
108 }
109 Deviation = (predicted - sensor.measurement);
110 wt *= exp((Deviation * Deviation) * inv_varience) * inv_base;
111 }
112 weights_sum += wt;
113 P.weight = wt;
114 }
115 }
116
117 if (weights_sum < MIN_WEIGHT) {
118 const double Weight = inv_num_particles;
119 for (auto &p : Particles) p.weight = Weight;
120 } else {
121 const double inv = 1.0 / weights_sum;
122 for (auto &p : Particles) p.weight *= inv;
123 }
124
125 CDF[0] = Particles[0].weight;
126 for (int i = 1; i < num_particles; ++i) {
127 CDF[i] = CDF[i - 1] + Particles[i].weight;
128 }
129
130 uniform_real_distribution<double> dist(0, inv_num_particles);
131 if(Resampled.size() != num_particles) Resampled.resize(num_particles);
132
133 for (int i = 0; i < num_particles; ++i) {
134 const double sample_point = i * (inv_num_particles) + dist(Random);
135 auto it = lower_bound(CDF.begin(), CDF.end(), sample_point);
136 int index = std::distance(CDF.begin(), it);
137 if(index >= num_particles) index = num_particles - 1;
138 Resampled[i] = Particles[index];
139 }
141
142 double new_x = 0.0, new_y = 0.0, total_weight = 0.0;
143 for (const auto& p : Particles) {
144 new_x += p.x * p.weight;
145 new_y += p.y * p.weight;
146 total_weight += p.weight;
147 }
148
149 if (total_weight > 0) {
150 new_x /= total_weight;
151 new_y /= total_weight;
152 }
153
154 X = new_x;
155 Y = new_y;
156
157 particle_mutex.give();
158
159 double dist_error = std::hypot(odomPose.x - X, odomPose.y - Y);
160
161 cout << " time: (" << pros::millis() - start_time << ") " << std::endl;
162
163 pros::Task::delay_until(&start_time, LOOP_DELAY_MS);
164 }
165 }
166
167 const float wheel_circumference = (float)lemlib::Omniwheel::NEW_325 * M_PI;
168 const float gear_ratio = 4.0f / 3.0f;
170
171 double getAvgVelocity(void) noexcept {
172 const double V = (leftMotors.get_actual_velocity() * rpm_to_ips_factor + rightMotors.get_actual_velocity() * rpm_to_ips_factor) / 2.0;
173 return V;
174 }
175}
pros::Distance backDistance(11)
pros::Distance frontDistance(13)
pros::Distance leftDistance(12)
pros::Distance rightDistance(6)
pros::MotorGroup rightMotors
lemlib::Chassis chassis
pros::MotorGroup leftMotors
Definition globals.cpp:20
Definition MCL.cpp:9
const float wheel_circumference
Definition MCL.cpp:167
vector< MCLDistanceSensor > activeSensors
Definition MCL.cpp:29
double Y
Definition MCL.cpp:10
const double LOOP_DELAY_MS
Definition MCL.cpp:37
mt19937 Random(random_device {}())
double Deviation
Definition MCL.cpp:15
double X
Definition MCL.cpp:10
double getAvgVelocity(void) noexcept
Definition MCL.cpp:171
double start_theta
Definition MCL.cpp:17
double Velo
Definition MCL.cpp:14
pros::Mutex particle_mutex
Definition MCL.cpp:31
const float gear_ratio
Definition MCL.cpp:168
const double LOOP_DT_SEC
Definition MCL.cpp:38
vector< MCLDistanceSensor > Sensors
Definition MCL.cpp:21
const float rpm_to_ips_factor
Definition MCL.cpp:169
vector< Particle > Particles(num_particles)
void MonteCarlo(void)
Definition MCL.cpp:63
vector< Particle > Resampled(num_particles)
double weights_sum
Definition MCL.cpp:16
double theta
Definition MCL.cpp:10
void StartMCL(double x_, double y_, double theta_)
Definition MCL.cpp:40
vector< double > CDF(num_particles)
Field field_
Definition MCL.cpp:28