forked from rocheparadox/Kalman-Filter-Python-for-mpu6050
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AngleOMeter.py
170 lines (136 loc) · 4.86 KB
/
AngleOMeter.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#Connections
#MPU6050 - Raspberry pi
#VCC - 5V (2 or 4 Board)
#GND - GND (6 - Board)
#SCL - SCL (5 - Board)
#SDA - SDA (3 - Board)
from Kalman import KalmanAngle
import smbus #import SMBus module of I2C
import time
import math
kalmanX = KalmanAngle()
kalmanY = KalmanAngle()
RestrictPitch = True #Comment out to restrict roll to ±90deg instead - please read: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
radToDeg = 57.2957786
kalAngleX = 0
kalAngleY = 0
#some MPU6050 Registers and their Address
PWR_MGMT_1 = 0x6B
SMPLRT_DIV = 0x19
CONFIG = 0x1A
GYRO_CONFIG = 0x1B
INT_ENABLE = 0x38
ACCEL_XOUT_H = 0x3B
ACCEL_YOUT_H = 0x3D
ACCEL_ZOUT_H = 0x3F
GYRO_XOUT_H = 0x43
GYRO_YOUT_H = 0x45
GYRO_ZOUT_H = 0x47
#Read the gyro and acceleromater values from MPU6050
def MPU_Init():
#write to sample rate register
bus.write_byte_data(DeviceAddress, SMPLRT_DIV, 7)
#Write to power management register
bus.write_byte_data(DeviceAddress, PWR_MGMT_1, 1)
#Write to Configuration register
bus.write_byte_data(DeviceAddress, CONFIG, 0)
#Write to Gyro configuration register
bus.write_byte_data(DeviceAddress, GYRO_CONFIG, 24)
#Write to interrupt enable register
bus.write_byte_data(DeviceAddress, INT_ENABLE, 1)
def read_raw_data(addr):
#Accelero and Gyro value are 16-bit
high = bus.read_byte_data(DeviceAddress, addr)
low = bus.read_byte_data(DeviceAddress, addr+1)
#concatenate higher and lower value
value = ((high << 8) | low)
#to get signed value from mpu6050
if(value > 32768):
value = value - 65536
return value
bus = smbus.SMBus(1) # or bus = smbus.SMBus(0) for older version boards
DeviceAddress = 0x68 # MPU6050 device address
MPU_Init()
time.sleep(1)
#Read Accelerometer raw value
accX = read_raw_data(ACCEL_XOUT_H)
accY = read_raw_data(ACCEL_YOUT_H)
accZ = read_raw_data(ACCEL_ZOUT_H)
#print(accX,accY,accZ)
#print(math.sqrt((accY**2)+(accZ**2)))
if (RestrictPitch):
roll = math.atan2(accY,accZ) * radToDeg
pitch = math.atan(-accX/math.sqrt((accY**2)+(accZ**2))) * radToDeg
else:
roll = math.atan(accY/math.sqrt((accX**2)+(accZ**2))) * radToDeg
pitch = math.atan2(-accX,accZ) * radToDeg
print(roll)
kalmanX.setAngle(roll)
kalmanY.setAngle(pitch)
gyroXAngle = roll;
gyroYAngle = pitch;
compAngleX = roll;
compAngleY = pitch;
timer = time.time()
flag = 0
while True:
if(flag >100): #Problem with the connection
print("There is a problem with the connection")
flag=0
continue
try:
#Read Accelerometer raw value
accX = read_raw_data(ACCEL_XOUT_H)
accY = read_raw_data(ACCEL_YOUT_H)
accZ = read_raw_data(ACCEL_ZOUT_H)
#Read Gyroscope raw value
gyroX = read_raw_data(GYRO_XOUT_H)
gyroY = read_raw_data(GYRO_YOUT_H)
gyroZ = read_raw_data(GYRO_ZOUT_H)
dt = time.time() - timer
timer = time.time()
if (RestrictPitch):
roll = math.atan2(accY,accZ) * radToDeg
pitch = math.atan(-accX/math.sqrt((accY**2)+(accZ**2))) * radToDeg
else:
roll = math.atan(accY/math.sqrt((accX**2)+(accZ**2))) * radToDeg
pitch = math.atan2(-accX,accZ) * radToDeg
gyroXRate = gyroX/131
gyroYRate = gyroY/131
if (RestrictPitch):
if((roll < -90 and kalAngleX >90) or (roll > 90 and kalAngleX < -90)):
kalmanX.setAngle(roll)
complAngleX = roll
kalAngleX = roll
gyroXAngle = roll
else:
kalAngleX = kalmanX.getAngle(roll,gyroXRate,dt)
if(abs(kalAngleX)>90):
gyroYRate = -gyroYRate
kalAngleY = kalmanY.getAngle(pitch,gyroYRate,dt)
else:
if((pitch < -90 and kalAngleY >90) or (pitch > 90 and kalAngleY < -90)):
kalmanY.setAngle(pitch)
complAngleY = pitch
kalAngleY = pitch
gyroYAngle = pitch
else:
kalAngleY = kalmanY.getAngle(pitch,gyroYRate,dt)
if(abs(kalAngleY)>90):
gyroXRate = -gyroXRate
kalAngleX = kalmanX.getAngle(roll,gyroXRate,dt)
#angle = (rate of change of angle) * change in time
gyroXAngle = gyroXRate * dt
gyroYAngle = gyroYAngle * dt
#compAngle = constant * (old_compAngle + angle_obtained_from_gyro) + constant * angle_obtained from accelerometer
compAngleX = 0.93 * (compAngleX + gyroXRate * dt) + 0.07 * roll
compAngleY = 0.93 * (compAngleY + gyroYRate * dt) + 0.07 * pitch
if ((gyroXAngle < -180) or (gyroXAngle > 180)):
gyroXAngle = kalAngleX
if ((gyroYAngle < -180) or (gyroYAngle > 180)):
gyroYAngle = kalAngleY
print("Angle X: " + str(kalAngleX)+" " +"Angle Y: " + str(kalAngleY))
#print(str(roll)+" "+str(gyroXAngle)+" "+str(compAngleX)+" "+str(kalAngleX)+" "+str(pitch)+" "+str(gyroYAngle)+" "+str(compAngleY)+" "+str(kalAngleY))
time.sleep(0.005)
except Exception as exc:
flag += 1