How to Use Cancoder as Sensor for Falcon 500

How do I use a CANcoder as a remote sensor for a Falcon 500?

Did you look at the documentation? What questions do you still have? You’ll need to be more specific so we can help you out

1 Like

WCP Swerve X uses a Cancoder to track the absolute angle of the wheel and the angle of the wheel is controlled by the Cancoder. Previously, we used an external PID with PIDController class, but we are now looking to use the Falcon 500’s internal PID. Verify the following is the correct setup for the Falcon and Cancoder to be connected.

angle.setBrake(true);
angle.configRemoteFeedbackFilter(encoder.getDeviceID(), RemoteSensorSource.CANCoder, 0);
angle.configSelectedFeedbackSensor(FeedbackDevice.RemoteSensor0);

encoder.configFactoryDefault();
encoder.clearStickyFaults();
encoder.configAbsoluteSensorRange(AbsoluteSensorRange.Signed_PlusMinus180);
encoder.setPosition(0.0);
encoder.configSensorDirection(false);
encoder.configMagnetOffset(-zero);

angle is of class that extends WPI_TalonFX and encoder is of WPI_Cancoder

On thing that I am unsure on is the units for TalonFX internal PID. The many unit conversions between the Cancoder and Talon are confusing, so verify the conversion.
(2048 falcon_ticks/1 falcon_rot) * (10.29 falcon_rot/1 angle_rot) * (1 angle_rot/ 360 cancoder_angle) * (360 cancoder_angle/4096 cancoder_ticks) = 5.145 falcon_ticks/1cancoder_tick
that value is to be set in angle.configSelectedFeedbackCoefficient(1 / 5.145)

There is some debate in the community, but I recommend you use the Falcon’s built in encoder for closed loop control. Read the CANCoder’s angle at startup, and use it to seed the motor’s position with setSelectedSensorPosition.

I’m not sure about your conversion math. First, are you using degrees or radians for the angle? I suggest radians. Here is the basic formula to get the sensor coefficient. Divide the angle (in radians) by this coefficient to get the motor encoder position. To go the other way, multiply this coefficient by the encoder position to get the angle in radians:

positionCoefficient = 2.0 * Math.PI / TICKS_PER_ROTATION * STEERING_REDUCTION;

If you use the CANCoder for closed-loop control you don’t need the steering reduction because it should be directly reading the angle of the wheel.

Thanks so much for your help! In regards for the coefficient, will getSelectedSensorPosition return in raw sensor units still?

Yes, I was suggesting you do the math with the coefficient in your Java code.

You can have the controller apply the coefficient with configSelectedFeedbackCoefficient, but I usually don’t. It might make the code a little more concise, but it’s harder to debug if the conversation isn’t right.

That’s valid. Thank you for the help, I’ll return to this post if I have any more questions.

Hello again, have successfully “seeded” the position of the motor using the starting angle of the Canocder with a margin error of 2 degrees. I did end up using configSelectedFeedbackCoefficient. Strangely, when comparing Cancoder readings to Falcon encoder readings, the latter is a double but with no decimals where as the Cancoder does have decimal numbers. Tuning PID with our changes has been different, to say the least and it does not oscillate as expected.