【TelloPy】TelloをMacbookのキーボード入力で遠隔操作した


###参考にしたサイト

- [【Tello】トイ・ドローンで遊んでみた♪～キーボードのキーを使ってTelloを制御](https://qiita.com/MuAuan/items/ccd0e7881fed8759904d)
- [GitHub github.com/MuAuan/Tello/blob/master/simple_takeoff_KeyTelloCamera.py](https://github.com/MuAuan/Tello/blob/master/simple_takeoff_KeyTelloCamera.py) 


###実行画面

```bash:Terminal
electron@diynoMacBook-Pro Tello % python3 tellopy_keyboard_control_flight_wo_camera.py
Tello: 21:18:29.696:  Info: start video thread
========
Telloへの接続を開始します。（60秒間tryし続けます）
========
Tello: 21:18:29.697:  Info: send connection request (cmd="conn_req:9617")
Tello: 21:18:29.697:  Info: video receive buffer size = 524288
Tello: 21:18:29.697:  Info: state transit State::disconnected -> State::connecting
Tello: 21:18:29.735:  Info: connected. (port=9617)
Tello: 21:18:29.735:  Info: send_time (cmd=0x46 seq=0x01e4)
Tello: 21:18:29.735:  Info: state transit State::connecting -> State::connected
Telloに送る指示コマンドを入力してください。：  sTello: 21:18:31.571:  Info: recv: log_header: id=2113, 'b'BUILD May  7 2019 12:02:11''
Tello: 21:18:31.573:  Info: recv: log_header: id=4274, 'b'BUILD May  7 2019 12:02:11''
Tello: 21:18:31.624:  Info: LogData: UNHANDLED LOG DATA: id= 2064, length=  64
Tello: 21:18:31.625:  Info: LogData: UNHANDLED LOG DATA: id= 2208, length=  40
Tello: 21:18:31.625:  Info: LogData: UNHANDLED LOG DATA: id= 1000, length=  44
Tello: 21:18:31.625:  Info: LogData: UNHANDLED LOG DATA: id= 1001, length=  16
Tello: 21:18:31.625:  Info: LogData: UNHANDLED LOG DATA: id=10086, length=   4
Tello: 21:18:31.625:  Info: LogData: UNHANDLED LOG DATA: id=10085, length=  80
Tello: 21:18:31.625: Error: LogData: corrupted data at pos=1028, data=
Tello: 21:18:31.627: Error: LogData: corrupted data at pos=0, data=22 22 22 22 22 22 22 22 d6 23 aa 31 22 22 22 22 22 22 22 22 33 27 38 33 22 22 b1 77 55 1c 00 7a e9 03 34 7e 86 00 34 34 34 34 34 34 34 34 34 34 34 34 34 34 e8 31 3f d3 55 21 00 de 74 27 44 7e 86 00 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 7c 5e 55 84 00 cf 00 08 fd f6 86 00 fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 25 fd 6a bf 26 c8 83 46 cc 16 68 c6 21 91 7c 42 d9 89 88 41 95 a8 4b 47 97 50 8e c6 fd fd fd 7d fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 62 e5 a5 ff 90 ea fd fd fd fd fd fd 62 fd 8d d3 55 4c 00 0d 10 08 62 f7 86 00 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 e2 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 6a 62 62 60 32 62 62 62 62 62 10 60 55 34 00 cd a0 08 8f f7 86 00 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 0f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f 8f df 8f 8f 8f 93 95 55 10 00 37 66 27 8a 25 87 00 8a 8a 8a 8a 4c 96 55 5c 00 e1 65 27 d9 25 87 00 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 d9 e5 0a 55 84 00 cf 00 08 f7 8a 8a 00 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 e3 0d 61 b5 68 eb 2f 4c 4f 61 a2 cc a9 a5 76 48 b5 c7 8f 4b 87 10 f4 cd 66 3f f8 4c f7 f7 f7 77 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 6b ef af f5 99 e0 f7 f7 f7 f7 f7 f7 30 f7 58 a0 55 4c 00 0d 10 08 28 8b 8a 00 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 a8 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 20 28 28 20 4c 28 28 28 28 28 79 9b 55 34 00 cd a0 08 5e 8b 8a 00 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e de 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 5e 3a 5e 5e 5e b2 af 55 43 00 15 0c 00 e5 ee 8c 00 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 e5 05 f5 e5 f5 e5 e5 e5 e1 e5 e5 e5 e5 e5 f1 6f f9 c2 e5 e5 e5 e5 e5 e5 a2 e3 55 38 00 80 e8 03 35 a5 8d 00 2b 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 c1 34 bd 26 35 35 35 35 35 35 35 35 24 30 2f 24 35 35 ba 42 55 1c 00 7a e9 03 47 a5 8d 00 47 47 47 47 47 47 47 47 47 47 47 47 47 47 9b 42 79 50 55 84 00 cf 00 08 2c 1e 8e 00 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 51 d3 ba 6e 2a ee 2e 90 f8 75 09 17 3a 32 ad 93 c2 da a4 90 74 41 bf 96 dc a9 4a 96 2c 2c 2c ac 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c 2c b1 34 74 2e 42 3b 2c 2c 2c 2c 2c 2c c3 2c 63 2d ea f9
Tello: 21:18:31.675:  Info: LogData: UNHANDLED LOG DATA: id=10100, length=  21
Tello: 21:18:31.776:  Info: LogData: UNHANDLED LOG DATA: id= 1710, length=   6
Tello: 21:18:31.827:  Info: LogData: UNHANDLED LOG DATA: id=   16, length=   4
Tello: 21:18:32.083:  Info: LogData: UNHANDLED LOG DATA: id=   12, length=  55
Tello: 21:18:33.258:  Info: LogData: UNHANDLED LOG DATA: id= 1002, length=  27

キーボードからs'が入力されました。
離陸します。
Tello: 21:18:33.776:  Info: set altitude limit 30m
Tello: 21:18:33.776:  Info: takeoff (cmd=0x54 seq=0x01e4)
Tello: 21:18:33.873:  Info: LogData: UNHANDLED LOG DATA: id= 1306, length=  22
Tello: 21:18:33.873:  Info: LogData: UNHANDLED LOG DATA: id= 1305, length=  37
Tello: 21:18:33.923:  Info: LogData: UNHANDLED LOG DATA: id= 1307, length=  16
Tello: 21:18:34.230:  Info: LogData: UNHANDLED LOG DATA: id= 1304, length=  34
Tello: 21:18:34.793:  Info: LogData: UNHANDLED LOG DATA: id= 1200, length=  24
Tello: 21:18:34.793:  Info: LogData: UNHANDLED LOG DATA: id= 1202, length=  33
Tello: 21:18:34.793:  Info: LogData: UNHANDLED LOG DATA: id= 1203, length=   7
Tello: 21:18:34.793:  Info: LogData: UNHANDLED LOG DATA: id= 1300, length= 137
Tello: 21:18:35.766:  Info: LogData: UNHANDLED LOG DATA: id= 1303, length=  64
Telloに送る指示コマンドを入力してください。：  f
キーボードからf'が入力されました。
15前進します。
Tello: 21:18:44.796:  Info: forward(val=15)
Telloに送る指示コマンドを入力してください。：  h
キーボードからh'が入力されました。
15左移動します。
Tello: 21:18:54.500:  Info: left(val=15)
Telloに送る指示コマンドを入力してください。：  b
キーボードからb'が入力されました。
15後進します。
Tello: 21:19:01.386:  Info: backward(val=15)
Telloに送る指示コマンドを入力してください。：  kky
そのキーボード操作は無効（未定義）です。
Telloに送る指示コマンドを入力してください。：  ntc
そのキーボード操作は無効（未定義）です。
Telloに送る指示コマンドを入力してください。：  q
キーボードからq'が入力されました。
着陸します。
Tello: 21:23:06.188:  Info: land (cmd=0x55 seq=0x01e4)
drone.subscrive()します。
drone.quit()します。
Tello: 21:23:09.191:  Info: quit
Tello: 21:23:09.191:  Info: state transit State::connected -> State::quit
Tello: 21:23:09.303:  Info: exit from the recv thread.
Tello: 21:23:09.637:  Info: exit from the video thread.
electron@diynoMacBook-Pro Tello %
```

###ソースコード

```Python3:tellopy_keyboard_control_flight_wo_camera.py
from time import sleep
import tellopy
import cv2
import av
import numpy

def handler(event, sender, data, **args):
    drone = sender
    #if event is drone.EVENT_FLIGHT_DATA:
    #    print(data)

def test():
    drone = tellopy.Tello()
    print("========\nTelloへの接続を開始します。（60秒間tryし続けます）\n========")
    drone.connect()
    drone.wait_for_connection(60.0)

    while True:
        msg = input("Telloに送る指示コマンドを入力してください。：  ")
        if msg == "s":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("離陸します。")
            drone.takeoff()
            sleep(10)
        elif msg == "n":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("30下降します。")
            drone.down(30)
            sleep(3)
        elif msg == "u":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("30上昇します。")
            drone.up(30)
            sleep(3)
        elif msg == "h":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("15左移動します。")
            drone.left(15)
            sleep(3)
        elif msg == "j":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("15右移動します。")
            drone.right(15)
            sleep(3)
        elif msg == "b":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("15後進します。")
            drone.backward(15)
            sleep(3)
        elif msg == "f":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("15前進します。")
            drone.forward(15)
            sleep(3)
        elif msg == "c":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("10度時計回りに回転します。")
            drone.clockwise(10)
            sleep(3)
        elif msg == "q":
            print("キーボードから{0}'が入力されました。".format(msg))
            print("着陸します。")
            drone.land()
            sleep(3)
            print("drone.subscrive()します。")
            drone.subscribe(drone.EVENT_FLIGHT_DATA, handler)
            print("drone.quit()します。")
            drone.quit()
            break
        else:
            print("そのキーボード操作は無効（未定義）です。")
            continue
        

if __name__ == '__main__':
    test()

```