There are many off the shelf range finding components available including ultrasonic, infrared, and even laser rangefinders. All of these devices work well, but in the field of aerial robotics, weight is a primary concern. It is desirable to get as much functionality out of each component that is added to an air-frame. Miniature robotic rotor craft for example can carry about 100g of payload. It is possible to perform machine vision tasks such as obstacle identification and avoidance though the use of a webcam (or mini wireless camera interfaced to a computer via USB adapter). Better yet, two webcams can provide stereo machine vision thus improving obstacle avoidance because depth can be determined. The drawback of this of course is the addition of the weight of a second camera. This page describes how a mini laser pointer can be configured along with a single camera to provide mono-machine vision with range information.
Theory of Operation
The diagram below shows how projecting a laser dot onto a target that is in the field of view of a camera, the distance to that target may be calculated. The math is very simple, so this technique works very well for machine vision applications that need to run quickly.
So, here is how it works. A laser-beam is projected onto an object in the field of view of a camera. This laser beam is ideally parallel to the optical axis of the camera. The dot from the laser is captured along with the rest of the scene by the camera. A simple algorithm is run over the image looking for the brightest pixels. Assuming that the laser is the brightest area of the scene (which seems to be true for my dollar store laser pointer indoors), the dots position in the image frame is known. Then we need to calculate the range to the object based on where along the y axis of the image this laser dot falls. The closer to the center of the image, the farther away the object is.
As we can see from the diagram earlier in this section, distance (D) may be calculated:
Of course, to solve this equation, you need to know h, which is a constant fixed as the distance between your laser pointer and camera, and theta. Theta is calculated:
Put the two above equations together, we get:
OK, so the number of pixels from the center of the focal plane that the laser dot appears can just be counted from the image. What about the other parameters in this equation? We need to perform a calibration to derive these.
To calibrate the system, we will collect a series of measurements where I know the range to the target, as well as the number of pixels the dot is from the center of the image each time. This data is below:
|pixels from center||actual D (cm)|
Using the following equation, we can calculate the actual angle based on the value of h as well as actual distance for each data point.
Now that we have a Theta_actual for each value, we can come up with a relationship that lets us calculate theta from the number of pixels from image center. I used a linear relationship (thus a gain and offset are needed). This seems to work well even though it does not account for the fact that the focal plane is a plane rather than curved at a constant radius around the center of the lens.
From my calibration data, I calculated:
Offset (ro) = -0.056514344 radians
Gain (rpc) = 0.0024259348 radians/pixel
|pixels from center||calc D (cm)||actual D (cm)||% error|
There are not a lot of parts in my sample range finder. I used a piece of cardboard to hold a laser pointer to a webcam so that the laser pointer points in a direction that is parallel to that of the camera. The parts seen below are laid out on a one inch grid for reference.
My assembled range finder looks like this:
I have written software two ways, one using visual c++ and the other using visual basic. You will probably find that the visual basic version of the software is much easier to follow than the vc++ code, but with everything, there is a tradeoff. The vc++ code can be put together for free (assuming that you have visual studio), while the vb code requires the purchase of a third party software package (also in addition to visual studio).
The visual basic code that I have written is available as a package named vb_laser_ranger.zip at the bottom of this page. For this code to work, you will need the VideoOCX ActiveX component installed on your computer. The code that describes the functions found in the main form is seen below:
Screen shots from this code can be seen below:
My complete code for this project is available as a package named LaserRange.zip at the bottom of this page. Note, to run this executable, you will need to have both qcsdk and the qc543 driver installed on your computer. Sorry, but you are on your own to find both of these. Below are two examples of the webcam based laser range finder in action. Note how it looks like there are two laser dots in the second example. This "stray light" is caused by internal reflections in the camera. The reflected dot loses intensity as it bounces within the camera so it does not interfere with the algorithm that detects the brightest pixel in the image.
One specific improvement that can be made to this webcam based laser range finder is to project a horizontal line rather than a dot onto a target. This way, we could calculate the range for each column of the image rather than just one column. Such a setup would be able to be used to locate areas of maximum range as places that a vehicle could steer towards. Likewise, areas of minimum range would be identified as obstacles to be avoided.