コード例 #1
0
class RadioSubsystem(threading.Thread):
    """
    Threaded UAV radio subsystem.

    Enables threaded operation of radio.

    """
    def __init__(self, knowledge_base, lock, callback):
        """
        Extend threading class.

        Parameters
        ----------
        knowledge_base : object
            Handle to shared knoweldge base.
        lock : object
            File lock for concurrent access to knowledge base.
        initial_config : dict
            Initial radio configuration

        """
        threading.Thread.__init__(self)

        self.kb = knowledge_base
        self.lock = lock
        self.controller_callback = callback

        self.stop_event = threading.Event()

        self.data = NodeAData()
        self.packet = Packet('A')
        self.radio = RadioAPI()

        self._fsm_state = 'listen'
        self.radio_command = 'continue'
        self.tx_packet_number = 1

        self.ack_packet_number = 0
        self.goodput = 0

    def _configure_radio(self, power, frequency, data_rate, modulation):
        """
        Configure radio for operation.

        """
        self.radio.configure_radio(power, frequency, data_rate, modulation)

    def _send_packet(self):
        """
        Transmit packet.

        """
        self.packet.set_flags_node_a()
        location = self.kb.get_state()['current_location']
        data = self.data.pack_data()
        tx_packet = self.packet.make_packet(self.tx_packet_number, location,
                                            data)
        # self.tic = time.time()
        self.radio.transmit(tx_packet)

    def _receive_packet(self):
        """
        Receive packet.

        """
        # print "processing latency = %f" %(time.time() - self.tic,)
        self.rx_packet = self.radio.receive(rx_fifo_threshold=64, timeout=0.8)
        if self.rx_packet == []:  # this occurs when timeout has been exceeded
            # print "timeout exceeded"
            return
        else:
            rx_packet_number, time_stamp, location, flags, data = self.packet.parse_packet(
                self.rx_packet)
            self.ack_packet_number, self.goodput = self.data.unpack_data(data)
            if DEBUG:
                pass
                # print "rx_packet_number=%d  time_stamp=%f  location=%d  flags=0x%x" %(rx_packet_number,
                #                                                                       time_stamp,
                #                                                                       location,
                #                                                                       flags)
                # print "goodput for acknowledged packet #%d = %f bits/second" %(self.ack_packet_number,
                #                                                                self.goodput)

    def _listen(self):
        """
        Listen before talk.

        """
        status = self.radio.listen(rssi_threshold=100, timeout=1.0)
        if status == 'clear':
            if DEBUG:
                print "channel clear"
            else:
                pass

    def _fsm(self):
        self._listen()
        time.sleep(0.01)
        self._send_packet()
        time.sleep(0.01)
        self._receive_packet()
        time.sleep(0.01)

    def control_radio_operation(self, command):
        """
        Control radio operation.

        This function provides a method of controlling operation of the
        radio.

        Parameters
        ----------
        command : str
            One of {`pause` | `continue` | `reconfigure` | ... }

        """
        self.radio_command = command

    def run(self):
        """
        Run the radio subsystem.

        """
        print "Starting radio subsystem"

        self.radio.startup()
        default_radio_profile = self.kb.get_state()['default_radio_profile']
        power = default_radio_profile['power']
        frequency = default_radio_profile['frequency']
        data_rate = default_radio_profile['data_rate']
        modulation = default_radio_profile['modulation']
        self._configure_radio(power, frequency, data_rate, modulation)

        while not self.stop_event.isSet():

            if self.radio_command == 'continue':
                self._fsm()
                if not self.rx_packet == []:
                    self.controller_callback(self.tx_packet_number,
                                             self.ack_packet_number,
                                             self.goodput)
                    # self.lock.acquire()
                    # self.kb.sent_packets.append(self.tx_packet_number)
                    # self.kb.ack_packets.append((self.ack_packet_number, self.goodput))
                    # self.lock.release()
                self.tx_packet_number += 1

            elif self.radio_command == 'pause':
                time.sleep(0.01)
                continue

            elif self.radio_command == 'reconfigure':
                pass

    def join(self, timeout=None):
        """
        Stop radio subsystem.

        """
        self.stop_event.set()
        self.radio.shutdown()
        threading.Thread.join(self, timeout)
