跳到主要內容

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

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

差不多食譜:白糖粿 Beh Teung Guai 傳統小吃版的台式吉拿棒 Taiwanese Churros

只要有個油炸鍋,將糯米糰炸到表面金黃,裹上白糖,居家版「白糖粿」意外的簡單。 說到這「白糖粿」,就算在台灣土生土長,還是有很多人沒聽過這個點心。要不是它在網路上掀起熱門討論,恐怕到現在也只有老饕知道去哪裡解饞。但現在「差不多食譜」把它搬到回家,讓你在家裡也能自己做來吃。 至於怎麼跟外國朋友介紹,其實困擾了我一陣子。腦子裡根本沒有對應的東西,它很像年糕、麻糬、湯圓,實際上材料也一樣,但做法上的差異卻讓白糖粿又不同於上述那些食物。最後,看到西方的吉拿棒(churro),在做法和吃法上都很類似白糖粿,兩者都是弄成長條油炸,然後裹上糖粉食用。這樣,姑且就把它稱做台式的吉拿棒好了,英文除了音譯的Beh Teung Guai以外,就直翻成 Taiwanese Churros。不同於台北東區賣吉拿棒的 Street Curros,這可是道道地地 Taiwan Street Curros,而且好像只有南部限定喔!說太多了,直接看做法。

Excel運用VBA抓取Yahoo Finance APIs股票資料

Yahoo Finance APIs提供了多樣的應用程式接口,讓使用者能夠獲取Yahoo Finance的資料。這篇文章要介紹的,是多數人會用到的股票資料。實作的例子來自於 http://www.gummy-stuff.org/Yahoo-data.htm ,我只是將內容稍微解釋,並且換成台灣股票的例子。