Drive train PID's resources help

I am a relatively new programmer, as it is my first year in vex. I wanted to know if anyone had some good resources for coding, operating, and controlling a drive train PID loop. I have already followed many tutorials and other video resources online such as the one by Connor 1814D and REX 1727B. I have spent about three months cracking at this and my patience is thinning any help would be appreciated.

Just so we are working with the correct terms.

  • When we are talking about a Drivetrain on the forums we primarily are referring to the built in functionality using VexCode. A Drivetrain function is the primary method teams use when they first start with Vex. It has built in PID, turning, and distance controls but the PID cannot be tailored to the robot.
  • As teams advance with programming they may start using their own code where they call the motors individually. This entails using the Spin, SpinFor, and SpinTo methods but again they all have their own built-in proportional controls.
  • Finally you will have teams that want explicit control over the motors and the only way to do that is to control the voltage going to the motors. When the motors are controlled by voltage then there is no built-in PID being used and the programmer has to design any proportional features.
    The P (proportional) looks at the distance the motor has to travel (error) and adjust the voltage based on a ratio. As the motor gets closer to the destination the motor starts to slow down.
    The (pID) is where it gets more complicated. Imagine a car coming to a stop sign. You want the car to slow down as you get closer but if the car is only going 1 MPH for the last 50 feet before the intersection, the driver will get very impatient. The integral and derivative ease off the brakes so the robot is efficient at getting to the destination as fast as possible (without overrunning the stop).

Your should be starting to see the levels of complexity and you will need to determine how much you can handle. Again, a lot of good information on PID here on the forum if that is what you need. 80% of teams can probably use the built in Drivetrain and it will work just fine for them. Designing your own PID is difficult but it will get you that last little bit of efficiency that some teams need to succeed.

//Pseudo code to demonstrate proportional speeds.
//10 inches to go * 1.2 volts  = 12.  
// 3 inches to go * 1.2 volts = 3.6
Motor1.spin(forward, 3.6, voltageUnits::volt);

Gotcha. I haven’t looked too much into the terminology yet but I will try to get the hang of it soon.

This was a very comprehensive resource. I found it extremely useful for understanding it.

By the way, since you’re new and haven’t programmed a lot yet, I would greatly suggest using motor groups and .spin functions instead of the built in drive train. There’s a lot of cool things you can do. However, it’s better if you figure those out for yourself so you can become better at programming.

Also I would suggest (assuming you’re using vexcode C++ or pros) to learn general c++. It’s going to help you A LOT in vex.

1 Like

This is a great resource for a PID. If you have any questions about the tutorial a forum thread can be found here.

1 Like

Full disclosure, the drivetrain class has no PID control loops as such.

driveFor and driveTo use the motor’s capability, and then optionally wait for all motor to finish moving.

The same is true for turnFor and turnTo when not using an inertial sensor (or gyro etc.)

A P loop is used for turnFor and turnTo when using the inertial sensor.

and fun fact for advanced users.
The smartdrive does not directly interface with the inertial or gyro sensor, I have a class called “guido” (which comes from the NASA term for Guidance Officer) that these sensors are a sub class of. This means you could create your own sub class of guido that implements the necessary methods and pass an instance of that to the smartdrive, this allows other sources of “heading” to be used when performing turns.
You can see the guido class in the sdk headers, but I’ll post here for reference

guido class
/** @brief base class with virtual member functions used with IMU and gyro     */
// This class is never directly used except as a ptr to gyro or imu
namespace vex {
    class guido {
        virtual ~guido(){};
        // pure virtual methods that must be implemented
        virtual double angle( rotationUnits units = rotationUnits::deg ) = 0;
        virtual double heading( rotationUnits units = rotationUnits::deg ) = 0;
        virtual void   calibrate( int32_t value ) = 0;
        virtual bool   isCalibrating(void) = 0;
        virtual void   setHeading( double value, rotationUnits units ) = 0;
        virtual double rotation( rotationUnits units = rotationUnits::deg ) = 0;
        virtual void   setRotation( double value, rotationUnits units ) = 0;
        virtual turnType getTurnType( void ) = 0;