VEXcode - updated SDK

VEXcode preview 3 contains a new SDK release 20190410_18_00_00 (and yes, that means 6pm last Wednesday). There are a couple of new classes included, not finalized yet so consider them in beta.

First is a motor_group class. This allows several motors to be combined and treated as a single unit. Motors are instantiated in the usual way, set gearing and reverse flag as you normally would. Then create an instance of two or more motors. After doing that most of the motor methods such as spin and rotateTo are available to use on the motor group. The assumption is that motors in a motor group are mechanically coupled, either motors with the same gearing driving wheels on the floor, or motors attached to a lift or arm system. A motor group is a shorthand way of sending the same command to several motors to save writing several lines of code.

Second is a simple drivetrain class. This takes either two motors as left and right motors on a drive, or two motor groups, again as left and right. You then have some methods to drive forwards/backwards, drive to an encoder count or turn using motor encoders. For driving and turning to work successfully the wheel travel and distance between left and right wheels needs to be added when the drivetrain constructor is called, see the header file for details.

Here is a simple example of the use of the new classes.

Again, this is all subject to change and final VEXcode/SDK may change some of the method names.

#include "vex.h"

using namespace vex;

// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain       Brain;

// define your global instances of motors and other devices here
vex::motor motor_1( vex:: PORT1 );
vex::motor motor_2( vex:: PORT2 );

// motor groop
vex::motor_group motor_group_12( motor_1, motor_2 );

// drivetrain using two motors
// we could use motor groups as well.
vex::drivetrain  drive_1( motor_1, motor_2 );

int 
motorDisplay() {
  while(1) {
    Brain.Screen.printAt( 10, 40, "M1: %8.2f", motor_1.rotation( rotationUnits::rev ) );
    Brain.Screen.printAt( 10, 60, "M2: %8.2f", motor_2.rotation( rotationUnits::rev ) );
    this_thread::sleep_for( 100 );
  }
}

int main() {
    // thread to display motor position
    vex::thread  t(motorDisplay);

    // default velocity for all motors in the motor group.
    motor_group_12.setVelocity( 25, rpm );

    while(1) {
      // example motor group commands
      motor_group_12.spin( fwd );
      this_thread::sleep_for( 3000 );
      
      motor_group_12.stop();
      this_thread::sleep_for( 1000 );

      motor_group_12.rotateTo( 0, rotationUnits::rev, 50, velocityUnits::rpm );
      this_thread::sleep_for( 1000 );


      // example drivetrain commands
      drive_1.drive( directionType::rev );
      this_thread::sleep_for( 1000 );

      drive_1.stop( );
      this_thread::sleep_for( 1000 );

      drive_1.turnFor( turnType::left, 90, rotationUnits::deg );
      this_thread::sleep_for( 1000 );
    }           
}
7 Likes

Will this updated on the API website for VEX Coding Studio/VEXCode?

And an aside - but on a technical level, what’s the difference between tasks and threads. It seems both achieve similar results, but I want to know the difference when I instruct my students.

Eventually, but probably not until VEXcode hits V1.0. These classes are VEXcode only for now.

They really are the same thing, just different method names.
vex::task was the first implementation we did with methods similar to existing ROBOTC functions. It was then suggested that we create something for those already familiar with std::thread, that’s the basis for the vex::thread method names. They both use the same cooperative scheduler we have inside vexos.

2 Likes

What is the VEXcode short cut for getting to the header file for drivetrain?

you can right click on vex.h, use goto definition and then work your way down, however, here it is for reference. I should add that it’s deliberately very similar to the RobotMesh class of the same name.

vex_drivetrain.h
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Copyright (c) Innovation First 2017, All rights reserved.               */
/*                                                                            */
/*    Module:     vex_drivetrain.h                                            */
/*    Author:     James Pearman                                               */
/*    Created:    7 April 2019                                                */
/*                                                                            */
/*    Revisions:                                                              */
/*                V1.00     TBD - Initial release                             */
/*                                                                            */
/*----------------------------------------------------------------------------*/

#ifndef   VCS_DRIVETRAIN_CLASS_H
#define   VCS_DRIVETRAIN_CLASS_H

#include "vex_motorgroup.h"

