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.
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
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.
- 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;
- abandon using graphical configuration, I’ve never been a fan and personally don’t use it.