P loop timeout

I am looking to do a timeout for my P loop and cannot figure out how. Can someone give me an example of how to do it?

if you already have the loop just add a sleep for 10ms command. If you want it longer make it longer but I recommend syncing it with the brain refreshes

wait(10, msec);

Make it at the very end of the loop, right before the loop closing bracket

Thanks for the response, but I’m not talking about that. I’m trying to make the loop stop after it reaches a certain time limit if it doesn’t reach the correct degrees (if it gets hung up on a goal and can’t go forward anymore). I have seen other teams at my school do this. My auton has got caught before, and I don’t want it to happen again

Make the exit condition also based on time (in addition to the threshold). You’re gonna need to do some basic kinematics to approximate the theoretical amount of time needed to reach the target (or just trial and error).

2 Likes

Well, mvas beat me to it, but yeah that’s the idea. Have a timer and logic that says if timer is greater than the time it should take, break the loop

Could you also potentially do something to time out if the position of your encoder has been the same for an extended period of time? Like set a variable to the previous value and if the current value is equal to that value for like two seconds then time out.

2 Likes

so it would be

while(errorLeft<5 && time< x seconds){
pid stuff
}
1 Like

Yeah basically. If the error is still there and the time is less than, run pid

You could also do that, but that’s the purpose of the integral in a PID loop. Though it wouldn’t exit the loop, it would keep adding power until the robot overcomes the obstacle.

@squiddy_slapper –– I’d do it like this

//Kinematics
currentTime = millis() //returns current time in milliseconds
velocity = getRPMtoRPS() * wheelRadius; // pretend the first function converts the change in encoder value to radians per second
totalTime = (distance/velocity) + currentTime; // distance to target/velocity traveling to target –– make sure units work

while( fabs(error) > threshold || currentTime < totalTime){
...
}
5 Likes

how would I actually measure the time? I’m pretty sure there isn’t a thing that counts how long a specific thing has been running

In VexCode you need to declare a timer object and in PROS you can just call the time directly with a function

I see, yeah that would help a lot with turning. What I had in mind was when teams go to score a goal but the program overshoots and gets stuck at the goal (this has happened to my team since we use tracking wheels).

I am not sure estimating the total time a step should take makes sense for a simple P loop.

I think the better approach here would be to pass user specified hard time limit to each autonomous step and then exit PID loop based on that. For example:

void drive(int leftSideDistance, int rightSideDistance, int timeLimit_msec)
{
   uint32_t startTime = vex::timer::system();

   while(1)  // main P controller loop
   {
     if( abs( startTime - vex::timer::system() ) > timeLimit_msec )
         break; // on time limit exceeded ; also may return false
     ... // do PID thing
     if( fabs(errorLeftSide) < threshold &&
         fabs(errorRightSide) < threshold )
         break; // on reaching the target ; also may return true
   }
}

void autonomous()
{
   drive(100,100, 2000); // drive forward, with 2 sec time limit
   drive(-50,+50, 1000); // turn left, with 1 sec time limit
   ...
}

See this topic for more information: Exiting a PID loop
https://api.vexcode.cloud/v5/html/classvex_1_1timer.html

Then you may get fancy and return true/false from drive function to indicate success of reaching the goal.

3 Likes

You’re right that it won’t be as robust as user input time but at least it won’t be as tedious. The kinematics can make for a good guess to at least get ballpark values (especially because the code I posted assumes the velocity of the robot is constant throughout the motion which it isn’t). I actually think combining the two methods makes for the best experience.

You approximate the total time duration of the movement (that eliminates most of the trial and error) and then you add a supplementary wait period (passed as a parameter) to the movement to compensate for the timing of your auton run and the gradual acceleration of the robot.

1 Like

Sometimes it can be hard to determine if the timeout occurred or the loop settled. One feature that can be added is logging each occurrence of a timeout which you can view afterwards. The simplest way to do this would be to print a message to the screen if the timeout condition is met. If you want to get more advanced you could set up a way to keep track of multiple timeouts and their corresponding context.

2 Likes

I think one good idea is developing a PID loop whenever you can instead of a mere P loop. I am aware that there are instances where a P loop would be better like settling an arm against hardstops, but due to these hardstops they always hold a reliable value you can utilize. In a scenario where there are no hardstops, a PID loop should almost always be used. Based on your sensory feedback, if you use a PID algorithm (or a P loop against a hardstop) you can set it such that if the condition is met within a deadband of the desired position, and the position has not moved for a period of time, then we know the algorithm settled on the desired position and we can exit

int deadband = 2

int leTime = 0;
while(1){

//PID containing derivative, error, and integral

if (abs(error) < deadband)
leTime+= 20;
else
leTime = 0;

if (leTime/1000 > 1.0) //If longer than one second at desired state
break;

vex::task::sleep(20);

}
1 Like

Sure a settle time & I and D terms are useful but neither of those will help you in a situation when the robot gets stuck. If it cannot get within the acceptable bounds, the while-loop will keep blocking until time expires. I think the objective of a timeout serves the purpose of exiting a loop regardless of the robot’s state once it has been running for too long. Depending on the context you may or may not be able to correct for any error in subsequent movements. However, I do agree that using a timeout to exit every movement is improper usage.

1 Like

Last year, this timeout concept would’ve been super helpful in depositing stacks in auton/prog skills. Often times the robot would go into the scoring zone but get caught on the lip of the goal preventing the execution of the stack deposit and all further functions (even more so with tracking wheels since they can’t slip at all).

With odometry, after the loop force exits from the timeout, you can account for the deviation in the path caused by the obstacle which is yet another layer of robustness that can make for a really strong program. Just an idea :slight_smile:

1 Like