runner.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. from Tkinter import *
  2. import random
  3. import math
  4. import target_py.target as target
  5. from sccd.runtime.libs.ui import ui
  6. from sccd.runtime.statecharts_core import Event
  7. from sccd.runtime.tkinter_eventloop import *
  8. width_railway = 20
  9. marked = {}
  10. kind_of_object = {}
  11. class SimulationGUI(Tk):
  12. def __init__(self):
  13. def update_scale(value):
  14. if hasattr(self, "controller"):
  15. self.controller.addInput(Event("accel", "tkinter_input", [float(value)]))
  16. def press_continue():
  17. self.controller.addInput(Event("continue", "tkinter_input", []))
  18. def press_pause():
  19. self.controller.addInput(Event("pause", "tkinter_input", []))
  20. def press_open():
  21. self.controller.addInput(Event("open", "tkinter_input", []))
  22. def press_close():
  23. self.controller.addInput(Event("close", "tkinter_input", []))
  24. def press_awake():
  25. self.controller.addInput(Event("awake", "tkinter_input", []))
  26. Tk.__init__(self)
  27. self.travelled_x = 0.0
  28. self.travelled_x_int = 0
  29. self.next_light = 0.0
  30. self.frame = Frame(self)
  31. self.frame.focus_set()
  32. self.resizable(0, 0)
  33. self.canvas = Canvas(self.frame, height=150, width=1000, bg="white")
  34. self.img_train = PhotoImage(file="imgs/train.gif")
  35. self.img_red = PhotoImage(file="imgs/red.gif")
  36. self.img_yellow = PhotoImage(file="imgs/yellow.gif")
  37. self.img_green = PhotoImage(file="imgs/green.gif")
  38. self.img_station = PhotoImage(file="imgs/station.gif")
  39. self.img_railway = PhotoImage(file="imgs/rail.gif")
  40. self.label_error = Label(self.frame, text="")
  41. self.slider_acceleration = Scale(self.frame, command=update_scale, orient=HORIZONTAL, resolution=0.01, from_=-1, to=1)
  42. self.button_continue = Button(self.frame, text="continue", command=press_continue)
  43. self.button_pause = Button(self.frame, text="pause", command=press_pause)
  44. self.button_open = Button(self.frame, text="open", command=press_open)
  45. self.button_close = Button(self.frame, text="close", command=press_close)
  46. self.button_poll = Button(self.frame, text="poll", command=press_awake)
  47. self.label_speed = Label(self.frame, text="")
  48. self.label_doors = Label(self.frame, text="Doors are CLOSED")
  49. self.items = []
  50. self.rails = []
  51. x = 0
  52. while x <= 1000 + width_railway:
  53. self.rails.append(self.canvas.create_image(x, 80, image=self.img_railway, anchor=NW))
  54. x += width_railway
  55. self.item_train = self.canvas.create_image(0, 75, image=self.img_train, anchor=NW)
  56. self.label_speed.grid(row=0, column=0, columnspan=2)
  57. self.label_doors.grid(row=1, column=0, columnspan=2)
  58. self.canvas.grid(row=2, column=0, columnspan=2, sticky=W)
  59. self.label_error.grid(row=3, column=0, columnspan=2)
  60. self.slider_acceleration.grid(row=4, column=0, columnspan=2, sticky=W+E)
  61. self.button_continue.grid(row=5, column=0, sticky=W+E)
  62. self.button_pause.grid(row=5, column=1, sticky=W+E)
  63. self.button_open.grid(row=6, column=0, sticky=W+E)
  64. self.button_close.grid(row=6, column=1, sticky=W+E)
  65. self.button_poll.grid(row=7, column=0, columnspan=2, sticky=W+E)
  66. self.frame.grid()
  67. self.remainder = 0.0
  68. self.next_station = 1000
  69. self.counter = 0
  70. self.train = None
  71. self.light_change_events = []
  72. self.updateState()
  73. self.after(20, self.throwEvents)
  74. def openDoors(self):
  75. self.label_doors.config(text="Doors are OPEN")
  76. def closeDoors(self):
  77. self.label_doors.config(text="Doors are CLOSED")
  78. def trainIs(self, train):
  79. self.train = train
  80. def throwEvents(self):
  81. # check if we passed anything
  82. if hasattr(self, "controller"):
  83. for item in self.items:
  84. coords = self.canvas.coords(item)
  85. if coords[0] < 30 and item not in marked:
  86. # passed light or entered station
  87. t = kind_of_object[item]
  88. if t == "STATION":
  89. marked[item] = False
  90. self.controller.addInput(Event("enter", "tkinter_input", []))
  91. elif t == "RED":
  92. marked[item] = True
  93. self.controller.addInput(Event("red_light", "tkinter_input", []))
  94. elif t == "YELLOW":
  95. marked[item] = True
  96. self.controller.addInput(Event("yellow_light", "tkinter_input", []))
  97. elif t == "GREEN":
  98. marked[item] = True
  99. self.controller.addInput(Event("green_light", "tkinter_input", []))
  100. elif coords[0] < -170 and not marked[item]:
  101. self.controller.addInput(Event("leave", "tkinter_input", []))
  102. marked[item] = True
  103. self.after(20, self.throwEvents)
  104. def notify(self, msg, color):
  105. self.label_error.config(text=msg, bg=color)
  106. def updateState(self):
  107. def turn_green(item):
  108. kind_of_object[item] = "GREEN"
  109. self.canvas.itemconfigure(item, image=self.img_green)
  110. def turn_yellow(item):
  111. self.canvas.itemconfigure(item, image=self.img_yellow)
  112. kind_of_object[item] = "YELLOW"
  113. self.light_change_events.append((self.counter + random.random() * 500 + 300, item, turn_green))
  114. if self.train is not None:
  115. self.train.speed += self.train.acceleration / 2
  116. self.label_speed.config(text="Speed: %.2f" % self.train.speed)
  117. self.travelled_x += float(self.train.speed) / 20
  118. delta_x = -int(self.travelled_x - self.travelled_x_int)
  119. self.travelled_x_int = int(self.travelled_x)
  120. # move rails
  121. for item in self.rails:
  122. self.canvas.move(item, delta_x, 0)
  123. # move items and remove if necessary
  124. for item in self.items:
  125. self.canvas.move(item, delta_x, 0)
  126. if self.canvas.coords(item) < -100:
  127. self.canvas.delete(item)
  128. self.items.remove(item)
  129. # update rails
  130. while 1:
  131. coords = self.canvas.coords(self.rails[0])
  132. if coords[0] < -width_railway:
  133. self.canvas.delete(self.rails[0])
  134. self.rails.pop(0)
  135. self.rails.append(self.canvas.create_image(self.canvas.coords(self.rails[-1])[0]+width_railway, 80, image=self.img_railway, anchor=NW))
  136. self.canvas.tag_lower(self.rails[-1])
  137. else:
  138. break
  139. # add in an element only if there is space
  140. if self.next_station < self.travelled_x:
  141. # generate a station
  142. self.items.append(self.canvas.create_image(1000, 120, image=self.img_station, anchor=NW))
  143. kind_of_object[self.items[-1]] = "STATION"
  144. self.next_station += random.random() * 3000 + 2000
  145. if self.next_light < self.travelled_x:
  146. self.next_light += 500
  147. self.items.append(self.canvas.create_image(1000, 40, image=self.img_red, anchor=NW))
  148. kind_of_object[self.items[-1]] = "RED"
  149. self.light_change_events.append((self.counter + random.random() * 500, self.items[-1], turn_yellow))
  150. self.counter += 1
  151. for light_change in self.light_change_events:
  152. if light_change[0] <= self.counter:
  153. light_change[2](light_change[1])
  154. self.light_change_events.remove(light_change)
  155. root = SimulationGUI()
  156. if __name__ == "__main__":
  157. random.seed(1)
  158. controller = target.Controller(root, TkEventLoop(root))
  159. root.controller = controller
  160. controller.start()
  161. try:
  162. root.mainloop()
  163. finally:
  164. controller.stop()