WaitForComplete in Functions

What is the best practice to utilize the WatiForComplete when the motor methods are inside different functions?

motor left = motor(PORT1);
motor right = motor(PORT1);
motor lift = motor(PORT1);

double leftRot;
double rightRot;
double inToRot = .0796;

bool drive(double leftIn, double rightIn){
  leftRot = leftIn * inToRot;
  rightRot = rightIn * inToRot;
  left.spinTo(leftRot, rotationUnits::rev, false );
  return right.spinTo(rightRot, rotationUnits::rev, true );
}

bool liftArm(double value){
  return lift.spinTo(value, rotationUnits::rev,true);
}


void autonomous( void ) {
  //How do we get the program to wait until each step completes.
  drive(24,24);  
  liftArm(9); 
  drive(-12,-12);  
  liftArm(-4); 
}

Add a
vex::task::sleep(int time);
Or
wait(int time, timeUnits::units);
In between the tasks

Some added context would be nice, but if you are just waiting for a motor to stop spinning you could try something like this:

While(motor.isSpinning()){
    Task::sleep(30);
}
//here is where you add commands to run after the motor stops

Reading into your code (so this is a guess of what you want): if you just don’t want all of the functions running at once I think you already have it but your ā€˜return’ statements in the functions (unneeded as your functions aren’t sending anything back, change them to void, not bool functions) is causing the last command to not run.

2 Likes

Similar problem reported elsewhere. Similar advice - do some root cause analysis. First step is to determine if the software or the hardware is the problem.

To test if the software is the problem in this type of situation, one could eliminate all load from the motors. For the drive train, this could be as simple as suspending the robot above the ground so the wheels have no resistance. For intakes and lifts, it might be taking the shaft out of the motor. One may then run the program and observe whether the motors engage at the proper time in the expected direction.

If the motors do not behave as expected under these conditions, you likely have a software bug.

If the motors behave as expected without load, you are likely running into a problem where, under load, the motors cannot achieve the instructions you have given.

For example, a similar post likely had a skid-steer chassis and observed that the robots auton would not turn. I suspect it was because the program instructed the two front motors to go forward and the two back motors to go backward, rather than the right side go forward and the left backward.

Because the front and back motors were opposing each other, none of the 4 drive motors could rotation the number of revolutions indicated in the program.

Beyond the obvious solution to this particular bug, there may be other times where the motors cannot achieve the rotations specified - maybe the lift is too heavy or the robot drove into the wall. In this case, one could set the motor timeout to something reasonable, so that if the robot drove into a wall, program control would return after the command timed out. The trick here is that you might need to set the timeout to a different value for each movement. For example, you might need 1 second to move 1 rotation. If you wanted them to ove 2 rotations, you would need to set the motor timeout to 2 (or whatever value is appropriate)

I believe @jpearman has a recent thread that goes into more detail about motor timeouts here:

Best

3 Likes

Per the definition of SpinTo: @return Returns a Boolean that signifies when the motor has reached the target rotation value.

I was passing the SpinTo return on to the drive function return. One option is to use the following code to wait but I was hoping there was a better strategy.

while(!drive(24,24)){
  Task::sleep(30);
}
while(!liftArm(9)){
  Task::sleep(30);
}
1 Like

Remove your return statements. That way, you won’t have to add code and it’ll work like it’s supposed to (with the true statements at the end of the spinTo pausing all following code).