VexCode V5 (Python) new Motor Groups

The latest version of Vexcode V5 (not Vexcode Pro) added Motor Groups. I think in other programming environments motor groups will help sync motors so they run at the same speed. Do the new motor groups in Vexcode V5 do the synching?

I did some quick tests and I don’t think they do. I use this snippet when running two motors with very different loads on them:

A_encoder = Groupy_motor_a.position(TURNS)
B_encoder = Groupy_motor_b.position(TURNS)

A_diff = A_encoder - A_last
B_diff = B_encoder - B_last

if abs(A_diff) > 0:
    speed_offset = 1 - (B_diff / A_diff)
    print('%s, %s, %s, %s, %s' % (A_encoder, B_encoder, A_diff, B_diff, speed_offset * 100))

A_last = A_encoder
B_last = B_encoder

The last value, the percent difference between the two motors, reports roughly 3 percent difference between them after running for about 1 minute. If I use equivalent code controlling the motors individually, the error report is roughly the same.

For completeness, here is the full (Python) code using Motor Groups:
from vex import *

# Begin project code

Groupy.stop()
Groupy.set_velocity(90, PERCENT)

record = Event()

A_last = 0
B_last = 0

recording = False
spinning = False


def do_record():
    global recording
    global A_last
    global B_last

    recording = True
    A_last = 0
    B_last = 0
    print('A position, B position, A difference, B difference, B percent of A')
    while recording:
        A_encoder = Groupy_motor_a.position(TURNS)
        B_encoder = Groupy_motor_b.position(TURNS)

        A_diff = A_encoder - A_last
        B_diff = B_encoder - B_last

        if abs(A_diff) > 0:
            speed_offset = 1 - (B_diff / A_diff)
            print('%s, %s, %s, %s, %s' % (A_encoder, B_encoder, A_diff, B_diff, speed_offset * 100))

        A_last = A_encoder
        B_last = B_encoder

        wait(0.1,SECONDS)


record(do_record)

def do_spin():
    global spinning
    
    spinning = True
    Groupy.set_position(0,TURNS)
    record.broadcast()
    Groupy.spin(FORWARD)
    
def stop_spin():
    global spinning
    global recording

    spinning = False
    recording = False
    Groupy.stop()
    
controller_1.buttonA.pressed(do_spin)
controller_1.buttonA.released(stop_spin)

Here is the code using two non-grouped Motors:
from vex import *

# Begin project code

A.stop()
B.stop()
A.set_velocity(90, PERCENT)
B.set_velocity(90, PERCENT)

record = Event()

A_last = 0
B_last = 0

recording = False
spinning = False


def do_record():
    global recording
    global A_last
    global B_last

    recording = True
    A_last = 0
    B_last = 0
    print('A position, B position, A difference, B difference, B percent of A')
    while recording:
        A_encoder = A.position(TURNS)
        B_encoder = B.position(TURNS)

        A_diff = A_encoder - A_last
        B_diff = B_encoder - B_last

        if abs(A_diff) > 0:
            speed_offset = 1 - (B_diff / A_diff)
            print('%s, %s, %s, %s, %s' % (A_encoder, B_encoder, A_diff, B_diff, speed_offset * 100))

        A_last = A_encoder
        B_last = B_encoder

        wait(0.1,SECONDS)


record(do_record)

def do_spin():
    global spinning
    
    spinning = True
    A.set_position(0,TURNS)
    B.set_position(0,TURNS)
    record.broadcast()
    A.spin(FORWARD)
    B.spin(FORWARD)
    
def stop_spin():
    global spinning
    global recording

    spinning = False
    recording = False
    A.stop()
    B.stop()

controller_1.buttonA.pressed(do_spin)
controller_1.buttonA.released(stop_spin)

So to my understanding motor groups do nothing other than allow you to treat multiple motors as one. I do not believe they do any processing such as equalization although it would be very cool if they did. I’m pretty sure you will have to do that yourself. If you have motors under significantly different loads it can be easier to control them separately and create your own functions that emulate motor groups like you have in the last example. You can also still use motor groups for simple commands like spin and set each motors velocity separately.

3 Likes

All motor groups do is allow a number of motors to be treated as a single object. The same commands are sent to all motors in the group.

motor groups have also been available in Python since our initial release last year and in C++ for some time before that. The only addition to VEXcode was the graphical configuration for motor groups and the use of them in blocks.

3 Likes

A question about the motor groups:

Is the grouping done inside VEXos and simply accessible via the API/SDK or the grouping is done though classes at the different programming environments level (VEXcode/pro, RMS, PROS and whatever else is out there).

Question is related to commands that ask motors to spin and not release processing until a certain amount of encoder ticks is reached (degrees, revs, whatever units): motor_spin_for, motor_spin_to - the so called blocking commands.

In a grouping command, based on above answers, I’m assuming no clever averaging / error correcting is used so then how does the grouping command decide which motor’s encoder to read and use to break the loop?

In a competition robot scenario this matters as wheels can get stuck or can slip etc. Yes I know we can write our own, but just curious how things work.

Thanks.

vexos does not handle motor groups, for VEXcode, we have a motorgroup class as part of the sdk.

The motor group class will wait until all motors have reached the command position or a timeout occurs. spinTo etc. all send the commanded position to the motor which handles moving the motor to that position. Once the motor has reached the target, a flag is set, we monitor this for all motors in the group.

The motor group class was really designed for use where motors are mechanically coupled, for example, several motors driving a lift mechanism. It’s a convenience class, it just removes the need to send the same command to several motors.

5 Likes

Thanks James, much appreciated you clarifying this.

1 Like

Yes, thank you. It is very helpful.

1 Like