[PYTHON] PyODE Tutorial 2

PyODE sample execution example

I tried to execute "Tutorial 2" of Honke PyODE-sama site.

-- Click here for other tutorial implementation articles ↓ ・ "Tutorial 1" (Falling object, Matplotlib drawing added) ・ "Tutorial 3" (multibody contact, OpenGL)

--

The main subject is "Tutorial 2", The original content is -Construct a pendulum by connecting ** 3 objects ** with 2 hinges. ・ Angular velocity / torque is set for one hinge -Visualization is ** 2D drawing by Pygame **.

The angular velocity setting is commented out here. I also changed the screen size and coloring to output a GIF movie.

Environment etc.

・ Win10 ・ Python 3.8.0 64bit ・ Pyo de 0.15.2 ・ Pygame 1.9.6 ・ Pillow 7

Fix when running "Tutorial 2" as it is

In my environment, the code on the PyODE site was executed as it was.

Pygame error message excerpt


pygame.draw.circle(srf, rgb, coord( xyz ), 20, 0)
TypeError: integer argument expected, got float

Action: In the routine called coord () at the beginning of the code I've enclosed each of the two returned values in int ().

Deal with pygame errors


def coord(x,y):
    "Convert world coordinates to pixel coordinates."
    return int(320+170*x), int(400-170*y)

result

When executed, a 2D video table by Pygame is displayed. Here, the file saved in GIF format is posted. tutorial_2.gif

There are only three ODE objects. The line is just drawn. Black objects are fixed in space. (This object does not have to be.) Changes have been made to joint settings, drawing settings, etc.

Code (all)

There are some unnecessary parts left Since it is a small cord, I will put it on the whole.

Python3


# pyODE example 2: Connecting bodies with joints
##  Modified: Window-sizing, jointing-condition, and others.

import pygame
from pygame.locals import *
import ode


W = 640
H = 640
CX = 320
CY = 320
S = 80.
def coord(xyz):
    (x,y,z) = xyz
    "Convert world coordinates to pixel coordinates."
    return int( CX +S*x ), int( CY -S*y)



from PIL import Image, ImageDraw

def storeImage( srfc, images ):
    if NI_MAX <= len(images):
        return
    s = srfc
    buf = s.get_buffer()
    im = Image.frombytes( "RGBA", s.get_size(), buf.raw )
    B,G,R,A = im.split()
    img = Image.merge("RGBA",(R,G,B,A))
    images.append(img)

def gif(images):
    print(' @ gif(), ')
    savepath = 'tutorial_2.gif'

    image0 = images[0]
    image_end = images[-1]
    for i in range( 5 ):
        images.insert(0,image0)
    for i in range( 5 ):
        images.append(image_end)

    images[0].save( savepath, save_all=True, append_images=images[1:], optimize=not False, duration=100, loop=0 )
    print(' Exported : [%s]'%savepath)

NI_MAX = 10000
images=[]



# Initialize pygame
pygame.init()

# Open a display
srf = pygame.display.set_mode( (W,H) )

#

# Create a world object
world = ode.World()
world.setGravity((0,-9.81,0))

#

# Create two bodies
body0 = ode.Body(world)
M = ode.Mass()
M.setSphere(2500, 0.05)
body0.setMass(M)
body0.setPosition( (0,0,0) )

body1 = ode.Body(world)
M = ode.Mass()
M.setSphere(2500, 0.05)
body1.setMass(M)
body1.setPosition( (1,1,0) )

body2 = ode.Body(world)
M = ode.Mass()
M.setSphere(2500, 0.05)
body2.setMass(M)
body2.setPosition( (0,2,0) )

bodys = [body0,body1,body2]


# Connect body0 with the static environment
if True:
    j0 = ode.BallJoint(world)
    j0.attach(body1, ode.environment)
    j0.setAnchor( body0.getPosition() )
