How to time an action in teleop without delaying teleop.

So me and my team are programming in java, and as head of programming I kind of have to have it together. (I don’t. I am a Sophomore and we are a 2nd year team.) What I’m trying to do is trigger a single solenoid, wait for a short time like 65-100 MS and then close the solenoid again, but I’m not sure how to do that without hitting my teleop routine with a 100 MS lag spike in which the whole teleop loop is delayed when the solenoid is opened up. Thanks!
-5683 Programming Dept.

Are you using the Command framework, or just SampleRobot?

If you are using commands, I would create a Command with a 100 ms timeout, which would open the solenoid in the initialize() method, and close it in the end() method.

If you are just using a simple teleop loop, then it is a little more complicated. Here is some psuedo code that should give you an idea of how to do it:


// Class variables (their values must persist between iterations of the loop)
boolean solenoidOpen = false;
long solenoidOpenTime;

// Runs on each iteration of the teleop loop
if (!solenoidOpen) {
    if(solenoidShouldBeTriggered) {
        openSolenoid();
        solenoidOpened = true;
        solenoidOpenTime = System.currentTimeMillis();
    }
} else {
    if (System.currentTimeMillis() - solenoidOpenTime > 100) {
         closeSolenoid();
         solenoidOpen = false;
    }
}

If you want more clarification, just ask.

You can use java.util.Timer and java.util.TimerTask to schedule something to happen in the future while your program still runs.


// local or class variables
final int solenoidDelay = 65; // milliseconds
final Timer myTimer = new Timer();
final TimerTask closeSolenoidTask = new TimerTask() {

    @Override
    public void run() {
        closeSolenoid();
    }
};

...

mySolenoid.open();
myTimer.schedule(closeSolenoidTask, solenoidDelay);

This method would work in this case (assuming the Solenoid methods are thread-safe), but I would be worried about possible race conditions if more complicated logic were to later be added in the TimerTask.

Also: Hi Sam!

Hey Ben!

Solenoid methods are thread-safe. I’d be more worried about scheduling a close, doing some stuff, then opening the solenoid (and expecting it to stay open) before the scheduled close happens. In this case, the methods for opening/closing the solenoid should have checks to see if it’s been claimed by a different call.


private boolean claimed = false;

public void openSolenoid() {
    if (!claimed) {
        claimed = true;
        // open it
    }
}

public void closeSolenoid() {
    if (claimed) {
        claimed = false;
        // close it
    }
}

But I don’t think it’s a problem for something this simple.

Definitely need to switch to command-based robot and don’t forget to use requires(); with your commands and subsystems, otherwise your whole robot will still pause. WPIlib documentation should be able to take it from there.

It can be solved by limiting the exposure of the solenoid to a class that governs the entire mechanism, then by calling TimerTask.cancel() to eliminate the auto-close when the mechanism is told to do something different.