-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathfgo.py
55 lines (48 loc) · 2.39 KB
/
fgo.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
from math import radians, sin, sqrt, atan2, cos, degrees
from utils import safe_tangent, wrap
from display import Display
from truthdata import TruthData
display = Display()
TD = TruthData()
''' FGO = Fixed-Gain Observers
'''
class AltitudeObserver:
''' http://diydrones.com/profiles/blogs/no-baro-altitude-filter-for#comments
'''
def __init__(self):
self.altitude = 0.0
def estimate(self, theta, Vair, GPS_altitude, dt):
k = -0.01
alpha = radians(0.52) # average angle of attack
gamma = theta - alpha
self.altitude += Vair * sin(gamma) * dt
error = self.altitude - GPS_altitude
self.altitude += k * error
return self.altitude
class WindObserver:
''' Ryan Beall is awesome.
'''
def __init__(self):
self.k = 0.05
self.Wn_fgo = 0.0
self.We_fgo = 0.0
def estimate(self, theta, psi, Vair, ground_speed, course_over_ground, dt):
''' Units:
radians: theta, psi, course_over_ground
meters per second: Vair, ground_speed
seconds: dt
Issues to fix:
Speeds need to come in as the right units for this estimator to work properly
'''
# if they come in as knots
#Vair = Vair / 0.5144444444
#ground_speed = ground_speed / 0.5144444444
#display.register_scalars({"Vair":Vair, "GSPD":ground_speed, "TD.Wdir":TD.WIND_DIRECTION, "TD.Wvel":TD.WIND_VELOCITY}, "Wind FGO")
wind_north_error = (Vair * cos(psi) * cos(theta)) - (ground_speed * cos(course_over_ground)) - self.Wn_fgo
wind_east_error = (Vair * sin(psi) * cos(theta)) - (ground_speed * sin(course_over_ground)) - self.We_fgo
self.Wn_fgo += self.k * wind_north_error
self.We_fgo += self.k * wind_east_error
#display.register_scalars({"CoG":course_over_ground,"psi":psi,"Wn error": wind_north_error, "We error": wind_east_error, "Wn_fgo": self.Wn_fgo, "We_fgo": self.We_fgo, "cos(psi)": cos(psi), "cos(theta)": cos(theta), "sin(psi)": sin(psi), "cos(cog)": cos(course_over_ground), "sin(cog)": sin(course_over_ground), "wind_north_error": wind_north_error, "wind_east_error": wind_east_error}, "Wind FGO")
wind_direction = degrees(atan2(self.We_fgo,self.Wn_fgo))
wind_velocity = sqrt(self.We_fgo**2 + self.Wn_fgo**2) / 0.5144444444 # convert from m/s to knots
return wind_direction, wind_velocity