| 1 | #!/usr/bin/python |
|---|
| 2 | |
|---|
| 3 | """ |
|---|
| 4 | This program sets the UAV in AUTO mode. It reads the GPS information and |
|---|
| 5 | writes the most recent entry to a file. This entry is read by the CentMesh |
|---|
| 6 | sensing APP which saves it to a server. |
|---|
| 7 | """ |
|---|
| 8 | import re, sys, os, socket, select, time |
|---|
| 9 | import tempfile |
|---|
| 10 | from datetime import datetime |
|---|
| 11 | |
|---|
| 12 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '../lib')) |
|---|
| 13 | |
|---|
| 14 | import mavlink_apm, FTL_util |
|---|
| 15 | |
|---|
| 16 | # The following will be used in figuring out when to print GPS info |
|---|
| 17 | INTERVAL = 5 |
|---|
| 18 | new_time = current_time = datetime.now() |
|---|
| 19 | |
|---|
| 20 | #This sample application writes the current GPS reading to this file, |
|---|
| 21 | # overwriting the previous entry. This file is used by sensor application |
|---|
| 22 | file_gps_data_for_sensing_app = "/tmp/gps_data" |
|---|
| 23 | |
|---|
| 24 | # Object used for accessing utility functions |
|---|
| 25 | FTL_util_obj = FTL_util.FTL_util() |
|---|
| 26 | |
|---|
| 27 | MAX_SIZE = 1024 |
|---|
| 28 | """Utility function: checks if the given filename exists and warns the user |
|---|
| 29 | if there exists one""" |
|---|
| 30 | def check_file_name_exists(file_name_provided): |
|---|
| 31 | if os.path.exists(file_name_provided): |
|---|
| 32 | print "The provided file name %s exists. Do you wish to overwrite it?(y/n)" % file_name_provided |
|---|
| 33 | while 1: |
|---|
| 34 | data = sys.stdin.readline() |
|---|
| 35 | if not data.lower() == 'y\n'.lower() and not data.lower() == 'n\n'.lower(): |
|---|
| 36 | print 'Please enter \"y\" or \"n\"' |
|---|
| 37 | continue |
|---|
| 38 | elif data.lower() == 'n': |
|---|
| 39 | print "Quitting..please try again" |
|---|
| 40 | sys.exit(1) |
|---|
| 41 | else: |
|---|
| 42 | with open(file_name_provided, "w") as file_reference: |
|---|
| 43 | file_reference.close() |
|---|
| 44 | break |
|---|
| 45 | |
|---|
| 46 | """ Print GPS info, this function is invoked every time a hearbeat message |
|---|
| 47 | is received. The function saves only if the last 'save' has happened |
|---|
| 48 | atleast 5 seconds ago. |
|---|
| 49 | Independent of this save, the value is written to a temporary file |
|---|
| 50 | /tmp/gps_data. This file is used by the sensing application""" |
|---|
| 51 | def save_gps_info (decoded_message, file_gps_info): |
|---|
| 52 | global current_time, new_time, last_gps_info_saved, FTL_util_obj, MAX_SIZE |
|---|
| 53 | global file_gps_data_for_sensing_app |
|---|
| 54 | last_gps_info_saved = str(decoded_message) |
|---|
| 55 | with tempfile.NamedTemporaryFile( |
|---|
| 56 | 'w', dir=os.path.dirname(file_gps_data_for_sensing_app), delete=False) as tf: |
|---|
| 57 | tf.write(last_gps_info_saved) |
|---|
| 58 | tempname = tf.name |
|---|
| 59 | os.rename(tempname, file_gps_data_for_sensing_app) |
|---|
| 60 | |
|---|
| 61 | # Check if we need to save it to the provided file name |
|---|
| 62 | new_time = datetime.now() |
|---|
| 63 | if (new_time - current_time).seconds >= int(INTERVAL): |
|---|
| 64 | print "Time to save!!!!" |
|---|
| 65 | with open(file_gps_info, "a") as file_reference: |
|---|
| 66 | file_reference.write("\n" + str(decoded_message)) |
|---|
| 67 | file_reference.close() |
|---|
| 68 | # Update the current timers |
|---|
| 69 | current_time = new_time |
|---|
| 70 | |
|---|
| 71 | """ Get address of MAVProxy """ |
|---|
| 72 | def get_mavproxy_address (mav_obj,mavproxy_sock): |
|---|
| 73 | heartbeat_received = 'False' |
|---|
| 74 | mavproxy_sock.setblocking(1) |
|---|
| 75 | print "Waiting for heartbeat message..." |
|---|
| 76 | while not heartbeat_received.lower() == 'TRUE'.lower(): |
|---|
| 77 | # Wait for heartbeat message to get the remote address |
|---|
| 78 | # used by MAVProxy |
|---|
| 79 | try: |
|---|
| 80 | data_from_mavproxy,address_of_mavproxy = mavproxy_sock.recvfrom (MAX_SIZE) |
|---|
| 81 | except socket.error as v: |
|---|
| 82 | print "Exception when trying to obtain address of MAVProxy" |
|---|
| 83 | print os.strerror(v.errno) |
|---|
| 84 | decoded_message = mav_obj.decode(data_from_mavproxy) |
|---|
| 85 | msg_id = decoded_message.get_msgId() |
|---|
| 86 | if msg_id == mavlink_apm.MAVLINK_MSG_ID_HEARTBEAT: |
|---|
| 87 | # Undo the change made |
|---|
| 88 | heartbeat_received = 'True' |
|---|
| 89 | print 'Got the address of MAV, proceeding..' |
|---|
| 90 | print address_of_mavproxy |
|---|
| 91 | mavproxy_sock.setblocking(0) |
|---|
| 92 | return address_of_mavproxy |
|---|
| 93 | |
|---|
| 94 | """ The main function """ |
|---|
| 95 | def main(): |
|---|
| 96 | # Use the global values for MAX_SIZE and INTERVAL |
|---|
| 97 | global MAX_SIZE, INTERVAL |
|---|
| 98 | file_gps_info = "" |
|---|
| 99 | if len(sys.argv) != 3: |
|---|
| 100 | print "Usage: ./uav_auto_mode.py <MAVProxy port> <File_to_save_GPS_info>" |
|---|
| 101 | sys.exit(1) |
|---|
| 102 | |
|---|
| 103 | mavproxy_port = int(sys.argv[1]) |
|---|
| 104 | print "MAVProxy port is %d" % mavproxy_port |
|---|
| 105 | file_gps_info = sys.argv[2] |
|---|
| 106 | try: |
|---|
| 107 | HOST = '' |
|---|
| 108 | # Create a server socket for MAVProxy |
|---|
| 109 | mavproxy_sock = socket.socket (socket.AF_INET,socket.SOCK_DGRAM) |
|---|
| 110 | print 'created UDP socket for MAVProxy' |
|---|
| 111 | mavproxy_sock.setblocking(0) |
|---|
| 112 | mavproxy_sock.bind((HOST,mavproxy_port)) |
|---|
| 113 | print 'Binding socket for MAVProxy connection' |
|---|
| 114 | # Create the mavproxy object |
|---|
| 115 | mav_obj = mavlink_apm.MAVLink (mavproxy_sock) |
|---|
| 116 | |
|---|
| 117 | except Exception as ex: |
|---|
| 118 | template = "An exception of type {0} occured. Arguments:\n{1!r}" |
|---|
| 119 | message = template.format(type(ex).__name__, ex.args) |
|---|
| 120 | print message |
|---|
| 121 | sys.exit(1) |
|---|
| 122 | |
|---|
| 123 | # File name check |
|---|
| 124 | check_file_name_exists(file_gps_info) |
|---|
| 125 | |
|---|
| 126 | #Get the address of mavproxy |
|---|
| 127 | address_of_mavproxy = get_mavproxy_address (mav_obj, mavproxy_sock) |
|---|
| 128 | return_status = FTL_util_obj.set_mav_mode(FTL_util_obj.auto_mode,mav_obj, |
|---|
| 129 | mavproxy_sock, address_of_mavproxy) |
|---|
| 130 | if return_status < 0: |
|---|
| 131 | print "Error while setting mode, please check the parameters passed..." |
|---|
| 132 | sys.exit(1) |
|---|
| 133 | # ARM the UAV |
|---|
| 134 | component_id = mavlink_apm.MAV_COMP_ID_SYSTEM_CONTROL |
|---|
| 135 | # Same command for arming or disarming, arm_flag controls whether the UAV |
|---|
| 136 | # armed or disarmed. arm_flag=1->arm, arm_flag=0->disarm |
|---|
| 137 | command = mavlink_apm.MAV_CMD_COMPONENT_ARM_DISARM |
|---|
| 138 | arm_flag = 1 |
|---|
| 139 | # Number of confirmations needed for this command. 0 means immediately |
|---|
| 140 | confirmation = 0 |
|---|
| 141 | # Other parameters are ignored by this command and are to be set to zero. |
|---|
| 142 | PARAM_IGNORE = 0 |
|---|
| 143 | msg = mav_obj.command_long_encode (1,component_id,command,confirmation, |
|---|
| 144 | arm_flag,PARAM_IGNORE,PARAM_IGNORE, |
|---|
| 145 | PARAM_IGNORE,PARAM_IGNORE,PARAM_IGNORE, |
|---|
| 146 | PARAM_IGNORE) |
|---|
| 147 | try: |
|---|
| 148 | mavproxy_sock.sendto(msg.get_msgbuf(),(address_of_mavproxy)) |
|---|
| 149 | except socket.error as v: |
|---|
| 150 | print "Exception when trying to ARM the copter:" |
|---|
| 151 | print os.strerror(v.errno) |
|---|
| 152 | print "ARMED" |
|---|
| 153 | |
|---|
| 154 | # 'Listen' passively for messages from MAVProxy and filter |
|---|
| 155 | # messages with GPS information. |
|---|
| 156 | list_read_sockets = [mavproxy_sock] |
|---|
| 157 | list_write_sockets = [] |
|---|
| 158 | list_error_sockets = [] |
|---|
| 159 | while 1: |
|---|
| 160 | readable, writable, error = select.select(list_read_sockets, |
|---|
| 161 | list_write_sockets, |
|---|
| 162 | list_error_sockets, |
|---|
| 163 | int(INTERVAL)) |
|---|
| 164 | if readable: |
|---|
| 165 | # print "Data received from MAVProxy!!!!" |
|---|
| 166 | data_from_mavproxy,address_of_mavproxy = mavproxy_sock.recvfrom (MAX_SIZE) |
|---|
| 167 | decoded_message = mav_obj.decode(data_from_mavproxy) |
|---|
| 168 | msg_id = decoded_message.get_msgId() |
|---|
| 169 | # Check if this information is GPS information. |
|---|
| 170 | if msg_id == mavlink_apm.MAVLINK_MSG_ID_GPS_RAW_INT: |
|---|
| 171 | save_gps_info(decoded_message, file_gps_info) |
|---|
| 172 | else: |
|---|
| 173 | print 'select() timeout, continue...' |
|---|
| 174 | continue |
|---|
| 175 | |
|---|
| 176 | if __name__ == '__main__': |
|---|
| 177 | main() |
|---|