Realisitic movement in space using a joystick

Blitz3D Forums/Blitz3D Programming/Realisitic movement in space using a joystick

my_name_is_alex_hello__(Posted 2006) [#1]
Hi, I'm currently working on a space simulator, and since im doing a level maths i thought i'd introduce the principles of taking moments and resolving into the movement of the spaceship. The way this works is to define thrusters, their force, their position relative to the ship and their direction, and then enable or disable these thrusters depending on the joystick position, and then resolve and take moments to find out the movement and rotation of the ship. However, although ive worked this out on paper and as far as i know it should work, when I try to fly the ship in game, the angles are clearly not getting translated into proper forces in the proper directions.
It would be great if someone would look over the following code and tell me if ive put a cos in the wrong place or somthing stupid like that. Thanks in advance, Alex

--------------IMPORANT-----------------
The code below will not work on its own, you need to make a text document called '1.txt' in the same directory which contains data about the thrusters on the ship. The text for 1.txt is below the code for the program.


The code itself is here:

[CODE]
;Controls- either joystick input OR
;use arrows for pitch and yaw, Q and E for roll left and roll right. W and S are forwards and backwards
;A and D are strafe left and right
;When the ship turns, the downward force of the thrusters not only turns the ship but also causes
;it to move, this is intended since it is what would actually happen.

;The problem with this code, I suspect, is that I am either taking the angle of the ship incorrectly
;or I am using sin and cos in the wrong places, or another stupid error like that :(
Graphics3D 800,600,32,2
SetBuffer BackBuffer()
;Cubes for frame of reference
For c=1 To 20
cu=CreateCube()
PositionEntity cu,Rand(-20,20),Rand(-20,20),Rand(-20,20)
Next
;Star background
s=CreateSphere(32)
FlipMesh s
ScaleEntity s,100,100,100
t=CreateTexture(512,512)
SetBuffer TextureBuffer(t)
For i=1 To 300
size=Rand(1,2)
Rect Rand(0,512),Rand(0,512),size,size
Next
EntityTexture s,t
SetBuffer BackBuffer()
;Globals
Global x#,y#,z#,xv#,yv#,zv#,ax#,ay#,az#,axv#,ayv#,azv#
Global shipname$,shipmass#
;Types
Type thruster
Field ax#,ay#,az#,x#,y#,z#,thrust#,parent,on#,id
End Type
;Load the thruster profile for the ship (this textfile must be made in order for the program to funtion)
loadthrusters("1.txt")
Global ship=CreateCube()
Global cam=CreateCamera(ship)
EntityType ship,1
EntityRadius ship,2
EntityType s,2
Collisions 1,2,2,3
While Not KeyHit(1)

;DETECT JOYSTICK INPUT. (For the purposes of this test I have also enabled key input)
;LEFT Y AXIS
roll#=JoyRoll()
If Abs(roll#)<1 Then roll#=0
If roll#<0.01 Then
choosethruster(4,(roll#/180.0))
choosethruster(5,(roll#/180.0))
EndIf
If KeyDown(203) Then
choosethruster(4,1)
choosethruster(5,1)
EndIf
;RIGHT Y AXIS
If roll#>0.01 Then
choosethruster(3,(roll#/180.0))
choosethruster(6,(roll#/180.0))
EndIf
If KeyDown(205) Then
choosethruster(3,1)
choosethruster(6,1)
EndIf
;UP X AXIS
pitch#=JoyY()
If pitch#<0.01 Then
;steer down
choosethruster(7,pitch#)
choosethruster(10,pitch#)
EndIf
If KeyDown(208) Then
choosethruster(7,1)
choosethruster(10,1)
EndIf
If pitch#>0.01 Then
;steer up
choosethruster(8,pitch#)
choosethruster(9,pitch#)
EndIf
If KeyDown(200) Then
choosethruster(8,1)
choosethruster(9,1)
EndIf
;ROLLING
yaw#=JoyX()
If yaw#>0.01 Then
choosethruster(12,yaw#)
choosethruster(11,yaw#)
EndIf
If KeyDown(16) Then
choosethruster(12,1)
choosethruster(11,1)
EndIf
If yaw#<0.01 Then
choosethruster(13,yaw#)
choosethruster(14,yaw#)
EndIf
If KeyDown(18) Then
choosethruster(13,1)
choosethruster(14,1)
EndIf
;Primary Engine Thrusters
If KeyDown(31) Then choosethruster(1,1)
If KeyDown(17) Then choosethruster(2,1)
If KeyDown(30) Then
choosethruster(3,1)
choosethruster(5,1)
EndIf
If KeyDown(32) Then
choosethruster(5,1)
choosethruster(6,1)
EndIf

takemoments()
resolve()
updateship()
UpdateWorld()
RenderWorld()

Text 10,10,"Pitch "+EntityPitch(ship)
Text 10,30,"Yaw "+EntityYaw(ship)
Text 10,50,"Roll "+EntityRoll(ship)

Text 10,70,"z acc "+zv#
Text 10,90,"x acc "+xv#
Text 10,110,"y acc "+yv#
Flip
Wend


Function choosethruster(id,amount#)
;Enables the correct thruster for the input recieved, with the correct force as determined
;by the joystick push amount
For t.thruster= Each thruster
If t\id=id Then
t\on#=Abs(amount#)
EndIf
Next
End Function

Function takemoments()
;Takes moments of the thrusters, this increases the angle of the ship depending on thruster angle,
;power, and distance fromt the center of mass of the ship
For t.thruster=Each thruster
If Not t\on#=0 Then
axv#=axv#+(((t\z#)*(t\on#*Sin(-t\ax#)))/shipmass#)
azv#=azv#+(((t\x#)*(t\on#*Sin(-t\ax#)))/shipmass#)
ayv#=ayv#+(((t\z#)*(t\on#*Sin(-t\ay#)))/shipmass#)
EndIf
Next
End Function

Function resolve()
;Increases the velocity of the ship taking into account the angle of the ship relative to the
;absolute coordinate vectors (if that is what they are named)
For t.thruster=Each thruster
If Not t\on=0 Then
yv#=yv#+((t\on#*Sin(ax#-t\ax#))/shipmass#)
xv#=xv#+((t\on#*Sin(ay#-t\ay#))/shipmass#)
zv#=zv#+((t\on#*Cos(ay#-t\ay#))/shipmass#)
EndIf
t\on#=0
Next
End Function

Function updateship()
;Limits the maximum speed of the ship, dampens the velocity of the ship, and
;moves and rotates the ship using turn and translateentity.
If ayv#<-2 Then ayv#=-2
If ayv#>2 Then ayv#=2

axv#=axv#*0.99
ayv#=ayv#*0.99
azv#=azv#*0.99
xv#=xv#*0.99
yv#=yv#*0.99
zv#=zv#*0.99
;Translateentity is used rather than moveentity because if the entity was moved, the spaceship
;Would not behave in the correct way.
TranslateEntity ship,xv#,yv#,zv#
TurnEntity ship,axv#,ayv#,azv#
End Function


Function loadthrusters(name$)
Print "loading ships..."
f=OpenFile(name$)
For i=1 To 13
ReadLine$(f)
Next

shipname$=ReadLine$(f)
shipmass#=ReadLine$(f)
Print shipname$+" at"+shipmass+"Kg"
numthrust=ReadLine$(f)
Repeat
reached=reached+1
t.thruster=New thruster
ReadLine$(f)
t\id=ReadLine$(f)
t\thrust#=ReadLine$(f)
t\x#=ReadLine$(f)
t\y#=ReadLine$(f)
t\z#=ReadLine$(f)
t\ax#=ReadLine$(f)
t\ay#=ReadLine$(f)
t\az#=ReadLine$(f)
If reached=numthrust Then Exit
Forever
Print "Loaded "+numthrust+"thrusters"
;WaitKey()

End Function

[/CODE]

THE ALL IMPORTANT SHIP THRUSTER DATA IS HERE:::

[CODE]
FORMAT FOR SHIP THRUSTERS IS AS FOLLOWS: (ship info followed by as many thrusters as you like)
shipname
shipmass
numthrusters
editinfo
thrusterid
thrusterthrust
thrusterx
thrustery
thrusterz
thrusterxa
thrusterya
thrusterza
viper
1000
14
Primary thruster
1
10
0
0
-1
0
180
0
Reverse thruster
2
3
0
0
5
0
0
0
Steer left thruster
3
1
0
0
5
0
90
0
Steer right thruster
4
1
0
0
5
0
-90
0
steer left (rear) thruster
6
2
0
0
-2.5
0
-90
0
steer right (rear) thruster
5
2
0
0
-2.5
0
90
0
steer down thruster
7
1
0
0
5
-90
0
0
steer up thruster
8
1
0
0
5
90
0
0
steer down (rear) thruster
10
2
0
0
-2.5
90
0
0
steer up (rear) thruster
9
2
0
0
-2.5
-90
0
0
roll left thruster
12
1
2
0
0
90
0
0
roll right thruster
13
1
-2
0
0
90
0
0
roll left (opposite) thruster
11
1
-2
0
0
-90
0
0
roll right (opposite) thruster
14
1
2
0
0
-90
0
0
[/CODE]

Good Luck :D


_PJ_(Posted 2006) [#2]
http://www.blitzbasic.com/codearcs/codearcs.php?code=327


I also ran into some problems with trying this mthod, and instead resorted to a pivot and vector-driven style, having a separate velocity for 3 dimensions.


my_name_is_alex_hello__(Posted 2006) [#3]
Is that not what i'm doing, or are you talking about vectors that rotate with the ship? If thats the case then the only difference is that you would use moveentity instead of translateentity, otherwise im not sure I get what you mean