Microsoft Small Basic

Program Listing: ZFJ443
' Inverted Pendulum with Physics Engine Framework
' Copyright (c) 2016 Nonki Takahashi. The MIT License.
' Last update 2016-02-14
'
title = "Inverted Pendulum 0.1"
GraphicsWindow.Title = title
Engine_Init()
len = 100
' add anchor
x = 0
y = 250
GraphicsWindow.BrushColor = "Gray"
GraphicsWindow.FillRectangle(x, y, gw, gh - y)
width = 2
height = 2
GraphicsWindow.BrushColor = "Black"
anchor = Shapes.AddEllipse(width, height)
LDPhysics.AddFixedShape(anchor, 0.9, 0.5)
LDPhysics.SetPosition(anchor, x, y, 0)
' add slider
x = gw / 2
width = 6
height = 6
slider = Shapes.AddEllipse(width, height)
LDPhysics.AddMovingShape(slider, 0.99, 0.5, 1)
LDPhysics.SetPosition(slider, x, y, 0)
LDPhysics.AttachShapesWithJoint(anchor, slider, "Prismatic_H", "False", "")
' add joint
x = gw / 2
width = 8
height = 8
joint = Shapes.AddRectangle(width, height)
LDPhysics.AddMovingShape(joint, 0.9, 0.5, 1)
LDPhysics.SetPosition(joint, x, y, 0)
LDPhysics.AttachShapesWithJoint(slider, joint, "Revolute", "False", "")
' add rod
y = y - len / 2
width = 2
height = len
rod = Shapes.AddRectangle(width, height)
LDPhysics.AddMovingShape(rod, 0.9, 0.5, 1)
LDPhysics.SetPosition(rod, x, y, 0)
LDPhysics.AttachShapes(rod, joint)
' add weight
y = y - len / 2
width = 30
height = 30
weight = Shapes.AddEllipse(width, height)
LDPhysics.AddMovingShape(weight, 0.9, 0.5, 1)
LDPhysics.SetPosition(weight, x, y, 0)
LDPhysics.AttachShapes(rod, weight)
iy = 0
While "True"
If keyDown Then
key = GraphicsWindow.LastKey
If key = "Left" Then
ix = -200
LDPhysics.SetImpulse(weight, ix, iy)
ElseIf key = "Right" Then
ix = 200
LDPhysics.SetImpulse(weight, ix, iy)
EndIf
keyDown = "False"
EndIf
LDPhysics.DoTimestep()
angle = Math.Floor(Math.Remainder(LDPhysics.GetAngle(joint), 360) * 100) / 100
If angle < 0 Then
angle = angle + 360
EndIf
Control()
Program.Delay(20)
EndWhile
Sub Control
scale = 1
If 270 < angle And angle < 360 Then
ix = (angle - 360) * scale
ElseIf 90 < angle And angle <= 180 Then
ix = -100 * scale
ElseIf 0 < angle And angle < 90 Then
ix = angle * scale
ElseIf 180 < angle And angle < 270 Then
ix = 100 * scale
Else
ix = 0
EndIf
LDPhysics.SetImpulse(slider, ix, iy)
EndSub
Sub Engine_Init
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.PenWidth = 0
keyDown = "False"
GraphicsWindow.KeyDown = OnKeyDown
EndSub
Sub OnKeyDown
keyDown = "True"
EndSub