Exemples

Cette page propose un ensemble de scripts Lua de pilotage. Les commandes sont expliquées sur cette page.

Notez que des exemples sont disponibles dans le dossier test du répertoire racine de Jakopter.

Avant de lancer ces exemples vous devez avoir connecté votre ordinateur au réseau Wifi du drone (e.g. ardrone_xxx).

 

Faire décoller et atterrir le drone

Les scripts suivants font respectivement décoller et atterrir le drone.

Décollage

-- package.cpath = package.cpath .. ";?.dylib" -- si vous êtes sur mac osx
l=require("libjakopter")
l.connect() -- connexion au drone
l.takeoff() -- ordre de décollage

 

Atterrissage

l=require("libjakopter")
l.connect() -- connexion au drone
l.land() -- ordre d'atterrissage

 

Une séquence de vol

Le script suivant donne un exemple de trajectoire de vol.

l=require("libjakopter")
l.connect() -- connexion
l.takeoff() -- décollage
l.forward(0.5) -- en avant vitesse (0 immobile, 1 maximum), pendant environ 1 seconde
l.forward(0.5)
l.forward(0.5)
l.up(0.5) -- ascension
l.up(0.5)
l.left(0.5)  -- à gauche
l.left(0.5)
l.forward(0.5) -- en avant
l.forward(0.5)

 

Affichage de la vidéo et des informations de vol

Ce script affiche le flux vidéo du drone. Il fait usage de com_channel pour faire parvenir diverses informations de vol au module d’affichage vidéo, afin que ce dernier puisse les exposer en overlay (niveau de batterie, indicateur d’attitude, boussole…)

--Boucle de contrôle du drone + affichage vidéo

l=require("libjakopter")
l.connect() -- connexion au drone
l.connect_video() -- connexion au flux vidéo du drone
--Envoi des navdata au module vidéo
--vérifier le timestamp (tt) pour voir si de nouvelles données sont arrivées
--initialement, il vaut 0.
tt = 0
tt_new = 0
-- on crée une boucle infinie qui lit les données de vol et les envoie au module de gestion de la vidéo
while true do
 --ne mettre à jour les données que si elles ont changé
 repeat
 --yield pour éviter d'occuper le CPU avec plein de tests inutiles
 l.yield()
-- attendre l'avancement à la frame vidéo suivante
 tt_new = l.cc_get_timestamp(1)
 until tt_new > tt
 
 tt = tt_new
 --Le canal de navdata est n°1, celui de vidéo n°2
 bat = l.cc_read_int(1, 0)
 alt = l.cc_read_int(1, 4)
 --angles en millidegrés, il faut les convertir en degrés.
 pitch = l.cc_read_float(1, 8) / 1000
 roll = l.cc_read_float(1, 12) / 1000
 yaw = l.cc_read_float(1, 16) / 1000
 --envoi des données à la vidéo
 l.cc_write_int(2, 0, bat)
 l.cc_write_int(2, 4, alt)
 l.cc_write_float(2, 8, pitch)
 l.cc_write_float(2, 12, roll)
 l.cc_write_float(2, 16, yaw)
end

Script de pilotage simple

Ce script lit les codes d’entrée du clavier.

l=require("libjakopter")
l.connect_video()
l.connect()
--Canal de com navdata (lecture des données)
ccn = 1
--Canal de com de la video pour envoyer les infos
ccv = 2
-- Canal de com de l'entrée clavier
cck = 4
previous =-1
-- boucle de contrôle du drone - lecture des données utilisateurs; des données de vol; d'envoi des données de vol
while true do
-- lecture de la valeur fournie par le programme "keyb_control" (via le fichier /tmp/jakopter_cmd.txt)
  valk1 = l.cc_read_int(cck,0)
-- ne pas répéter l'ordre donné
  if valk1 ~= previous then
     previous = valk1
-- retour chariot pour terminer
  if valk1 == 10 then
     os.exit()
-- flèche montante pour décoller
  elseif valk1 == 65 then
    l.takeoff()
-- flèche descendante pour atterrir
  elseif valk1 == 66 then
    l.land()
-- flèche gauche pour rotation gauche
  elseif valk1 == 68 then
    l.left(0.5)
-- flèche droite pour rotation droite
  elseif valk1 == 67 then
    l.right(0.5)
