forked from droghio/QuadSimulator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gamelogic.py
134 lines (90 loc) · 4.23 KB
/
gamelogic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
Quadcopter Simulator
--
A quick way to test stabilzation algorithms.
John Drogo
Septemer 15, 2014
YOU NEED TO USE THIS IN BLENDER!
Look for spots that say CHANGE THIS and modify them as needed.
This simulator does not take aerodynamics or pressure into account.
The red marks on the quadcopter mark its front,
each fan is numbered clockwise with fan 0 being the front left.
ALL UNITS ARE IN SI!
(Angles are in radians.)
When using the acceleration or velocity lists index 0 indicates the x axis,
1 is the y, and 2 is the z.
I consider clockwise a positive RPM, and counterclockwise as negative.
Happy flying!
"""
import bge
import random
import math
import mathutils
def main():
cont = bge.logic.getCurrentController()
quad = cont.owner
quad_pos = quad.worldPosition
try:
if quad["last_vel"]:
pass
except:
print("Last velocity point does not exist.")
quad["last_vel"] = [ 0, 0, 0 ]
random.seed()
force = [ 0.0, 0.0, 0.0 ]
torque = [ 0, 0, 0]
#Quadcopter description.
#CHANGE THIS
p_m = .018 #Propellor mass.
p_r = .10 #Prop length.
p_rpm = [ quad["rpm0"], quad["rpm1"], quad["rpm2"], quad["rpm3"] ] #Prop rpm. (Change in game window or don't at all.)
q_m = quad.mass #Mass of quadcopter (set using the physics tab below.
q_r = .15 #Distance from prop center to quad center of mass.
#Now we calculate the prop's angular momentum. (No need to change this.)
p_w = [ (p_rpm[0] / 60) * 2 * math.pi, (p_rpm[1] / 60) * 2 * math.pi, (p_rpm[2] / 60) * 2 * math.pi, (p_rpm[3] / 60) * 2 * math.pi ]
#Your thrust curve. (CHANGE THIS!)
def thrustRPM(propnum):
#Basic efficency curve, assuming linear relation. Don't forget to flip the thrust on your ccw props.
return p_rpm[propnum]/(10000)*quad["maxThrust"] * (-1 if propnum % 2 else 1)
# Resolve force components to moments and total force.
torque[0] = q_r/math.sqrt(2) * ( -thrustRPM(0) - thrustRPM(1) + thrustRPM(2) + thrustRPM(3) ) #x axis
torque[1] = q_r/math.sqrt(2) * ( -thrustRPM(0) - thrustRPM(3) + thrustRPM(1) + thrustRPM(2) ) #y axis
torque[2] = ( (p_m * (p_r * p_r)) / 2 * p_w[0] ) + ( (p_m * (p_r * p_r)) / 2 * p_w[1] ) + ( (p_m * (p_r * p_r)) / 2 * p_w[2] ) + ( (p_m * (p_r * p_r)) / 2 * p_w[3] ) #z axis
force[2] = ( thrustRPM(0) + thrustRPM(1) + thrustRPM(2) + thrustRPM(3) )
local = True
quad.applyForce(force, local)
quad.applyTorque(torque, local)
#Calculates change in velocity.
#Each tick should occur at 60Hz.
def calculateAccel():
#Simulate the effects of gravity on the accelerometer.
R = quad.worldOrientation
g_l = mathutils.Vector((0.0, 0, -9.8)) #Gravity.
g_l.rotate(R) #Localize gravity.
#print("Rotation matrix:", R)
#print("Gravity:", g_l.xyz) #Local gravity vector (won't always be straight down.)
accel = [ 0, 0, 0 ]
vel = quad.getLinearVelocity(0)
#Simulate the acceleromter values by adding the localized gravity vector.
accel[0] = (vel[0] - quad["last_vel"][0]) * 60 + g_l[0]
accel[1] = (vel[1] - quad["last_vel"][1]) * 60 + g_l[1]
accel[2] = (vel[2] - quad["last_vel"][2]) * 60 + g_l[2]
quad["last_vel"] = vel
print(accel)
return accel
#Sets the rpm for each fan.
#Max rpm is 10000.
#Fan 0 = fl, then number clockwise.
#CHANGE THIS!
def stabilzationTick(accel, angVel):
maxRPM = 10000
print("Angular velocity:", angVel)
if (accel[2] > -9.8):
return [ quad["rpm0"] - 200, quad["rpm1"] + 200, quad["rpm2"] - 200, quad["rpm3"] + 200 ]
elif (accel[2] < -9.8):
return [ quad["rpm0"] + 70, quad["rpm1"] - 70, quad["rpm2"] + 70, quad["rpm3"] - 70 ]
return [ quad["rpm0"], quad["rpm1"], quad["rpm2"], quad["rpm3"] ]
#Update RPMs based on accelerometer and gyroscope date.
quad["rpm0"], quad["rpm1"], quad["rpm2"], quad["rpm3"] = stabilzationTick(calculateAccel(), quad.localAngularVelocity)
return
main()