PIDController getting intermittent NAN

Hi All,

Trying to write an autopilot to fly a simulated aircraft using a stm32 'Blue Pill'. currently i have three PID controller's setup, Pitch, Roll and Heading. But i seem to be having an issue with my third PID controller. It returns nan about half of the time. Ive tried to debug this by setting fixed values to be computed but it hasnt changed anything.

this is in autopilot 'mode 3'.

the patten seems to be repeating. as follows but may just be chance.

11.50
11.50
nan
11.50
nan
11.50
11.50
nan
11.50
nan
11.50
11.50
nan
11.50

#include <PIDController.h>
int PitchCommand;
int RollCommand;
float PitchTarget;
float RollTarget;
int HeadingAP;
PIDController PitchPid;
PIDController RollPid;
PIDController HeadingPid;

void startPID()
{
  PitchPid.begin();
  RollPid.begin();
  HeadingPid.begin();
  PitchPid.tune(60, 0.1, 20.00);
  RollPid.tune(60, 0.1, 20.00);
  HeadingPid.tune(1,1,1);
  RollPid.limit(-100,100);
  PitchPid.limit(-100,100);
  HeadingPid.limit(-100,100);
}

void ControlLoop()
{
    Throttle = RCIN.getValue(3);
    if(flightMode == 1)// direct law
    {
      PitchCommand = RCIN.getValue(2);
      RollCommand = RCIN.getValue(1);
    }
    else if(flightMode == 2)// Fly by wire
    {
      if(Throttle < 1500){PitchPid.limit(-50,50);}
      else{PitchPid.limit(-75,75);}
      //debug = Roll;
      PitchTarget =(RCIN.getValue(2) - (float)1500) / (float)50;
      RollTarget = (RCIN.getValue(1) - (float)1500) / (float)20;
      PitchPid.setpoint(PitchTarget);
      RollPid.setpoint(RollTarget);
      PitchCommand = ((PitchPid.compute((int)-Pitch)) * 5) + 1500;
      RollCommand = ((RollPid.compute((int)(-Roll))) * 5) + 1500;
    }
    else if(flightMode == 3)// autopilot
    {
      if(Throttle < 1500){PitchPid.limit(-50,50);}
      else{PitchPid.limit(-75,75);}
      PitchTarget =(RCIN.getValue(2) - (float)1500) / (float)50;
      HeadingPid.setpoint(10);
      //debug = HeadingAP;
      //RollTarget = HeadingPid.compute(5);
      Serial.println(HeadingPid.compute(5)); // this returns 11.5 sometimes and nan other times for the exact same inputs.
      //debug = RollTarget;
      PitchPid.setpoint(PitchTarget);
      //RollPid.setpoint(RollTarget);
      PitchCommand = ((PitchPid.compute((int)-Pitch)) * 5) + 1500;
      RollCommand = ((RollPid.compute((int)(-Roll))) * 5) + 1500;
    }
}

Anyone have any ideas? just seem to be going around in circles for the last couple hours...

I reproduced the calculations in a new project and its returns 11.5 as ecpected every time, no nan's. so is something classing? perhaps a memory issue?

#include <PIDController.h>
PIDController One;
PIDController two;
PIDController HeadingPid;
float RollTarget;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("PID test 1");
  One.begin();
  two.begin();
  HeadingPid.begin();
  One.tune(1,1,1);
  two.tune(1,1,1);
  HeadingPid.tune(1,1,1);
  One.limit(-100,100);
  two.limit(-100,100);
  HeadingPid.limit(-100,100);

}

void loop() {
  // put your main code here, to run repeatedly:
  HeadingPid.setpoint(10);
  RollTarget = HeadingPid.compute(5);
  Serial.println(RollTarget);
  delay(10);
}

No, but a quite bad library. It starts with using String objects as flags to select library options. What a waste of computing power!

You problem disappears in the second sketch because you inserted a delay() in your loop. That ensures that this calculation doesn't trigger a division-by-zero exception:

  unsigned long now = millis();
  double timeChange = (double)(now - lastTime);
  double dErr = (error - lastErr) / timeChange;

The experience programmer may have noted the choice of "double" as the type of the timeChange variable...

If you want to stay with this library you may insert a delay(1) call in your first sketch's loop(), the nan will disappear.

ugh: PIDArduino/src/PIDController.h at 349f17936bb15a6cf3072686c933bebfefee5c07 · DonnyCraft1/PIDArduino · GitHub