How can you figure out robot speed?!?!

Our robot has the camera, two Hall-Effect (GTS) sensors, the gyro, and (maybe) the accelerometer. It is driven by two small CIM motors. I have not gotten the accelerometer to work, and I desperately need to know the speed of the robot (accurately if possible).

Any suggestions?

Thanks in advance,
Robinson

figure out how many counts per rotation for the GTS…

Put the robot up on blocks…

Run the robot at max speed for 5 seconds…

record the final count of the GTS…

rough_speed = GTS / counts_per_rotation_of_robot_wheel * robot_wheel_diameter * PI / 12 / seconds_robot_drove_for

that a number in feet/sec

If you want a live speed, then you can take the current GTS count and subtract from it the GTS count at the last cycle, then apply to that number the following formula:

rough_speed = delta_GTS * robot_wheel_diameter * PI * 38.1 / counts_per_rotation_of_robot_wheel

that’s a number in in/sec, for a bit better resolution.

BTW, everything other than GTS and delta_GTS can be calculated and combined before hand. That is, they are constant.

if you need live speed a simple way to do it is like this:


 int time;
int gearteeth;
int speed;
if(time<38)
{
 gearteeth+=// put code in for gear tooth counter
time++;
}
else
{
speed = time;
time=0;
}


this will give you the amount of gear teeths over the given time since the default routine runs at roughly 38Hz that should give you a number fairly close to gear teeth count /sec

Don’t assume that the default routine runs at any speed. It can vary from 26.2ms at the minimum up to nearly half a second (before you trigger the Blinking Red Light of Death). Instead, use one of the four available PIC timer modules. Look around for information on how to use them to tell time…

Knowing speed is actually harder than any one has made it out to be.

Shaft encoders are limited by the slip of the wheels. (They tell you how fast you SHOULD be going, not how fast you are going)

Accelerometers are limited by the huge amounts of noise they generate. If you want a cheap accelerometer… Analog devices makes some 5v ones that will plug right into an analog input on the RC.
ADI iMems Sensor

Keep in mind that an accelerometer isn’t at all useful if you hit something. Additionally you have to integrate them to get velocity.

What you really need is an external reference. Something like using the camera on an orthogonal plane to your plane of motion to compute differences in the images and compute distance based on the shift.

In general this is a very nontrivial problem and is something I’m working on as a Master’s Thesis in Computer Engineering.
That doesn’t mean you can’t fudge it a little bit.

Hope that helps.

To eliminate wheel slip as a factor, put the shaft encoders on a non-driven wheel.

We did this last year and they worked great. Unfortunately at the Championship we had to remove one because of a weight problem. We used 4 inch skyway solid wheels and an IR quadrature encoder. The only problem I ever saw with them was wheelies (which we did a lot of), but if you just want a top speed they’d be great.

To get a very accurate reading of speed from encoders requires interrupts, as you’re very likely to be recieving more than one click per 26.
You could count the number of clicks per a known time period, or time period per click. In both cases, you need to have an interrupt fire when the encoder sends a signal. Kevin Watson’s interrupts package at kevin.org gives an amazing example of how to do this.
Once you know clicks/time or time/click, you can make a ratio of distance/click (d = 2 pi * wheel_radius / clicks_per_rotation) and compute it.

If you want to do clicks/time, the simplest way is have an interrupt increment a counter for each side, and then use the default loop for timing. The default loop runs approximately every 26.2 ms, so the speed for each side would be counter/.026 in clicks/second. (You probably want to use milliseconds to avoid decimals.) However, that 26.2 milliseconds is not always accurate, so you may instead want to use a timer that is guaranteed to run at a certain rate. See Kevin Watson’s interrupts example for how to use timers. Using a timer, you can instead take readings over some arbitrary time period, say, 25ms, and be almost guaranteed of the 25ms.

This year, we chose to do it a bit differently, we only had about 4 clicks per 26.2ms loop, giving us an awful precision. We considered computing every 2-4 loops, but instead settled on measuring the time between clicks. To do this, set up a timer considerably faster than your encoder will send values. (We chose .5ms or 1ms, I believe) and incremement a “clock” for each encoder every time the timer fires. Then, when the encoder sends a value, save that time to an array. 1/that time is the clicks/time, which again derives to the velocity.
However, this method has some problems. Firstly, if you don’t get a reading for a long time, you’re stuck with your old ones. To avoid this, simply assume that you’re going at least as slow as 1/clock if the clock is considerably bigger than the past few readings. Also, this method can give somewhat inaccurate, noisy readings. We found it necessary to average a few readings, and discard ones that are very far off from the last one. In the end, it all worked out and we ended up with a solid PID controller functioning off of this velocity reading. (However, this controller was not set up to go backwards. To drive backwards, we just switched the sides of the sensors and outputs.