Answering because this looks like a good problem. And we will both
learn even if my answer is totally wrong. Please note I've read just
enough about ROS to be dangerous, so take what I say with a grain of
salt until someone with a clue checks it... But I think you are on the
right track with the low encoder resolution.
Looking at this code (which I am guessing(!) you are running, except
maybe indigo version?):
https://github.com/hbrobotics/ros_arduino_bridge/blob/hydro-devel/ros_arduino_firmware/src/libraries/ROSArduinoBridge/diff_controller.h
Looking at a few lines in the doPID method (Treat my comments as
hypothesis to test):
input = p->Encoder - p->PrevEnc; //Since you have few encoder
updates, input is generally 0, rarely 1
// I think you count 1 tick
every 13 degrees or so
Perror = p->TargetTicksPerFrame - input; // resetPID sets
TargetTicksPerFrame to 0.0
// I can't see where it is
ever changed after that
// I'm missing something here,
this is probably set somewhere else earlier
output = (Kp * Perror - Kd * (input - p->PrevInput) + p->ITerm) / Ko;
// So this looks like a small
number divided by 50
p->PrevEnc = p->Encoder; // And this is usually a noop
output += p->output; // often 0 + 0 = 0
p->ITerm += Ki * Perror; // Ki = 0 after resetPID, ITerm
is initialized to 0
// 0 + (0 * Perror) = 0...
The updatePID method reads the encoders, decides if the PIDs need to be
reset, runs doPID, and calls setMotorSpeeds. Poking around in this (or
these) method(s) will tell you on what values you are basing the settings.
If this is the code managing your "twist to M command math", try
changing Ko to a smaller number. I don't think this is the right fix,
but your wheels should spin faster! (You do have your 'bot on a stand,
right?) At least it will confirm you are running this code (or you
aren't). Kp is more likely to be a correct tuning parameter, but I'm a
little rusty on PID control right now.
And looking at this code from another angle, using your wheel diameter
and encoder ticks, your target distance of 0.1 meters is about a 1/2
rotation, so about 13 ticks of the encoder away (applying small angle
approximation for sines). Therefore I think Perror should start at
about 13, so where does targetTicksPerFrame get set, what is its value?
Perror depends on this. Then I would expect output = (20*13 - 0 + 0)/50
= 5.2 as the initial move using the default PID tuning parameters. This
is Kp*Perror - the derivative term (you haven't moved yet) + the
integral term (again, you haven't moved yet). But you are getting 0,
not 5... So hmm... What is the value of targetTicksPerFrame? Assuming
this *is* the correct piece of code...
Regards and good luck,
Rudy