Custom Drive Function

I am a programmer who is new to custom functions in Vexcode V5 Pro… I was wondering if there was a way to use strings to dictate the spin(dir, rotation, units) For example, when the user input in a function drive(“fwd”, 5, 100); all of the wheels turns 5 rotations forward at 100 percent. I am currently using if statements to solve this problem.
Attached is my code currently.
image

Technically what you have can work. I would advise against the use of strings for this purpose because if you input anything other than a correct string, the program will not work and not error out when you are compiling wrong direction words. The program would download, but the function would do nothing.

I would suggest the use of an enum class to solve this. An enum is a series of strings that actually disguise integer numbers. For example

enum class directions
{
  forward,
  right,
  left,
  down
};

In this enum class, using the “forward” term is a disguised zero, “right” is a disguised 1 and so on. To use this, your function would be structured like drive(directions d, double r, double v) in my example. Using the function, you would type directions::forward in . If an invalid direction is entered the program will have an error and not build, preventing confusion when the robot program builds and then does nothing. This is a slightly more complicated topic, so I might suggest having a look at this website for more information.

11 Likes

so is the enum class what vex is doing with direction type?

Exactly, Vex created a few enum classes to simplify direction names. They force the use of correct names.

4 Likes

Okay. This clears up things for me. Thank you

I was trying to implement enumerators in my drive function and it didn’t work. What is wrong with my syntax?

#include "vex.h"

using namespace vex;

enum class direction{
  forward, 
  right, 
  down, 
  left
};
void
drive(direction d,double r, double v){
  leftDownMotor.setVelocity(v, percent);
  leftUpMotor.setVelocity(v, percent);
  rightDownMotor.setVelocity(v, percent);
  rightUpMotor.setVelocity(v, percent);
 
  leftUpMotor.spinFor(d,r,turns, false);
  rightUpMotor.spinFor(d,r,turns, false);
  leftDownMotor.spinFor(d,r,turns, false);
  rightDownMotor.spinFor(d,r,turns, false);
}

spinFor does/cannot accept a custom enum. There are various overloads (that means ways of calling spinFor) but usually you pass a parameter that if of type vex::directionType. There is no cast (meaning conversion) available from your custom enum to directionType.

4 Likes

Remember that your enum is only really just a number. the setVelocity command can only interpret values for forward or reverse values and your enum is intended for more than this. I think my suggestion for this would be to use the switch statement. Switch is a short form of a large if/else statement.
You could use the switch statement for each option in your enum to set the correct motor directions.

Borrowing your code…
#include “vex.h”

using namespace vex;

enum class direction{
  forward, 
  right, 
  down, 
  left
};
void
drive(direction d,double r, double v){
  leftDownMotor.setVelocity(v, percent);
  leftUpMotor.setVelocity(v, percent);
  rightDownMotor.setVelocity(v, percent);
  rightUpMotor.setVelocity(v, percent);
 
  // choose the correct motor directions
  switch(d)
  {
    case directions::forward:
    // motor commands here
    break;
}

You can find more information for the switch statement here.

7 Likes

For some odd reason, now it says that forward is a vex::direction type. I then changed it to north but now it keeps saying that north is undeclared?
code snippet 1 code snippet 2 code snippet 3
The first code snippet is from a file called autonFunctions.cpp, the second snippet is from a file called autonFunctions.h, the third one is from main.cpp. I included autonFunctions.h in vex.h and the syntax for creating separate files for custom functions has worked in the past. Idk why it doesn’t work now.

Not near a compiler, but you have made an enumeration class, so I think you’ll need to say

drive( direction::north, …

to let the compiler know that it’s a class.

4 Likes

That makes sense. I thought I could just write it rather than putting the class in. It works now. Thank you all for all of the help that you guys have given me.

1 Like

Glad it’s working. You can put your forward, backward,left and right in your class and then overlay them in the switch statement

case direction::north, direction::forward:

Good luck

2 Likes

Glad that this is working as well. While I’m here I have one more little nitpick on your switch statement. You should always end each case with a break line. This forces the switch statement to finish, preventing the code from using CPU cycles to evaluate the other cases in the switch. It is really just a small code optimization to prevent logic from slowing down.

2 Likes

It’s a lot more than just optimizing, it’s necessary, otherwise all following statements will be executed. Passing “east” will cause all code for east, south and west to be executed. It’s called Fallthrough.

7 Likes

Yeah I realized that I forgot all of the breaks. I added them in.

I actually didn’t know this. Are you saying if in @CrazyKingRoyale 's code above, if the direction::east case were to be true, both the south and west cases would run regardless of if those cases matched the switch input? I have never tested this myself.

That’s what I’m saying. Sometimes that feature is used, most of the time it is not.

7 Likes

Final custom Function:

#include "vex.h"

using namespace vex;

//thank you to VEX forum users invalidflaw, jpearman, and Foster for all of their help to program this custom function.
void
drive(direction d,double r, double v){
  
  switch(d){
    case direction::forward:
    leftUpMotor.spinFor(r, turns, v, velocityUnits::pct, false);
    rightUpMotor.spinFor(r, turns, v, velocityUnits::pct, false);
    leftDownMotor.spinFor(r, turns, v, velocityUnits::pct, false);
    rightDownMotor.spinFor(r, turns, v, velocityUnits::pct);
    break;
    case direction::right:
    leftUpMotor.spinFor(r, turns, v, velocityUnits::pct, false);
    rightUpMotor.spinFor(r, turns, -v, velocityUnits::pct, false);
    leftDownMotor.spinFor(r, turns, v, velocityUnits::pct, false);
    rightDownMotor.spinFor(r, turns, -v, velocityUnits::pct);
    break;
    case direction::backward:
    leftUpMotor.spinFor(r, turns, -v, velocityUnits::pct, false);
    rightUpMotor.spinFor(r, turns, -v, velocityUnits::pct, false);
    leftDownMotor.spinFor(r, turns, -v, velocityUnits::pct, false);
    rightDownMotor.spinFor(r, turns, -v, velocityUnits::pct);
    break;
    case direction::left:
    leftUpMotor.spinFor(r, turns, -v, velocityUnits::pct, false);
    rightUpMotor.spinFor(r, turns, v, velocityUnits::pct, false);
    leftDownMotor.spinFor(r, turns, -v, velocityUnits::pct, false);
    rightDownMotor.spinFor(r, turns, v, velocityUnits::pct);
    break;
  }

}
1 Like