mmera
mmera

Reputation: 337

Looking for an algorithm to switch lights in traffic light

Given a greenLightDuration and a yellowLightDuration, I need to switch lights (including red Light) based on duration. This all happens inside a run method for the traffic light. The reason for the run method is because it is used when running the entire simulation (trafficLight is an Agent).

   //Run method for agents in Model
    public void run(double duration) {
            if (disposed)
                throw new IllegalStateException();
            for (int i=0; i<duration; i++) {
                time++;
                for (Agent a : agents.toArray(new Agent[0])) {
                    a.run(time);
                }
                super.setChanged();
                super.notifyObservers();
            }
        }

In Light I have the run method...

 public void run(double runTime){   
  double check_time = runtime - time;

        if(check_time >= yellowLightDuration&& color == Color.RED){
            color = Color.GREEN;
            time = runtime;

        }else if(check_time >= greenLightDuration&& color == Color.GREEN){
            color = Color.RED;
            time = runtime;
        }

...but it was just something silly I did to get the lights switching from red/green and obviously does not work for yellow or is not proportionate to green/yellow light duration(I don't think).

For color I use Color.RED, Color.YELLOW, Color.GREEN from java.awt.Color.

public void run(double runtime){
        if(this.color == Color.GREEN){
            if(time%greenLightDuration==0){
                color = Color.YELLOW;
            }
        }
        if(this.color == Color.YELLOW){
            if(time%yellowLightDuration == 0){
                color = Color.RED;
            }
        }
        else
            color = Color.GREEN;
    }

Tried this but the three colors are blinking furiously. I set green to 200 and yellow to 40.

Upvotes: 0

Views: 1914

Answers (2)

Linus
Linus

Reputation: 894

the three colors are blinking furiously.

The first/main cause of this is the simulator/model, and not necessarily the traffic light (though your traffic light my still be a problem). The issue is that your current model for time is just some sketchy for-loop, which will run however fast it runs... and it clearly runs a lot faster than your eyes would like.

What you can do is attempt to control the time in your simulation, using Thread.sleep() to delay the program momentarily. The following version will run an iteration roughly once per millisecond...

//Run method for agents in Model
public void run(double duration) {
        if (disposed)
            throw new IllegalStateException();
        for (int i=0; i<duration; i++) {
            time++;
            try{ Thread.sleep(1); } //wait 1ms
            catch(Exception e){} //just resume after interruption
            for (Agent a : agents.toArray(new Agent[0])) {
                a.run(time);
            }
            super.setChanged();
            super.notifyObservers();
        }
    }

Now a duration of 300 for green lights takes roughly 0.3 seconds, which is brisk but not unobservable.

Upvotes: 0

Davislor
Davislor

Reputation: 15144

Since this is a cycle, you want to get the current phase of the cycle using the modulus operator. Something like: double phase = (runTime - startTime) % (greenDuration + yellowDuration + redDuration). You can take the modulus of a floating-point number in Java.

Upvotes: 1

Related Questions