Jump to content

Mechanical Walker


Canardia
 Share

Recommended Posts

First attempt to try to make a physics controlled mech. You can just copy the lua script to the SDK folder, no additional assets needed, and then drag it over ScriptEditor or Engine.exe:

post-2-0-48759600-1312570329_thumb.png

d=-4	-- camera distance
h=0	-- mech creation origin height
f=20	-- walk force	 -- 20 is minimum force to walk, 16 is zombie like crawling,
 -- which ends up in quite stable walking though after a while
 -- interestingly, the stable walk occurs when legs start to move cross-over in sync

require("Scripts/constants/keycodes") 

--Register abstract path 
RegisterAbstractPath("") 
--Set graphics mode 
if Graphics(800,480)==0 then 
Notify("Failed to set graphics mode.",1) 
return 
end 
fw=CreateFramework()

material=LoadMaterial("abstract::cobblestones.mat")

function MakeArm(mainbody,x,z,z2)
local body=CreateBodyBox(0.1,0.1,0.5)
local cube=CreateCube(body)
cube:Paint(material)
ScaleMesh(cube,Vec3(0.1,0.1,0.5))
body:SetMass(0.1)
body:Move(Vec3(x,h,z-z2))
body:SetCollisionType(2)
local joint=CreateJointHinge(mainbody,body,Vec3(x,h,z),Vec3(1,0,0)) --,Vec3()
return body
end

camera=fw.main.camera
camera:Turn(Vec3(0,45,0))
camera:Move(Vec3(0,0.5,d))
camerapivot=CreatePivot()
camera:SetParent(camerapivot)

groundbody=CreateBodyBox(1000,1,1000)
ground=CreateCube(groundbody) 
ground:SetScale(Vec3(1000.0,1.0,1000.0)) 
ground:Paint(material) 
groundbody:Move(Vec3(0,-1,0))
groundbody:SetCollisionType(1)

light=CreatePointLight(50)
light:SetShadowmapSize(2048)
light:Move(Vec3(0,5,5)) 

--DebugPhysics(1)
SetSSAO(1)
AFilter(16)

-- mech body assembly
mech1body = CreateBodyBox(1,0.5,2)
cube=CreateCube(mech1body)
cube:Paint(material) 
ScaleMesh(cube,Vec3(1,0.5,2))
mech1body:SetMass(1)
mech1body:SetGravityMode(1)
mech1body:SetCollisionType(1)
mech1body:Move(Vec3(0,h,0))

-- mech arms assembly
mech1arm          = MakeArm(mech1body, 0.6,-0.8,0.18)		-- x,z
mech1armleft      = MakeArm(mech1body,-0.6,-0.8,0.18)		-- x,z
mech1armfront     = MakeArm(mech1body, 0.6, 0.8,0.18)	-- x,z
mech1armfrontleft = MakeArm(mech1body,-0.6, 0.8,0.18)	-- x,z

-- mech legs assembly
mech1leg          = MakeArm(mech1arm,           0.7,-1.2,0.0)
mech1legleft      = MakeArm(mech1armleft,      -0.7,-1.2,0.0)
mech1legfront     = MakeArm(mech1armfront,      0.7, 0.8-0.4,0.0)
mech1legfrontleft = MakeArm(mech1armfrontleft, -0.7, 0.8-0.4,0.0)

mech1armaxle=CreateCylinder(8,1)
mech1armaxle:SetScale(Vec3(0.1,1.1,0.1))
mech1armaxle:Turn(Vec3(0,0,90))
mech1armaxle:SetParent(mech1body)
mech1armaxle:Paint(material)
mech1armaxlefront=mech1armaxle:Copy()
mech1armaxlefront:SetParent(mech1body)
mech1armaxle:Move(Vec3(0,0,-8))
mech1armaxlefront:Move(Vec3(0,0,8))

Collisions(1,1,1)
MoveMouse(400,240)

while AppTerminate()==0 do
fw:Update()	
if KeyHit(KEY_ESCAPE)==1 then
	break
end 
mx=400-MouseX()
camerapivot:Turn(Vec3(0, (mx), 0))
c1=mech1body:GetPosition()
c2=camerapivot:GetPosition()
c2.x=Curve(c1.x,c2.x,400)
c2.y=Curve(c1.y,c2.y,400)
c2.z=Curve(c1.z,c2.z,400)
camerapivot:SetPosition(c2)
MoveMouse(400,240)
if KeyDown(KEY_RIGHT)==1 then
	mech1arm:AddTorque(Vec3( f,0,0))
	mech1armleft:AddTorque(Vec3( f,0,0))
	mech1armfront:AddTorque(Vec3( f,0,0))
	mech1armfrontleft:AddTorque(Vec3( f,0,0))
end
if KeyDown(KEY_LEFT)==1 then
	mech1arm:AddTorque(Vec3(-f,0,0))
	mech1armleft:AddTorque(Vec3(-f,0,0))
	mech1armfront:AddTorque(Vec3(-f,0,0))
	mech1armfrontleft:AddTorque(Vec3(-f,0,0))