コード例 #2
0
class RadioSubsystem(threading.Thread):
    """
    Threaded UAV radio subsystem.

    Enables threaded operation of radio.

    """
    def __init__(self, update_flag, update_data, reconfig_flag):
        """
        Extend threading class.

        Parameters
        ----------
        callback : obj
            Callback for controller, relays data from rf subsystem to
            controller

        """
        threading.Thread.__init__(self)

        self.update_flag = update_flag
        self.update_data = update_data
        self.reconfig_flag = reconfig_flag

        self.stop_event = threading.Event()

        self.data = NodeAData()
        self.packet = Packet('A')
        self.radio = RadioAPI()

        self.last_state = 'stop'
        self.current_state = 'stop'
        self.current_location = 1

        self.tx_packet_number = 1

        self.cw_rssi = []

    def set_state(self, current_state):
        """
        Set state of rf subsystem finite state machine.

        This function provides a method of cotrolling operation of the
        RF subsystem.

        Parameters
        ----------
        state : str
            One of {`stop` | `stream` | `update` | `reconfigure` | `listen`}

        """
        if current_state not in [
                'stop', 'stream', 'update', 'reconfigure', 'listen'
        ]:
            print "State error: `current_state` must be one of"
            print "{`stop` | `stream` | `update` | `reconfigure` | `listen`}."
            raise ValueError
        self.current_state = current_state

    def run(self):
        """
        Run the radio subssytem.

        Start the threaded radio subsystem using `RadioSubsystem.start()`.

        """

        self.radio.startup()

        index = 0
        rssi = []

        # TODO: record RSSI before every tranmission
        while not self.stop_event.isSet():

            ###################################################################
            if self.current_state == 'stop':
                if self.last_state == 'stop':
                    continue

                # `update` and `reconfigure` should stop on their own
                elif self.last_state == 'stream':
                    self.last_state = 'stop'
                    # logging.info("radio_subsystem::run: stop")
                    continue

                elif self.last_state == 'update':
                    self.last_state = 'stop'
                    # logging.info("radio_subsystem::run: stop")
                    continue

                elif self.last_state == 'reconfigure':
                    self.last_state = 'stop'
                    # logging.info("radio_subsystem::run: stop")
                    continue

                elif self.last_state == 'listen':
                    self.last_state = 'stop'
                    print "\n\n\n"
                    print self.cw_rssi
                    print "\n\n\n"
                    self.cw_rssi = []
                    # logging.info("radio_subsystem::run: stop")
                    continue

                else:
                    # logging.debug("radio_subsystem::Error 1 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################

            ###################################################################
            elif self.current_state == 'stream':
                if self.last_state in ['stop', 'stream']:
                    self.last_state = 'stream'
                    # logging.info("radio_subsystem::run: stream")

                    self.radio.configure_radio(self.eirp, self.frequency,
                                               self.bitrate, self.modulation)
                    rssi.append(self.radio.get_rssi_dBm())
                    self._send_packet('stream_data')
                    index += 1

                    continue

                else:
                    # logging.debug("radio_subsystem::Error 2 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################

            ###################################################################
            elif self.current_state == 'update':
                if self.last_state == 'stop':
                    self.last_state = 'update'
                    # logging.info("radio_subsystem::run: update")

                    self.radio.configure_radio(self.eirp, self.frequency,
                                               self.bitrate, self.modulation)
                    self._send_packet('request_data')

                    pkt_num, loc, flags, data = self._receive_packet()
                    packets_received = self.data.unpack_data(data)

                    # logging.info("radio_subsystem::packets received by Node B = %d" %(packets_received,))
                    # logging.info("radio_subsystem::packets sent by Node A = %d" %(index,))

                    rssi = np.array(rssi)
                    rssi = np.mean(rssi)

                    self.update_data(tx_packets=index,
                                     rx_packets=packets_received,
                                     signal_strength=rssi)
                    self.update_flag(flag=True)

                    index = 0
                    rssi = []

                    self.current_state = 'stop'
                    continue

                else:
                    # logging.debug("radio_subsystem::Error 3 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################

            ###################################################################
            elif self.current_state == 'reconfigure':
                if self.last_state == 'stop':
                    self.last_state = 'reconfigure'
                    # logging.info("radio_subsystem::run: reconfigure")
                    self.radio.configure_radio(self.eirp, self.frequency,
                                               self.bitrate, self.modulation)
                    self._send_packet('send_reconfig_command',
                                      self.reconfig_mod, self.reconfig_eirp,
                                      self.reconfig_bitrate)

                    pkt_num, loc, flags, data = self._receive_packet()
                    # print pkt_num, loc, flags, data
                    if (flags & 0x04) == 0x04:
                        # logging.info("radio_subsystem::run: reconfigure acknowledged")
                        self.reconfig_flag(flag=True)
                        self.current_state = 'stop'
                        continue

                    else:
                        # logging.debug("radio_subsystem::Warning 1 in RadioSubsystem.run()")
                        # logging.debug("radio_subsystem::reconfig request not acknolwedged")
                        # logging.debug("radio_subsystem::flagse = 0x%x" %(flags,))
                        continue

                else:
                    # logging.debug("radio_subsystem::Error 4 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################

            ###################################################################
            elif self.current_state == 'listen':
                self.last_state = 'listen'

                self.radio.configure_radio(self.eirp, self.frequency,
                                           self.bitrate, self.modulation)
                self.cw_rssi.append(self.radio.get_rssi_raw())
                continue
            ###################################################################

            ###################################################################
            else:
                # logging.debug("radio_subsystem::Error 5 in RadioSubsystem.run()")
                # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                continue
            ###################################################################

    def _send_packet(self, mode, mod=None, eirp=None, bitrate=None):
        """
        Transmit data.

        Parameters
        ----------
        mode : str
            Mode of operation. Used to create appropriate packet header and payload.
            {`send_reconfig_command` | `request_data` | `stream_data`}.
        mod : str, opt
            Modulation, one of {`fsk` | `gfsk` | `ook` }.
        eirp : int, opt
            Transmit power, one of { 8 | 11 | 14 | 17 }.
        bitrate : float, opt
            Radio bitrate, one of {...}
            
        """

        if mode == 'stream_data':
            self.packet.set_flags_node_a(send_stream=True)
            payload = self.data.pack_data(mode)

        elif mode == 'send_reconfig_command':
            self.packet.set_flags_node_a(send_command=True)
            payload = self.data.pack_data(mode, mod, eirp, bitrate)

        elif mode == 'request_data':
            self.packet.set_flags_node_a(request_data=True)
            payload = self.data.pack_data(mode)

        else:
            print "error in _send_packet, no mode specified"
            raise ValueError

        tx_packet = self.packet.make_packet(self.tx_packet_number,
                                            self.current_location, payload)
        self.tx_packet_number += 1
        self.radio.transmit(tx_packet)
        # logging.info("packet sent")

    def _receive_packet(self):
        """
        Receive packet

        """
        (self.rssi_level, rx_packet) = self.radio.receive(rx_fifo_threshold=63,
                                                          timeout=None)
        # rx_packet = self.radio.receive(rx_fifo_threshold=64, timeout=None)
        pkt_num, t, loc, flags, data = self.packet.parse_packet(rx_packet)

        return pkt_num, loc, flags, data

    def set_current_location(self, current_location):
        """
        Set current location.

        Used by controller to tell radio subsytem the current physical
        location.

        Parameters
        ----------
        current_location : int
            Value of barcode representing current location.

        """

        self.current_location = current_location

    def set_config_packet_data(self, modulation, eirp, bitrate):
        """
        Set reconfig-packet data.

        This function is used by the controller to set the contents of
        the packet that is used in a reconfiguration request. NOTE:
        use this function to set the config packet data *before*
        sending a reconfiguration packet.

        """
        self.reconfig_mod = modulation
        self.reconfig_eirp = eirp
        self.reconfig_bitrate = bitrate

    def set_radio_configuration(self, modulation, eirp, bitrate, frequency):
        """
        Set radio configuration.

        This function is used by the controller to set the local radio
        configuration.

        Parameters
        ----------
        modulation : str
            Modulation, one of {`fsk` | `gfsk` | `ook` }.
        eirp : int
            Transmit power, one of { 8 | 11 | 14 | 17 }.
        bitrate : float
            Radio bitrate, one of {...}
        frequency : float
            Center frequency, this should be between 240.0e6 and 930.0e6.
         
        """
        self.modulation = modulation
        self.eirp = eirp
        self.bitrate = bitrate
        self.frequency = frequency

    def join(self, timeout=None):
        """
        Stop radio subsystem.

        """
        self.stop_event.set()
        self.radio.shutdown()
        threading.Thread.join(self, timeout)
