autonomus drive for specific time / distance

hi, im wondering how to code a robot to run in autonomous just to move forward to the baseline (for example)
and i know about two options - one option is with delay - to start drive and then after a few seconds (for example after 3 seconds) to stop the robot (although that its not the best option) and the second option that i know is with accelerometer (but i dont know how to use it) - and i know that the accelerometer isnt very good, and the best way to do this is with encoders for the drive, but we dont have encoders.
so i tried with the delay, but it didnt worked, i tried to make the robot to drive forward for one second (or more) but it didnt worked. i tried to make the robot to drive when im clicking on button 12 (of course that in the end, it will be inside the autonomus function, but for now im trying to do this in the teleop - with a button)
i tried to do something like this



if (js1.getRawButton(12)) {
right_bd.set(0.3);
right_fd.set(0.3);
left_bd.set(0.3);
left_fd.set(0.3);
sleep(1000);
right_bd.set(0.0);
right_fd.set(0.0);
left_bd.set(0.0);
left_fd.set(0.0);


so the robot should start driving and then the code should “wait” for one second (the function sleep its just thread sleep with try catch) but its doesnt working, the robot drive just while im clicking the button, so i tried a lot of different ways to do this - with for loop (for the delay) or with sleep but with counter (for the seconds) and a lot of other ways, but nothing worked, most of the times the robot drive just when im clicking the button, and sometimes it didnt worked either if im clicking on the button or not

so how can i code the robot to drive forward for a specific time / distance ? (and distance with the accelerometer (i have the accelerometer - “frc gyro and accelerometer”, im not sure whats the correct name))

1 Like

You should probably be calling a drive function (like arcadeDrive or cartesianDrive (mecanum)). Also your try increasing the power set on the motor. As for delays try


Timer.delay(seconds); // import timer from WPILib

1 Like

Not the best code. If the watchdog is disabled, it should work. However:

.3 is about the minimum to get the robot moving. If you put the robot on blocks, so the wheels can spin freely, do they move? The wheel motors should move at 0.3 if there is no resistance.

Ideally you want something like this:

In autonomus Init:
StartTime=0;

In Autonomus Periodic:

If (StartTime == 0) {StartTime=time()} [or whatever the time function is]

If ((time() - StartTime) <= 1.0 [or whatever time you want to run your motors] {
right_bd.set(0.3);
right_fd.set(0.3);
left_bd.set(0.3);
left_fd.set(0.3);
} else {
right_bd.set(0.0);
right_fd.set(0.0);
left_bd.set(0.0);
left_fd.set(0.0);
}

All of this is for iterative code, and keep in mind I’m an idiot with barely any software experience.

Using timer.delay is a very poor way to implement autonomous code as it will cause watchdog errors and prevents code from looping. If you have anything running in e.g. robotPeriodic, it will not loop. You should use variables / objects to track your time through multiple loops of the code, which is more robust and safer and won’t require you to disable safety features on your robot to make it work.

Here is a terrible simple example code:


//assuming a RobotDrive object named drivetrain is set up in robotInit

//declare this globally
Timer autoTimer;
int autoCase;

//put this in your autonomousInit code
autoTimer = new Timer();
autoTimer.start();
autoCase = 0;

//have your autonomousPeriodic call this function based on 
//whatever method you are using to choose your autonomous mode
void driveForwardAuton()
{
    switch (autoCase)
    {
        case 0:
            drivetrain.arcadeDrive(0.5, 0); //drive straight forward at 50%
            if (autoTimer > 3) {autoCase++;} //once time has passed move on
            break;
        case 1:
        default:
            drivertrain.arcadeDrive(0, 0);
            break;
    }
}

You could use if statements instead of switch cases if you like, for something so simple (and that saves a global variable) - but using a switch case like this makes it a bit easier to add steps in later, or to write autonomous code with multiple steps that don’t always run in the same order.

The code should not cause watchdog errors - it has a default case that assigns the drive to not move if anything goes wrong, nothing in the code causes delays which prevent the code from looping, and it is easy to find what you need to change later.