Since motor speeds can be slightly different, I’m interested in automating the process of calibrating the motors on a robot. I’ve done this by hand before but it was a bit tedious and error prone.
Toward this end I stumbled across a description of a robot that used downward facing reflectance sensors to accomplish this. The robot could calibrate itself by turning each wheel forward and backward while on a sheet of paper that had a black line drawn on it. It apparently measured the time between detection at various speeds.
Has anyone done this?
Thanks Tom
To err is human.
To really foul up, use a computer.
Having built my first robot with a downward facing reflectance sensor and wheel encoders, I decided to try to code a self calibrating robot.
So why would I want to do that?
I mostly program my robots with a cooperative scheduler that generates rotational and translational velocities for the motors. Those velocities need to be turned into PWM duty cycle values for each wheel. That’s where the motor calibration comes in. With a table of motor duty cycles to wheel velocities (distance/time) I can usually create linear equations and plug them into a steer procedure.
In my cooperative scheduler each robot behavior that I’ve coded gets a chance at controlling the robot’s actuators (wheels in this case). Each behavior updates two arrays, left_vel[beh_id] and right_vel[beh_id], with their preferences by calling the steer procedure. The scheduler decides which behavior wins and will execute the winner’s motor speed commands after which the whole thing starts over again…
void _steer(float rotation, float translation, unsigned char beh_id) { float radius = baseline/1000.0; // the radius of rotation = baseline, only in meters not mm float velRight, velLeft, leftWheelSpeed, rightWheelSpeed = 0; // Calculation of left and right wheel velocities // from forward velocity v(t) and rotational velocity w(t). // Let L = the baseline in meters, velocities are in units of meters/sec, // rotational velocity is in radians/sec. // vRight = v + (wL/2); // vLeft = v - (wL/2); so -w => clockwise and +w => counter clockwise // velLeft = translation - (rotation * radius)/2; velRight = translation + (rotation * radius)/2; if (rotation == 0.0 && translation == 0.0) { left_vel[beh_id] = 0; right_vel[beh_id] = 0; } else { // calculate wheel speeds (ie duty cycle) from velocity rightWheelSpeed = 621.98 * fabs(velRight) + 6.56; right_vel[beh_id] = rightWheelSpeed * signfloat(velRight); // float to int16 leftWheelSpeed = 629.06 * fabs(velLeft) + 5.72; left_vel[beh_id] = leftWheelSpeed * signfloat(velLeft); // float to int16 } }
This is the table of results I got when grabbing duty cycle and its velocity for both wheels. My program just spins the robot over a dark line one wheel at a time to collect the data points. If any duty cycle takes more than 10 seconds to cross the dark line the first time I consider it a dead zone and ignore it. I do have to physically move the robot when the program switches wheels.
I calculate the linear equation using the min and max duty cycle data points like this:
// figure out the slope y2-y1 / x2 - x1; rise/run float slopeRight = (maxRightDC - minRightDC) / (maxRightVel - minRightVel); // substitute slope into slope intercept form of a line: y = mx+b; using the first observation, then find b. // eg. minRightDC = slopeRight * minRightVel + bRight float bRight = minRightDC - (slopeRight * minRightVel); // and for the left wheel float slopeLeft = (maxLeftDC - minLeftDC) / (maxLeftVel - minLeftVel); float bLeft = minLeftDC - (slopeLeft * minLeftVel); printf("Left wheel linear equation: y = %3.4f x + %2.3f\n", slopeLeft, bLeft); printf("Right wheel linear equation: y = %3.4f x + %2.3f\n", slopeRight, bRight);
Here are the graphs from a spreadsheet that fits the best linear equation using all of the data points.
Although my self calibrating robot doesn’t go perfectly straight, it’s close enough...
Tom
To err is human.
To really foul up, use a computer.
@thrandell WOW, that's not at all how I thought it was done.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, 360, fairly knowledge in PC plus numerous MPU's & MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Hi Tom
Toward this end I stumbled across a description of a robot that used downward facing reflectance sensors to accomplish this.
Are you able to provide a link to the description? I have had trouble understanding your description of the process.
Self calibration is a must do and indeed recalibration is a must do. It is something I have spend time experimenting with. I know that some robot vacuum cleaners fuse encoder data with data from gyroscope and accelerometer sensors to monitor the result of their actions.
John
Hmmm, as I recall it was from a paper describing the design of a swam robot. Sorry I don’t have a link. There wasn’t anything more than what I wrote in my first post. I’m not sure how to describe it any better. This is from my code:
An effort to automate the motor calibration that I usually do by hand. Turn the robot over a piece of paper that has a dark line drawn on it gathering: duty cycle, the count of encoder clicks and the time it took to move between two dark lines. From these data points I should be able to create a linear equation that approximates a line through each point (x axis = velocity; y axis = duty cycle).
This is the starting position for the process. It will just spin on the right wheel gathering the data points, then I reposition it to the opposite wheel and it spins on the left wheel.
Tom
To err is human.
To really foul up, use a computer.
Ok. Thanks for the reply. I guess I am too thick to understand what is being solved or what is required in that area regarding swarm robots. The closest I came to swarm behavior was only in simulations and non player characters in top/down computer games.
In your builds, what do you do to ensure that the robot moves straight when you want it to? How do you control the speed of the robot? That’s all this is. Controlling speed and direction.
To err is human.
To really foul up, use a computer.
Mostly the speed is flat out or stop. Ever since I joined this forum I have been using encoder enabled motorized wheels from robot vacuum cleaners.
I haven't built zippy little robots like yours. Instead they are medium sized and have been limited to the speed of a robot vacuum cleaner.
The problem of travelling in a straight line is something I was going to post about. Essentially you have to keep both wheels turning at the same rate. Pointing the robot accurately in the right direction by rotation is also an issue. Just a small error will result in a big error at the end of its travel no matter how straight the path itself.
Essentially a robot has to be controlled by the environment to keep it on course and/or adjust its direction of travel. I imagined that is how it would work for swarm bots where other bots and obstacles controlled its actions.
There are a lot of things I think about trying to improve a straight line travel such as the little module that combines an accelerometer, a magnetometer, and a gyroscope all in one tiny package with an Arduino friendly I2C interface to supplement the encoder readings which I have somewhere collecting dust at the moment.