WPILib Trajectory Tutorial but with NEOs

I’m trying to implement path following on my robot using this WPILib tutorial: https://docs.wpilib.org/en/latest/docs/software/examples-tutorials/trajectory-tutorial/index.html

I want to use our drivetrain’s NEOs’ built in encoders, but this tutorial uses the .getDistance() method of the WPILib encoder library. Here is a link to the info on that method: https://first.wpi.edu/FRC/roborio/beta/docs/java/edu/wpi/first/wpilibj/Encoder.html#getDistance--

I saw that it returns the distance since the last reset. Does it just mean the last time the encoder was reset in code?

How can I write a “.getDistance()” method for our NEOs?

You can use the getPosition() method on the internal encoder object (retrieved via getEncoder()). By default this value is in rotations of the motor shaft so you’ll have to convert to meters using the gearing and wheel radius.

2 Likes

To add on to Prateeks reply, getPosition() returns the number of rotations that your neo motor has performed. So you’ll manually need to convert that to the number of shaft rotation (based on your gearbox) and then you can use pi * wheel diameter to calculate how far each side of your robot has travelled. If you don’t know the gearing, then rotate your wheel 10 full times, see the value that getPosition() has changed by, divide it by 10, and that will be a conversion factor that you can use to determine one wheel rotation.

1 Like

First, thanks for this post. I found this at just the right time and it cleared up a few of the questions I had.

Secondly, I want to check my understanding of the differences between CANEncoder and Encoder. CANEncoder has methods to set the position scale and the velocity scale. So that when you call the .getPosition() method you get the same result as .distance() in the Encoder class. Likewise CANEncoder.getVelocity() will then give the same results as 'Encoder.getRate()` would have.

I’m trying to do this:

// set scaling factor for CANEncoder.getPossition() so that it matches the output of
// Encoder.getDistance() method.
m_leftEncoder.setPositionConversionFactor(DriveConstants.kDistancePerWheelRevolutionMeters * DriveConstants.kGearReduction);
m_rightEncoder.setPositionConversionFactor(DriveConstants.kDistancePerWheelRevolutionMeters * DriveConstants.kGearReduction);

// Native scale is RPM. Scale velocity so that it is in meters/sec
m_leftEncoder.setVelocityConversionFactor(DriveConstants.kDistancePerWheelRevolutionMeters * DriveConstants.kGearReduction / 60.0);
m_rightEncoder.setVelocityConversionFactor(DriveConstants.kDistancePerWheelRevolutionMeters * DriveConstants.kGearReduction / 60.0);

If I understand correctly this will have m_leftEncoder.getPosition() return a distance in meters and m_leftEncoder.getVelocity() return the speed of the left wheel in meters/sec. (Given that my conversion factor is in meters)

This is a question and not a statement. I’d test this theory myself, except I’m snowed in and don’t have access to a robot!