end
fw:Render()
DrawText("Left/Right: Walk",200,0)
Flip(0)
end

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Second test: Standing up by itself, and staying up very steady, next I need to move a leg.

EDIT: Legs are moving now, and walk is quite stable. After a longer walk, the Newton joints get out of position, and you need to stop the mech, to let them slowly return to their positions again. This makes game development with Newton quite impossible, and it would be better to use Bullet physics.

post-2-0-81768700-1312582893_thumb.png

sx=800	-- screen x size
sy=480	-- screen y size
cx=sx/2	-- screen x center
cy=sy/2	-- screen y center
d=-4	-- camera distance
h=1	-- mech creation origin height

require("Scripts/constants/keycodes") 

--Register abstract path 
RegisterAbstractPath("") 
--Set graphics mode 
if Graphics(sx,sy)==0 then 
Notify("Failed to set graphics mode.",1) 
return 
end 
fw=CreateFramework()

material=LoadMaterial("abstract::cobblestones.mat")

function MakeArm(mainbody,x,z,z2)
local body=CreateBodyBox(0.1,0.1,0.5)
local cube=CreateCube(body)
cube:Paint(material)
ScaleMesh(cube,Vec3(0.1,0.1,0.5))
body:SetMass(0.1)
body:Move(Vec3(x,h,z-z2))
body:SetCollisionType(2)
local joint=CreateJointHinge(mainbody,body,Vec3(x,h,z),Vec3(1,0,0)) --,Vec3()
return body
end

function AlignArm(body,x)
local v=body:CalcOmega(Vec3(x,0,0),1)
body:SetOmega(Vec3(v.x*20,v.y*20,v.z*20))
end

function Length(v)
return math.sqrt(v.x*v.x+v.y*v.y+v.z*v.z)
end

camera=fw.main.camera
camera:Turn(Vec3(0,45,0))
camera:Move(Vec3(0,0.5,d))
camerapivot=CreatePivot()
camera:SetParent(camerapivot)

terrain=CreateTerrain(1024)
terrain:SetCollisionType(1)
SetTerrainTexture(terrain,LoadTexture("abstract::terrain_savannah_dirt.dds"))
SetTerrainTextureScale(terrain,3,0)

light=CreatePointLight(50)
light:SetShadowmapSize(2048)
light:Move(Vec3(0,5,5)) 

--DebugPhysics(1)
SetSSAO(1)
AFilter(16)
SetDistanceFog(1)
SetDistanceFogRange(20,80)
SetDistanceFogColor(Vec4(0,0,0,0.8))

-- mech body assembly
mech1body = CreateBodyBox(1,0.5,2)
cube=CreateCube(mech1body)
cube:Paint(material) 
ScaleMesh(cube,Vec3(1,0.5,2))
mech1body:SetMass(1)
mech1body:SetGravityMode(1)
mech1body:SetCollisionType(1)
mech1body:Move(Vec3(0,h,0))

-- mech right arm assembly
mech1arm          = MakeArm(mech1body, 0.6,-0.8,0.18)		-- x,z
mech1armleft      = MakeArm(mech1body,-0.6,-0.8,0.18)		-- x,z
mech1armfront     = MakeArm(mech1body, 0.6, 0.8,0.18)	-- x,z
mech1armfrontleft = MakeArm(mech1body,-0.6, 0.8,0.18)	-- x,z

-- mech legs assembly
mech1leg          = MakeArm(mech1arm,           0.7,-1.2,0.18)
mech1legleft      = MakeArm(mech1armleft,      -0.7,-1.2,0.18)
mech1legfront     = MakeArm(mech1armfront,      0.7, 0.8-0.4,0.18)
mech1legfrontleft = MakeArm(mech1armfrontleft, -0.7, 0.8-0.4,0.18)

mech1armaxle=CreateCylinder(8,1)
mech1armaxle:SetScale(Vec3(0.1,1.1,0.1))
mech1armaxle:Turn(Vec3(0,0,90))
mech1armaxle:SetParent(mech1body)
mech1armaxle:Paint(material)
mech1armaxlefront=mech1armaxle:Copy()
mech1armaxlefront:SetParent(mech1body)
mech1armaxle:Move(Vec3(0,0,-8))
mech1armaxlefront:Move(Vec3(0,0,8))

Collisions(1,1,1)
MoveMouse(cx,cy)
local walkphase=0	-- 0=stopped, 1=left cross-legs up, 2=right cross-legs up
local walksine=0	-- leg phase
while AppTerminate()==0 do
fw:Update()	
if KeyHit(KEY_ESCAPE)==1 then
	break
end 
if walkphase==0 or walkphase==1 then
	AlignArm(mech1arm,-90)
	AlignArm(mech1armleft,-90)
	AlignArm(mech1armfront,-90)
	AlignArm(mech1armfrontleft,-90)
	AlignArm(mech1leg,-90)
	AlignArm(mech1legleft,-90)
	AlignArm(mech1legfront,-90)
	AlignArm(mech1legfrontleft,-90)
