Lentokoneen fysiikat

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
Latexi95
Guru
Posts: 1166
Joined: Sat Sep 20, 2008 5:10 pm
Location: Lempäälä

Lentokoneen fysiikat

Post by Latexi95 »

Julkaisin pikku pelit topicissa pari vuotta sitten lentokoneen fysiikat. Meinasin ne jo silloin laittaa tänne omaan topiciin, mutta se jäi sitten tekemättä. Innostuin kuitenkin eilen illalla vähän parantelemaan tätä ja korjasin ison läjän virheitä kaavoissa. Jos jotakuta kiinnostaa tehdä lentokonepeliä, niin tästä voi ottaa koodia fysiikoihin. Yritin käyttää BAe Hawkin tietoja pohjana tälle, mutta kaikkia tietoja ei löytynyt, niin jouduin heittämään arvoja päästäni ja säätämään sopivaksi. Nyt lennettävyys on kohtuu hyvä ja tuntuu käyttäytyvän kohtuullisesti fysiikanlakien mukaan. Liitteessä on mukana tarvittavat mediat (ja myös alempi koodi) esimerkin suorittamiseen.

Code: Select all

//Lentokoneena: BAe Hawk
SCREEN 1000,600
 
Const PHYSICS_ACCURACY = 3
 
Const AIR_DENSITY = 1.225
 
//Skaalaus
Const PIXEL_TO_METER = 0.1186
Const METER_TO_PIXEL = 8.4317032040472175379426644182125
 
Const GRAVITY = 9.81
 
Const ELEVATOR_DISTANCE_FROM_CENTER_OF_MASS = 5.1
Const ELEVATOR_AREA = 0.8 //m^2
Const ELEVATOR_DRAG_COEFFICIENT = 10.0
 
Const ROTATION_DRAG_COEFFICIENT = 100.0 //
 
Const WING_AREA = 16.69 //m^2
Const PLANE_MASS = 4000 //Kg
Const PLANE_MOMENT_OF_INERTIA = 4000 //Kg *m^2       Miten tämän saisi selville? Heitetty päästä ominaisuuksiin sopivaksi
Const DRAG_COEFFICIENT_X = 2.3 //Kerrottuna pinta-alalla  TODO: Näillä arvoilla toimii, mutta ne eivät vastaa todellisuutta...
Const DRAG_COEFFICIENT_Y = 10.0
Const LIFT_DF_COEFFICIENT = 1.6
Const MOTOR_MAX_FORCE = 29130 //N
 
Const LIFT_COEFFICIENT_COUNT = 72
Dim LiftCoefficient(LIFT_COEFFICIENT_COUNT) As Float
Dim ElevatorLiftCoefficient(LIFT_COEFFICIENT_COUNT) As Float
 
 
InitLiftCoefficient()
 
floor=MakeObjectFloor()
grid=LoadImage("whitegrid.bmp")
PaintObject floor,grid
 
 
plane = LoadObject("aircraft.png", 180)
planeVX# = 50 //m/s
planeVY# = 0 //m/s
planeVA# = 0 //deg/s
 
 
 
planeThrottle# = 1.0 //Kaasun asento
elevatorAngle# = 0
 
