2017-04-24 3 views
1

Ich muss ein Lager mit mehreren autonomen Fahrzeugen simulieren, die sich auf einem gegebenen Layout mit einfachen Prioritätsregeln bewegen. Nach meinem Verständnis kann das Problem mit der diskreten Ereignissimulation (DES) leicht angegangen werden, und ich würde dafür SimPy verwenden.Visualisierung einer diskreten Ereignissimulation auf einem Gitter/Lager Layout

Das Problem, das ich sehe, ist, dass es mir sehr schwer scheint, die tatsächlichen Trajektorien und Interaktionen dieser Fahrzeuge zu visualisieren. Natürlich kann ich alle Positionen aller Fahrzeuge in allen Perioden protokollieren, aber wie kann ich dann fortfahren, um eine Visualisierung zu erstellen?

Der dümmste Weg wäre, eine Million Bilder zu erstellen, aber es muss einen besseren Weg geben. Gibt es eine Bibliothek oder ein Werkzeug, um Bewegungen von Objekten auf einem Gitter zu visualisieren, indem man Symbole vor einem Hintergrund bewegt? Eine andere Möglichkeit wäre, einen agentenbasierten Ansatz mit einer Software wie AnyLogic zu verwenden, aber das scheint mir komplizierter zu sein und ich möchte einen DES-Ansatz anwenden, vorzugsweise mit Open-Source-Software.

+1

Bitte beachten Sie, dass die Abfrage von Empfehlungen für Bibliotheken oder Tools ausdrücklich als Kriterium für die Beantwortung Ihrer Frage angegeben wird. Allerdings bieten kommerzielle DES-Produkte wie Simio, Arena oder ExtendSim Animations-/Visualisierungsfunktionen. Die schlechte Nachricht ist, dass sie teuer sind. Ein möglicher Lichtblick ist, dass einige von ihnen für akademische Zwecke leicht verfügbar sind. – pjs

+0

Danke für die Klarstellung. Ich bin mir nicht sicher, wie und wo ich Hilfe für meine Frage bekomme, wenn nicht auf SO. Wo würdest du fragen oder wie müsste ich meine Frage umformulieren? – mondano

Antwort

0

Ich fand, dass die R-Bibliothek gganimate tut was ich will. Ich habe jedoch keine Entsprechung für Python gefunden (vielleicht, weil es weder ein Äquivalent zu ggplot2 noch animate in Python gibt ...)

0

Ich würde nur alle erforderlichen Daten sammeln und sie irgendwo speichern (eine Datei, HDF5, SQL, ...). Später (oder parallel) können Sie diese Daten visualisieren. Entweder durch Erzeugen einer großen Anzahl von Bildern mit z. B. Matplotlib oder durch Ausführen etwas Fantastischeres mit D3.js.

+0

Meine Frage war * wie genau * ich diesen Visualisierungsteil machen würde. Wenn ich eine Simulation für eine Wanduhrzeit von 8h habe und jede Sekunde ein "Bild" mache, habe ich 8h * 60 min/h * 60 sek/min * 1 MB = 28,8 GB für die Visualisierung eines Simulationslaufs. Das scheint ein bisschen zu viel. Ich suche nach einer effizienteren Lösung. Ich habe für dieses dynamische Problem keine entsprechende D3.js-Diagrammoption gefunden. Kannst du mich direkt auf einen verweisen? – mondano

2

Ich würde vorschlagen, die tkinter Bibliothek auschecken. Wir machen all unsere simplen Visualisierungen damit.

Hier ist ein sehr einfaches Beispiel für die Art von Animation, die erreicht werden kann, die dramatischen Aufnahmen pardon: https://www.youtube.com/watch?v=xnZQ0f--Ink

Hier ist der Quellcode der beschreibt, in etwa, was Sie oben sehen: https://github.com/harrymunro/Simulations/blob/master/termini_simulation_animation.py

Hier eine Kopie Paste der Animation Komponente:

################ SET UP ANIMATION CANVAS ################# 
class Train: 
    def __init__(self, canvas, x1, y1, x2, y2, tag): 
     self.x1 = x1 
     self.y1 = y1 
     self.x2 = x2 
     self.y2 = y2 
     self.canvas = canvas 
     self.train = canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill="red", tags = tag) 
     self.train_number = canvas.create_text(((self.x2 - self.x1)/2 + self.x1), ((self.y2 - self.y1)/2 + self.y1), text = tag) 
     self.canvas.update() 

    def move_train(self, deltax, deltay): 
     self.canvas.move(self.train, deltax, deltay) 
     self.canvas.move(self.train_number, deltax, deltay) 
     self.canvas.update() 

    def remove_train(self): 
     self.canvas.delete(self.train) 
     self.canvas.delete(self.train_number) 
     self.canvas.update() 

class Clock: 
    def __init__(self, canvas, x1, y1, x2, y2, tag): 
     self.x1 = x1 
     self.y1 = y1 
     self.x2 = x2 
     self.y2 = y2 
     self.canvas = canvas 
     self.train = canvas.create_rectangle(self.x1, self.y1, self.x2, self.y2, fill="#fff") 
     self.time = canvas.create_text(((self.x2 - self.x1)/2 + self.x1), ((self.y2 - self.y1)/2 + self.y1), text = "Time = "+str(tag)+"s") 
     self.canvas.update() 

    def tick(self, tag): 
     self.canvas.delete(self.time) 
     self.time = canvas.create_text(((self.x2 - self.x1)/2 + self.x1), ((self.y2 - self.y1)/2 + self.y1), text = "Time = "+str(tag)+"s") 
     self.canvas.update() 


if show_animation == True: 
    animation = Tk() 
    #bitmap = BitmapImage(file="uxbridge.bmp") 

    im = PhotoImage(file="uxbridge_resized.gif") 

    canvas = Canvas(animation, width = 800, height = 400) 
    canvas.create_image(0,0, anchor=NW, image=im) 
    animation.title("Uxbridge Termini Simulation") 

    canvas.pack() 

#### matplotlib plots 


if show_animation == True and hide_plots == False: 
    f = plt.Figure(figsize=(5,4), dpi=100) 

    a1 = f.add_subplot(221) # mean headway 
    a2 = f.add_subplot(222) # TPH meter 
    a3 = f.add_subplot(223) # headway distribution 
    a4 = f.add_subplot(224) # train count 

    a1.plot() 
    a2.plot() 
    a3.plot() 
    a4.plot() 

    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 

    dataPlot = FigureCanvasTkAgg(f, master=animation) 
    dataPlot.show() 
    dataPlot.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) 
    f.tight_layout() 

    canvas.pack() 

# platforms 
if show_animation == True: 
    canvas.create_rectangle(50, 100, 200, 150, fill = "yellow") 
    canvas.create_rectangle(50, 200, 200, 250, fill = "yellow") 

    canvas.create_line(50, 75, 200, 75, fill="green", width=3) # platform 4 
    canvas.create_line(50, 175, 200, 175, fill="green", width=3) # platform 2/3 
    canvas.create_line(50, 275, 200, 275, fill="green", width=3) # platform 1 

    canvas.create_text(125, 110, text = "Platform 4") 
    canvas.create_text(125, 140, text = "Platform 3") 
    canvas.create_text(125, 210, text = "Platform 2") 
    canvas.create_text(125, 240, text = "Platform 1") 

# track 
    canvas.create_line(200, 75, 650, 75, fill="green", width=3) # platform 4 run out 
    canvas.create_line(200, 175, 650, 175, fill="green", width=3) # platform 2/3 run in 
    canvas.create_line(300, 175, 400, 75, fill="green", width=3) 
    canvas.create_line(450, 75, 600, 175, fill="green", width=3) 
    canvas.create_line(450, 175, 600, 75, fill="green", width=3) 
    canvas.create_line(200, 275, 300, 275, fill="green", width=3) 
    canvas.create_line(300, 275, 400, 175, fill="green", width=3) 

############ END OF CANVAS ################# 
+1

Danke, das ist eine wirklich interessante Lösung! – mondano

1

Wenn die Animation 2D sollten Sie die Pygame Bibliothek nutzen könnten. Ich animierte eine kleine simple Simulation damit und es funktionierte gut. Beachten Sie, dass Sie Threads verwenden müssen, sonst wird Ihr Fenster nach ein paar Sekunden einfrieren. Diese einfache Methode zeichnet für jeden eingehenden Kunden einen roten Kreis und zeichnet ihn grün, wenn der Kunde bedient wird.

def draw(env, timelist): 
    gameDisplay.fill(white) 
    start = time.clock() 
    kdnr = 0 
    kdaktuell = -1 
    kdstart = -10 
    while True: 
     timer = (time.clock() - startzeit) 
     if timer > 15: #simulation for 15 sec 
       break 

    # incoming customers 
    if kdnr < len(timelist): 
     if timelist[kdnr] <= timer: 
      pygame.draw.circle(gameDisplay,red,(50+30*kdnr,400),10) 
      print('Customer '+str(kdnr+1)+ ' arrived in minute: ' + str(timelist[kdnr])) 
      kdnr = kdnr + 1 

    # served customers 
    if (kdstart+3) <= timer: 
     kdaktuell = kdaktuell + 1 
     kdstart = time 
     pygame.draw.circle(gameDisplay,green,(50+30*kdaktuell,400),10) 
     print('Customer '+str(kdaktuell+1)+ ' gets served.') 

    pygame.display.update() 
Verwandte Themen