123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
- from pypdevs.simulator import Simulator
- from pypdevs.infinity import INFINITY
- import random, math, sys, getopt
- import Tkinter as tk
- class Canvas:
- def __init__(self, resolution):
- self.width = resolution[0]
- self.height = resolution[1]
- class ParticleState:
- def __init__(self):
- self.remaining = 0.0
- self.curr_frames = 0.0
- class Particle(AtomicDEVS):
- def __init__(self, canvas):
- AtomicDEVS.__init__(self, "Particle")
-
- self.r = random.uniform(5.0, 30.0)
- x = random.uniform(self.r, canvas.width - self.r)
- y = random.uniform(self.r, canvas.height - self.r)
- self.pos = (x, y)
-
- self.POS_OUT = self.addOutPort("POS_OUT")
- self.INTERRUPT = self.addInPort("INTERRUPT")
-
- self.state = ParticleState()
-
- def timeAdvance(self):
- return self.state.remaining
-
- def outputFnc(self):
- return {self.POS_OUT: [self.pos, self.r]}
-
- def intTransition(self):
- self.state.curr_frames += self.timeAdvance()
- self.state.remaining = 1
- return self.state
-
- def extTransition(self, inputs):
- self.state.remaining -= self.elapsed
- print 'extTransition'
- return self.state
- class Field(CoupledDEVS):
- def __init__(self, canvas):
- CoupledDEVS.__init__(self, "Field")
-
- self.INTERRUPT = self.addInPort("INTERRUPT")
- self.POS_OUT = self.addOutPort("POS_OUT")
- self.particle = self.addSubModel(Particle(canvas))
- self.connectPorts(self.INTERRUPT, self.particle.INTERRUPT)
- self.connectPorts(self.particle.POS_OUT, self.POS_OUT)
- class ParticleVisualization:
- def __init__(self, circle_id, canvas, sim):
- self.circle_id = circle_id
- self.canvas = canvas
- self.sim = sim
-
- self.canvas.tag_bind(self.circle_id, "<Button-1>", self.on_click)
-
- def on_click(self, event):
- self.sim.realtime_interrupt("INTERRUPT myValue")
- class Visualizer(tk.Toplevel):
- def __init__(self, root, resolution, sim):
- tk.Toplevel.__init__(self)
-
- self.sim = sim
- self.root = root
- self.particle = None
-
- self.geometry('{}x{}'.format(resolution[0], resolution[1]))
- CANVAS_SIZE_TUPLE = (0, 0, self.winfo_screenwidth(), self.winfo_screenheight())
- self.canvas = tk.Canvas(self, relief=tk.RIDGE, scrollregion=CANVAS_SIZE_TUPLE)
- self.canvas.pack(expand = True, fill=tk.BOTH)
- self.protocol("WM_DELETE_WINDOW", lambda: self.root.destroy())
-
- def handle_output(self, msgs):
- for msg_contents in msgs:
- if self.particle == None:
- (x, y), r = msg_contents
- circle_id = self.canvas.create_oval(x - r, y - r, x + r, y + r, fill="red")
- self.particle = ParticleVisualization(circle_id, self.canvas, self.sim)
- else:
- (x, y), r = msg_contents
- curr_x, curr_y = self.canvas.coords(self.particle.circle_id)[0:2]
- self.canvas.move(self.particle.circle_id, x - r - curr_x, y - r - curr_y)
- if __name__ == '__main__':
- root = tk.Tk()
- root.withdraw()
-
- model = Field(Canvas((800, 600)))
-
- sim = Simulator(model)
- sim.setRealTime(True, 1.0 / 30)
- sim.setRealTimeInputFile(None)
- sim.setRealTimePorts({'INTERRUPT': model.INTERRUPT})
- sim.setRealTimePlatformTk(root)
- sim.setDSDEVS(True)
- sim.setClassicDEVS(True)
- sim.setTerminationTime(60 * 30)
- sim.setVerbose("minimalOutputFile")
-
- visualizer = Visualizer(root, (800, 600), sim)
- visualizer.title('ParticleInteraction')
- sim.setListenPorts(model.POS_OUT, visualizer.handle_output)
-
- sim.simulate()
- root.mainloop()
|