The Ultimate Solution?
After going back and forth through several different iterations trying to get Maxwell to move consistently and predictably, it's time to take a step back from the problem and see if there isn't a better approach.
Basically, all we want is for the robot to execute a few simple movements.
It should be able to move in a straight line forwards and backwards. It should be able to rotate about its center clockwise or counterclockwise for a specified angle. It should be able to pivot around either wheel through a specified angle.
If it can perform those basic moves, then more complex moves can be executed by combining or extending the basic moves. For example, by interleaving commands for a turn and a linear move, we can have it follow the path in the figure above.
In theory, it seems very simple, but in practice it's turned out to be frustratingly difficult....
Perhaps the problem stems from the fact that everything is running 'open loop' - without any active feedback mechanism. The previous attempts have tried to deal with servo motor linearity, and balancing of the speed of the two drive servos. While it may be possible to succeed using that approach, it runs a significant risk of being totally hardware dependent. If the characteristics of one servo changes, or if one of them needs to be replaced, then the program constants would have to be retested and adjusted accordingly.
An alternative approach would be to implement wheel encoders to measure the actual rotation of each wheel. This is roughly equivalent to the technique used to measure the servo linearity, only the measurement would be done real-time, while the robot is moving.
More importantly, the level of abstraction changes - hopefully for the better. With wheel encoders the control program focuses its attention on moving each wheel by a given number of degrees or rotations. Ignoring the problem of slipping for the moment, each wheel movement will result in the robot moving by a predictable amount - independent of the servo speed. In effect, it would longer care what the servo linearity happens to be. It would simply send commands to increase, maintain, or decrease the servo speed to acheive the wheel rotation it needs. Servo motors could be changed without the need for recalibration. Complex movements should be simplier to implement. Moving in a straight line becomes a problem in matching the actual rotation if each wheel - as reported by the encoders. The distance calculations should be much more straight forward since they should be directly proportional to encoder steps (ignoring slippage for the moment.) And all of this should be fairly independent of the servo motor speeds.
So, it looks like it's time to seriously consider implementing wheel encoders for Maxwell. The good news is that the same strategy should have a lot of application to future projects. None of the learning will be wasted - quite the opposite.
You might also enjoy: