Is it possible to EnableContinuousInput on Falcon Internal PID controller

Is there a way to enable Continuous input on the PID controller that is onboard the Falcon FX to wrap at custom values. Like the WPILib PID controllers do.

We use the internal PID controller inside the Falcon 500 on the steering of swerve modules. The inputs to the PID controllers are -180 to +180 degrees. This needs to get converted to native sensor units for the Falcon that is controlling the steering.

( angle / 360 x 2048 x 150 / 7) with the 150/7 being the steering reduction on the SDS Modules.

So the PID controller in the Falcon is position targeting values from -21942 to +21942.

The issue arises when the swerve module is at say 179 degrees and the next update wants the swerve module at say -179 degrees (2 degree of angle change.) If you don’t have your own custom code that monitors this boundary point the swerve module will take the long way around and travel 358 degree to effectively move the heading by 2 degrees.

Currently we use a counter member variable that measures the number of times this boundary is crossed and it either increments or decrements depending on the direction that the boundary is crossed. Then this counter value is multiplied by 43886 and added to the set point of Position PID controller.

This code works fine, but it is messy and could be eliminated completely if there was an enable Continuous inputs on the Falcon internal PID controller.

Short of using the slower software PID controller on the RIO (20ms loop times compared to 1ms loop times) how do other teams handle this windup/ boundary crossing?

1 Like

Some simple code to calculate the value of the angle change (say 2 degrees) then some more simple code to translate 2 degrees into the appropriate number of counts. Add required change in counts to the current target value.

You need to keep in mind that the falcon counts are continuous. All you are doing is sending a count setpoint. You just add or subtract. The required count change from the current set point.

1 Like

This is how we handle it at the moment.

It works fine as is and its very easy to see whats happening from the comments. I just thought someone might have a more condensed version or even a one liner that handles the four if statements in one statement.

Keep in mind that a one liner isn’t always the best for readability and maintainability.

FWIW here’s our implementation if your interested.

We do this, and it seems to work; it’s one of the more compact implementations I’ve seen of this kind of thing:

  public double angleMod360(double naiveDesiredAngle) {
    // Calculate the change in angle from the current angle to the desired angle
    double delta = naiveDesiredAngle - getAngle();

    // Ensure that the change in angle is within the range of [-180, 180] degrees
    double deltaMod360 = delta % 360;
    deltaMod360 = deltaMod360 < 360 ? deltaMod360 + 360 : deltaMod360;
    deltaMod360 = deltaMod360 > 180 ? deltaMod360 - 360 : deltaMod360;

    // Calculate the final desired angle by adding the change in angle to the current angle
    double desiredAngle = getAngle() + deltaMod360;

    return desiredAngle;
  }

Note that getAngle() returns degrees.

1 Like