How to make an accurate drive forward function

(V5 C++) How would I make a function that would make the robot accurately drive forward and backward? The issue is, it is not accurate. Ask it to drive forward 80 inches, and it will drive forward 50. It’s also inconsistent. My idea was to make a drive function based on rotation, utilizing the motors’ internal sensors. It is not working. I would like to know what might be the issue with my function, or what might be a better idea/alternative.

void Drive(double number) {
  lb.spinFor(forward, 1, turns);
  lm.spinFor(forward, 1, turns);
  lf.spinFor(forward, 1, turns);
  rb.spinFor(forward, 1, turns);
  rm.spinFor(forward, 1, turns);
  rf.spinFor(forward, 1, turns);
}

(We have 6 motors) When running Drive(any number) our robot makes a noise but does not turn or move. We have replaced the 1 turns with 90, 360, and 9999 degrees and it does the same exact thing. I’ve tried reversing and unreversing the motors and setting up the robot differently, but it does not work.

In order to make all the spinFor functions spin at the same time, you need to add an additional false parameter at the end because it is by default blocking. Add false to the end of all of them except the last one.
Corrected code:

void Drive(double number) {
  lb.spinFor(forward, 1, turns, false);
  lm.spinFor(forward, 1, turns, false);
  lf.spinFor(forward, 1, turns, false);
  rb.spinFor(forward, 1, turns, false);
  rm.spinFor(forward, 1, turns, false);
  rf.spinFor(forward, 1, turns);
}

As for why the drive function wasn’t working, assuming you were using the built-in drivebase class’s functions, it may be not accounting for an external gear ratio. If you want to increase ethe accuracy and speed of your distance drive I recommend looking into making it a PID.

5 Likes

I am making a PID (or trying to) already, but how would I apply this to a drive instead of just the turns?

The only difference between a drive PID and a turn PID is that the drive PID uses the rotation of the motors to calculate error.

3 Likes

I recycled code from your help with my P turn function and made this. Would this work? I got no errors but can’t test at the moment.

int DriveTurns(float number){
leftDrive.spinFor(forward, 1, turns, false);
rightDrive.spinFor(forward, 1, turns);
  return 0;
}

void Drive(float DriveTurns, float kP){
     float error = DriveTurns-((leftDrive.position(turns)*rightDrive.position(turns))/2);
     while(error>1 || error<-1){
          error = DriveTurns-((leftDrive.position(turns)*rightDrive.position(turns))/2);
          leftDrive.spin(forward, error*kP, volt); 
          rightDrive.spin(forward, error*kP, volt);
          wait(15, msec);
     }
}
1 Like

Here we go again

motor_group   leftDrive( lb, lm, lf );
motor_group   rightDrive( rb, rm, rf );

void drive(float degrees, float kP){
     float error;
     leftDrive.resetRotation();
     while(error>5 || error<-5){
          error = degrees-leftDrive.rotation(deg);
          leftDrive.spin(forward, error*kP, volt);
          rightDrive.spin(forward, error*kP, volt);
     }
}

drive(1000, 0.1);
2 Likes

I didn’t think about it working even when only defining the position of one motor group, so I took too many steps. Thank you! I think I understand this now. However, I’m still having issues. “rotation” and “resetRotation” apparently don’t work in V5, so I tried replacing them with “position” and “setPosition(0)” and I got the error that I can’t initialize a vex::rotationUnits parameter with float. So, I changed the type for degrees to vex::rotationUnits and it said "invalid operands to binary expression (vex::rotationUnits and double) despite the fact that there is no usage of the type double anywhere in the code. I then tried changing the type on kP and even removing it and related bits altogether, but it didn’t fix the issue.

1 Like

Again again…

motor_group   leftDrive( lb, lm, lf );
motor_group   rightDrive( rb, rm, rf );

void drive(float degrees, float kP){
     float error;
     leftDrive.setPosition(0);
     while(error>5 || error<-5){
          error = degrees-leftDrive.position(deg);
          leftDrive.spin(forward, error*kP, volt);
          rightDrive.spin(forward, error*kP, volt);
     }
}

drive(1000, 0.1);
1 Like

You might consider block coding, or maybe Python, until you’re ready to handle functional programming, scope, and C++ in general.

2 Likes

This needs to be
leftDrive.setPosition(0, deg);

1 Like

Resetting rotation on a motor should be used like so :

LF.resetPosition();

Setting position should be used like this :

LF.setPosition(0,deg);

and getting rotation like this :

LF.position(deg);