if False:
    j0 = ode.HingeJoint(world)
    j0.attach(body1, ode.environment)
    j0.setAnchor( body0.getPosition() )
    j0.setAxis( (0,0,1) )

    #j0.setParam(ode.ParamVel, 3)
    #j0.setParam(ode.ParamFMax, 22)

# Connect body1 with body0
j01 = ode.BallJoint(world)
j01.attach(body0, body1)
j01.setAnchor( body0.getPosition() )

# Connect body2 with body1
j12 = ode.BallJoint(world)
j12.attach(body1, body2)
j12.setAnchor( body1.getPosition() )

joints = [j0, j01, j12]




RGBs = { body0:(63, 63, 63), body1:(127, 63, 63), body2:(63, 127, 63) }


####################################################
# Simulation loop...

fps = 50
dt = 1.0/fps
loopFlag = True
clk = pygame.time.Clock()

ti = -1
while loopFlag:
    ti += 1
    events = pygame.event.get()
    for e in events:
        if e.type==QUIT:
            loopFlag=False

        if e.type==KEYDOWN:
            gif( images )
            loopFlag=False

    # Clear the screen
    srf.fill((255,255,255))


    for joint in joints:
        if joint is j0:
            continue
        rgb = (127,127,127)
        
        SIMPLE=False
        if SIMPLE:
            p0 = coord( joint.getBody(0).getPosition() )
            p1 = coord( joint.getBody(1).getPosition() )
        else:    ####        joint.attach(body, ode.environment)Correspondence to the anchor position in the case of, and color coding of the line
            b_move = None
            b0 = joint.getBody(0)
            if b0:
                if b0.getPosition() != joint.getAnchor():
                    b_move = b0
            if None is b0:
                p0 = coord( joint.getAnchor() )
                if None is p0:
                    p0 = coord( body0.getPosition() )
            else:
                p0 = coord( b0.getPosition() )
            b1 = joint.getBody(1)
            if b1:
                if b1.getPosition() != joint.getAnchor():
                    b_move = b1
            if None is b1:
                p1 = coord( joint.getAnchor() )
                if None is p1:
                    p1 = coord( body0.getPosition() )
            else:
                p1 = coord( b1.getPosition() )
        
            rgb = RGBs[b_move]

        lw = 5
        pygame.draw.line( srf, rgb, p0,p1, lw)

    for body in bodys:
        xyz = body.getPosition()
        rgb = RGBs[body]
        pygame.draw.circle(srf, rgb, coord( xyz ), 20, 0)
    
    pygame.display.flip()

    if ti % 4 == 0:
        storeImage(srf,images)

    # Next simulation step
    world.step(dt)

    # Try to keep the specified framerate    
    clk.tick(fps)
    
    #if not loopFlag:
    #    gif( images )

Recommended Posts

PyODE Tutorial 2
PyODE Tutorial 1
PyODE Tutorial 3
sqlalchemy tutorial
Python tutorial
TensorFlow tutorial tutorial
RabbitMQ Tutorial 5 (Topic)
Quantopian Tutorial LESSON 8
Quantopian Tutorial LESSON 1, 2
Quantopian Tutorial LESSON 6
Python Django Tutorial (5)
RabbitMQ Tutorial 6 (RPC)
django tutorial memo
Ryu tutorial Addendum
Python Django Tutorial (8)
Python Django Tutorial (6)
Start Django Tutorial 1
Quantopian Tutorial LESSON 9
Quantopian Tutorial LESSON 5
Quantopian Tutorial LESSON 3
Quantopian Tutorial LESSON 7
5 minute gRPC tutorial
Python Django Tutorial (7)
Python Django Tutorial (1)
Quantopian Tutorial LESSON 4
Python Django tutorial tutorial
Try using PyODE
Quantopian Tutorial LESSON 11
Python Django Tutorial (3)
RabbitMQ Tutorial 4 (Routing)
zipline Beginner Tutorial
[Translation] hyperopt tutorial
Python Django Tutorial (4)