DrawToWorld ON
Repeat
    planeThrottle# = Max(0.0,Min(1.0,planeThrottle+(UpKey()-DownKey())*0.01))
    ElevatorAngle# = CurveAngle((RightKey()-LeftKey())*45.0,elevatorAngle#,30)
 
        If KeyHit(cbKeyR) Then
                planeVX# = 100 //m/s
                planeVY# = 0 //m/s
                planeVA# = 0 //deg
                planeA# = 0
        EndIf
 
    planeA# = ObjectAngle(plane)
    planeX# = ObjectX(plane)*PIXEL_TO_METER
    planeY# = ObjectY(plane)*PIXEL_TO_METER
    timestep# = 1.0/60.0/PHYSICS_ACCURACY
    For physics_step = 1 To PHYSICS_ACCURACY
           
        //Nollataan voimat
        planeFX# = 0
        planeFY# = 0
        planeFA# = 0
   
       
        //Suunta vektori
        planeAX# = Cos(planeA#)
        planeAY# = Sin(planeA#)
       
        //Muunnettaan lentokoneen liike sen omaan koordinaatistoon
        planeLVX# = planeVX#*planeAX# + planeVY#*planeAY#
        planeLVY# = planeVY#*planeAX# - planeVX#*planeAY#
           
        airspeed# = Distance(0,0,planeVX#,planeVY#)
        AngleOfAttack# = WrapAngle(-GetAngle(0,0,planeLVX#,-planeLVY#))
       
        //Lasketaan noste
        lift# = CalcLift(AngleOfAttack,airspeed#)
        df# = CalcDF(AngleOfAttack, airspeed#)
       
        aoaAX# = Cos(angleOfAttack)
        aoaAY# = Sin(angleOfAttack)
       
        //Lasketaan ilmanvastus
        airresistY# = 0.5*AIR_DENSITY*planeLVY#*planeLVY#*DRAG_COEFFICIENT_Y
        airresistX# = 0.5*AIR_DENSITY*planeLVX#*planeLVX#*DRAG_COEFFICIENT_X
        airresistA# = 0.5*AIR_DENSITY*planeVA#*planeVA#*ROTATION_DRAG_COEFFICIENT
       
        //Ilmanvastuksen etumerkit oikein
        If planeLVX# > 0.0 Then airresistX# = -airresistX#
        If planeLVY# > 0.0 Then airresistY# = -airresistY#
        If planeVA# > 0.0 Then airresistA# = -airresistA#
       
       
        liftLVX# = lift# * aoaAY
        liftLVY# = lift# * aoaAX#
       
        planeLFY# = (liftLVY# + df# + airresistY#) //Noste + ilmanvastus
        planeLFX# = (airresistX# + liftLVX# + planeThrottle*MOTOR_MAX_FORCE)//Ilmanvastus + moottorin voima
       
        planeFA# = (airresistA# + CalcElevatorLift(angleOfAttack+elevatorAngle#,airspeed#)*ELEVATOR_DISTANCE_FROM_CENTER_OF_MASS)
       
        planeFX# = planeLFX#*planeAX# - planeLFY#*planeAY#
        planeFY# = planeLFX#*planeAY# + planeLFY#*planeAX# - GRAVITY * PLANE_MASS
       
        planeVX# = planeVX# + (planeFX# / PLANE_MASS) * timestep#
        planeVY# = planeVY# + (planeFY# / PLANE_MASS) * timestep#
        planeVA# = planeVA# + (planeFA# / PLANE_MOMENT_OF_INERTIA) * timestep#
       
       
 
        //LIsätään sijaintiin ja kulmaan liikkeet
        planeX# = planeX# + planeVX#*timestep#
        planeY# = planeY# + planeVY#*timestep#
        planeA# = planeA# + planeVA#*timestep#
    Next physics_step
   
    Text 10,10,"VX#:"+LSet(Str(planeVX#) + "m/s" , 12)+" VY#:"+LSet(Str(planeVY#) + "m/s", 12)+" VA#:"+LSet(Str(planeVA#) +"deg/s", 13)+" Angle:"+LSet(Str(planeA#) + "deg", 13)+" Lift:"+LSet(Str(lift#) + "N", 10)
    Text 10,20,"ARX:"+LSet(Str(airresistX#) + "N", 10)+" ARY:"+LSet(Str(airresistX#) + "N", 10)
    Text 10,30,"LVX:"+planeLVX#
    Text 10,40,"Throttle:"+planeThrottle#+" Elevator angle:"+DirAngle(ElevatorAngle#)
    Text 10,50,"Elevator force:"+elevatorForce#+ "AoA:"+DirAngle(AngleOfAttack#)
    Text 10,60,"FX#:"+planeFX#+" FY#:"+planeFY#+" FA#:"+planeFA#
        Text 10,70,"FPS:" + FPS() + " Air speed:" + Distance(0, 0, planeVX#, planeVY#)
    PositionObject plane,planeX#*METER_TO_PIXEL,planeY#*METER_TO_PIXEL
    RotateObject plane,planeA#
    CloneCameraPosition plane
   
    DrawGame
   
   
    DrawScreen
Forever
 
 
Function InitLiftCoefficient()
//http://en.wikipedia.org/wiki/File:Lift_curve.svg
        //0deg
               
        //For i = 0 To 72
        //      LiftCoefficient(i) = Sin(i * 5.0 + 10) * 1.6 * (1 - (i / 150))
        //Next i
       
    LiftCoefficient(0) = 0.6
    LiftCoefficient(1) = 1.0
    LiftCoefficient(2) = 1.5
    LiftCoefficient(3) = 1.8
    LiftCoefficient(4) = 1.6
    LiftCoefficient(5) = 1.4
    LiftCoefficient(6) = 1.25
    LiftCoefficient(7) = 1.08
    LiftCoefficient(8) = 0.9
    LiftCoefficient(9) = 0.6
    LiftCoefficient(10) = 0.4
    LiftCoefficient(11) = 0.3
    LiftCoefficient(12) = 0.2
    LiftCoefficient(13) = 0.1
    LiftCoefficient(14) = 0.05
    LiftCoefficient(15) = -0.05
    LiftCoefficient(16) = -0.1
    LiftCoefficient(17) = -0.15
 
        //90deg
        LiftCoefficient(18) = -0.22
        LiftCoefficient(19) = -0.3
        LiftCoefficient(20) = -0.3
        LiftCoefficient(21) = -0.25
        LiftCoefficient(22) = -0.25
        LiftCoefficient(23) = -0.3
        LiftCoefficient(24) = -0.3
        LiftCoefficient(25) = -0.3
        LiftCoefficient(26) = -0.3
        LiftCoefficient(27) = -0.3
        LiftCoefficient(28) = -0.3
        LiftCoefficient(29) = -0.3
        LiftCoefficient(30) = -0.3
        LiftCoefficient(31) = -0.3
        LiftCoefficient(32) = -0.3
        LiftCoefficient(33) = -0.3
    LiftCoefficient(34) = -0.3
        LiftCoefficient(35) = -0.3
       
        //180deg
        LiftCoefficient(36) = -0.3
        LiftCoefficient(37) = -0.25
        LiftCoefficient(38) = -0.20
        LiftCoefficient(39) = -0.15
        LiftCoefficient(40) = -0.10
        LiftCoefficient(41) = -0.05
        LiftCoefficient(42) = -0.0
        LiftCoefficient(43) = -0.0
        LiftCoefficient(44) = -0.0
        LiftCoefficient(45) = -0.0
        LiftCoefficient(46) = -0.0
        LiftCoefficient(47) = 0
        LiftCoefficient(48) = 0
        LiftCoefficient(49) = 0
        LiftCoefficient(50) = 0
        LiftCoefficient(51) = 0
        LiftCoefficient(52) = 0
        LiftCoefficient(53) = 0
       
        //270deg
        LiftCoefficient(54) = 0
        LiftCoefficient(55) = 0
        LiftCoefficient(56) = 0
        LiftCoefficient(57) = 0
        LiftCoefficient(58) = 0
        LiftCoefficient(59) = 0
        LiftCoefficient(60) = 0
        LiftCoefficient(61) = -1.0
        LiftCoefficient(62) = -1.5
        LiftCoefficient(63) = -1.4
        LiftCoefficient(64) = -1.4
        LiftCoefficient(65) = -1.4
        LiftCoefficient(66) = -1.3
        LiftCoefficient(67) = -1.2
        LiftCoefficient(68) = -1.2
        LiftCoefficient(69) = -0.9
        LiftCoefficient(70) = -0.5
        LiftCoefficient(71) = 0.1
       
        //360deg
        LiftCoefficient(72) = 0.6
 
    LiftCoefficient(72) = 0.6
    LiftCoefficient(71) = 0.0
    LiftCoefficient(70) = -0.5
    LiftCoefficient(69) = -0.9
    LiftCoefficient(68) = -1.2
    LiftCoefficient(67) = -1.9
    LiftCoefficient(66) = -2.8
    LiftCoefficient(65) = -3.3
    LiftCoefficient(64) = -3.9
    LiftCoefficient(63) = -4.8
        LiftCoefficient(62) = -5.5
        LiftCoefficient(61) = -5.5
        LiftCoefficient(60) = -5.5
       
       
   
    For i = 0 To 72
        ElevatorLiftCoefficient(i) = -((1.0-Abs((i Mod 18)-9)/9.0))*ELEVATOR_DRAG_COEFFICIENT
        If (i > 18 And i < 36) Or (i > 54) Then ElevatorLiftCoefficient(i)= -ElevatorLiftCoefficient(i)
        ElevatorLiftCoefficient(i) = ElevatorLiftCoefficient(i)
    Next i
    //TODO: Tarkempi taulukko + enemmän arvoja
EndFunction
 
Function DirAngle(a#)
    a = WrapAngle(a)
    If a > 180 Then Return a - 360
    Return a
EndFunction
 
Function CalcElevatorLift(AngleOfAttack#,airspeed#)
    aoa# = WrapAngle(AngleOfAttack#)/360.0*LIFT_COEFFICIENT_COUNT
    aoamin# = ElevatorLiftCoefficient(Int(Max(0,RoundDown(aoa#))))
    aoamax# = ElevatorLiftCoefficient(Int(Min(LIFT_COEFFICIENT_COUNT,RoundUp(aoa#))))
    Return 0.5*AIR_DENSITY*airspeed#*airspeed#*ELEVATOR_AREA*(aoamin+(aoamax-aoamin)*(((aoa#-RoundDown(aoa#)) / 4.0)/LIFT_COEFFICIENT_COUNT))
EndFunction
 
Function CalcDF(aoa#, airspeed#)
    c# = Sin(aoa#) * LIFT_DF_COEFFICIENT
    Return 0.5 * airspeed# * airspeed# * c# * WING_AREA * AIR_DENSITY
EndFunction
 
Function CalcLift(AngleOfAttack#,airspeed#)
    aoa# = WrapAngle(AngleOfAttack#)/360.0*LIFT_COEFFICIENT_COUNT
    aoamin# = LiftCoefficient(Int(Max(0,RoundDown(aoa#))))
    aoamax# = LiftCoefficient(Int(Min(LIFT_COEFFICIENT_COUNT,RoundUp(aoa#))))
    Return 0.5*AIR_DENSITY*airspeed#*airspeed#*WING_AREA*(aoamin+(aoamax-aoamin)*(((aoa#-RoundDown(aoa#)) / 4.0)/LIFT_COEFFICIENT_COUNT))
EndFunction
Attachments
Airplane.zip
(9.68 KiB) Downloaded 514 times
qekko

Re: Lentokoneen fysiikat

Post by qekko »

Vau! Komeet käsialaa!
atomimalli
Moderator
Moderator
Posts: 227
Joined: Wed Aug 29, 2007 3:55 pm

Re: Lentokoneen fysiikat

Post by atomimalli »

Ooh! Melkeen ois ainesta uuteen top landeriin!
Jännästi noita kertoimia riittää vaikka on noinkin vähille kulmille :o

Olen ylä- ja ala-asteen vaihteesta asti miettinyt että lentosimulaatiota olisi kiva joskus koittaa tehdä, mutten ole päässyt sitä vielä koittamaan.
Post Reply