TalonFX using CANCoder as remote sensor

I am attempting to use a CANCoder as a remote sensor for a TalonFX and it is not working.
What I have tried:
Using TalonFXConfig:

    TalonFXConfiguration config = new TalonFXConfiguration();
    config.sum0Term = FeedbackDevice.RemoteSensor0;
    config.diff0Term = FeedbackDevice.RemoteSensor0;
    config.remoteFilter0.remoteSensorSource = RemoteSensorSource.CANCoder;
    config.remoteFilter0.remoteSensorDeviceID = cancoder.getDeviceID();

    config.primaryPID.selectedFeedbackSensor = FeedbackDevice.RemoteSensor0;
    // periodic
    SmartDashboard.putNumber("Position", getPos());
    SmartDashboard.putNumber("CANCoder pos (deg)", cancoder.getAbsolutePosition());
    SmartDashboard.putNumber("CANCoder pos (units)", cancoder.getAbsolutePosition() * DEGREES_TO_MOTOR_POS);

image

Using Phoenix Tuner:


It still does not read the value for the sensor and returns 0 using motor.getSelectedSensorPosition()

1 Like

Is there a reason you don’t just synchronize your CANCoder to the integrated encoder periodically?

We are trying to do as much as possible on the motor controller itself because our RoboRIO is having random spikes of CPU usage (around every 30 seconds) and we are not sure what is causing that.

Will also try that, thank you.

Some things to double check:

  • Is your Talon FX firmware up-to-date? (current v5 latest is 22.1.1.0)
  • Is your CANcoder firmware up-to-date? (current v5 latest is 22.0.1.2)
    [Note latest firmware version list is here]
  • Is your CANcoder on the same CAN bus as the Talon FX? If one is on the RIO and the other is on a CANivore or vice-versa, the remote sensor features won’t be able to work.

What is the getPos() function you’re using in the SmartDashboard put? Just to simplify the path of data I would recommend replacing that with talonName.getSelectedSensorPosition().

Also, do a self-test snapshot of the TalonFX in Phoenix Tuner. What does the self-test say the selected sensor position is? If it matches what you expect from CANcoder that means the config setup & hardware is correct and it’s a code-side issue; if the value is always zero like in your smartdash reporting then it’s either a config or CAN bus issue.

1 Like
  • Will check firmware/do self-test snapshot later today at our meeting
  • Both the CANcoder and the motor are on the same CAN bus (“Canivore 1”)
  • getPos() is as follows:
  public double getPos() {
    return motor.getSelectedSensorPosition();
  }

We are planning to use this and some calculations after the CANcoder works with the Falcon to get the degrees instead of encoder units.

Also, I read that if a CANcoder is a remote sensor for a motor it must have an CAN ID of 15 or less. Is that still a problem or has it been fixed? Current CANcoder ID is 15 and the motor ID is 10.

It was actually any remote sensor CAN ID that was affected - but yes, it’s fixed in firmware.

(Note that linked page has errata/fixes prior to the 2023 season, this season and beyond are in the changelog I linked earlier)

1 Like

We fixed it by testing a bunch of things. For people wondering, here is the solution (not sure about some parts of it but it worked for us)

    // cancoder is defined as a CANCoder and motor is a WPI_TalonFX
    // this is in the subsystem constructor

    // init motors
    cancoder = new CANCoder(15, "Canivore 1");
    motor = new WPI_TalonFX(10, "Canivore 1");
    
    // cancoder config
    cancoder.configAbsoluteSensorRange(AbsoluteSensorRange.Unsigned_0_to_360);
    cancoder.configMagnetOffset(95.009765625);

    // not sure if this is necessary:
    motor.configIntegratedSensorInitializationStrategy(SensorInitializationStrategy.BootToAbsolutePosition);
    // not sure if both of these are needed or if one does the job:
    motor.configSelectedFeedbackSensor(TalonFXFeedbackDevice.RemoteSensor0, 0, 0);
    motor.configRemoteFeedbackFilter(cancoder, 0, 0);
    // more motor config
    motor.setNeutralMode(NeutralMode.Coast);
    motor.setInverted(true);
    motor.config_kP(0, 1);
    // not sure if this is needed
    cancoder.setPosition(-cancoder.getAbsolutePosition());

Hope this helps anybody looking for the solution!

A more concise solution:

    motor.configRemoteFeedbackFilter(cancoder, 0, 0);
    motor.configSelectedFeedbackSensor(TalonFXFeedbackDevice.RemoteSensor0, 0, 0);