跳到主要內容

控制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 囉!


留言

熱門文章

差不多食譜:壽桃 Birthday Bunns

「壽桃」可不是老人家生日的專利,小巧玲瓏的壽桃超級受到小朋友歡迎,直說「好可愛喔!」其實壽桃就是一種造型饅頭/包子,只要掌握了這些方法,要做其他的造型都沒問題。

差不多食譜:巧克力杏仁餅乾 Chocolate Almond Cookies

老闆!來杯咖啡!這杯咖啡怎麼硬硬的?裡頭還一片片白白的東西?別擔心,差不多食譜不會向您介紹壞掉的東西,這也不是咖啡,不過是裝在咖啡杯裡頭的巧克力杏仁餅乾。這麼說來,這已經是第三份和巧克力有關的餅乾食譜了。從最早黑黑的「 手工巧克力餅乾 」,後來加了咖啡液黑白相間的「 咖啡巧克力餅乾 」,現在則是把黑白比例倒過來的「巧克力杏仁餅乾」。喜歡巧克力和手工餅乾的朋友們,千萬別錯過囉!

差不多食譜:檸檬餅乾 Lemon Biscuits

寒流來襲,氣象局持續發布低溫特報。在這冷颼颼的冬日,差不多食譜為您準備了一支有溫度的影片食譜「檸檬餅乾 Lemon Biscuits」。檸檬的酸味能夠讓您有清新的味覺,用檸檬做的餅乾則讓您解除冬日過份進補的油膩感,同時又滿足一直想吃東西的衝動。但我可沒說這種吃法的卡路里不高,對您的身材不會有影響。恐怕您還是得自己稍微節制些! 不過,說老實話,我單純是因為天氣太冷,所以把烤箱拿來當暖爐用。坐在烤箱後面等待餅乾完成,果真有暖呼呼的感覺。