class Crubyflie::Crazyflie

This is the main entry point for interacting with a Crazyflie It allows to connect to the Crazyflie on the specified radio URL and make use of the different facilities: log, param, commander and console. Facilities are instantiated and packages delivered to their queues from here. For example, you can use the @crazyflie.commander.set_sendpoint() to send a new setpoint to a Crazyflie

Constants

CALLBACKS

Groups of callbacks available

Attributes

cache_folder[R]
callbacks[RW]
commander[R]
console[R]
crtp_queues[R]
log[R]
param[R]
radio_opts[R]

Public Class Methods

new(cache_folder=nil, radio_opts={}) click to toggle source

Initialize a Crazyflie by registering default received-packet callbacks and intializing Queues for every facility. Packets will be queued for each facility depending on their port @param cache_folder [String] folder path to store logging TOC cache

# File lib/crubyflie/crazyflie.rb, line 57
def initialize(cache_folder=nil, radio_opts={})
    @cache_folder = cache_folder
    # Callbacks will fire in some specific situations
    # Specially when receiving packages
    @callbacks = {}
    CALLBACKS.each do |cb|
        @callbacks[cb] = {}
    end
    register_default_callbacks()

    @crtp_queues = {}
    CRTP_PORTS.keys().each do |k|
        @crtp_queues[k] = Queue.new
    end

    # Thread that regularly checks for packages
    @receive_packet_thread = nil
    @retry_packets_thread = nil

    # A hash with keys "port_<portnumber>"
    @retry_packets = {}

    @commander = Commander.new(self)
    @console   = Console.new(self)
    @param     = Param.new(self)
    @log       = Log.new(self)

    @link = nil
    @radio_opts = radio_opts
end

Public Instance Methods

active?() click to toggle source

Checks if there is an open link @return [TrueClass, FalseClass] true if there is an open link

# File lib/crubyflie/crazyflie.rb, line 134
def active?
    return !@link.nil?
end
scan_interface() click to toggle source

Calls RadioDriver::scan_interface() @return [Array] List of radio URIs where a crazyflie was found

# File lib/crubyflie/crazyflie.rb, line 140
def scan_interface
    if @link
        logger.error "Cannot scan when link is open. Disconnect first"
        return []
    end
    begin
        RadioDriver.new().scan_interface()
    rescue Exception
        logger.error("Cannot scan interfaces: #{$!}")
        return []
    end
end
send_packet(packet, expect_answer=false) click to toggle source

Send a packet @param packet [CRTPPacket] packet to send @param expect_answer [TrueClass, FalseClass] if set to true, a timer

will be set up to
resend the package if
no response has been
received in 0.1secs
# File lib/crubyflie/crazyflie.rb, line 160
def send_packet(packet, expect_answer=false)
    return if @link.nil?
    @link.send_packet(packet)
    setup_retry(packet) if expect_answer
end

Private Instance Methods

call_cb(cb, *args) click to toggle source
# File lib/crubyflie/crazyflie.rb, line 223
def call_cb(cb, *args)
    @callbacks[cb].each do |name, proc|
        proc.call(*args)
    end
end
receive_packet() click to toggle source
# File lib/crubyflie/crazyflie.rb, line 167
def receive_packet
    packet = @link.receive_packet(false) # block here
    return if packet.nil?
    call_cb(:received_packet, packet)
    port = packet.port
    facility = CRTP_PORTS.invert[port]
    queue = @crtp_queues[facility]
    if queue then queue << packet
    else logger.warn "No queue for packet on port #{port}" end
end
receive_packet_thread() click to toggle source
# File lib/crubyflie/crazyflie.rb, line 193
def receive_packet_thread
    @receive_packet_thread = Thread.new do
        Thread.current.priority = -2
        loop do
            if @link.nil? then sleep 1
            else receive_packet(); Thread.pass() end
        end
    end

    # This threads resends packets for which no answer has been
    # received.
    @retry_packets_thread = Thread.new do
        Thread.current.priority = -5

        loop do
            @retry_packets.each do |k,v|
                now = Time.now.to_f
                ts = v[:timestamp]
                if now - ts >= 0.2
                    pk = v[:packet]
                    logger.debug("Replay on #{pk.port}:#{pk.channel}")
                    send_packet(v[:packet], true)
                end
            end
            sleep 0.2
        end
    end
end
register_default_callbacks() click to toggle source

Register some callbacks which are default

# File lib/crubyflie/crazyflie.rb, line 231
def register_default_callbacks
    @callbacks[:received_packet][:delete_timer] = Proc.new do |pk|
        sym = "port_#{pk.port}".to_sym
        @retry_packets.delete(sym)
        #logger.debug("Packet: #{pk.port}: #{pk.channel}")
    end

    @callbacks[:disconnected][:log] = Proc.new do |uri|
        logger.info "Disconnected from #{uri}"
    end

    @callbacks[:connection_failed][:log] = Proc.new do |m|
        logger.error "Connection failed: #{m}"
    end

    @callbacks[:connection_initiated][:log] = Proc.new  do |uri|
        logger.info "Connection initiated to #{uri}"
    end

    @callbacks[:connection_setup_finished][:log] = Proc.new do |uri|
        logger.debug "TOCs extracted from #{uri}"
        logger.info "Connection ready!"
    end

    # The message is an integer from 0 - 100
    @callbacks[:link][:quality] = Proc.new  do |m|
        #logger.debug "Link quality #{m}"
    end

    @callbacks[:link][:error] = Proc.new  do |m|
        logger.error "Link error: #{m}"
        close_link()
    end
end
setup_connection() click to toggle source
# File lib/crubyflie/crazyflie.rb, line 179
def setup_connection
    # Logging will send other packets such RESET_LOGGING
    # We make sure to handle them by running the thread
    # while we refresh the Log TOC
    #logger.debug("Setup connection: Log TOC refresh")
    @log.start_packet_reader_thread()
    @log.refresh_toc()
    @log.stop_packet_reader_thread()
    #logger.debug("Setup connection: Param TOC refresh")
    @param.refresh_toc()
    call_cb(:connection_setup_finished, @link.uri.to_s)
end
setup_retry(packet) click to toggle source

A retry will fire for this request

# File lib/crubyflie/crazyflie.rb, line 268
def setup_retry(packet)
    retry_sym = "port_#{packet.port}".to_sym
    @retry_packets[retry_sym] = {
        :packet => packet,
        :timestamp => Time.now.to_f
    }

end