Reinforcement learning is also showing signs that it will be hot next year with the environment of gym and DeepMind, but after all, do you often want to solve your own short (robot control) problem?
In The environment of the line tracer was made OpenAI I / F -Qiita, the line tracer ignoring the physics rule was moving around, but in the future, In order to tackle the problem of tire grip and gravitational acceleration, we have to incorporate physics into the simulation.
There are various 3D robot simulators such as Gazebo and Webot on the market, but 2D is lighter for PoC and the speed to try conceptually is faster, so I would like to recommend this first for PoC. I personally think.
That's why for a while, physics simulation with Box2D, which was popular, and animation with the classic wxPython (for me).
I still use the bad environment of Windows, so I had to prepare Swig first ⇒ [SWIG introduced to Windows -Volo di notte](http://chachay.hatenablog.com/entry/2016/12/ 18/090010)
Now, clone and install pybox2d!
python setup.py build
python setup.py install
Windows people may need a VC ++ build tool or something. check.
I recently switched to Python3, so make a note of the wxPython installation. From Index of /Phoenix/snapshot \ -builds, "https://www.wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix- 3.0.3.dev2700 + c524ed1-cp35-cp35m-win_amd64.whl "Pick up the link of the wheel package that applies to you,
pip install https://www.wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev2700+c524ed1-cp35-cp35m-win_amd64.whl
The ease of building an environment around here is the best in python.
Let's box2D
First determine the scale factor and time of the simulation
PPM = 20.0 # pixels per meter
TimeStep = 20 # ms
This is the only package to use
# -*- coding: utf-8 -*-
import Box2D
from Box2D.b2 import (world, polygonShape, staticBody, dynamicBody)
import wx
It is the same as the previous Chachay series, but we will make it with the following configuration based on the wx.App class.
class APPWINDOW(wx.Frame):
def __init__(self, parent=None, id=-1, title=None):
# 1.Initialization of drawing window, timer initialization
# 2.CloseWindow bind
# 3.Physics engine initialization+Physical object(The ground or objects)Definition of
# 4.Start timer loop
def CloseWindow(self, event):
#Simple termination process
def OnTimer(self, event):
# 1.Clear window clean
# 2.Drawing physics objects
# 3.Physical simulation for 1 step
First, define gravity in the world, create the ground (Create Static Body), and then place the box in the air (Create Dynamic Body).
# 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)
Simulation is super easy if you define it so far. Just call the Step function. After that, I devised only the place to draw a picture. You can use kivy or whatever you like as an animation.
This is a simulation of a box falling from the air and landing on the ground.
def OnTimer(self, event):
# 1.Clear window clean
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.Drawing physics objects
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.Physical simulation for 1 step
self.phys_world.Step(TimeStep/1000, 10, 10)
# -*- 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.Initialization of drawing window, timer initialization
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 bind
self.Bind(wx.EVT_CLOSE, self.CloseWindow)
# 3.Physics engine initialization+Physical object(The ground or objects)Definition of
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.Start timer loop
self.timer.Start(TimeStep)
def CloseWindow(self, event):
#Simple termination process
wx.Exit()
def OnTimer(self, event):
# 1.Clear window clean
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.Drawing physics objects
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.Physical simulation for 1 step
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