[SOLVED] New GoPiGo3 Encoder Difference

ROSbot is exhibiting a strange behavior:

  • turn_degrees(90) turns about 45, turn_degrees(180) turns about 90
  • drive_cm(50) drives 18.7cm and drive_cm(-50) returns 18.7cm
  • set_motor_position(GPG.MOTOR_LEFT+GPG.MOTOR_RIGHT,360) drives 76mm, (I think this should be 209mm (66.5mm wheel dia * Pi ), and the encoders read indeed read 360 when it stops.

I’ve unplugged and replugged both ends of the motor/encoder cables.
I’ve made sure the encoder sensors are paper thickness from the encoder wheels.

I don’t know what else to try.

I just thought of something to try - try DexterOS…


I don’t have any good ideas - I’ve never tried those commands. Where are they from?
Does sound like a calibration issue somewhere.


They are all examples from ~/Dexter/GoPiGo3/Software/Python/Examples/

I need to try DexterOS on ROSbot, and try Ubuntu 20.04 on Carl. I’m tending to think it is something to do with how I set up Ubuntu 20.04 64-bit. Hopefully easily fixable.

(As I was beginning to test the picamera, the “64-bit dark clouds” may be gathering. I saw a github issue on picamera that said “Do not install - not avail for 64-bit arch yet”)

1 Like

Ah - got it. That’s one of the things I find interesting about ROS - you can run other things while ROS is running - even directly accessing the motors, etc. I vaguely remember in my initial set-up doing tests to check the wheel diameter, etc. Is there a config file somewhere? But I don’t think ROS would use that - it would rely on the URDF.

Good luck with the 64-bit bit :crossed_fingers:

1 Like

Actually yes and you may be using it without knowing it.

# load wheel diameter & wheel base width
        # should there be a problem doing that then save the current default configuration
        except Exception:

    def load_robot_constants(self, config_file_path="/home/pi/Dexter/gpg3_config.json"):

But if you only use gopigo3.py it is hard-coded:

class GoPiGo3(object):
    WHEEL_BASE_WIDTH         = 117  # distance (mm) from left wheel to right wheel. This works with the initial GPG3 prototype. Will need to be adjusted.
    WHEEL_DIAMETER           = 66.5 # wheel diameter (mm)
    WHEEL_BASE_CIRCUMFERENCE = WHEEL_BASE_WIDTH * math.pi # The circumference of the circle the wheels will trace while turning (mm)
    WHEEL_CIRCUMFERENCE      = WHEEL_DIAMETER   * math.pi # The circumference of the wheels (mm)

    MOTOR_GEAR_RATIO           = 120 # Motor gear ratio # 220 for Nicole's prototype
    ENCODER_TICKS_PER_ROTATION = 6   # Encoder ticks per motor rotation (number of magnet positions) # 16 for early prototypes
    MOTOR_TICKS_PER_DEGREE = ((MOTOR_GEAR_RATIO * ENCODER_TICKS_PER_ROTATION) / 360.0) # encoder ticks per output shaft rotation degree

Yes you can, BUT it is easy to for one program to twist the truth for another program. When one program initializes its GoPiGo3 class or an EasyGoPiGo3 class and sets a motor limit or resets the encoders the values in the red board get changed, but another program does not have a way of being alerted.

I ran into this with Carl’s docking program. It was setting a motor speed of 150 DPS to have very accurate turns. Then during Carl’s playtime I would try out various programs, which reset the motor speed to the default 300 DPS, and set the wheel-base and wheel diameter to the default 117 and 66.5mm. Later when it came time for Carl to dock, he was spinning around too fast for accurate turns, and having a hard time docking because the distances were wrong and the angles off due to the Wheel-Base changed. I had to add specific “Don’t trust anything to be the same as you left it” steps.



Same issue using GoPiGo OS, so it appears I am getting extra encoder pulses, equally from both motors based on the set_motor_position(360) command driving straight, and both encoders reading 360 +/- 1 at the end.



Interestingly, when I command a set_motor_position(360) on an old GoPiGo3 motor from my junk box, the old motor revolves exactly one complete revolution, while the new motors turn only 135 degrees.


I’ll have to look for this. Thanks.

No idea on your particular issue. Is it the same for both motors?


The issue has been confirmed. We’re investigating on our side.
I’ll let you know more in a couple of days (contacting China is always a bit slow)


Glad you are on to it - the ENCODER_TICKS_PER_ROTATION = 16 works like a charm (along with finding the calibration (effective Wheel Dia. and Base).

ROSbot just drove an exact 12 inch square with 90 degree corners using:

egpg = EasyGoPiGo3(use_mutex=True)

egpg.WHEEL_DIAMETER = 67.0
egpg.WHEEL_BASE_WIDTH = 112.0
egpg.WHEEL_BASE_CIRCUMFERENCE = egpg.WHEEL_BASE_WIDTH * math.pi # The circumference of the circle the wheels will trace while turning (mm)
egpg.WHEEL_CIRCUMFERENCE      = egpg.WHEEL_DIAMETER   * math.pi # The circumference of the wheels (mm)
egpg.MOTOR_TICKS_PER_DEGREE = ((egpg.MOTOR_GEAR_RATIO * egpg.ENCODER_TICKS_PER_ROTATION) / 360.0) # encoder ticks per output shaft rotation degree

(I also changed the ENCODER_TICKS_PER_ROTATION in /home/pi/Dexter/GoPiGo3/Software/Python/gopigo3.py, and ran sudo setup.py install as you suggested.)


Question: I have figured out how to get correct distance and angles, but I think there is more needed to get DPS speed correct.

When I use the EasyGoPiGo3.set_speed(150) the bot is moving much slower than when I use GoPiGo3.set_motor_limits(dps=150).

1 Like

We noticed a difference in power but it will take a couple of days for the new motors to reach me

1 Like

[SOLVED] had to move the EasyGoPiGo3.set_speed(150) to after I set the parms, instead of before …

But still have to check how DPS limit affects turning speed - 90 degree turns at 90DPS seem to take more than 1 second, and 180 at 90DPS takes longer than 2 seconds. Not critical, but I previously identified 150DPS as best accuracy turn speed.


@cleoqc I am thinking that this “New GoPiGo3 has16 ticks per rotation” is fortuitous for my ROSbot, in that with the appropriate constants, the theoretical driving, turning, and spinning precision might be roughly two and a half times better than Carl that “only has 6 ticks per rotation”. (If the red board can keep up with the higher pulse rate - that needs to be checked.)

In the code, it says that your original prototype had 16 ticks but the final shipped GoPiGo3 only had 6 ticks per rotation. Do you remember the design decision for the change?

As for MR supporting two variant in the wild, is it possible for the gopigo3.py interface to check the serial number and decide to use 6 or 16 as appropriate?


The decision to go down to 6 ticks was purely economical. There was no gain in having 16 ticks for an educational robot.
However our first design was indeed with 16 ticks originally. No changes were made to the red board that would impact it not being able to follow the increased pulse rate.


Initially both 6 and 16 seemed really low to me. But then I was reminded when I was looking at the hardware specs (for other reasons) that there is a 1:120 gear reduction. So 6 ticks per motor rotation = 720 ticks per wheel rotation. At one tick one per 1/2 degree, this seems plenty accurate - I’m sure that slippage and tread-flexing wouldn’t allow any more precise dead reckoning anyway.



Is there any way to tell by looking at a motor assembly if it is the “6-tick” or “16-tick” variety?

What needs to change to compensate for the number of ticks?

1 Like

@jimrh Not by looking at the motor, but @cleoqc has been busy creating a multi-faceted approach to this issue:

  1. added ticks to the gpg_config.json handling
  2. if no ticks in config file, compare GoPiGo3 serial number against list of many “new GoPiGo3”,
    if in list set ticks=16, else =6
  3. A new desktop GUI calibration (and maybe GPGOS browser home?) app checks 1 and 2 above,
    then if needed tries ticks=6 first and if the bot only traveled 1/3-1/2 the calibrated distance, the app suggests user press “retry” and it tries ticks=16.

If you want to manually check a serial number:

  1. python /home/pi/Dexter/GoPiGo3/Software/Python/Examples/Read_Info.py
  2. see if the serial number appears in the pickle file viewable on github (link above)

There may be some “rogue” GoPiGo3, with uncertainty with respect to encoder ticks, that the “retry if way off” feature will return to civility.

@cleoqc’s solution and MR’s attention to the problem really show the “new owners” are committed to supporting our favorite little bot!

Actually, there is but not just looking:

  1. place a mark on the encoder disk at one of the “detectors”. I used a silver Sharpie.
  2. Launch “python /home/pi/Dexter/GoPiGo3/Software/Python/Examples/Motor_Encoder.py”
  3. Note the right and left encoder values
  4. Manually turn the encoder disk with a light touch exactly one revolution
    (Do not try to do this by turning the robot’s wheel/tires)
  5. Note the new value of the rotated encoder
  6. The number of ENCODER_TICKS_PER_ROTATION is twice the difference in encoder value
    Because the encoder API divides the encoder ticks by two.

If you see a difference of 8 for one revolution of the encoder disk, you have a “new” GoPiGo3 that needs ENCODER_TICKS_PER_ROTATION = 16 (and results in MOTOR_TICKS_PER_DEGREE = 5.3333333333)

MOTOR_TICKS_PER_DEGREE = ((MOTOR_GEAR_RATIO * ENCODER_TICKS_PER_ROTATION) / 360.0) # encoder ticks per output shaft rotation degree

I have confirmed number of ticks does not affect turning speed - by the math that escapes me a 90 degree spin with one wheel moving forward at 90 DPS and one wheel moving backward at 90DPS will rotate the bot at some slower speed:

===== Spin 90.0 WHEEL_DIAMETER:66.77 WHEEL_BASE_WIDTH:106.14 mm at 90 dps ========
Encoder Values: 0 0
Turn Time: (Wall Time) 1.6s
Encoder Value: 143 -143
Delta Value: 143 143
Delta Degrees: 90.0 90.0
Accuracy: 100.0% 100.0%
Spin Rate:55.7 dps Wheel Rate:88.4 dps (includes start/stop effect)

(probably has something to due with the ratio of the wheel diameter to the wheel base - hey look at that 66.77 / 106.14 * 90 = 56.6 pretty close to 55.7 seen in the test.)