Intersection.jl 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Agents
  2. using DEVS2Agents
  3. import DEVS2Agents: time_advance, int_transition!, ext_transition!, output!, send_message!, format_state, format_message
  4. @enum PoliceState Patrolling Directing
  5. @agent struct PoliceAgent{I, O}(AtomicDEVS{I, O})
  6. state::PoliceState = Patrolling
  7. end
  8. format_state(agent::PoliceAgent) = "$(agent.state)"
  9. function time_advance(agent::PoliceAgent, model)
  10. if agent.state == Patrolling
  11. return 60.0
  12. elseif agent.state == Directing
  13. return 30.0
  14. end
  15. return Inf
  16. end
  17. function output!(agent::PoliceAgent, model)
  18. msg::String = ""
  19. if agent.state == Patrolling
  20. msg = "Take Control"
  21. elseif agent.state == Directing
  22. msg = "Release Control"
  23. end
  24. if msg == ""
  25. return
  26. end
  27. send_message!(agent, model, :out, msg)
  28. end
  29. function int_transition!(agent::PoliceAgent, model)
  30. if agent.state == Patrolling
  31. agent.state = Directing
  32. else
  33. agent.state = Patrolling
  34. end
  35. end
  36. @enum LightState Green Yellow Red Interrupted
  37. @agent struct TrafficLight{I, O}(AtomicDEVS{I, O})
  38. state::LightState = Green
  39. end
  40. format_state(agent::TrafficLight) = "$(agent.state)"
  41. function time_advance(agent::TrafficLight, model)
  42. if agent.state == Interrupted
  43. return Inf # Suspend
  44. elseif agent.state == Green
  45. return 45.0
  46. elseif agent.state == Yellow
  47. return 5.0
  48. elseif agent.state == Red
  49. return 50.0
  50. end
  51. return Inf
  52. end
  53. function int_transition!(agent::TrafficLight, model)
  54. if agent.state == Green
  55. agent.state = Yellow
  56. elseif agent.state == Yellow
  57. agent.state = Red
  58. elseif agent.state == Red
  59. agent.state = Green
  60. end
  61. end
  62. function ext_transition!(agent, model, e, bag)
  63. command = first(bag[:in])
  64. if command == "Take Control"
  65. agent.state = Interrupted
  66. elseif command == "Release Control"
  67. agent.state = Red # Restart TrafficLight
  68. end
  69. end
  70. intersection = CoupledDEVS(:Intersection)
  71. police = add_submodel!(intersection, :Police, PoliceAgent;
  72. out_ports=(; out=String))
  73. light = add_submodel!(intersection, :Light, TrafficLight;
  74. inbox=(; in=String[]))
  75. connect!(intersection, police.out, light.in)
  76. engine = compile_devs(intersection; logging="")
  77. simulate_devs!(engine, 120)