What's wrong with this PI_Loop?

I’ve been working on a PI Loop but when I use it it just shoots to the side. I thought the problem might be the kI value, but after removing it nothing changed. What’s the problem with this?

#pragma config(Sensor, in2, Potentiometer, sensorPotentiometer)
#pragma config(Motor, port2, Arm, tmotorVex393_MC29, openLoop)
//!!Code automatically generated by ‘ROBOTC’ configuration wizard !!//

task main()
{

int setpoint;
setpoint = 1633;
float error;
float power; // / //
float kP; // /-
float kI;
kI = 00.25;
kP = 0.0819;
float area;
float integral;

while(1==1)

{

error = setpoint - SensorValue[Potentiometer];
area = error25;
integral = integral + area;
power = error
kP + integral*kI;
if(power > 127)
{
power = 127;
}
if(power < -127)
{
power = -127;
}
motor[Arm] = power;//@Everyone
datalogDataGroupStart();
datalogAddValue( 0, setpoint );
datalogAddValue( 1, error );
datalogAddValue( 2, power );
datalogAddValue( 3, SensorValue[Potentiometer] );
datalogAddValue( 4, area );
datalogAddValue( 5, integral );
datalogDataGroupEnd();

wait1Msec(25);
}

}

Should just be:

integral += error;

Remember, your target is 127 Max, since you had *25 in there, the largest error you could have before saturation was 5. And you are looping so it wound up almost immediately.

Also, you need to reset your integral

No, that’s just an option. +=, just like ++, are shortcuts, not right v. wrong.

You forgot about kI. But still, this could remain an issue, and as well as the point about resetting.

Other questions: Is it rotating the wrong direction? How far off does it commonly start?

In order to simplify the problem, set kI as 0 for now. I don’t see any problems with the program itself, although some things could be improved.

This might be a stupid question, but are you using a motor controller?

I wasn’t saying it was wrong, just that it didn’t need to be integral = integral + area. the form I used was just what I would use in that case.

Didn’t forget about it, was trying to walk before we ran since clearly OP is new to this. Yes, it’s actually nice that they realized the integral was the area of the rectangle formed by the time, 25ms, and the error. If they wanted to continue down this path, which would be great because they can simply change one constant (call it I_MS_DELAY for now) which defines the time delay and the area under the curve, then they could adjust Ki to make up for it or they could use I_MS_DELAY in the wait1Msec() and (I_MS_DELAY * 0.001) in the area = error * (I_MS_DELAY * 0.001) and keep area in the integral addition.

It is just a matter of moving the decimal place around, the gain was way too high at 25.

I like the use of I_MS_DELAY because you can later change your PID loop time without affecting the tuning. Otherwise, the loop time is baked into the Ki gain by default and needs to be adjusted every time you change the timing in the wait loop.

Gonna miss these great questions when V5 takes over. I just get the feeling default PID in the smart motors will take the place of many teams learning about these great control loops.

What do the datalogAddValue commands do?


datalogAddValue()

adds a value to, as noted, the data log, part of the robotc debugger. Google will assist you further.

Back to original thread topic, what do you mean by “shoots off to the side”?
Try just running a P controller to diagnose the issue. Once you’ve done that (and I suspect that will work perfectly fine) tune your integral windup and kI.
Generally speaking the common implementation of integral controller in vex is pretty bad, so I also suggest avoiding integral term completely.