We were doing our class and implementing P controllers and was wondering the best method to break out of a control loop when it is not a background task and you ant to move on to the next step? This would work for a variety of control loop types I think.
We’ve used within an absolute value of an error with a timer kick out but if you overshoot, then you are not guaranteed to still be in that range because the first time you see it, you kick out and the robot could still be carried by momentum a bit further.
Timers for how long you normally take that step and settle down only as it allows for the correction. This seems like it wastes time and could be dependent upon battery voltage.
The timer seems to allow for settling but you could still be oscillating or have overshot. Has anyone done anything else trickier?
a) look for the rate of settling and change in error to be sufficiently low over a period of time?
b) look for being within an absolute value range of error for a minimum period of time?
c) wait until you are pretty much exactly where you want to be and kick out with a timer when you are not there in time? (like #1 above but a really narrow range)
Yes, this is the typical way to have the background tasks do the work, but the main auton task needs to know when to move on to the next thing. First occurrence of the limit range may just be on the way to overshoot, and not settled into your target.
We used #1 this last year, and #2 the year before. Just looking at error seemed to work fine; your position controller just needs to be tuned so that you don’t get any overshoot (which admittedly does lead to erring on the slow side). We used (a) for our flywheels in auton last year; using just a couple readings rather than one (so only several more milliseconds) seemed to make a big difference.
Theoretically waiting for velocity to be 0 and absolute value of error to be less than some threshold should work the best perhaps, but deriving the velocity of your drive at low speeds requires a slower update time.
Technically, if you are tuned well your P only loop should not overshoot. The big issue with this is deadzone in the motors. If you are using a P only loop you will be dead from -20 to 20, so fixing this will cause oscillation.
I generally use #2 (time-based). It might waste a small amount of time, but I’ve found it tends to be more accurate. The other advantage is that if your robot never makes it to a low error state, it won’t be stuck forever trying to get there. I believe the other BNS programmers tend to use the other method however. I might experiment with something more complicated this year.
My team uses a combination of both. We check the error within a threshold over a series of timesteps (I think we repeat 5 times if the error is in the threshold). However, we also use a timeout to help prevent issues with stalling motors and bad IME readings (we still get a lot of both, however). This is made much easier by RobotC’s multitasking.
Our control loops go in a separate task. No our autonomous function, we have a custom blockLim function to block the main program from progressing under certain conditions. It looks like this:
void blockLim(bool cond, int timeOut) {
int time = nSysTime;
while(!cond && (nSysTime - time < timeOut))
wait1Msec(20);
}
As a parameter for it, you can pass in multiple conditions, such as multiple drive PIDs on target. That looks like this: