2D-Physiksimulation mit Box2d und wxPython

In der Umgebung von Fitnessstudio und Deep Mind gibt es Anzeichen dafür, dass es nächstes Jahr heiß werden wird, aber möchten Sie doch oft Ihr eigenes kurzes Problem (Robotersteuerung) lösen?

In Die Umgebung des Linien-Tracers wurde zu Open AI I / F \ -Qiita gemacht bewegte sich der Linien-Tracer, der das physikalische Gesetz ignorierte, herum, aber in Zukunft Um das Problem der Reifenhaftung und der Schwerkraftbeschleunigung anzugehen, müssen wir das physikalische Gesetz in die Simulation einbeziehen.

Es gibt verschiedene 3D-Robotersimulatoren wie Gazebo und Webot auf dem Markt, aber 2D ist für PoC leichter und konzeptionell schneller zu testen. Daher möchte ich dies zuerst für PoC empfehlen. Persönlich denke ich.

Deshalb für eine Weile Physiksimulation mit Box2D, was sehr beliebt war, und Animation mit dem klassischen wxPython (für mich).

2016-12-18.png

Einführung von Box2d

Ich benutze immer noch die schlechte Umgebung von Windows, daher musste ich zuerst Swig vorbereiten ⇒ [SWIG in Windows eingeführt \ -Volo di notte](http://chachay.hatenablog.com/entry/2016/12/ 18/090010)

Klonen und installieren Sie jetzt pybox2d!

python setup.py build
python setup.py install

Windows-Benutzer benötigen möglicherweise VC ++ - Build-Tools. prüfen.

Einführung von wxPython

Ich habe kürzlich zu Python3 gewechselt. Notieren Sie sich daher die Installation von wxPython. Aus Index von / Phoenix / snapshot \ -builds, "https://www.wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix- 3.0.3.dev2700 + c524ed1-cp35-cp35m-win_amd64.whl "Nehmen Sie den Link des Radpakets auf, das für Sie gilt.

pip install https://www.wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev2700+c524ed1-cp35-cp35m-win_amd64.whl

Die Leichtigkeit, hier eine Umgebung aufzubauen, ist die beste in Python.

Let's box2D

Bestimmen Sie zunächst den Skalierungsfaktor und die Zeit der Simulation

PPM = 20.0  # pixels per meter
TimeStep = 20 # ms

Dies ist das einzige zu verwendende Paket

# -*- coding: utf-8 -*-
import Box2D 
from Box2D.b2 import (world, polygonShape, staticBody, dynamicBody)
import wx

wxPython-Initialisierung

Es ist dasselbe wie die vorherige Chachay-Serie, aber wir werden es mit der folgenden Konfiguration basierend auf der wx.App-Klasse erstellen.

class APPWINDOW(wx.Frame):
    def __init__(self, parent=None, id=-1, title=None):
        # 1.Initialisierung des Zeichenfensters, Initialisierung des Timers
        # 2.CloseWindow-Bindung
        # 3.Initialisierung der physischen Engine+Physikalisches Objekt(Der Boden oder Gegenstände)Definition von
        # 4.Timer-Schleife starten
    def CloseWindow(self, event):
        #Einfacher Kündigungsprozess
    def OnTimer(self, event):
        # 1.Fenster sauber machen
        # 2.Zeichnen von physischen Objekten
        # 3.Physikalische Simulation für 1 Schritt

Initialisierung der physischen Engine

Definieren Sie zuerst die Schwerkraft in der Welt, erstellen Sie den Boden (Statischen Körper erstellen) und platzieren Sie dann die Box in der Luft (Dynamischen Körper erstellen).

        # pybox2d world
        self.phys_world = world(gravity=(0, -10), doSleep=True)
        self.ground_body = self.phys_world.CreateStaticBody(
            position=(0, 1),
            shapes=polygonShape(box=(50, 5)),
        )
        self.dynamic_body = self.phys_world.CreateDynamicBody(position=(10, 15), angle=15)
        self.box = self.dynamic_body.CreatePolygonFixture(box=(2, 1), density=1, friction=0.3)

Timer-Loop-Verarbeitung

Wenn Sie es bisher definieren, ist die Simulation sehr einfach. Rufen Sie einfach die Step-Funktion auf. Danach habe ich mir nur noch den Ort ausgedacht, an dem ich ein Bild zeichnen kann. Sie können Kivy oder was auch immer Sie als Animation verwenden.

Es ist eine Simulation einer Kiste, die aus der Luft fällt und auf dem Boden landet.

    def OnTimer(self, event):
        # 1.Fenster sauber machen
        self.bdc = wx.BufferedDC(self.cdc, self.bmp)
        self.gcdc = wx.GCDC(self.bdc)
        self.gcdc.Clear()
        
        self.gcdc.SetPen(wx.Pen('white'))
        self.gcdc.SetBrush(wx.Brush('white'))
        self.gcdc.DrawRectangle(0,0,640,640)
        
        # 2.Zeichnen von physischen Objekten
        for body in (self.ground_body, self.dynamic_body):  # or: world.bodies
            for fixture in body.fixtures:
                shape = fixture.shape

                vertices = [(body.transform * v) * PPM for v in shape.vertices]
                vertices = [(int(v[0]), int(480 - v[1])) for v in vertices]
                
                self.gcdc.SetPen(wx.Pen(wx.Colour(50,50,50)))
                self.gcdc.SetBrush(wx.Brush(wx.Colour(colors[body.type])))
                self.gcdc.DrawPolygon(vertices)
        
        # 3.Physikalische Simulation für 1 Schritt
        self.phys_world.Step(TimeStep/1000, 10, 10)

Die ganze Quelle

# -*- coding: utf-8 -*-
import Box2D 
from Box2D.b2 import (world, polygonShape, staticBody, dynamicBody)
import wx

PPM = 20.0  # pixels per meter
TimeStep = 20 # ms

colors = {
    staticBody: (150,150,150),
    dynamicBody: (112,146,190),
}

class APPWINDOW(wx.Frame):
    def __init__(self, parent=None, id=-1, title=None):
        # 1.Initialisierung des Zeichenfensters, Initialisierung des Timers
        wx.Frame.__init__(self, parent, id, title)
        self.MainPanel = wx.Panel(self, size=(640, 480))
        self.MainPanel.SetBackgroundColour('WHITE')
        
        self.panel = wx.Panel(self.MainPanel, size = (640,480))
        self.panel.SetBackgroundColour('WHITE')

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(self.panel)

        self.SetSizer(mainSizer)
        self.Fit()
        
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        
        self.cdc = wx.ClientDC(self.panel)
        w, h = self.panel.GetSize()
        self.bmp = wx.Bitmap(w,h)

        # 2.CloseWindow-Bindung
        self.Bind(wx.EVT_CLOSE, self.CloseWindow)
        
        # 3.Initialisierung der physischen Engine+Physikalisches Objekt(Der Boden oder Gegenstände)Definition von
        self.phys_world = world(gravity=(0, -10), doSleep=True)
        self.ground_body = self.phys_world.CreateStaticBody(
            position=(0, 1),
            shapes=polygonShape(box=(50, 5)),
        )
        self.dynamic_body = self.phys_world.CreateDynamicBody(position=(10, 15), angle=15)
        self.box = self.dynamic_body.CreatePolygonFixture(box=(2, 1), density=1, friction=0.3)
        
        # 4.Timer-Schleife starten
        self.timer.Start(TimeStep)

    def CloseWindow(self, event):
        #Einfacher Kündigungsprozess
        wx.Exit()

    def OnTimer(self, event):
        # 1.Fenster sauber machen
        self.bdc = wx.BufferedDC(self.cdc, self.bmp)
        self.gcdc = wx.GCDC(self.bdc)
        self.gcdc.Clear()
        
        self.gcdc.SetPen(wx.Pen('white'))
        self.gcdc.SetBrush(wx.Brush('white'))
        self.gcdc.DrawRectangle(0,0,640,640)
        
        # 2.Zeichnen von physischen Objekten
        for body in (self.ground_body, self.dynamic_body):  # or: world.bodies
            for fixture in body.fixtures:
                shape = fixture.shape

                vertices = [(body.transform * v) * PPM for v in shape.vertices]
                vertices = [(int(v[0]), int(480 - v[1])) for v in vertices]
                
                self.gcdc.SetPen(wx.Pen(wx.Colour(50,50,50)))
                self.gcdc.SetBrush(wx.Brush(wx.Colour(colors[body.type])))
                self.gcdc.DrawPolygon(vertices)
        
        # 3.Physikalische Simulation für 1 Schritt
        self.phys_world.Step(TimeStep/1000, 10, 10)

if __name__ == '__main__':
    app = wx.App()
    w = APPWINDOW(title='Box2D Test')
    w.Center()
    w.Show()
    app.MainLoop()

Recommended Posts

2D-Physiksimulation mit Box2d und wxPython
AtCoder ARC080 D Simulation mit Ruby und Python gelöst
Probieren Sie die DB-Operation mit Python aus und visualisieren Sie sie mit d3
Ausgabe des 2D-Wärmediffusionssimulationsergebnisses mit Python VTK
Erstellen Sie mit PyQt5 und PyQtGraph einen 3D-Modell-Viewer
3D-Plot mit Matplotlib
3D oder D mit Py
Lösen mit Ruby und Python AtCoder ABC178 D Dynamische Planungsmethode
Lösen mit Ruby und Python AtCoder ABC151 D Suche nach Breitenpriorität
Lösen mit Ruby und Python AtCoder ABC133 D Kumulative Summe
Lösen mit Ruby und Python AtCoder AISING2020 D Iterative Square-Methode
Versuchen Sie eine MD-Simulation mit ANN-Potenzial unter Verwendung von Aenet und ASE
Erstelle ein 2D-Rollenspiel mit Ren'Py (3) -Items and Tool Shop
Lösen mit Ruby und Python AtCoder ABC138 D Benachbarte Liste
Leistungsvergleich zwischen zweidimensionaler Matrixberechnung und für mit Numpy