View Full Version : How to deal with unexpected stops.

04-01-2009, 12:58 AM
Here is the situation I am running into.

I got a PI velocity loop that works pretty well.

But occasionally due to a sensor glitch or something, it stops. Especially when going slow.

My algorithm basically works like this

if (new sensor data exists)
find proportional error term
find intergral error term
compute value to send to motor controller and store as a global variable

send value to motor
This way, if there is no new data, it will simply send the old data.

The problem arises when it decides it is going way to fast and tells the motor to stop, and it does. At this point it gets no new sensor data so it doesn't know to start going again and it keeps on sending the old data that told it to stop.

Basically, with wheel encoders, whats a good way to sense that you are stopped? Just have a counter continuously run in the background that keeps track of how long sense the last update and if it counts too long, say that you stopped? I have looked at code that apparently doesn't do this, but I don't see how it avoids this problem. (I have mostly been looking at the examples on the nubotics website)

04-01-2009, 06:00 AM
That's basically what a watchdog timer does, however it resets the entire controller.
A counter is incremented independently of the program flow, and when it overflows, the controller is reset.

So if the software doesn't clear the timer every once in a while, something is bound to be wrong, and the device is reset to resolve the issue, unless the issue is bad programming offcourse :)

04-01-2009, 09:27 AM
I think the more common logic would be to use 2 interrupts. One interrupt is triggered by the encoder's A channel going high, and increments a counter variable. A second interrupt would be triggered by a timer, maybe at something like 60hz, everytime this interrupt triggers it would compare the counter variable (actual speed) against the setpoint (desired speed) and adjust the PWM values as necessary.

int actual_speed, desired_speed;

INTERRUPT (on pulse recieved){
increment actual_speed;

INTERRUPT (on clock){
if(actual_speed > desired_speed)
lower PWM;
raise PWM;
}You could of course have more complex code in the clock interrupt, in your case, it would be a PI controller.

This has the added bonus, that both of these are interrupt routines, so you haven't really created the main body of your program -- its all background stuff.