Tracking Wheels for Odometry using the Potentiometer V2

Previously, every VRC team implementing odometry with tracking wheels (otherwise known as dead wheels) have used the quadrature encoders to gather their measurements. To those familiar with the algorithm this is a no-brainer. You need 360° tracking, high refresh rates, and good resolution. These encoders have a 10ms refresh rate with the V5 brain through the ADI port and measure 360 ticks/rotation or 1°/tick. This is good, and a lot better than the 20ms for the new rotation sensor.

The trade you make by using the rotation sensor, now that it’s released, is you half your rate, but gain 100x more resolution (360° vs 360.00°). I’ll leave arguments over whether this is a worthwhile trade to other threads. What I’m proposing is a 3rd option that takes the best of both, adds a bit of complexity in, but results in an overall better result.


The new potentiometers are a perfect candidate for use on tracking wheels. Continuous rotation, 333° sensing range, 12 bit precision, and run off the 3-Wire ports.

These sensors return [0,4096) over [0,333), giving us ≈12.3 ticks/degree of resolution, they update every 10ms, and all they need is minimal logic to swap between two sensors to avoid the 27° dead zone as they rotate.

So long as we orient the internals of the potentiometers opposite of each other, guaranteeing both dead zones are as far apart as possible, we give ourselves more than enough buffer to ensure we never spin into a dead zone before switching. You’re welcome to double check my math, but on a 350 RPM 4" wheel drive (1400π inches/minute) with these sensors mounted to a 2.75" wheel, the maximum degrees/10ms window is ≈30.546° which can never cross both dead zones so long as you don’t screw up orientation. When it comes to implementing the switching in code, simply alternating the sensor once it is 50° from it’s deadzone on both sides provides ample buffer and minimal complexity.

Obviously a major priority for this all is the space tracking wheels take up, but using two of these potentiometers doesn’t take up more space than a quadrature encoder or rotation sensor. Excluding hardware these are <1/2 the height of the quadrature encoders and ≈1/2 the height of the rotation sensor. Therefore, with hardware they are better than or equal to the alternatives when it comes to space requirements. In the quick build I made here not much time was put into minimizing space, but easy changes to start with are switching from 2 external collars to 1 internal collar, using thin nylocks, and the wires can be bent back quite a bit to further lower the profile.

So, in summary, these new potentiometers introduce a new alternative for tracking wheels. An alternative that offers 12x the resolution of the traditional method, and 2x the refresh rate of the alternative offered by the rotation sensors. They take up just as much or less space, and they don’t add all that much complexity to the code. Overall they seem like an extremely attractive option.


Just so you know, you can (to my knowledge) adjust the update rate of the rotation sensor down to 10ms or 5ms in the latest vexos.


Noted. I actually tested the rates using vexcode for all 3 sensors before posting to idiot check myself on the current version but didn’t look into adjusting them myself down to 10ms or 5ms. I’ll look into that more tomorrow when I have access again.

1 Like

You can actually get it down to 5 ms


That’s a clever idea, but how much mechanically robust are they?

My main concern is that the specific part used inside V5 potentiometer sensor may not have been designed to withstand that many rotations under continuous load and fast 360 deg spinning.

Google says that a typical rotary potentiometer lifespan is around 5 million cycles with proper care and regular lubrication.

If you assume robot driving at 350 RPM on 4" omnis with 2.75" tracking wheels, this will result in ~500 RPM for potentiometers or around 30k rotations per hour of driving. Obviously, you don’t drive at max speed all the time so lets make it as little as 10k rotations per hour.

Still, if you practice driving around 10 hours a week, it will be 100k rotations per week, or about 50 weeks to use up your budget of 5 million cycles.

I don’t think I will be that much comfortable knowing that a potentiometer could die any time during the season.

On the other hand, if you know how to detect potentiometer deteriorating condition from your code and replace it before it fails.
Also, you can make sure to pair a new and old potentiometers on the same tracking wheel, then you may be able to handle an unexpected part failure in software and ride it out with clever algorithm. Would make an interesting programming challenge.

Just wanted to reiterate, that if you use proper algorithms for odometry (like a Kalman Filter), that predict robot trajectory between measurements, then refresh rate is not as important as the precise time stamp of each measurement. Refresh rate is only important for situations when you need to react to a sudden external force. For example, flying a quadcopter in the gusty wind.


You could utilize two potentiometers on the tracker while at the same time using the IME’s on all four motors to estimate a relative speed that the potentiometers should be having, with simple trial-and-error or using trig. The potentiometer with the speed closest to that of the estimated speed from motor IME’s will be selected, so if any potentiometer breaks and gives untrustworthy values, the system would use the backup potentiometer.

// Returns the potentiometer with the closest velocity to the motor's Velocity
int reliableSpeedSelect(motorVelocity, Pot1Velocity, Pot2Velocity){

int diff1 = abs(motorVelocity - Pot1Velocity);
int diff2 = abs(motorVelocity - Pot2Velocity);

if(diff1 < diff2) return 1;
return 2;


// Receive the selected potentiometer to use
int pot_to_use = reliableSpeedSelect(motor_vel, pot1_vel, pot2_vel);
1 Like