The speed of two continuous servos is not syncing

Hello
I have two continuous servo motors that I bought from Pololu and their speeds aren't syncing. I am using the Servo library with two SpringRC SM-S4303R Continuous Rotation Servos. I used the write() function to set the servos to the same speed, but when I upload the program one servo goes slightly faster than the other. This is not good, because I am trying to make a 2WD robot and I need it to drive in a straight line.

//Servo motor 2WD
#include <Servo.h> 
 
// create  2 servo objects 
Servo rservo;
Servo lservo; 
 

void setup() 
{ 
     rservo.attach(9);   // attach the right servo to pin 9 
     lservo.attach(10);  // attach the left servo to pin 10
} 
 
void loop() 
{ 
    //Set servos to full speed forward
    rservo.write(75); 
    lservo.write(105);    
}

Since this is a 2WD robot and the servos are facing away from each other, the number values for write() are different. They are both 15 above or below 90.

Servo that have been modified for continuous rotation are no longer precision servos anymore, but rather they are morphed into becoming a geared bidirectional motor drive. And as there is no longer any internal feedback being used by the 'servo's' electronic one can't expect them to be exactly the same speed given the same angle command, even if the same model servo, unless you could match two from a large batch. Your best bet is to try and characterize your two servos and have a software 'offset' variable to adjust the faster to match the slower. However even then it might not be linear over the whole speed range.

and it offers easy access to the rest-point adjustment potentiometer

Per the above, the servo has an adjustment for the internal pot. Send the servo a 1500us position command, then adjust the pot so the servo is not moving. Do this for both servos. Using writeMicroseconds() provides better control with continuous rotation servos. below is some servo test code that can be used for the setup.

// zoomkat 12-25-13 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// Send an a to attach servo or d to detach servo
// for IDE 1.0.5 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h> 
String readString; //String captured from serial port
Servo myservo;  // create servo object to control a servo 
int n; //value to write to servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7, 500, 2500);  //the pin for the servo control, and range if desired
  Serial.println("servo all-in-one test code 12-25-13"); // so I can keep track of what is loaded
  Serial.println();
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 

      // attach or detach servo if desired
    if (readString == "d") { 
      myservo.detach(); //detach servo
      Serial.println("servo detached");
      goto bailout; //jump over writing to servo
    }
    if (readString == "a") {
      myservo.attach(7); //reattach servo to pin 7
      Serial.println("servo attached");
      goto bailout;
    }    

    n = readString.toInt();  //convert readString into a number

    // auto select appropriate value
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n); 
    }

bailout: //reenter code loop
    Serial.print("Last servo command position: ");    
    Serial.println(myservo.read());
    Serial.println();
    readString=""; //empty for next input
  }
}

GeckoDiode:
...one servo goes slightly faster than the other. This is not good, because I am trying to make a 2WD robot and I need it to drive in a straight line...

As it has already been noted, even if you did modify the settings for the servos via the hardware or the software, it is unlikely to remain synced over the entire speed range, or on varying terrain (especially carpeting for an indoor floor roverbot).

In order to correct for this, you need to be able to monitor how fast the wheels are turning. Typically, this is done via an optical encoder of some sort - for instance:

As the wheels (and encoder) are turned by the servos, you monitor the transition periods of the sensors; if one sensor (wheel) is taking longer than the other (that is, if the transition periods differ), then you need to either speed up the slow wheel, or slow down the fast wheel - until they match again.

Even then, you will still have "noise" on the output - things won't be 100% perfect (this is the real world, unfortunately). You might be able to augment things with a compass sensor.

Or - you could take a different approach. Unless you have an absolute requirement for "perfect" precision and accuracy, you might instead just "go with the flow", let your robot meander a bit, but recognize that noise in your path planning, mapping, and localization algorithms.

Once of the core fundamentals that I learned about when I took the Udacity CS373 course, was that in the real world, all sensors and all systems in robotics have "noise"; you can't completely filter it out, so instead your algorithms need to take it into account - which is why there is so much emphasis on statistics, probabilities, etc - in SLAM (simultaneous localization and mapping) algorithms.

Why is it that 2WD robot kits like BOE-bot with continuous servo motors seem to navigate fine in a straight line?

cr0sh:
As it has already been noted, even if you did modify the settings for the servos via the hardware or the software, it is unlikely to remain synced over the entire speed range, or on varying terrain (especially carpeting for an indoor floor roverbot).

GeckoDiode:
Why is it that 2WD robot kits like BOE-bot with continuous servo motors seem to navigate fine in a straight line?

Who claims that? Have you verified these are legitimate claims?
Apart from the servo syncing and the terrain there are lots of other parameters that will influence the straightness

  1. servo power
  2. servo quality
  3. power supply
  4. wheel diameter
  5. wheel width
  6. wheel surface
  7. Wheel material
  8. The location of the center of gravity of the robot
  9. The quality of your caster-ball

If you are not really experienced in these mechanical features (which is 90% or more of the community member) it is just easier to add an I2C compass. Then it can even run more or less straight in rough terrain.
Best regards
Jantje