I corrected the spelling of odometry in the title. I thought I'd document the approach I worked out, and perhaps some others would find it useful. Please overlook I am replying to my own post.
First have a look at Gary Lucas's article on the SRS site
formatting link
and one on differential steering on his site
formatting link
Notice Gary said, "Rather than looking at the problem as a matter of controlling two motors, I looked at the robot as a whole." I on the other hand had started out making PID work on one motor, then added two motors, and then I took a profiling program I'd written for an arm, and applied it to these motor PIDs. So I came up quite the other way 'round.
My problem was I had two motors under PID control, but no coordination between them. The result was one wheel, or the other, would fall behind in its profiled target point. Although PID would compensate, it would not be until after the error occurred. So the wheel that had the least turning resistance would run steadier speed. The lagging, then corrected wheel, would cause the turned body to straighten on course, but each lag would cause an accumulated error, which became a lateral displacement. Here a little ASCII art might be useful: | is the straight path, and \ is a lag followed by a correction.
actual intended ^ ^ | | \ | | | | | | | \ | | | | | | | \ | | | ^
I think a higher update rate would have made this problem less visible, but that is a bit like sweeping it under the rug.
So while both wheels on the robot were PID controlled, the body did not move in a straight line. This was a surprise when discovered, but makes sense in retrospect. The underspeed of one wheel would cause the I term to generate a correcting overspeed, but while this would again turn the robot straight, it wouldn't correct for the lateral movement imparted during the underspeed.
Interestingly, the odometry doing the tracking of position knew this displacement was taking place. If the problem was measurable, it should be correctable. This started my beginning work on the steering program.
Here is basically how my steering works. If the heading was not the same as the course, then an error is generated. You might first imagine one would speed the outside wheel up and bit and slow down the inside wheel to get a course correction. But! This assumes you can speed up the outside wheel. If you are trying to go full speed, the outside wheel simply can't be made to go faster. In fact, if you've turned off course, it is because the outside wheel didn't go as fast as the inside wheel, so it may already be going as fast as it can and too slow anyway. So the art of steering can be accomplished by slowing down the inside wheel.
How much should the inside wheel be slowed down? It was tempting to just adjust the course so the robot would steer again toward the course. However, if the robot veered off course, correcting back to course would produce a curved path of veer, and return, veer and return. Instead, to hold a straight line, a correction should over compensate, to not only steer toward the point, but past it, to regain the original line.
The greater the error of the actual path traveled the greater the turning force required. Yet this can be over done as well, producing an oscillating path, or even a loss of path. So I computed the difference to slow the inside wheel by taking the relative bearing times a settable gain factor times, and limiting the output to + or - PI, then taking the cosine and multiplying this by the outside wheels actual speed, and applying this to the inside wheels commanded speed.
Here is where the profiling became a problem. The formula gave an instantaneous result for course correction, but for larger turning problems, which occur when the robot reaches a way point and then has to make for another, say, 90 degrees from the original heading, the differential between the wheels would be delayed by the profiling. Consequently, the robot would build up angular momentum, and shoot past the desired heading, and thereby reversing the inside vs. the outside wheel. The result was an unpleasant "waggle" around the new course line.
The problem was solved by setting a maximum differential allowed between the two tires, essentially a limit on angular rotation. The difference between the two wheels was measured against the commanded rotation. If the difference was greater than the commanded rotation, then both wheels were slowed. Slowing down for a corner is a very reasonable and pleasing response. This deceleration of both wheels continued until the outside wheel was at one half of the commanded velocity, which means on a hard turn, the cosine result would command the inside wheel to turn backwards at the same rate as the outside wheel.
In short, the robot would do a decelerated curve into a radial spin (turn on central axis), if its target point changed radically. Yet, when the new heading was approached, the gained-cosine result would lessen, and then become positive, gradually. The limited commanded rotation meant the difference the inside tire had to regain was not so far as to cause overshoot. The inside wheel could soon "catch" the outside wheel and hold the new heading.
While the individual wheels are PID controlled, and the steering manages them by controlling the profiling above the PID routine, and the steering response is more P than PID, I like this algorithm. Given any point to drive to, and a change to any other point, this algorithm will produce smooth and accurate turning to, and then steering to, the new point.
Hope someone finds this helpful or interesting. Feel free to comment.