/*-----------------------------------------------------------------------------*/
/** @file    vex_drivetrain.h
  * @brief   Drivetrain class header
*//*---------------------------------------------------------------------------*/

namespace vex {

  class drivetrain  {
    private:
      vex::motor_group  lm;
      vex::motor_group  rm;

      double _wheel_circumference;
      double _wheel_track;

      int32_t _timeout;
      bool   _waitForCompletionAll();
      double _distanceToRevs( double distance, distanceUnits units );
      double _angleToRevs( double angle, rotationUnits units );

    public:
      drivetrain( motor_group &l, motor_group &r, double wheelTravel=320, double trackWidth=380, distanceUnits unit=distanceUnits::mm );
      drivetrain( vex::motor &l, vex::motor &r, double wheelTravel=320, double trackWidth=380, distanceUnits unit=distanceUnits::mm );

      ~drivetrain();

      /** 
       * @brief Sets the velocity of the drive based on the parameters set in the command. This command will not run the motor.  Any subsequent call that does not contain a specified motor velocity will use this value.
       * @param velocity Sets the amount of velocity.
       * @param units The measurement unit for the velocity value. 
       */
      void  setVelocity( double velocity, velocityUnits units );

      /** 
       * @brief Sets the timeout for the motor group. If the motor group does not reach its' commanded position prior to the completion of the timeout, the motors will stop.
       * @param time Sets the amount of time.
       * @param units The measurement unit for the time value.
       */
      void  setTimeout( int32_t time, timeUnits units );

      /** 
       * @brief Sets the stopping mode of the motor group by passing a brake mode as a parameter.
       * @param mode The stopping mode can be set to coast, brake, or hold.  
       */
      void  setStopping( brakeType mode );

      /** 
       * @brief Turns the motors on, and drive in the specified direction
       * @param dir The direction to drive.
       */
      void 	drive( directionType dir ) ;

      /**
       * @brief Turn on the motors and drive in the specified direction and a specified velocity.
       * @param dir The direction to drive. 
       * @param velocity Sets the amount of velocity.
       * @param units The measurement unit for the velocity value. 
      */
      void 	drive( directionType dir, double velocity, velocityUnits units );

      /**
       * @brief Turn on the motors and drive a distance at the default velocity.
       * @return Returns a Boolean that signifies when the motor has reached the target rotation value.
       * @param distance Sets the distance to drive.
       * @param units The measurement unit for the distance value.
       * @param waitForCompletion (Optional) If true, your program will wait until the motor reaches the target rotational value. If false, the program will continue after calling this function. By default, this parameter is true.
      */
      bool 	driveFor( directionType dir, double distance, distanceUnits units, bool waitForCompletion=true );

      /**
       * @brief Turn on the motors and drive a distance at a specified velocity.
       * @return Returns a Boolean that signifies when the motor has reached the target rotation value.
       * @param distance Sets the distance to drive.
       * @param units The measurement unit for the distance value.
       * @param velocity Sets the amount of velocity.
       * @param units_v The measurement unit for the velocity value.
       * @param waitForCompletion (Optional) If true, your program will wait until the motor reaches the target rotational value. If false, the program will continue after calling this function. By default, this parameter is true.
      */
      bool 	driveFor( directionType dir, double distance, distanceUnits units, double velocity, velocityUnits inits_v, bool waitForCompletion=true );

      /**
       * @brief Turn on the motors and drive a distance at the default velocity but does not wait for the motors to stop.
       * @param distance Sets the distance to drive.
       * @param units The measurement unit for the distance value.
      */
      void 	startDriveFor( directionType dir, double distance, distanceUnits units) ;

      /**
       * @brief Turn on the motors and drive a distance at a specified velocity but does not wait for the motors to stop.
       * @param distance Sets the distance to drive.
       * @param units The measurement unit for the distance value.
       * @param velocity Sets the amount of velocity.
       * @param units_v The measurement unit for the velocity value.
      */
      void 	startDriveFor( directionType dir, double distance, distanceUnits units, double velocity, velocityUnits units_v );

      /** 
       * @brief Turns the motors on, and rotate in the specified direction
       * @param dir The direction to rotate the robot.
       */
      void 	turn( turnType dir);

