| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- using Agents
- using DEVS2Agents
- import DEVS2Agents: time_advance, int_transition!, ext_transition!, output!, send_message!, format_state, format_message
- @enum PoliceState Patrolling Directing
- @agent struct PoliceAgent{I, O}(AtomicDEVS{I, O})
- state::PoliceState = Patrolling
- end
- format_state(agent::PoliceAgent) = "$(agent.state)"
- function time_advance(agent::PoliceAgent, model)
- if agent.state == Patrolling
- return 60.0
- elseif agent.state == Directing
- return 30.0
- end
- return Inf
- end
- function output!(agent::PoliceAgent, model)
- msg::String = ""
- if agent.state == Patrolling
- msg = "Take Control"
- elseif agent.state == Directing
- msg = "Release Control"
- end
- if msg == ""
- return
- end
- send_message!(agent, model, :out, msg)
- end
- function int_transition!(agent::PoliceAgent, model)
- if agent.state == Patrolling
- agent.state = Directing
- else
- agent.state = Patrolling
- end
- end
- @enum LightState Green Yellow Red Interrupted
- @agent struct TrafficLight{I, O}(AtomicDEVS{I, O})
- state::LightState = Green
- end
- format_state(agent::TrafficLight) = "$(agent.state)"
- function time_advance(agent::TrafficLight, model)
- if agent.state == Interrupted
- return Inf # Suspend
- elseif agent.state == Green
- return 45.0
- elseif agent.state == Yellow
- return 5.0
- elseif agent.state == Red
- return 50.0
- end
- return Inf
- end
- function int_transition!(agent::TrafficLight, model)
- if agent.state == Green
- agent.state = Yellow
- elseif agent.state == Yellow
- agent.state = Red
- elseif agent.state == Red
- agent.state = Green
- end
- end
- function ext_transition!(agent, model, e, bag)
- command = first(bag[:in])
- if command == "Take Control"
- agent.state = Interrupted
- elseif command == "Release Control"
- agent.state = Red # Restart TrafficLight
- end
- end
- intersection = CoupledDEVS(:Intersection)
- police = add_submodel!(intersection, :Police, PoliceAgent;
- out_ports=(; out=String))
- light = add_submodel!(intersection, :Light, TrafficLight;
- inbox=(; in=String[]))
- connect!(intersection, police.out, light.in)
- engine = compile_devs(intersection; logging="")
- simulate_devs!(engine, 120)
|