-- d pour descendre
  elseif valk1 == 100 then
    l.down(0.5)
-- u pour up (ascension)
  elseif valk1 == 117 then
    l.up(0.5)
  elseif valk1 == 97 then
-- letter "a" pour arrêt
    l.stay()
  elseif valk1 == 102 then
-- letter "f" pour avancer (forward)
    l.forward(0.5)
  elseif valk1 == 98 then
-- letter "b" pour reculer (backward)
   l.backward(0.5)
  end
  end
-- on pourrait attendre ici l'avancement à la frame vidéo suivante (omis pour simplifier le code)
-- lecture du niveau de charge de la batterie
  bat = l.cc_read_int(ccn, 0)
-- lecture de l'altitude 
  alt = l.cc_read_int(ccn, 4)
--angles en millidegrés, il faut les convertir en degrés.
-- indication de la profondeur
  pitch = l.cc_read_float(ccn, 8) / 1000
-- indication de roulis
  roll = l.cc_read_float(ccn, 12) / 1000
-- indication de la direction
  yaw = l.cc_read_float(ccn, 16) / 1000
--envoi des données à la vidéo pour incrustation
-- position 0 dans le canal, indication de batterie
  l.cc_write_int(ccv, 0, bat)
-- position 4 dans le canal l'altitude
  l.cc_write_int(ccv, 4, alt)
-- position 8 dans le canal la profondeur
  l.cc_write_float(ccv, 8, pitch)
-- position 12 dans le canal le roulis
  l.cc_write_float(ccv, 12, roll)
-- position 16 dans le canal la direction
  l.cc_write_float(ccv, 16, yaw)
end

Incruster une image sur la vidéo

Détecter un visage

Récupérer les coordonnées du motion capture

d = require("libjakopter")
if d.connect() < 0 then
    print("Can't connect to the drone")
    os.exit()
end

if d.connect_coords() < 0 then
    print("Can't connect to the coords listener")
    os.exit()
end

d.takeoff()
while true do
    coords = {
--Translations en millimètres
        t_x = d.cc_read_float(5, 0),
        t_y = d.cc_read_float(5, 4),
        t_z = d.cc_read_float(5, 8),
-- Rotations en degré de -180 à 180, 0 aligné avec l'axe y, sens horaire
        r_x = math.deg(d.cc_read_float(5, 12)),
        r_y = math.deg(d.cc_read_float(5, 16)),
        r_z = -math.deg(d.cc_read_float(5, 20))
    }
-- Si le drone dépasse la zone, on quitte la boucle et on le fait atterrir
    if coords.t_x > 1200 or coords.t_x < -1200
        or coords.t_y < -2400 or coords.t_y > 2600 then
        print("END: " .. coords.t_x .. " ".. coords.t_y)
        break
    end
end

d.land()

Communiquer avec un serveur HTTP

d = require("libjakopter")
-- Utiliser lua-json (voir sur github)--
require("json")
-- On précise l'ID du drone dans l'adresse
local input = "http://127.0.0.1?id=1"
local output = "http://127.0.0.1/index.php"

old_seq = 0
d.connect_network(input, output)

d.cc_write_int(chan_net_out, 0, 1)

--On renvoie les données que l'on reçoit
while true then
    --On récupère la chaîne contenant le JSON
    local str = d.cc_read_string(chan_net_in,0)
    if str then
        local tree = json.decode(str)
        if tree.seq ~= old_seq then
            print("My id "..tree.id)
            print("T_x"..tree.t_x)
            goal = {
                t_x= tree.t_x,
                t_y= tree.t_y,
                t_z= tree.t_z,
                r_x= tree.r_x,
                r_y= tree.r_y,
                r_z= tree.r_z
            }
            d.cc_write_float(chan_net_out, 8+256, goal.t_x)
            d.cc_write_float(chan_net_out, 8+256+4, goal.t_y)
            d.cc_write_float(chan_net_out, 8+256+8, goal.t_z)
            d.cc_write_float(chan_net_out, 8+256+16, goal.r_x)
            d.cc_write_string(chan_net_out, 4, "hello world!")
            d.cc_write_int(chan_net_out, 0, math.tointeger(tree.id))
        end
        old_seq = tree.seq
    end
end
--wait the messages to be send
d.usleep(100000)
d.stop_network()