Following on from my previous blog post using a webcam and a laser as a rangefinder, it’s now mounted on a cheap 3 euro stepper motor and used to make a 2d map of the surroundings. As you can see from the video the results are not great, I think with a bit more work there is room for improvement. A PIC18f14k50 is used to control the stepper motor and send the current step value over to the computer where a python script matches this to the current laser distance. Then using basic trigonometry x-y points can be found and plotted on a graph.
The laser and webcam were just glued to a piece of wood, then that piece of wood was stuck onto a stepper motor and the stepper motor is being held in a vice. The webcam is a Sweex WC003V3, available for 10 euros delivered on ebay. The laser diode is from china so that cost around 4 dollars delivered. The stepper motor is a 28BYJ-48 model, available for 3 euros delivered from china. All in all your looking at around 30 quid for some basic 2d mapping when you include the PIC microcontroller and H-Bridge IC etc.
Theory of operation:
We can work out theta by knowing how many many steps the stepper motor has taken and D is calculated using the webcam and laser combination. From there, by using basic trigonometric equations the x,y points can be worked out.
So the webcam-laser rig is rotated through 360 degrees, as it is rotating values of D are matched with values of theta. After it has stopped rotating this information can be converted into x-y points and plotted on a graph. The datasheet for the stepper motor says there are 4096 steps per 360 degrees. I think that might be incorrect though as I found 2048 steps results in a 360 degree turn. From this information we can work out the minimum step angle possible.
This minimum angle is important for figuring out what the smallest gap that can be “seen” at the maximum range of the device. In this case the webcam and laser rig is calibrated to around 2.5 metres max range. To find the smallest gap noticeable simple trig can be used:
This means that at a range of 2.5 meters, the smallest gap that can be reliably detected is 0.763 cm wide. This is quite low, an ideal value for making a detailed map of a room. However this is a theoretical limit, this value assumes every step angle is matched with a value of distance from the webcam. This is not the case due to the fps of the webcam.
The main limitation is how fast you can store the information being received from both the PIC microcontroller and the webcam. The bottleneck in the process is definitely the webcam. At best I could get around 8 fps at 640×480 resolution. A higher fps could be achieved with a lower resolution and this is something I’m going to try in an attempt to get a faster, more detailed scan. As a result of the fairly low fps, the stepper needed to rotate fairly slowly to make up for the loss in scan resolution. The stepper takes 25 seconds to complete a full revolution.
In one second, the stepper rotates through 14.4 degrees. Since the webcam is running at 8fps, this gives us a new angle of 14.4/8 = 1.8 degrees. So now the minimum gap visible at max range becomes:
This brings the resolution down to 7.85 centimeters at the maximum range. This is still usable but it’s something I might try and improve. The easiest way would be getting a better webcam. The PlayStation eye toy camera works with opencv and it can easily capture 60 fps. So that is definitely an option.
Here is the code for the microcontroller to control the stepper and send the current step value over serial:
Here is the Python script to grab frames from the webcam, calculate distance, match that with a step number,calculate the x-y points and then plot those points:
As I said in the video, where it hits my door with all the clothes hanging on it, the map goes a bit mad.
A higher FPS rate would allow for a faster scan time. This would then make possible a real time 2d map. For something like that I’d probably look into using processing to display the map on screen because matplotlib doesn’t seem to be all that fast at updating the display. From there it could be mounted on an autonomous robot of some kind. Removing the need for a computer would the main goal, that and making everything smaller. I have tried something like this with a Raspberry Pi but I just couldn’t get a decent FPS with the webcam using it. Using an FPGA might be an option.