跳到主要內容

控制Tello: 直接用 Node.js 就夠啦!


介紹完 Scratch 控制 Tello 的方式後,我又仔細看了官網提供的 Tello.js 檔案,其實不一定要 Scratch,直接拿 Tello.js 改寫成命令列,或直接做成本地端的網頁就可以了。不多說,下面就來介紹一下到底要怎麼做。


Step 1. 下載 Node.js

相信有看過前一篇怎麼用 Scratch 去飛 Tello 的朋友,都已經裝上 Node.js 了。還沒裝的,不妨看看上一篇文章(傳送門在此),先把 Node.js 裝起來。要不然,下面都不用玩了。



Step 2. UDP通訊

不管你用哪個程式語言去寫,在沒有駭進 Tello 裡的狀況下,與 Tello 的通訊走的就是 UDP (用戶資料報協定,User Datagram Protocol)。我不是唸通訊的,詳細到底是怎麼溝通的我搞不懂,反正得用這個協定來寫程式才會動。所以在 Node.js 裡面,就得先把會用到的dgram擴充功能拉進來,用udp4的方式打開網路插座(socket)。

const dgram = require('dgram');
const socket = dgram.createSocket('udp4');


從官方的SDK可以看到,Tello 的 IP 是 192.168.10.1,用的通訊埠(port)則是8889,這時候順道再把這兩項參數設為常數。

const HOST = '192.168.10.1';
const PORT = 8889;


再過來,需要透過網路插座把指令送到 Tello ,這時候你需要 send() 這個動作。

socket.send(commandStr, PORT, HOST);

上面我沒有寫到 commandStr 是個字串,可以送出去的指令都在 Tello 的 SDK 裡面,包括 command, takeoff, land, flip, battery?等等,自己查一下印象會比較深刻。

最後,我們還得知道 Tello 收到指令之後做了什麼回應,這時就需要靠 message 這個事件處理來做,並利用 console.log() 將結果顯示出來。

socket.on('message', (msg, info) => {
    console.log('Data received from Tello: ' + msg.toString());

});

這麼一來,和 Tello 最基本的溝通工作就完成囉!


Step 3. 加入命令列互動

要加入命令列的互動,我們還需要另一個擴充功能 readline ,並且創造一個處理輸出輸入的界面(interface)。

const readline = require('readline');
const rl = readline.createInterface(
    process.stdin,
    process.stdout
);


為了要讓輸入的介面跳出來,這邊要使用到 prompt()。可以設一個自訂的開頭,方便辨識這是 Tello 的命令列。

rl.setPrompt('Tello> ');
rl.prompt();


再過來,要利用 line 事件,也就是按下 Enter 鍵之後,把輸入的指令送給 Tello 。因為經常會不小心多按到空白鍵,所以我們會加個字串的 trim() 功能把多出來的空格給忽略掉。

rl.on('line', (input) => {
    var commandStr = input.trim();
    console.log(`Command: {$commandStr}`);
    socket.send(commandStr, PORT, HOST);
});


到這裡,用命令列和 Tello 進行互動的功能基本上已經完成。再過來,我們多做一個結束的指令,也就輸入 quit 之後,把網路插座給關上並結束命令列。不需要寫太多,把上面那段改寫一下就可以。

rl.on('line', (input) => {
    var commandStr = input.trim();
    if (commandStr === 'quit') {
        socket.close();
        rl.close();
    }
    else {
        console.log(`Command: ${commandStr}`);
        socket.send(commandStr, PORT, HOST);
    }
});



Step 4. 執行命令列互動

完整的程式碼寫在這邊,用文字編輯器把它存成 TelloCommandLine.js。

const dgram = require('dgram');
const socket = dgram.createSocket('udp4');

const HOST = '192.168.10.1';
const PORT = 8889;

const readline = require('readline');
const rl = readline.createInterface(
    process.stdin,
    process.stdout
);

rl.setPrompt('Tello> ');
rl.prompt();

socket.on('message', (msg, info) => {
    console.log('Data received from Tello: ' + msg.toString());
    rl.prompt();
});

rl.on('line', (input) => {
    var commandStr = input.trim();
    if (commandStr === 'quit') {
        socket.close();
        rl.close();
    }
    else {
        console.log(`Command: ${commandStr}`);
        socket.send(commandStr, PORT, HOST);
    }
});


然後在同一個目錄下,輸入 node TelloCommandLLine.js ,就可以用命令列來控制 Tello 囉!


留言

熱門文章

差不多食譜:手工巧克力餅乾 Chocolate Cookies

又是手工餅乾,最近一連出了兩份餅乾食譜,這個「手工巧克力餅乾」已經是第三份了。會不會有更多呢?我可以告訴大家,這是肯定的。 要怪就怪這個陰鬱的冬季雨天,哪裡都不方便去,也懶得出去。餅乾櫃空在那邊已經很久了,雖然有時候會嘴饞,但也沒有迫切去補貨的必要。反正經常開伙,平常該有的材料都會有,自己弄個成分完全透明的零食,也是個不錯的選擇。再說,用烤箱進行烘焙時,房間會變得比較乾燥,也比較溫暖。在夏天是個折磨,但到了冬天,這種感覺還滿不錯的。 話不多說,開始進行這一道「手工巧克力餅乾」的準備工作。

差不多食譜:炙燒烏魚子 Grilled Mullet Roe

要吃出烏魚子原本的滋味,只需要用火稍微燒一下就夠囉!無論你是用酒燒,或是拿料理噴槍,利用高溫將表面烤香,就是好吃的烏魚子。當然,蒜苗與白蘿蔔的搭配也是不能少的,或者夾片蘋果,摻和些水果的甜味,也是味覺的一大享受。下面差不多食譜將介紹這兩種烏魚子的炙燒方法,我們是覺得用料理噴槍比較簡單啦!

「抓烏龜」的麻將遊戲

今天要和大家分享一個打發時間的簡單遊戲——抓烏龜。這可是我老爸老媽特別從美國學回來的,是個名符其實的「海歸」遊戲,據說是在下雪時無聊打發時間用的。