As part of my autonomous car project (http://jeffsinventions.com/?p=577), I need the car to avoid obstacles. This is a video of my autonomous car using ultrasonic sensor data to choose the nearest obstacle-free heading towards its destination.
Basically, an ultrasonic sensor mounted on a servo takes distance measurements at a number of angles and chooses the obstacle-free angle closest to that required to get to the next way point.
- Before I’m satisfied with the car’s obstacle avoidance capability, I need to do some more testing to make sure it is behaving as expected.
- After the car is up and running, I will experiment with adding stereo cameras and fiddle with edge detection algorithms, stereo vision (when images from the two cameras are compared, the parts with lots of differences tend to be closer while the parts with more similarities tend to be farther), and optical flow (while moving, the things that move faster tend to be closer and the things that move slower tend to be farther)
Which proximity sensor will I use?
I chose to use an ultrasonic proximity sensor. Specifically, I opted for a Parallax PING (http://www.parallax.com/tabid/768/ProductID/92/Default.aspx). Here’s why I didn’t choose other sensor technologies:
- Capacitive (range is only a few inches)
- Inductive (range is only a few inches)
- Infra-red (struggles in daylight)
- Laser range-finder (expensive)
Why get a 2-D representation of the world?
If the car only had a sensor measure distance directly in front of the car, it would have to avoid obstacles by guess and check–it would drive until it sees an obstacle, back up, turn a little, and try again until it doesn’t see an obstacle. This would take forever. With a 2-D representation of the space in front of it, the car can choose from a variety of directions.
How get a 2-D representation of the world?
One option would be to buy a bunch of sensors and array them at different angles in front of the car, but it would be expensive to accomplish any respectable resolution with this approach. A more attractive option would be to mount a sensor on a servo and collect readings while the sensor rotates.
Fortunately, there is a kit for mounting the ultrasonic sensor on a servo (http://www.parallax.com/Store/Robots/RoboticAccessories/tabid/145/ProductID/248/List/0/Default.aspx?SortField=ProductName,ProductName). However, this kit was designed for Parallax’s Boe Bot, not my RC car. So, I took off the front bumper of my RC car, machined a bracket for mounting the servo from an aluminium angle, and screwed the bracket into the holes where the bumper was.
One question to figure out is how many measurements I want the sensor to take in a single pass. If I take too many measurements, the pass will be slow and the car could crash while waiting for the sensor to complete its pass. If I take to few measurements, the car could fail to detect obstacles or available paths. I chose 36 measurements per pass, because it seemed to strike the balance between these extremes. I get a good resolution, but I am able to complete a pass in well under a second.
What distance threshold?
Another balance that needs to be struck is choosing the distance below which the car classifies something as an obstacle. If the distance is too short, the car could be unable to stop before crashing into something. If the distance is too far, the car could unnecessarily rule out viable paths.
How will I power the servo and sensor?
A wiring guide for the ultrasonic sensor suggests the sensor be powered by the Arduino (http://arduino.cc/en/Tutorial/Ping). The Arduino servo library also suggests that the servo be powered by the Arduino (http://arduino.cc/it/Reference/Servo). However, when I tried to power both devices using the Arduino, the sensor reported bad data and the servo misbehaved.
To fix the issue, I ran both of the devices off of the RC car batteries, stepping the voltage down using a voltage divider. Thanks to DuaneB from the Arduino forum (http://arduino.cc/forum/index.php/topic,102369.msg767877.html#msg767877) for pointing out that inadequate power was the cause of the problem.
What obstacle-avoidance algorithm will I use?
The car will constantly cycle through these steps:
- Sweep a proximity sensor over and back in front of the car by mounting it on a servo
- At 36 angles along the way, the ultrasonic sensor measures distance
- Filter out any angles where the distance is less than four feet
- Of the remaining angles, choose the angle closest to way-point
One challenge I encountered while setting this up was that the car seemed to take forever at the end of each pass to decide where to go. Two changes fixed this problem: I stopped displaying all of the measurements on the Serial Monitor sped up the Serial transfer rate from 9600 baud to 11520 baud. Thanks to dxw00d and Nick Gammon from the Arduino forum (http://arduino.cc/forum/index.php/topic,102369.msg768401.html#msg768401) for these fixes.