Issues with the new VEXCode V5 Pro update

Anyone using motor_groups and written smart drive code? Did anyone notice that the 2.0.5 vex code pro is now giving an error? I have a couple teams that wrote out the smart drives instead of using the GUI for more useability, and it worked at all our tournaments all season but since the upgrade to the new code program they only get this screen

As soon as we remove the motor groups the error goes away, but our auton is useless

When did the update come out? I have the same type of code and I have not been able to check it yet today and I am worried this might happen to me.

Our states was around February, and after states my High School teams were saying they cant use their old style. here’s a snippet of her code:

/* /
Module: main.cpp /
Author: VEX /
Created: Thu Sep 26 2019 /
Description: Competition Template /

// Robot Configuration:
// [Name] [Type] [Port(s)]
// BR motor 18
// FR motor 19
// BL motor 13
// FL motor 11
// FBR motor 12
// FBL motor 20
// Front digital_out H
// In inertial 14
// Back digital_out A
// Ring motor 17
// Controller1 controller

#include “vex.h”

using namespace vex;

vex::motor_group leftSide(FL, BL);

vex::motor_group rightSide(FR, BR);

vex::smartdrive driveTrain(leftSide, rightSide, In, 13, 14, 12.5);

1 Like

send me the project, I’ll take a look. Only thing I can think of is it accidentally worked before and we “fixed” something that broke it.


The issue with the code is primarily caused by use of the inertial sensor instance before it has been constructed. The reason it is broken in VEXcode 2.0.5 is because of a change I made to the smartdrive constructor, it now calls a class member function of the inertial instance, this fails if the inertial instance does not exist. (and I will look for a workaround for this in a future SDK release, but no promises)

from a stack exchange reply.

Global variables are initialized in the order in which they’re declared. So their constructor will be called in the same order in which they’re initialized. This is true within one translation unit. However, the initialization order across multiple translation-units is not defined by the language specification.

what this means is that if you have the following all in one file.

motor rightFront = motor(PORT10, ratio6_1, false);
motor rightBack = motor(PORT20, ratio6_1, false);
motor leftFront = motor(PORT1, ratio6_1, true);
motor leftBack = motor(PORT11, ratio6_1, true);

motor_group LeftSide(leftFront, leftBack);
motor_group RightSide(rightFront, rightBack);

inertial Inertial12 = inertial(PORT12);

smartdrive robotDrive(LeftSide, RightSide, Inertial12, 10.21, 14, 12, distanceUnits::in);

The global instances will be created in that order, but if some of those are in a different file, then there’s no guarantee as to which file will processed first.

It just so happens that the gcc linker we use will process files in alphabetical order, that means that constructors will be called for all globals in main.cpp before those in robot-config.cpp. (this is an ongoing issue with things like digital_out that want to access the Brain.ThreeWirePort instance)

so why did I change it ?

The sensor we pass to smartdrive is a subclass of another called “guido” (which comes from the NASA term for Guidance Officer). On the V5 this can be the inertial sensor, the legacy yaw rate gyro, the GPS sensor or a special sensor you create yourself. On the IQ generation 2 this could be the legacy gyro or the internal inertial sensor. But this causes us a problem because the legacy IQ gyro increases the angle as it turns counter-clockwise, but all of the recent sensors reverse that and increase angles when turning clockwise (the legacy cortex yaw rate gyro did that and became the basis for all new sensors). This in itself is not a big deal, but it becomes an issue when creating a class such as the smartdrive which we would like to be generic and handle code written for V5, EXP, IQ generation 2 and 1 without significant modification. The solution was to attach a property to the sensors which are subclassed from guido that indicates their turning direction, it easily allows code written for say an IQ generation 1 using the legacy gyro to be ported to IQ generation 2 using it’s internal IMU without have to understand that all turns may be reversed (we can tell the internal IMU when created to turn to the left and match the old gyro).

How do I fix it ?

A few options.

  1. keep all global instances of motors, sensors and drivetrain in the same file, for VEXcode this means switching to expert mode so as to be able to edit robot-config.cpp

  2. create the instance of the inertial sensor in the same file as the smartdrive. The fact that motors do not yet exist is less of an issue as they do not get accessed when the smartdrive is created. For the code above, you may do this.

vex::motor_group leftSide(FL, BL);
vex::motor_group rightSide(FR, BR);
inertial In1 = inertial(PORT14);
vex::smartdrive driveTrain(leftSide, rightSide, In1, 13, 14, 12.5);

It doesn’t really matter that you have created two inertial sensors both on PORT14, but probably best to remove the one in graphical config.

  1. use another file and rely on the gcc linker behavior of alphabetical order processing. For example, I created another file called yetmore-config.cpp and moved the drivetrain and motor groups there.

then in main.cpp or vex.h add a declaration for the drivetrain so as to be able to access it.

extern vex::smartdrive driveTrain;
  1. abandon using graphical configuration, I’ve never been a fan and personally don’t use it.

Thank you so much for your help!!

1 Like

So my 8th grade team went with option 2, and we had to remove the inertial sensor from the GUI to make sure it worked, it couldn’t figure out how to use two inertials in the same port haha.

Thank you again!

1 Like