Tracking Wheel Width
If you plan on tuning wheel diameter, you must do that before this!
What is it?​
Track width is calculated at your tracking wheel by default. Modifying tracking wheel width offsets your "tracking center", and the goal is to get this as close to the center of rotation of your robot as possible.
Modifying width on left/right trackers will move your tracking center to the left/right.
- If this isn't accurate, the robot may behave differently when moving to the right vs moving to the left
- The more accurate this is, the closer your autons will be after mirroring them
Modifying width on front/back trackers will move your tracking center forwards and backwards.
- If this isn't accurate, the robot's XY position will change during turns and will make where the robot currently is unintuitive
If you aren't using tracking wheels, you don't need any offsets!
measure_offsets()​
As of 3.2.0, the example project ships with an autonomous routine called measure_offsets()
that will turn the robot 10 times and calculate out what your offsets should be.
///
// Calculate the offsets of your tracking wheels
///
void measure_offsets() {
// Number of times to test
int iterations = 10;
// Our final offsets
double l_offset = 0.0, r_offset = 0.0, b_offset = 0.0, f_offset = 0.0;
// Reset all trackers if they exist
if (chassis.odom_tracker_left != nullptr) chassis.odom_tracker_left->reset();
if (chassis.odom_tracker_right != nullptr) chassis.odom_tracker_right->reset();
if (chassis.odom_tracker_back != nullptr) chassis.odom_tracker_back->reset();
if (chassis.odom_tracker_front != nullptr) chassis.odom_tracker_front->reset();
for (int i = 0; i < iterations; i++) {
// Reset pid targets and get ready for running an auton
chassis.pid_targets_reset();
chassis.drive_imu_reset();
chassis.drive_sensor_reset();
chassis.drive_brake_set(MOTOR_BRAKE_HOLD);
chassis.odom_xyt_set(0_in, 0_in, 0_deg);
double imu_start = chassis.odom_theta_get();
double target = i % 2 == 0 ? 90 : 270; // Switch the turn target every run from 270 to 90
// Turn to target at half power
chassis.pid_turn_set(target, 63, ez::raw);
chassis.pid_wait();
pros::delay(250);
// Calculate delta in angle
double t_delta = util::to_rad(fabs(util::wrap_angle(chassis.odom_theta_get() - imu_start)));
// Calculate delta in sensor values that exist
double l_delta = chassis.odom_tracker_left != nullptr ? chassis.odom_tracker_left->get() : 0.0;
double r_delta = chassis.odom_tracker_right != nullptr ? chassis.odom_tracker_right->get() : 0.0;
double b_delta = chassis.odom_tracker_back != nullptr ? chassis.odom_tracker_back->get() : 0.0;
double f_delta = chassis.odom_tracker_front != nullptr ? chassis.odom_tracker_front->get() : 0.0;
// Calculate the radius that the robot traveled
l_offset += l_delta / t_delta;
r_offset += r_delta / t_delta;
b_offset += b_delta / t_delta;
f_offset += f_delta / t_delta;
}
// Average all offsets
l_offset /= iterations;
r_offset /= iterations;
b_offset /= iterations;
f_offset /= iterations;
// Set new offsets to trackers that exist
if (chassis.odom_tracker_left != nullptr) chassis.odom_tracker_left->distance_to_center_set(l_offset);
if (chassis.odom_tracker_right != nullptr) chassis.odom_tracker_right->distance_to_center_set(r_offset);
if (chassis.odom_tracker_back != nullptr) chassis.odom_tracker_back->distance_to_center_set(b_offset);
if (chassis.odom_tracker_front != nullptr) chassis.odom_tracker_front->distance_to_center_set(f_offset);
}
Displaying to Screen​
These offsets will get displayed to the first blank page, this also ships with the example project as of 3.2.0.
/**
* Simplifies printing tracker values to the brain screen
*/
void screen_print_tracker(ez::tracking_wheel *tracker, std::string name, int line) {
std::string tracker_value = "", tracker_width = "";
// Check if the tracker exists
if (tracker != nullptr) {
tracker_value = name + " tracker: " + util::to_string_with_precision(tracker->get()); // Make text for the tracker value
tracker_width = " width: " + util::to_string_with_precision(tracker->distance_to_center_get()); // Make text for the distance to center
}
ez::screen_print(tracker_value + tracker_width, line); // Print final tracker text
}
/**
* Ez screen task
* Adding new pages here will let you view them during user control or autonomous
* and will help you debug problems you're having
*/
void ez_screen_task() {
while (true) {
// Only run this when not connected to a competition switch
if (!pros::competition::is_connected()) {
// Blank page for odom debugging
if (chassis.odom_enabled() && !chassis.pid_tuner_enabled()) {
// If we're on the first blank page...
if (ez::as::page_blank_is_on(0)) {
// Display X, Y, and Theta
ez::screen_print("x: " + util::to_string_with_precision(chassis.odom_x_get()) +
"\ny: " + util::to_string_with_precision(chassis.odom_y_get()) +
"\na: " + util::to_string_with_precision(chassis.odom_theta_get()),
1); // Don't override the top Page line
// Display all trackers that are being used
screen_print_tracker(chassis.odom_tracker_left, "l", 4);
screen_print_tracker(chassis.odom_tracker_right, "r", 5);
screen_print_tracker(chassis.odom_tracker_back, "b", 6);
screen_print_tracker(chassis.odom_tracker_front, "f", 7);
}
}
}
// Remove all blank pages when connected to a comp switch
else {
if (ez::as::page_blank_amount() > 0)
ez::as::page_blank_remove_all();
}
pros::delay(ez::util::DELAY_TIME);
}
}
pros::Task ezScreenTask(ez_screen_task);
Modifying Constants​
Go to the measure_offsets()
page on the autonomous selector and run the autonomous (press B
and DOWN
at the same time, or use a competition switch). This will start running the measure_offsets()
autonomous routine.
Once this is complete, go to Blank Page 1. The new widths that measure_offsets()
calculated will be here.
Go into your code and replace your tracking wheel widths with these new values. Replace 4.0
with your new values.
ez::tracking_wheel right_tracker({-'A', -'B'}, 2.75, 4.0); // ADI Encoders
ez::tracking_wheel left_tracker(1, {'C', 'D'}, 2.75, 4.0); // ADI Encoders plugged into a Smart port
ez::tracking_wheel horiz_tracker(1, 2.75, 4.0); // Rotation sensors