HardWare/MobileNode/Programming: uav_guided_mode.py

File uav_guided_mode.py, 7.6 KB (added by rmarmav, 21 months ago)

Source file for sample APP 2

Line 
1#!/usr/bin/python
2
3"""
4This program reads the RAW GPS readings from a file every INTERVAL seconds, converts them to GPS coordinates and directs the uav to traverse to those. After all the waypoints are traversed, it sets the UAV to RTL mode.
5"""
6import re
7import sys, os
8import socket
9import select
10import time
11
12sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '../lib'))
13
14import mavlink_apm, FTL_util
15
16INTERVAL = 5
17MAX_SIZE = 1024
18
19# Following are used for converting RAW GPS data into GPS coordinates
20raw_int_to_float_lat_lon = 10**7
21raw_int_to_float_alt = 10**3
22
23# Object used for accessing utility functions
24FTL_util_obj = FTL_util.FTL_util()
25
26""" This function sets the next waypoint the UAV has to traverse to"""
27def send_wp (mav_obj, mavproxy_sock, latitude, longitude,altitude,
28                        address_of_mavproxy):
29    global MAX_SIZE, INTERVAL
30    # A simpler way of assigning would be a,b,c,d = p1,p2,p3,p4. But for
31    # readability sake, we stick with the usual assignment
32    target_system = target_component = 1
33    seq = 0
34    #frame = mavlink_apm.MAV_FRAME_GLOBAL_RELATIVE_ALT
35    frame = mavlink_apm.MAV_FRAME_GLOBAL
36    command = mavlink_apm.MAV_CMD_NAV_WAYPOINT
37     # signifies whether this is the current waypoint to proceed to,
38     # any positive value is true
39    current = 2
40    autocontinue = 1 # continue to next waypoint
41    param1 = param2 = param3 = param4 = PARAM_IGNORE = 0
42
43    # Send the waypoint message and wait till the ACK is received for 2 seconds
44    list_read_sockets = [mavproxy_sock]
45    list_write_sockets = list_error_sockets = []
46    while 1:
47        msg = mav_obj.mission_item_encode(target_system, target_component,seq,frame,command,current,autocontinue,param1,param2,param3,param4,latitude,longitude,altitude-584.0)
48        try:
49            mavproxy_sock.sendto(msg.get_msgbuf(),(address_of_mavproxy))
50        except socket.error as v:
51            print "Exception when setting WP:"
52            print os.strerror(v.errno)
53            time.sleep(1)
54            continue
55        readable, writable, error = select.select(list_read_sockets,
56                              list_write_sockets,
57                              list_error_sockets,INTERVAL)
58        if readable:
59            data_from_mavproxy,address_of_mavproxy = mavproxy_sock.recvfrom (MAX_SIZE)
60            decoded_message = mav_obj.decode(data_from_mavproxy)
61            msg_id = decoded_message.get_msgId()
62
63            # Check if this is a waypoint request message
64            if msg_id == mavlink_apm.MAVLINK_MSG_ID_MISSION_ACK:
65                print 'ACK for this way-point received received...'
66                break
67            else:
68                #print "Expected message ID 47, received %d" % msg_id
69                continue
70        else:
71            # Send the message again
72            print "Timeout on receiving waypoint ACK message"
73            continue
74   
75    return
76
77""" This function parses the RAW GPS data and returns latitude, longitude
78and altitude"""
79def parse_gps_info(gps_info):
80    latitude = longitude = altitude = 0
81    # Get Latitude
82    match_for_latitude =  re.search(r'lat : (.+?),',gps_info)
83    if not match_for_latitude:
84        print "Error - no latitude information found, return!"
85        return 0,0,0
86    else:
87        latitude = match_for_latitude.group(1) 
88
89    # Get longitude
90    match_for_longitude =  re.search(r'lon : (.+?),',gps_info)
91    if not match_for_longitude:
92        print "Error - no longitude information found, return!"
93        return 0,0,0
94    else:
95        longitude = match_for_longitude.group(1) 
96
97    # Get altitude
98    match_for_altitude =  re.search(r'alt : (.+?),',gps_info)
99    if not match_for_altitude:
100        print "Error - no altitude information found, return!"
101        return 0,0,0
102    else:
103        altitude = match_for_altitude.group(1)
104
105    return latitude, longitude, altitude
106
107""" This function is invoked to obtain the  address of MAVProxy"""
108def get_mavproxy_address (mav_obj,mavproxy_sock):
109    MAX_SIZE = 1024
110    heartbeat_received = 'False'
111    mavproxy_sock.setblocking(1)
112    print "Waiting for heartbeat message..."
113    while not heartbeat_received.lower() == 'TRUE'.lower():
114        # Wait for heartbeat message to get the remote address
115        # used by MAVProxy
116        try:
117            data_from_mavproxy,address_of_mavproxy = mavproxy_sock.recvfrom (MAX_SIZE)
118        except socket.error as v:
119            print "Exception when trying to obtain address of MAVProxy"
120            print os.strerror(v.errno)
121        decoded_message = mav_obj.decode(data_from_mavproxy)
122        msg_id = decoded_message.get_msgId()
123        if msg_id == mavlink_apm.MAVLINK_MSG_ID_HEARTBEAT:
124            # Undo the change made
125            heartbeat_received = 'True'
126            print 'Got the address of MAV,  proceeding..'
127            print address_of_mavproxy
128            mavproxy_sock.setblocking(0)
129    return address_of_mavproxy
130
131""" The main function """
132def main():
133    global MAX_SIZE, raw_int_to_float_lat_lon, raw_int_to_float_alt
134    file_handle = ""
135
136    if len(sys.argv) != 3:
137        print "Usage: ./uav_guided_mode.py <MAVProxy port> <path to file with GPS info>"
138        sys.exit(1)
139    mavproxy_port = int(sys.argv[1])
140    file_name_with_gps_info = sys.argv[2]
141    # Check if the file exists
142    if not os.path.exists(file_name_with_gps_info):
143        print "File name %s does not exist" % file_name_with_gps_info
144        sys.exit(1)
145
146    # Check if the file is not empty
147    if not (os.path.getsize(file_name_with_gps_info) > 0):
148        print "File %s is empty" % file_name_with_gps_info
149        sys.exit(1)
150   
151    try:
152        HOST = '' # Listen on all interfaces
153        # Create a server socket for MAVProxy
154        mavproxy_sock = socket.socket (socket.AF_INET,socket.SOCK_DGRAM)
155        mavproxy_sock.setblocking(0)
156        print 'created UDP socket for MAVProxy'
157        mavproxy_sock.bind((HOST,mavproxy_port))
158        print 'Binding socket for MAVProxy connection'
159        # Create the mavproxy object
160        mav_obj = mavlink_apm.MAVLink (mavproxy_sock)
161
162        # Get the address used by MAVProxy
163        address_of_mavproxy = get_mavproxy_address (mav_obj, mavproxy_sock)
164
165        # ARM the UAV
166        component_id = mavlink_apm.MAV_COMP_ID_SYSTEM_CONTROL
167        # Same command for arming or disarming, arm_flag controls whether the UAV
168        # armed or disarmed. arm_flag=1->arm, arm_flag=0->disarm
169        command = mavlink_apm.MAV_CMD_COMPONENT_ARM_DISARM
170        arm_flag = 1
171        # Number of confirmations needed for this command. 0 means immediately
172        confirmation = 0
173        # Other parameters are ignored by this command and are to be set to zero.
174        PARAM_IGNORE = 0
175        msg = mav_obj.command_long_encode (1,component_id,command,confirmation,
176                                          arm_flag,PARAM_IGNORE,PARAM_IGNORE,
177                                          PARAM_IGNORE,PARAM_IGNORE,PARAM_IGNORE,
178                                          PARAM_IGNORE)
179        try:
180            mavproxy_sock.sendto(msg.get_msgbuf(),(address_of_mavproxy))
181        except socket.error as v:
182            print "Exception when trying to ARM the copter:"
183            print os.strerror(v.errno)
184        print "ARMED"
185        file_handle = open(file_name_with_gps_info, 'r')
186
187        # For each line which represents raw GPS data, generate and set a waypoint     
188        for line in file_handle:
189            # Skip empty lines
190            if line not in ['\n','\r\n']:
191                latitude, longitude, altitude = parse_gps_info(line)
192                # Filter unexpected values
193                if not longitude or not latitude or not altitude:
194                    print "Erroneous values, skip.."
195                    continue
196                latitude = float(latitude)/raw_int_to_float_lat_lon
197                longitude = float(longitude)/raw_int_to_float_lat_lon
198                altitude = float(altitude)/raw_int_to_float_alt
199                send_wp (mav_obj, mavproxy_sock, latitude,longitude,
200                                altitude,address_of_mavproxy)
201                # Sleep for INTERVAL seconds
202                time.sleep(float(INTERVAL))
203       
204        return_status = FTL_util_obj.set_mav_mode(FTL_util_obj.rtl_mode,mav_obj, 
205                                                mavproxy_sock, address_of_mavproxy)
206        if return_status < 0:
207            print "Error while setting mode, please check the parameters passed..."
208            sys.exit(1)
209               
210    except Exception as ex:
211        template = "An exception of type {0} occured. Arguments:\n{1!r}"
212        message = template.format(type(ex).__name__, ex.args)
213        print message
214        sys.exit(1)
215
216    if file_handle:
217        file_handle.close()
218
219if __name__ == '__main__':
220    main()