コード例 #3
0
class RadioSubsystem(threading.Thread):
    """
    Threaded UAV radio subsystem.

    Enables threaded operation of radio.

    """

    def __init__(self, update_flag, update_data, reconfig_flag):
        """
        Extend threading class.

        Parameters
        ----------
        callback : obj
            Callback for controller, relays data from rf subsystem to
            controller

        """
        threading.Thread.__init__(self)

        self.update_flag = update_flag
        self.update_data = update_data
        self.reconfig_flag = reconfig_flag

        self.stop_event = threading.Event()
        
        self.data = NodeAData()
        self.packet = Packet('A')
        self.radio = RadioAPI()

        self.last_state = 'stop'
        self.current_state = 'stop'
        self.current_location = 1
        
        self.tx_packet_number = 1

        self.cw_rssi = []



    def set_state(self, current_state):
        """
        Set state of rf subsystem finite state machine.

        This function provides a method of cotrolling operation of the
        RF subsystem.

        Parameters
        ----------
        state : str
            One of {`stop` | `stream` | `update` | `reconfigure` | `listen`}

        """
        if current_state not in ['stop', 'stream', 'update', 'reconfigure', 'listen']:
            print "State error: `current_state` must be one of"
            print "{`stop` | `stream` | `update` | `reconfigure` | `listen`}."
            raise ValueError
        self.current_state = current_state




    def run(self):
        """
        Run the radio subssytem.

        Start the threaded radio subsystem using `RadioSubsystem.start()`.

        """

        self.radio.startup()

        index = 0
        rssi = []

        # TODO: record RSSI before every tranmission
        while not self.stop_event.isSet():

            ###################################################################
            if self.current_state == 'stop':
                if self.last_state == 'stop':
                    continue

                # `update` and `reconfigure` should stop on their own
                elif self.last_state == 'stream':  
                    self.last_state = 'stop'
                    # logging.info("radio_subsystem::run: stop")
                    continue
                

                elif self.last_state == 'update':  
                    self.last_state = 'stop'
                    # logging.info("radio_subsystem::run: stop")
                    continue


                elif self.last_state == 'reconfigure':  
                    self.last_state = 'stop'
                    # logging.info("radio_subsystem::run: stop")
                    continue



                elif self.last_state == 'listen':  
                    self.last_state = 'stop'
                    print "\n\n\n"
                    print self.cw_rssi
                    print "\n\n\n"
                    self.cw_rssi = []
                    # logging.info("radio_subsystem::run: stop")
                    continue


                else:
                    # logging.debug("radio_subsystem::Error 1 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################


            ###################################################################
            elif self.current_state == 'stream':
                if self.last_state in ['stop', 'stream']:
                    self.last_state = 'stream'
                    # logging.info("radio_subsystem::run: stream")

                    self.radio.configure_radio(self.eirp, self.frequency, self.bitrate, self.modulation)
                    rssi.append(self.radio.get_rssi_dBm())
                    self._send_packet('stream_data')
                    index += 1

                    continue

                else:
                    # logging.debug("radio_subsystem::Error 2 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################
                


            ###################################################################
            elif self.current_state == 'update':
                if self.last_state == 'stop':
                    self.last_state = 'update'
                    # logging.info("radio_subsystem::run: update")

                    self.radio.configure_radio(self.eirp, self.frequency, self.bitrate, self.modulation)
                    self._send_packet('request_data')

                    pkt_num, loc, flags, data = self._receive_packet()
                    packets_received = self.data.unpack_data(data)

                    # logging.info("radio_subsystem::packets received by Node B = %d" %(packets_received,))
                    # logging.info("radio_subsystem::packets sent by Node A = %d" %(index,))

                    rssi = np.array(rssi)
                    rssi = np.mean(rssi)

                    self.update_data(tx_packets=index, rx_packets=packets_received, signal_strength=rssi)
                    self.update_flag(flag=True)

                    index = 0
                    rssi = []

                    self.current_state = 'stop'
                    continue

                else:
                    # logging.debug("radio_subsystem::Error 3 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################
                    

            ###################################################################
            elif self.current_state == 'reconfigure':
                if self.last_state == 'stop':
                    self.last_state = 'reconfigure'
                    # logging.info("radio_subsystem::run: reconfigure")
                    self.radio.configure_radio(self.eirp, self.frequency, self.bitrate, self.modulation)
                    self._send_packet('send_reconfig_command', self.reconfig_mod,
                                      self.reconfig_eirp, self.reconfig_bitrate)

                    pkt_num, loc, flags, data = self._receive_packet()
                    # print pkt_num, loc, flags, data
                    if (flags & 0x04) == 0x04:
                        # logging.info("radio_subsystem::run: reconfigure acknowledged")
                        self.reconfig_flag(flag=True)
                        self.current_state = 'stop'
                        continue

                    else:
                        # logging.debug("radio_subsystem::Warning 1 in RadioSubsystem.run()")
                        # logging.debug("radio_subsystem::reconfig request not acknolwedged")
                        # logging.debug("radio_subsystem::flagse = 0x%x" %(flags,))
                        continue

                else:
                    # logging.debug("radio_subsystem::Error 4 in RadioSubsystem.run()")
                    # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                    # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                    continue
            ###################################################################


            ###################################################################
            elif self.current_state == 'listen':
                self.last_state = 'listen'

                self.radio.configure_radio(self.eirp, self.frequency, self.bitrate, self.modulation)
                self.cw_rssi.append(self.radio.get_rssi_raw())
                continue
            ###################################################################


            ###################################################################
            else:
                # logging.debug("radio_subsystem::Error 5 in RadioSubsystem.run()")
                # logging.debug("radio_subsystem::self.current_state == %s" %(self.current_state,))
                # logging.debug("radio_subsystem::last state == %s" %(self.last_state,))
                continue
            ###################################################################
                    






    def _send_packet(self, mode, mod=None, eirp=None, bitrate=None):
        """
        Transmit data.

        Parameters
        ----------
        mode : str
            Mode of operation. Used to create appropriate packet header and payload.
            {`send_reconfig_command` | `request_data` | `stream_data`}.
        mod : str, opt
            Modulation, one of {`fsk` | `gfsk` | `ook` }.
        eirp : int, opt
            Transmit power, one of { 8 | 11 | 14 | 17 }.
        bitrate : float, opt
            Radio bitrate, one of {...}
            
        """

        if mode == 'stream_data':
            self.packet.set_flags_node_a(send_stream=True)
            payload = self.data.pack_data(mode)

        elif mode == 'send_reconfig_command':
            self.packet.set_flags_node_a(send_command=True)
            payload = self.data.pack_data(mode, mod, eirp, bitrate)

        elif mode == 'request_data':
            self.packet.set_flags_node_a(request_data=True)
            payload = self.data.pack_data(mode)

        else:
            print "error in _send_packet, no mode specified"
            raise ValueError

        tx_packet = self.packet.make_packet(self.tx_packet_number, self.current_location, payload)
        self.tx_packet_number += 1
        self.radio.transmit(tx_packet)
        # logging.info("packet sent")


    def _receive_packet(self):
        """
        Receive packet

        """
        (self.rssi_level, rx_packet) = self.radio.receive(rx_fifo_threshold=63, timeout=None)
        # rx_packet = self.radio.receive(rx_fifo_threshold=64, timeout=None)
        pkt_num, t, loc, flags, data = self.packet.parse_packet(rx_packet)

        return pkt_num, loc, flags, data

                    
    def set_current_location(self, current_location):
        """
        Set current location.

        Used by controller to tell radio subsytem the current physical
        location.

        Parameters
        ----------
        current_location : int
            Value of barcode representing current location.

        """

        self.current_location = current_location


    def set_config_packet_data(self, modulation, eirp, bitrate):
        """
        Set reconfig-packet data.

        This function is used by the controller to set the contents of
        the packet that is used in a reconfiguration request. NOTE:
        use this function to set the config packet data *before*
        sending a reconfiguration packet.

        """
        self.reconfig_mod = modulation
        self.reconfig_eirp = eirp
        self.reconfig_bitrate = bitrate

            
    def set_radio_configuration(self, modulation, eirp, bitrate, frequency):
        """
        Set radio configuration.

        This function is used by the controller to set the local radio
        configuration.

        Parameters
        ----------
        modulation : str
            Modulation, one of {`fsk` | `gfsk` | `ook` }.
        eirp : int
            Transmit power, one of { 8 | 11 | 14 | 17 }.
        bitrate : float
            Radio bitrate, one of {...}
        frequency : float
            Center frequency, this should be between 240.0e6 and 930.0e6.
         
        """
        self.modulation = modulation
        self.eirp = eirp
        self.bitrate = bitrate
        self.frequency = frequency
        

    def join(self, timeout=None):
        """
        Stop radio subsystem.

        """
        self.stop_event.set()
        self.radio.shutdown()
        threading.Thread.join(self, timeout)