Changes to vex::motor API

Yesterday I explained in the VEX VSCode extension topic that we have removed some of the motor and motor_group functions that we now consider obsolete. Specifically we have removed all of the motor movement functions that start with “rotate”, “startRotate”, “startSpin” and anything related to rotation.

This will almost certainly break some existing code, but it stops having two groups of functions (rotate and spin) that have identical functionality.

The specific functions removed are these

obsolete motor API
bool rotateTo( double rotation, rotationUnits units, double velocity, velocityUnits units_v, bool waitForCompletion=true );
bool rotateTo( double rotation, rotationUnits units, bool waitForCompletion=true );
bool rotateFor( double rotation, rotationUnits units, double velocity, velocityUnits units_v, bool waitForCompletion=true );
bool rotateFor( directionType dir, double rotation, rotationUnits units, double velocity, velocityUnits units_v, bool waitForCompletion=true );
bool rotateFor( double rotation, rotationUnits units, bool waitForCompletion=true );
bool rotateFor( directionType dir, double rotation, rotationUnits units, bool waitForCompletion=true );
bool rotateFor( double time, timeUnits units, double velocity, velocityUnits units_v );
void rotateFor( directionType dir, double time, timeUnits units, double velocity, velocityUnits units_v );
void rotateFor( double time, timeUnits units );
void rotateFor( directionType dir, double time, timeUnits units );

void resetRotation( void );
void setRotation( double value, rotationUnits units );
double  rotation( rotationUnits units );

void startRotateTo( double rotation, rotationUnits units, double velocity, velocityUnits units_v );
void startSpinTo( double rotation, rotationUnits units, double velocity, velocityUnits units_v );
void startRotateTo( double rotation, rotationUnits units );
void startSpinTo( double rotation, rotationUnits units );
void startRotateFor( double rotation, rotationUnits units, double velocity, velocityUnits units_v );     
void startSpinFor( double rotation, rotationUnits units, double velocity, velocityUnits units_v );
void startRotateFor( directionType dir, double rotation, rotationUnits units, double velocity, velocityUnits units_v );     
void startSpinFor( directionType dir, double rotation, rotationUnits units, double velocity, velocityUnits units_v );     
void startRotateFor( double rotation, rotationUnits units );
void startSpinFor( double rotation, rotationUnits units );
void startRotateFor( directionType dir, double rotation, rotationUnits units );
void startSpinFor( directionType dir, double rotation, rotationUnits units );

Some background.

As most of you know, when the V5 system was released VEX provided a programming environment called Vex Coding Studio. The roots of VCS were in an older environment that was only available for VEX IQ called Modkit, a blocks only environment that was first available in 2013 (or about that time). For those who have never programmed using Modkit, a sequence of blocks with some motor commands looks like this.

Notice that the commands use “spin” and are somewhat similar to what we have today in VEXcode.

When VCS was created, there was a thought that “spin” should be kept for unlimited motor movement and “rotate” should be used for commands that would cause a motor to go to a given position.
Similar code in VCS would look like this.

Block code in VCS had the limitation that it could not handle optional parameters, so it wasn’t possible to have the “and don’t wait” option we have in VEXcode on some of the motor blocks. The only solution was to have an alternate block, and hence C++ API, called startRotate that would have that functionality.

The VCS blocks above when converted to text looked like this.

That was where we were in mid 2018 when VCS was being used.

By early 2019 we realized we had made a mistake and should have stayed with the “spin” APIs for everything, so they were added back in and have been the preferred way of working with VEXcode ever since.

This is current VEXcode IQ with the same motor blocks and generated C++ code.

But lots of code from 2018 is still being copied and reused that has the original APIs and sometimes a mixture of the two. With the release of the VSCode extension we decided now would be a good time to finally retire “rotate” and get everyone on the “spin” versions moving forwards.

Conversion from the rotate API to the spin API is not difficult and could be achieved with careful use of global find and replace in either VEXcode or VSCode. The code below shows many old API functions converted to their spin equivalent, the old API is commented out and the new one in the line below.

These changes apply to both the vex::motor and vex::motor_group classes.

This change will also be rolled out in future versions of VEXcode for V5, EXP and IQ.

example of API updates
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       james                                                     */
/*    Created:      Wed Aug 24 2022                                           */
/*    Description:  V5 project                                                */
/*                                                                            */
/*----------------------------------------------------------------------------*/

#include "vex.h"

using namespace vex;

vex::motor  motor1(PORT1);

int main() {
    // dumb code that does nothing useful
    //motor1.rotateTo( 180, degrees, 100, rpm );
    motor1.spinToPosition( 180, degrees, 100, rpm );
    //motor1.rotateTo( 180, degrees );
    motor1.spinToPosition( 180, degrees );
    //motor1.rotateTo( 180, degrees, 100, rpm, false );
    motor1.spinToPosition( 180, degrees, 100, rpm, false );
    //motor1.rotateTo( 180, degrees, false );
    motor1.spinToPosition( 180, degrees, false );

    //motor1.rotateFor( 180, degrees, 100, rpm );
    motor1.spinFor( 180, degrees, 100, rpm );
    //motor1.rotateFor( forward, 180, degrees, 100, rpm );
    motor1.spinFor( forward, 180, degrees, 100, rpm );
    //motor1.rotateFor( 180, degrees );
    motor1.spinFor( 180, degrees );
    //motor1.rotateFor( forward, 180, degrees );
    motor1.spinFor( forward, 180, degrees );

    //motor1.rotateFor( 2, seconds, 100, rpm );
    motor1.spinFor( 2, seconds, 100, rpm );
    //motor1.rotateFor( forward, 2, seconds, 100, rpm );
    motor1.spinFor( forward, 2, seconds, 100, rpm );
    //motor1.rotateFor( 2, seconds );
    motor1.spinFor( 2, seconds );
    //motor1.rotateFor( forward, 2, seconds );
    motor1.spinFor( forward, 2, seconds );

    //motor1.startRotateTo( 180, degrees );
    motor1.spinToPosition( 180, degrees, false );
    //motor1.startSpinTo( 180, degrees );
    motor1.spinToPosition( 180, degrees, false );
    //motor1.startRotateFor( 180, degrees );
    motor1.spinFor( 180, degrees, false );
    //motor1.startSpinFor( 180, degrees );
    motor1.spinFor( 180, degrees, false );

    //motor1.resetRotation();
    motor1.resetPosition();
    //motor1.setRotation( 180, degrees );
    motor1.setPosition( 180, degrees );

    //double motor_encoder = motor1.rotation( rotationUnits::rev );
    double motor_encoder = motor1.position( rotationUnits::rev );
    
    printf("%.2f\n", motor_encoder );
}
17 Likes

How can I give 100x :heart:?
(speaking as someone who decided to write a full delegating proxy for vex::motor)

4 Likes

When speaking of motor APIs and since you’re giving it some love, would it be possible to add getters for some of the internal state? The reason I did the proxy was to allow retrieving of the full motor state. Besides stuff already accessible through existing API, I needed to retrieve:

  • What was the last command (and command mode), like:
    • “Last command was 120RPM”
    • or “Last command was 10V”
    • or “Last command was go to 350deg”
  • What is the current brake mode
  • Is the motor reversed?

This allows logging telemetry so you can, for example, chart commanded vs. actual RPM or behavior under voltage control. All very decoupled from the actual code that controls the motor.

6 Likes