Okapi movement timeout

Using OkapiLib is there a way to set a timeout for a motor movement? E.g. if a requested motor movement is physically impeded, is there a way to abort the movement?

The only way I know of is to moveDistanceAsync and sleep for xtime then check if it’s stopped and if not than stop it.

chassis->moveDistanceAsync(8_ft);
pros::delay(2000);
if (chassis->isSettled() != true) {
    chassis->stop();
}
2 Likes

The problem with that is it will have to wait the full 2 seconds even if the drive is settled before then. I would make a function like this:

void moveDistance(okapi::QLength distance, int timeout) {
     chassis->moveDistanceAsync(distance); // move to the target asynchronously (without waiting)
     long endTime = pros::millis() + timeout; determine when to stop if it hasnt settled
     while(!chassis->isSettled()) { // loop if not settled
          if(pros::millis() >= endTime) { // if not settled and time has ran out
               break; // break the loop and continue with autonomous
          }
     }
}

In autonomous you can use it like this

moveDistance(8_ft, 4000); // move 8 ft but continue if 4 seconds has gone by
4 Likes

@austinrobinson I’m up coding before a tournament and quickly implemented your code. It’s a nice way to add a timeout. It didn’t work for me immediately though. I had to add chassis->stop(); inside the if statement to make it work. If you find this is correct I would appreciate it if you’d update your post.

void moveDistance(okapi::QLength distance, int timeout) {
     chassis->moveDistanceAsync(distance); // move to the target asynchronously (without waiting)
     long endTime = pros::millis() + timeout; // determine when to stop if it hasnt settled
     while(!chassis->isSettled()) { // loop if not settled
          if(pros::millis() >= endTime) { // if not settled and time has ran out
             chassis->stop();
               break; // break the loop and continue with autonomous
          }
     }
}
1 Like

You might want to add a pros::delay(50) or something inside your while loop so it doesn’t chew up cycles.

2 Likes

@lerker100 You are correct. @LouisDotA I also will add a small delay in the loop. Since I can’t edit the original post you will have to mark this as the solution.

void moveDistance(okapi::QLength distance, int timeout) {
     chassis->moveDistanceAsync(distance); // move to the target asynchronously (without waiting)
     long endTime = pros::millis() + timeout; // determine when to stop if it hasnt settled
     while(!chassis->isSettled()) { // loop if not settled
          if(pros::millis() >= endTime) { // if not settled and time has ran out
               chassis->stop();
               break; // break the loop and continue with autonomous
          }
          pros::delay(20);
     }
}
4 Likes

You can also simplify the logic to:

void moveDistance(okapi::QLength distance, int timeout) {
     chassis->moveDistanceAsync(distance); // move to the target asynchronously (without waiting)
     long endTime = pros::millis() + timeout; // determine when to stop if it hasnt settled
    // loop until settled or timed out  
     while(!chassis->isSettled() && pros::millis() < endTime) { 
          pros::delay(20);
     }
    chassis->stop();
}
4 Likes