Sunday, September 28, 2014

Odometry

I wanted my robot to be able to do dead reckoning, so I needed wheel encoders. There are some encoders on the market that can work with the Dagu yellow motors, as in the Magician chassis, or with the Solarbotics gear motors. And Pololu makes an encoder for their micro metal gear motors that detects wheel motion and direction by detecting white reflective tabs built-in to the wheels.

But I had already decided to use continuous rotation servos, which don't have a second shaft on the non-drive side to mount an encoder disk. Instead, I decided to mount a paper ring of encoder stripes on the inside of a Solarbotics servo wheel. I needed some way to detect the changes between black and white as the wheel rotated.

I found a set of components from Optek on mouser.com that seemed promising. They were a combination of an LED and a phototransistor, packaged together in a trapezoidal case with a screw hole.



I first tried the Optek OPB742WZ, which costs about $3.50 from Mouser. It comes with four 24" leads and has an IR LED with small apertures for the LED and the phototransistor. I hoped this would make for a smaller illuminated spot that would allow more stripes on the encoder disk. In the end I was able to use a 30-stripe disk with no problems. I'd prefer more stripes, but had trouble getting a 50-stripe disk to work reliably.

To print the encoder disks I used Nick Ames Postscript wheel encoder generator, http://www.fetchmodus.org/projects/encoder/. To fit the Solarbotics wheels I used an outer diameter of 56mm and an inner diameter of 36mm. The encoder disk and wheel (not to scale):

The phototransistor on the OPB742WZ has analog output. I read it using an analog input pin on the Arduino. Using a 100 Ohm resistor for the LED side and a 10 KOhm pull-down resistor on the phototransistor side, I can read analog input values ranging from about 30 (black) to about 230 (white). This corresponds to about .1V to 1.25V output from the phototransistor. After you screw in the OPB742WZ, you can adjust the distance to the wheel to get the largest analog value for white.

It would be easier if I had added a Schmidt trigger so I could use a digital input to trigger interrupts, but being a software engineer I decided to emulate a trigger in software. In order to read the phototransistor as often as possible, I wrote an Arduino library to put the ADC chip into continuous reading mode, with an interrupt when the next reading is available. The library allows setting a scan order of analog pins and continuously asks the ADC to read a new pin as soon as a value is ready. A callback function then checks to see whether we have another transition from white to black or vice versa.

In order to make the trigger self-calibrating, another class keeps track of the minimum and maximum analog values that have been read. When the value goes three-quarters of the way from low to high or vice versa, another tick is recorded.

Results

The wheel encoders work very well. Using them I can update the robot's pose with pleasing accuracy. The robot can use the ticks recorded from the left and right wheels to update both its assumed heading and (x,y) position. I have been able to follow waypoints several meters apart around a course and end up within a few inches of the desired endpoint.

Other Alternatives

There are other Optek devices which use red LEDs instead of IR. I have bought a couple and will try them out to see if they work as well. The advantage of red LEDs is that students would get feedback when they connected the LED even before reading the analog phototransistor output. My initial results with one other Optek component having a red LED is that the voltage difference between white and black is not as large, but seems adequate. I'll write more results later as I have a chance to evaluate the other components more thoroughly.

No comments:

Post a Comment