This topic has 9 replies, 2 voices, and was last updated 1 year, 5 months ago by SuperDroid.

  • Author
  • #7232
     Scott Murchison

    I am building a mecanum robot with two Sabertooth controllers and the simplified serial with slave select mode. First, confirm for me that in a mecanum robot, I should power LF and RR motors together and RF and LR motors together. For mecanum omnidirectional operation, the motors need to be driven in pairs.

    That being said, I have the two rear wheels connected to one Sabertooth and the two front wheels connected to the other Sabertooth.

    The problem I am seeing is that when I give the motor pairs the same command, the wheels move at slightly different speeds. They are connected to different Sabertooth drivers. Why is this? If I can’t get the motors all running the exact speed for the same input value, the robot will not go where I want it too.

    I can expand a lot more, but first I want to make sure that this forum is being monitored.


    Hi Scott,
    We usually set up the motor controllers so that the front wheels are both on one motor controller, and the rear wheels are on the other. So it looks like you have that set up correctly.

    As far as the motor speeds go, it is an intrinsic problem with motors. they will all turn at slightly different speeds. The way that we can correct this is to use motors with encoders so that we can monitor the speed, and adjust the power to the motor independently.

    What you can do if you don’t have the encoder motors, is to run some tests and scale each motor down one by one until you see that they are moving the same speed. The only issue with this method is if you move to a different terrain, and the wheels encounter more or less resistance than they did when you tested them, but because this is a mecanum robot, you really won’t be doing much off roading with it, so the values should stay fairly constant.

    Let me know if you have any further questions.

     Scott Murchison

    I’m wishing now that I had purchased the encoder version of the motors. Had I known about this problem, I would have. In any event, your explanation makes sense and I will work on a formula to compensate for the differences between the wheel pairs. The original reason that I did not go with encoders is because I plan to use a camera on the robot facing down to identify April Tags or barcodes on the floor, which identify where I want the robot to end up. The visual feedback coupled with live calculations for vectoring will guide the robot to be centered over the symbol. I didn’t expect to run into differences in the motors.

    My robot is going to run on a smooth hard floor or flat carpet (in an office), so there will be no terrain changes.

    I’m using an Arduino to run the robot. Here is a partial sample of code to show how I am moving a motor pair. Does this look right to you? In this case, I have reversed the polarity of one motor so that I can give both motors the same value. Once I figure out the numbers I need to compenste for speed differences, I’ll incorporate them into the values, in this case, for RR and LF.

    #define Driver1Control 4 // control signal
    #define Driver2Control 5 // control signal

    RR = 206;
    digitalWrite(Driver1Control, HIGH); // enable
    mySerial1.write(RR); // send command to rotate right rear wheel
    digitalWrite(Driver1Control, LOW); // disable

    LF = 206;
    digitalWrite(Driver2Control, HIGH); // enable
    mySerial1.write(LF); // send command to rotate left front wheel
    digitalWrite(Driver2Control, LOW); // disable

    BTW, I wasn’t able to send int 0 to stop all motors, so I re-wrote the stop code to look like this.

    digitalWrite(Driver1Control, HIGH); // enable
    digitalWrite(Driver2Control, HIGH); // enable
    mySerial1.write((byte)0x0); // send command to stop all wheels
    digitalWrite(Driver1Control, LOW); // disable
    digitalWrite(Driver2Control, LOW); // disable


    I would suggest taking a look at the Sabertooth Arduino Library. Specifically the Packetized Serial example for controlling the motors. This way you will be able to control each wheel individually without having to swap the leads around.

    We also have some sample code for a RC Mecanum Robot on our github page that can give you an idea on how to do the mixing (lines 110 to 116).

    It looks like you have are going in the right direction, but I figured the above would make it easier on you in the long term.

     Scott Murchison

    Thanks. I’ve done many Arduino projects, many with stepper motors, but this is the first with mecanum wheels. I have to get my head wrapped around the concept. Given that the wheel speeds aren’t all the same, I still have to tweak the numbers for some of them.

    Also, since I’m not using RC, I’m finding it hard to understand how or if I need to incorporate strafe, drive and turn signals. i understand that these would come from the joystick(s) on the remote, but in my case, I will use other means to navigate. I’ll have the stock routines for moving fwd, rev, left, right, turn cw, turn ccw and beyond that, I’ll just need the math for moving off at a different angle, say 37 degrees.


    It was hard for me to understand at first as well, so you are not alone!
    Ideally you would want to create a system of movement that is independent of forward, back, left, right, and strafe because of the case where you would have to move at a non standard angle (like 37 degrees).

    In the RC example, we are taking 3 inputs from the RC controller (forward/back, turn, and strafe) and essentially normalizing them to each wheel so that it will move by a proportional amount.

    Let’s say you push the RC stick to the Right: that would mean that the turnVal would be at -127, and the wheels would be given the following speed values

    Front Right -127
    Front Left +127
    Rear Right -127
    Rear Left +127

    so the right wheels are turning backwards, and the left wheels are turning forwards, which turns the robot right.

    for the case where you have the RC stick is pushed forward and slightly right (driveVal = 127, turnval = -27)

    Front Right = -100
    Front Left = 127
    Rear Right = -100
    rear left = 127

    which would turn the right wheels slightly slower than the left wheels, and make the robot turn slightly to the right. Keep in mind that the max value of the drive val is 127, so any number beyond 127 will be set to 127.

    for your camera, if you were able to set up the vision to track where an object is relative to the center of the camera, you should be able to create a vector from the x and y coordinates and send that to move the robot proportionally.

    Hopefully this helps a little bit. Also, keep in mind that this isn’t the only way to achieve the mixing in the robot, so try searching around for other examples and see if any of those works better for your purposes.

     Scott Murchison

    Thank you for the explanation. It does make sense and it does help. In my case, I plan to use an OpenMV camera to locate a target position on the floor beneath the robot. Their software finds the target, say an Apriltag, and tells me where the center of it is in the FOV, along with its rotation angle. By simple math, I can determine what angle I need to move the robot over top that Apriltag. Whereas an RC controller gives three signals, I’ll have just my calculation and I have to figure out how much power to give the two pairs of motors to move in the right direction. That’s the secret sauce. While the robot is moving, I can keep update the robot position with respect to the Apriltag and tweak the motor settings.

    There is still the issue of calibrating the wheel pairs such that I compensate for any speed differences between the motors. I have found that if I send each motor 100 for 5 seconds, they don’t end up in the same place. I may have to adjust one motor to say 98 to get them to the same distance.


    Good, I’m glad it helped. And yes, the math will have to be changed a bit, but it shouldn’t be too hard.

    As far as the scaling goes, you are on the right track for the motors. It will take some trial and error, but I think you are off to a good start.

     Scott Murchison

    The Packetized Serial Mode, although more complex, looks enticing to use. Correct me if I am wrong, but it is already scaled to -127 (full speed reverse) to 127 (full speed forward) and each wheel can be controlled individually. Let me see if I have this right.

    #include <Sabertooth.h>

    #define RF 1
    #define LF 2
    #define RR 1
    #define LR 2

    Sabertooth ST1(128) // for first Sabertooth driver, set the address bits to 128
    Sabertooth ST2(129) // for second Sabertooth driver, set the address bits to 129

    // commands will look like this
    ST1.motor(1,POWER) // for M1A (RF) on ST1
    ST1.motor(2,POWER) // for M1B (LF) on ST1

    ST2.motor(1,POWER) // for M1A (RR) on ST2
    ST2.motor(2,POWER) // for M1B (LR) on ST2

    I can change the individual motor power setting to compensate for differences between motors

    Therefore, to move to the left, I would have a subroutine that looks like this.

    void MoveLeft(int power){
    // all motors get the same power to move directly left
    where power equates to speed and the individual power numbers can be slightly different for each motor to compensate for differences.


    It looks like you have it! you are probably right about the max speed being 127, and anything over that amount wouldn’t really be doing anything, but just to be on the safe side, I would still constrain it to -127 to 127 just to be safe.

    The sign of the motor might change depending how you have your motors hooked up, but it looks like it should work.

Viewing 10 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic.

Login Register

©2021 | All rights reserved.

Log in with your credentials


Forgot your details?

Create Account