HardWare/MobileNode/Programming: FTL_util.py

File FTL_util.py, 4.4 KB (added by rmarmav, 21 months ago)

Utility module for the sample applications

Line 
1#!/usr/bin/python
2"""
3This module has the utility functions required by both leader and follower.
4These include common functionality like obtaining a mode from heartbeat message.
5"""
6import re, sys, os, socket, select, time
7
8import mavlink_apm
9
10class FTL_util:
11    dict_mode_names = {}
12    # mode names for APM
13    # We can save this in the following way: x1,x2,x3 = A,B,C. But for
14    # readability sake, we stick to this format
15    stabilize_mode = 'STABILIZE'
16    auto_mode = 'AUTO'
17    guided_mode = 'GUIDED'
18    rtl_mode = 'RTL'
19    land_mode = 'LAND'
20    of_loiter_mode = 'OF_LOITER'
21    alt_hold_mode = 'ALT_HOLD'
22    loiter_mode = 'LOITER'
23    position_mode = 'POSITION'
24    circle_mode = 'CIRCLE'
25    approach_mode = 'APPROACH'
26    acro_mode = 'ACRO'
27    MAX_SIZE = 1024
28    """Constructor for the class. Takes nothing as argument and initializes
29        the dictionary mapping for <custom_mode>->mode name"""
30    def __init__(self):
31        self.dict_mode_names[0] = self.stabilize_mode
32        self.dict_mode_names[1] = self.acro_mode
33        self.dict_mode_names[2] = self.alt_hold_mode
34        self.dict_mode_names[3] = self.auto_mode
35        self.dict_mode_names[4] = self.guided_mode
36        self.dict_mode_names[5] = self.loiter_mode
37        self.dict_mode_names[6] = self.rtl_mode
38        self.dict_mode_names[7] = self.circle_mode
39        self.dict_mode_names[8] = self.position_mode
40        self.dict_mode_names[9] = self.land_mode
41        self.dict_mode_names[10] = self.of_loiter_mode
42        self.dict_mode_names[11] = self.approach_mode
43
44    """Destructor for the class, we do nothing here """
45    def __del__(self):
46        pass
47
48    """Internal function: Given the base mode and custom mode, this
49    function function returns the string for relevant mode. We are doing
50    this as a different function as we may need to add some functionality
51    here later.
52    UPDATE: We are currently using only the custom_mode. We may update
53    this part if the custom_mode is found to be insufficient"""
54    def __return_mav_mode__(self, base_mode, custom_mode):
55        if (custom_mode) in self.dict_mode_names:
56            return self.dict_mode_names[custom_mode]
57        else:
58            return ""
59   
60    """ Internal function to get the custom_mode corresponding to a string.
61        If mode is not found, returns -1 """
62    def __return_custom_mode__(self, mode_str):
63        # Get the value of custom_mode corresponding to the string passed
64        for key,value in self.dict_mode_names.items():
65            if value == mode_str:
66                return key
67        return -1
68       
69    """ Function that receives the mode as a string and sets the mode.
70        Returns 0 on success, -1 on failure"""
71    def set_mav_mode(self,mode_str,mav_obj,mavproxy_sock,address_of_mavproxy):
72        custom_mode = self.__return_custom_mode__(mode_str)
73
74        # Basic error checking
75        if custom_mode == -1 or not mav_obj or not mavproxy_sock or not address_of_mavproxy:
76            return -1
77        msg = mav_obj.set_mode_encode(1, 1, custom_mode)
78        list_read_sockets = [mavproxy_sock]
79        list_write_sockets = list_error_sockets = []
80        # Do not proceed until the MAV is set to the given mode
81        while 1:
82            try:
83                mavproxy_sock.sendto(msg.get_msgbuf(),(address_of_mavproxy))
84                data_from_mavproxy,address_of_mavproxy = mavproxy_sock.recvfrom (self.MAX_SIZE)
85            except socket.error as v:
86                print "Exception when trying to set AUTO mode:"
87                print os.strerror(v.errno)
88                time.sleep(1)
89                continue
90
91            decoded_message = mav_obj.decode(data_from_mavproxy)
92            msg_id = decoded_message.get_msgId()
93            # we are interested only if this is the heartbeat
94            if msg_id == mavlink_apm.MAVLINK_MSG_ID_HEARTBEAT:
95                # Get the mode from the message
96                mode = self.get_mav_mode(str(decoded_message))
97                if mode.lower() == mode_str.lower():
98                    print "Mode set as expected"
99                    return 0
100                else:
101                    continue
102
103       
104    """ Function that receives the heartbeat message as a string
105        and extracts base_mode and custom_mode."""
106    def get_mav_mode (self, heartbeat_message):
107        print "heartbeat message is %s" % heartbeat_message
108        # Get base_mode
109        match_for_base_mode =  re.search(r'base_mode : (.+?),',heartbeat_message)
110        if not match_for_base_mode:
111            print "Error - no base_mode found, return!"
112            return ""
113        else:
114           base_mode = match_for_base_mode.group(1) 
115
116        # Get custom_mode
117        match_for_custom_mode =  re.search(r'custom_mode : (.+?),',heartbeat_message)
118        if not match_for_custom_mode:
119            print "Error - no custom_mode found, return!"
120            return ""
121        else:
122           custom_mode = match_for_custom_mode.group(1)
123        return self.__return_mav_mode__(int(base_mode),int(custom_mode))