-
Notifications
You must be signed in to change notification settings - Fork 1
/
flightcode.py
174 lines (133 loc) · 6.59 KB
/
flightcode.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
171
172
173
174
#!/usr/bin/python
import os
import serial
import crcmod
import time
import time as time_
time_set = False
trigger = False # boolen to trigger event at 30km
# byte array for a UBX command to set flight mode
setNav = bytearray.fromhex("B5 62 06 24 24 00 FF FF 06 03 00 00 00 00 10 27 00 00 05 00 FA 00 FA 00 64 00 2C 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 DC")
# byte array for UBX command to disable automatic NMEA response from GPS
setNMEA_off = bytearray.fromhex("B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 80 25 00 00 07 00 01 00 00 00 00 00 A0 A9")
# function to disable all NMEA sentences
def disable_sentences():
GPS = serial.Serial('/dev/ttyAMA0', 9600, timeout=1) # open serial to write to GPS
# Disabling all NMEA sentences
GPS.write("$PUBX,40,GLL,0,0,0,0*5C\r\n")
GPS.write("$PUBX,40,GSA,0,0,0,0*4E\r\n")
GPS.write("$PUBX,40,RMC,0,0,0,0*47\r\n")
GPS.write("$PUBX,40,GSV,0,0,0,0*59\r\n")
GPS.write("$PUBX,40,VTG,0,0,0,0*5E\r\n")
GPS.write("$PUBX,40,GGA,0,0,0,0*5A\r\n")
GPS.close() # close serial
#create function equivalent to arduino millis();
def millis():
return int(round(time_.time() * 1000))
# fucntion to send commands to the GPS
def sendUBX(MSG, length):
ubxcmds = ""
for i in range(0, length):
GPS.write(chr(MSG[i])) #write each byte of ubx cmd to serial port
ubxcmds = ubxcmds + str(MSG[i]) + " " # build up sent message debug output string
GPS.write("\r\n") #send newline to ublox
crc16f = crcmod.predefined.mkCrcFun('crc-ccitt-false') # function for CRC-CCITT checksum
disable_sentences()
counter = 0 # this counter will increment as our sentence_id
# function to set the OS time to GPS time
def set_time(time):
data = list(time) # split the time into individual characters
# construct the hours and minutes variables
hours = time[0] + time[1]
minutes = time[2] + time[3]
parsed_datetime = hours + minutes # finalise the time to be set
os.system('sudo date --set ' + str(parsed_datetime)) # set the OS time
time_set = True # show that time is now set
# function to send both telemetry and packets
def send(data):
NTX2 = serial.Serial('/dev/ttyAMA0', 300, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_TWO) # opening serial at 300 baud for radio transmission with 8 character bits, no parity and two stop bits
NTX2.write(data) # write final datastring to the serial port
NTX2.close()
# function to read the gps and process the data it returns for transmission
def read_gps():
# set some fields to zero for transmitting without lock
satellites = 0
lats = 0
northsouth = 0
lngs = 0
westeast = 0
altitude = 0
time = 0
latitude = 0
longitude = 0
global counter
global trigger
gps = serial.Serial('/dev/ttyAMA0', 9600, timeout=1) # open serial for GPS
gps.write("$PUBX,00*33\n") # reuest a PUBX sentence
NMEA_sentence = gps.readline() # read GPS
print NMEA_sentence
end_time = millis() + 5000 # create an end time for while loop timeout
while not NMEA_sentence.startswith("$PUBX") and millis() < end_time: # while not got good sentence and not timed out
gps.write("$PUBX,00*33\n") # request a PUBX sentence
NMEA_sentence = gps.readline() # re-read ready for re-looping
print "Still Bad Sentence"
time.sleep(1)
if NMEA_sentence.startswith("$PUBX"): # if we got a PUBX sentence
gps.close() # close serial
print NMEA_sentence
data = NMEA_sentence.split(",") # split sentence into individual fields
if data[18] == "0": # if it does start with a valid sentence but with no fix
print "No Lock"
pass
else: # if it does start with a valid sentence and has a fix
# parsing required telemetry fields
satellites = data[18]
lats = data[3]
northsouth = data[4]
lngs = data[5]
westeast = data[6]
altitude = int(float(data[7]))
raw_time = data[2]
if time_set == False:
set_time(raw_time)
time = float(raw_time)
string = "%06i" % time # creating a string out of time (this format ensures 0 is included at start if any)
hours = string[0:2]
minutes = string[2:4]
seconds = string[4:6]
time = str(str(hours) + ':' + str(minutes) + ':' + str(seconds)) # the final time string in form 'hh:mm:ss'
latitude = convert(lats, northsouth)
longitude = convert(lngs, westeast)
# the data fields below can be sent when no lock from GPS
callsign = "Wonderworks-PP"
if altitude >= 29500 and trigger == False: # if altitude is more than 29800
#os.system('sudo /home/pi/leds.py &') # command to trigger LED script
#os.system('sudo /home/pi/motor.py &') # command to trigger LED script
trigger = True
string = str(callsign + ',' + str(time) + ',' + str(counter) + ',' + str(latitude) + ',' + str(longitude) + ',' + str(satellites) + ',' + str(trigger) + ',' + str(altitude)) # the data string
csum = str(hex(crc16f(string))).upper()[2:] # running the CRC-CCITT checksum
csum = csum.zfill(4) # creating the checksum data
datastring = str("$$" + string + "*" + csum + "\n") # appending the datastring as per the UKHAS communication protocol
counter += 1 # increment the sentence ID for next transmission
print "now sending the following:", datastring
send(datastring) # send the datastring to the send function to send to the NTX2
# function to convert latitude and longitude into a different format
def convert(position_data, orientation):
decs = ""
decs2 = ""
for i in range(0, position_data.index('.') - 2):
decs = decs + position_data[i]
for i in range(position_data.index('.') - 2, len(position_data) - 1):
decs2 = decs2 + position_data[i]
position = float(decs) + float(str((float(decs2)/60))[:8])
if orientation == ("S") or orientation == ("W"):
position = 0 - position
return position
while True:
GPS = serial.Serial('/dev/ttyAMA0', 9600, timeout=1) # open serial
GPS.flush() # wait for bytes to be physically read from the GPS
sendUBX(setNav, len(setNav)) # send command to enable flightmode
sendUBX(setNMEA_off, len(setNMEA_off)) # turn NMEA sentences off
GPS.flush()
GPS.close() # close the serial
read_gps() # run the read_gps function to get the data and parse it with status of flightmode