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

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.