No matter how clever your navigation and obstacle avoidance code is, occasionally, your robot will probably get stuck. Perhaps it bashes into a wall it didn’t see when it goes for a target, or maybe some appendage got snagged somewhere. Your robot just sits there. For an autonomous robot, that means game over. For the MASLAB (Mobile Autonomous Systems Laboratory) competition at MIT, this could mean your robot loses the match. In more serious contexts, it could mean horrible inefficiency (e.g. a factory robot) or failure to save lives (e.g. a battlefield robot). Here’s the Mars rover “Spirit” stuck in a sandy area a couple of years ago:
So what is a roboticist to do?
I will go over a few ways to tell whether your robot is not moving and how to effectively react to being stuck.
Your robot is stuck if its wheels are not spinning.
This one assumes that your robot does not stop moving unless it is stuck. Even if your robot does stop at briefly at times, for example to change direction, you can require that the wheels are still for a certain period of time before you determine that the robot is stuck. You can generally determine if your wheels are spinning, and how quickly by using wheel encoders. A wheel encoder generates a tick whenever the wheel moves a certain angular distance. For example, if your wheel is 0.1 meters in diameter, each tick represents 1 degree, and you go through 360 ticks, then your wheel has gone through a distance of 0.1 * pi meters. By timing the ticks, one can calculate the wheel velocity, which you can use to detect if you are stuck (or, you can just keep track of the position and check if it is not changing).
- Wheel encoders have consistent behavior. They don’t depend on battery charge or anything else that might vary over time.
- Most of the time when we are stuck the wheels are not spinning. This could be used as a powerful indicator (in conjunction with other indicators) of being stuck.
- Your robot’s wheels could slip. Your robot might be stuck with its wheels spinning in place.
- Depending on the type of encoder, the readings could be noisy.
Your motor current is high.
If you command your wheel motors to move, but prevent the wheels from moving, the current through the motors will increase. You can measure statistics involving the motor current (for example, average motor current over a time period) and set a threshold to indicate whether the robot is stuck or not.
- Your wheels could be slipping and you could still detect when you are stuck.
- Your robot might stop, turn, start again, etc, and each of these abrupt motions causes a transient response in the motor current (it jumps up and then decays away). On top of that, the signal can be very noisy. One can filter the signal in various ways (such as a low pass filter, or a moving average).
- It is difficult to set the threshold correctly, especially since the motor current (and its various statistics) depend on the velocity your robot is moving (or trying to move). If you’ve set a threshold for a fast robot but your robot slows down, the motor current will go down as well, and might get stuck without going over the preset threshold. One thing you might do is to create a model of the motor current when stuck and not stuck as a function of how fast your robot is moving (more accurately, how fast it is being commanded to move, in terms of PWM*). Thus, lower velocities will have lower current thresholds. However, this causes problems if you are averaging your current. Suppose you’ve been going at a very high velocity and your current has also been correspondingly high. All of a sudden, your robot decides that it wants to turn in place at a much lower velocity. Because you are averaging the current, it takes a while for the averaged value to drop because you are still including samples from when the current was high in your average. However, the velocity drops immediately, and with it drops the threshold. Because the averaged current is still taking its time to drop, it is now all of a sudden higher than the threshold, and we mistakenly think that we are stuck.
- Another problem that large time windows (read: slow accumulation) causes is that we might detect that we’re stuck after we’ve already gotten ourselves unstuck. Let’s say the filtered current lags behind the peak in real current by one second. Suppose we get stuck briefly for slightly less than a second and then manage to get unstuck. Just as we get unstuck and are ready to keep going, the filtered current peaks and we trigger the stuck-detection behavior. This is undesirable.
Enough time passes.
- Really simple to decide when you should trigger your “get unstuck” behavior. No need to deal with noisy sensor data.
- You can just use the standard timeouts you’ve implemented for all of your states (you have implemented timeouts, right?)
- Hard to tell exactly how long you should wait. Waiting too little might interrupt otherwise productive behavior, and waiting too long would just waste time.
Your range sensor readings are stable.
- Gets a better picture of the environment you are in when you are stuck, something that might be useful when you try to get unstuck
- Range sensors can be very noisy, especially when out of range. This can be mitigated by filtering out of range or highly fluctuating values, but this reduces the range of situations in which your sensor readings are valid when you are stuck. For example, if you are stuck, you are likely up against a wall somewhere, and some of your range sensors are too close to give correct readings.
- You could be “dynamically stuck”, where you are not sitting exactly still. Even the slightest movement would severely complicate the algorithm to esimate whether your range readings indicate stuckness.
Okay, now we have some idea of how ot detect if a robot is stuck. But how do we get it unstuck? Any ideas? More to come later …