      /** 
       * @brief Turns the motors on, and rotate in the specified direction and a specified velocity.
       * @param dir The direction to rotate the robot.
       * @param velocity Sets the amount of velocity.
       * @param units The measurement unit for the velocity value. 
       */
      void 	turn( turnType dir, double velocity, velocityUnits units );

      /**
       * @brief Turn on the motors and rotate an angle at the default velocity.
       * @return Returns a Boolean that signifies when the motor has reached the target rotation value.
       * @param angle Sets the angle to turn.
       * @param units The measurement unit for the angle value.
       * @param waitForCompletion (Optional) If true, your program will wait until the motor reaches the target rotational value. If false, the program will continue after calling this function. By default, this parameter is true.
      */
      bool 	turnFor( turnType dir, double angle, rotationUnits units, bool waitForCompletion=true );

      /**
       * @brief Turn on the motors and rotate an angle at a specified velocity.
       * @return Returns a Boolean that signifies when the motor has reached the target rotation value.
       * @param angle Sets the angle to turn.
       * @param units The measurement unit for the angle value.
       * @param velocity Sets the amount of velocity.
       * @param units_v The measurement unit for the velocity value.
       * @param waitForCompletion (Optional) If true, your program will wait until the motor reaches the target rotational value. If false, the program will continue after calling this function. By default, this parameter is true.
      */
      bool 	turnFor( turnType dir, double angle, rotationUnits units, double velocity, velocityUnits units_v, bool waitForCompletion=true );

      /**
       * @brief Turn on the motors and rotate an angle at the default velocity but do not wait for the motors to stop.
       * @param angle Sets the angle to turn.
       * @param units The measurement unit for the angle value.
      */
      void 	startTurnFor (turnType dir, double angle, rotationUnits units );

      /**
       * @brief Turn on the motors and rotate an angle at a specified velocity but do not wait for the motors to stop.
       * @param angle Sets the angle to turn.
       * @param units The measurement unit for the angle value.
       * @param velocity Sets the amount of velocity.
       * @param units_v The measurement unit for the velocity value.
      */
      void 	startTurnFor (turnType dir, double angle, rotationUnits units , double velocity, velocityUnits units_v );

      /** 
       * @brief Checks to see if any of the motors are rotating to a specific target.
       * @return Returns a true Boolean if the motor is on and is rotating to a target. Returns a false Boolean if the motor is done rotating to a target.
       */
      bool 	isSpinning( void );

      /** 
       * @brief Checks to see if all the motor are done rotating to a specific target.
       * @return Returns a false Boolean if the motor is on and is rotating to a target. Returns a true Boolean if the motor is done rotating to a target.
       */
      bool 	isDone( void );

      /** 
       * @brief Stops the drive using the default brake mode.
       */
      void  stop();

      /** 
       * @brief Stops the drive using a specified brake mode.
       * @param mode The brake mode can be set to coast, brake, or hold. 
       */
      void  stop( brakeType mode );

      void 	arcade( double drivePower, double turnPower, percentUnits units=percentUnits::pct );
     
    protected: 
      // Helper functions that can used by sub classes
      double  distanceToMm( double distance, distanceUnits units );
      double  angleToDeg( double angle, rotationUnits units );
      int32_t timeoutGet();
  };
};

#endif // VCS_DRIVETRAIN_CLASS_H

and vex::motor_group has the same method names as vex::motor (where it makes sense, there are a few ommitted, some things will only return a value for the first motor in the group )

1 Like

Thanks! Learn something new every day… I will probably use this for the example code we have - might have a couple more questions :slight_smile:

Which motor’s encoder is used for the group? The first one in the arguments?

So, I have a suggestion for the next update to the SDK. Its not a huge thing, since it can probably be worked around, but since function pointers, such as void (*ptr)(void) are a bit restrictive, as they don’t allow lambdas to be passed, could Competition.autonomous and Competition.usercontrol be changed to use std::function<void(void)>?

we have tried to make the SDK independent of the C++ standard library and all the underlying callback code we use is written in C not C++. However, it should be fairly easy to create your own competition class that does what you need, either monitor the competition status flags in a separate task or hook into our event system. After worlds I will start showing how to use some of the more advanced features, such as the event class, that we haven’t discussed much to date.

3 Likes