end
walksine=(math.sin(AppTime()*0.004))*90
if walkphase==1 then	-- wait for zero phase
	if walksine<0.01 and walkphase>-0.01 then
		walkphase=2
	end
end
if walkphase==2 then
	if walksine>0 then
		AlignArm(mech1armleft,-90+walksine)
		AlignArm(mech1armfront,-90+walksine)
	else
		AlignArm(mech1armleft,-100)
		AlignArm(mech1armfront,-100)
	end
	if walksine<0 then
		AlignArm(mech1arm,-90-walksine)
		AlignArm(mech1armfrontleft,-90-walksine)
	else
		AlignArm(mech1arm,-100)
		AlignArm(mech1armfrontleft,-100)
	end
	AlignArm(mech1leg,-90)
	AlignArm(mech1legleft,-90)
	AlignArm(mech1legfront,-90)
	AlignArm(mech1legfrontleft,-90)
end
local speed=Length(GetBodyVelocity(mech1body))
mx=Curve(cx-MouseX(),mx,8)
camerapivot:Turn(Vec3(0,mx,0))
c1=mech1body:GetPosition()
c2=camerapivot:GetPosition()
c2.x=Curve(c1.x,c2.x,200)
c2.y=Curve(c1.y,c2.y,200)
c2.z=Curve(c1.z,c2.z,200)
camerapivot:SetPosition(c2)
MoveMouse(cx,cy)
if KeyDown(KEY_UP)==1 then
	if walkphase==0 then walkphase=1 end
end
if KeyDown(KEY_DOWN)==1 then
	walkphase=0
end
if KeyDown(KEY_LEFT)==1 then
	mech1body:AddTorque(Vec3(0,-50,0))
end
if KeyDown(KEY_RIGHT)==1 then
	mech1body:AddTorque(Vec3(0,50,0))
end
fw:Render()
DrawText("Up/Down: Walk/Stop",200,0)
DrawText("Left/Right: Turn",200,15)
DrawText("Speed: "..speed,200,30)
Flip(1)
end

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Test 3: Double leg length equals double speed. Leg mass needed to be set higher for bigger joint stability, also minimum required SetOmega value gives better stability:

post-2-0-29993900-1312614852_thumb.png

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I was wondering also how they will walk obstacles and terrain hills, so I need to test that next.

My original idea was to make a humanoid walker, but I thought that they might be too difficult to start with, so I started with a 4 leg walker.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

That is really cool. Also, if it works in the engine, the same code will work with a real-life robot, if the other physical properties are similar enough, since the same equations are used for reality and our physics sim.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

That is really cool. Also, if it works in the engine, the same code will work with a real-life robot, if the other physical properties are similar enough, since the same equations are used for reality and our physics sim.

 

That is awesome!

Intel core 2 quad 6600 | Nvidia Geforce GTX460 1GB | 2GB DDR2 Ram | Windows 7.

 

Google Sketchup | Photoshop | Blender | UU3D | Leadwerks Engine 2.4

Link to comment
Share on other sites

You can also adjust the joint stiffness.

No I can't, unless I fix the bug in the engine. Right now joint:SetStiffness(1000.0) has no effect, also not -100, 0, 1, 2, 10, or any value. The joint keeps rotating at the same speed as a joint without stiffness settings, and it also stretches the joint by exactly the same amount when doing a body:AddTorque(Vec3(500,0,0)) to make it rotate so fast that the joint streches.

 

I looked at the source, and the whole NewtonJointSetStiffness is commented out, but it's not commented out for NewtonJointGetStiffness. Maybe I can just uncomment it, to fix the bug.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

No I can't, unless I fix the bug in the engine. Right now joint:SetStiffness(1000.0) has no effect, also not -100, 0, 1, 2, 10, or any value. The joint keeps rotating at the same speed as a joint without stiffness settings, and it also stretches the joint by exactly the same amount when doing a body:AddTorque(Vec3(500,0,0)) to make it rotate so fast that the joint streches.I looked at the source, and the whole NewtonJointSetStiffness is commented out, but it's not commented out for NewtonJointGetStiffness. Maybe I can just uncomment it, to fix the bug.

 

You know. That might be why I had one hell of a problem trying to get landing gear articulating correctly. I spent a week trying different approaches :/

 

Somewhat frustrating.

6600 2.4G / GTX 460 280.26 / 4GB Windows 7

Author: GROME Terrain Modeling for Unity, UDK, Ogre3D from PackT

Tricubic Studios Ltd. ~ Combat Helo

Link to comment
Share on other sites

mmmm yes. Really need the joint stiffness to work.. XD My wrecking ball looks more like a tennis ball bouncing around with an elastic band cable :(

STS - Scarlet Thread Studios

AKA: Engineer Ken

 

Fact: Game Development is hard... very bloody hard.. If you are not prepared to accept that.. Please give up now!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...