I am trying to help a student debug a program in EasyC. It’s a basic P controller (no ID).
A quad encoder is being used to measure the change in degrees of rotation, and a timer is being used to calculate the change in time. From this the angular velocity is calculated (in rotations per second). The measured speed is subtracted from the goal speed to find the error.
The speed is then set using the formula
Power = Power + Kp*Error;
Power is then limited to values between 0 and 127 with if statements.
I understand that there are many ways to improve this program, but this student is pretty new so I just wanted him to focus on the proportional term first. However, it isn’t working as expected. In an effort to debug, I am displaying the values of the variables on the graphic display. The values from the quad encoder, the time, the angular speed, and the error all look great and respond as expected when we manually turn the flywheel. However, when I try to display the power, it says “NaN,” which through research have discovered means “not a number”. These numbers are all floats.
Here’s the weird part.
In my efforts to help him debug, we found nothing to fix this. FInally, on a whim, I took the error value and multiplied it by 1000 and stored it in a variable called errorint (which is an integer). I then stored the value of errorint in a variable called errorfloat (which is a float). I then divided errorfloat by 1000 (the multiplying and dividing by 1000 was done to preserve 3 decimal places). Now when I set the power as
Power = Power + Kp*errorfloat;
It works great!
So what’s up with this??? What reasons could there be why my original float value stored in error was no good, but the new float value found by first converting it to an integer and then back to a float worked?
I have attached the easyc code, which has already been fixed.
#include "Main.h"
void OperatorControl ( unsigned long ulTime )
{
int leftup = 1;
int leftdown = 1;
int rightdown = 1;
int rightup = 1;
int intakespeed1 = 127;
int intakespeed2 = 100;
int launchhigh = 0;
int launchoff = 0;
int launchlow = 0;
int launchmed = 0;
int errorint = 0;
float errorfloat = 0;
StartQuadEncoder ( 1 , 2 , 0 ) ;
StartTimer ( 1 ) ;
PresetTimer ( 1 , 0 ) ;
while ( 1 )
{
Holonomic ( 1 , 2 , 1 , 4 , 9 , 2 , 8 , 1 , 1 , 1 , 1 , 0 ) ;
leftdown = GetJoystickDigital ( 2 , 5 , 1 ) ;
leftup = GetJoystickDigital ( 1 , 5 , 2 ) ;
rightdown = GetJoystickDigital ( 2 , 6 , 1 ) ;
rightup = GetJoystickDigital ( 1 , 6 , 2 ) ;
launchmed = GetJoystickDigital ( 2 , 8 , 3 ) ;
launchlow = GetJoystickDigital ( 2 , 8 , 1 ) ;
launchoff = GetJoystickDigital ( 2 , 8 , 4 ) ;
launchhigh = GetJoystickDigital ( 2 , 8 , 2 ) ;
if ( rightdown==1 && leftdown==0 )
{
SetMotor ( 10 , -intakespeed1 ) ;
}
else if ( leftdown ==1 && rightdown ==0 )
{
SetMotor ( 10 , intakespeed1 ) ;
}
else
{
SetMotor ( 10 , 0 ) ;
}
if ( rightup ==1 && leftup ==0 )
{
SetMotor ( 7 , -intakespeed2 ) ;
}
else if ( leftup ==1 && rightup ==0 )
{
SetMotor ( 7 , intakespeed2 ) ;
}
else
{
SetMotor ( 7 , 0 ) ;
}
if ( launchhigh ==1 )
{
goalspeed=1.6;
}
else if ( launchmed ==1 )
{
goalspeed=1.35;
}
else if ( launchlow ==1 )
{
goalspeed=1.2;
}
else if ( launchoff ==1 )
{
goalspeed=0;
}
Quad = GetQuadEncoder ( 1 , 2 ) ;
Time = GetTimer ( 1 ) ;
PrintTextToGD ( 1 , 0 , 0 , "Quad Value: %f\n" , Quad ) ;
RPS = ((Quad-LastQuad)/360)/((Time-LastTime)/1000);
PrintTextToGD ( 0 , 0 , 0 , "RPS: %f\n" , RPS ) ;
PrintTextToGD ( 5 , 0 , 0 , "goalspeed: %f\n" , goalspeed ) ;
LastTime = Time;
LastQuad = Quad;
error = goalspeed - RPS ;
errorint = error*1000;
errorfloat = errorint;
errorfloat = errorfloat/1000;
PrintTextToGD ( 13 , 0 , 0 , "errorint: %d\n" , errorint ) ;
PrintTextToGD ( 14 , 0 , 0 , "errorfloat: %f\n" , errorfloat ) ;
power=power + kp*errorfloat;
PrintTextToGD ( 6 , 0 , 0 , "power: %f\n" , power ) ;
PrintTextToGD ( 4 , 0 , 0 , "error: %f\n" , error ) ;
PrintTextToGD ( 7 , 0 , 0 , "time: %f\n" , Time ) ;
if ( power>127 )
{
power=127;
}
else if ( power<0 )
{
power=0;
}
SetMotor ( 3 , power ) ;
SetMotor ( 6 , power ) ;
Wait ( 100 ) ;
}
}
Any variable that you don’t see defined there is defined as a global variable (because he was initially trying to do part of his code as a user function. We tried switching them to be local variables, and there was still the same problem.