TelloEduをWifiルータに接続して、TellloをWifi子機、ルータをWifi親機の関係にする


###参考にしたサイト

- [Tello Eduを子機にしてwifiアクセスポイントに接続する【python】](https://qiita.com/kei31/items/b3417e084f2d75999f6f)
- [Tello eduで編隊飛行入門（Python）](https://qiita.com/Tsukkey/items/883ef749f41ff603e8d4)

##最初の状態

まず最初に、TelloEduの電源を入れます。
次に、Macbook PCのWifi接続先を、TelloEduにします。

![スクリーンショット 2021-07-27 0.20.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/51ee7770-e5ba-889e-fcd9-225d01596019.png)

すると、Wifiの親機と子機の関係は、次の状態になります。

- 親機：TelloEduドローン
- 子機：Macbook PC

![スクリーンショット 2021-07-26 23.55.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/874c9ccf-01b4-539c-b05d-e475d0677b40.png)

###TelloEduをWifiルーターに接続させる

次に、TelloEduにつながっているMacbook PCのTerminalで、次のコードを叩きます。

```Python3:Terminal
>>> import socket
>>> tello_ip = '192.168.10.1'
>>> tello_port = 8889
>>> socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> tello_address = (tello_ip , tello_port)
>>> socket.sendto('command'.encode('utf-8'),tello_address)
>>> socket.sendto('ap aterm-xxxxxxxxxx yyyyyyyyyyy'.encode('utf-8'),tello_address)
```

上の最後の1行が実行されると、TelloEduは、（Macbook PCからの指令を受けて）__'ap aterm-xxxxxxxxxx yyyyyyyyyyy'にWifi接続をしにいきます。__

ここで、__ap__は、__Wifi Access Point__を意味します。
__'ap aterm-xxxxxxxxxx yyyyyyyyyyy'__とは、具体的には__Wifiルーター__を指しています。

このWifiルータは、「aterm-xxxxxxxxxx」というSSIDを持っていて、このWifiルータに（Wifi）接続するためには、「yyyyyyyyyyy」という（認証）パスワードが必要になります。


- 接続先のWifiルータのSSID名：aterm-xxxxxxxxxx 
- 接続先のWifiルータのパスワード：yyyyyyyyyyy

なお、Wifiルータが持つSSIDと認証パスワードは、お手持ちのWifiルータの本体や説明書に書かれているので、調べてみてください。

この時点で、__TelloEduは自らWifi電波の発信源（Wifi親機）であることをやめて__、（Wifi電波を発信中の）Wifiルータにつながりにいく__「Wifi子機」へと変身しています__。

__TelloEduドローンを、Wifi親機からWifi子機に変身させた__のは、次の１行です。

```Python3:Terminal
>>> socket.sendto('ap aterm-xxxxxxxxxx yyyyyyyyyyy'.encode('utf-8'),tello_address)
```

いまや、TelloEduは、Wifi子機になっています。
Wifiの親機と子機の関係は、次のように切り替わっています。

- 親機：Wifiルーター
- 子機１：TelloEduドローン
- 子機２：Macbook PC

なお、コントローラーとなるMacbook PCも、Wifi接続先をWifiルーターに切り替えます。
Macbook PCのWifi接続先をWifiルーターに切り替える作業は、Macbook PC上で、手動で行います。

このとき、Macbook PCから、接続可能なWifiアクセスポイントの一覧を探しにいくと、最初に表示されていたはずのTelloEduのWifiアクセスポイント（AP）が、いなくなっています。

![スクリーンショット 2021-07-27 0.24.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/1cb31e73-410e-44dc-0267-c7de35827deb.png)


ここで、親機であるWifiルータから、子機であるTelloEduドローンに対して、どのプライベートIPアドレスが割り振られたのかを確認します。

今回は、__[「Fing」というIPアドレスチェッカーアプリ](https://apps.apple.com/jp/app/fing-%E3%83%95%E3%82%A3%E3%83%B3%E3%82%B0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%84%E3%83%BC%E3%83%AB/id430921107)__をインストール済みのiPhoneを、事前に用意しておきました。

このアプリは、アプリをインストールしたiPhone端末が、いま現在つながっているWifiルーターの情報を表示してくれます。Wifiルーターにつながっているすべての端末（これにはFingアプりを入れたiPhone端末も含まれる）について、次の情報が表示されます。

- 端末製品名
- 端末メーカー名
- （ルーターがその端末に割り振った）プライベートIPアドレス

ここで、Fingアプリの入ったiPhoneを、__「TelloEduドローンがつながっているWifiルーター」__にWifi接続することで、__TelloEduドローンに割り振られている（プライベート）IPアドレス__を知ることができます。

今回は、__「192.168.0.9」という（プライベート）IPアドレスがTelloEduドローンに割り振られている__ことが分かりました。

![スクリーンショット 2021-07-26 23.32.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/d5741014-00b7-4da3-2081-aa0ae47a439d.png)

![スクリーンショット 2021-07-27 0.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/d27b57ed-5e97-4834-d7c5-4b524adfd0ef.png)


なお、Macbookから、__*ping 192.168.0.9*__を実行すると、この端末は生きていることがわかりました。

```bash:Terminal
electron@diynoMacBook-Pro ~ % ping 192.168.0.9
PING 192.168.0.4 (192.168.0.4): 56 data bytes
64 bytes from 192.168.0.9: icmp_seq=0 ttl=64 time=82.683 ms
64 bytes from 192.168.0.9: icmp_seq=1 ttl=64 time=109.259 ms
^Z
zsh: suspended  ping 192.168.0.9
electron@diynoMacBook-Pro ~ % 
```

##Macbook PCからTelloEduドローンを操作してみる

それでは、同じWifi親機（Wifiルータ）にWifi接続している、Wifi子機の兄弟分であるTelloEduドローンと、Macbook PCどうしで、通信をさせてみます。

今回は、（Wifi子機） Macbook PCから、(Wifi子機） TelloEduドローンに向けて、操縦コマンドを送信してみます。

別の記事では、この反対方向のデータ送信の例として、(Wifi子機） TelloEduドローンから（Wifi子機） Macbook PCに向けて送信される、次のデータを、Macbook PC側でConsole（Terminal）や　ウィンドウに表示してみたいと思います。

- ドローンの現在状態を示す信号（飛行高度、気圧、速度、ロール、ヨー、ピッチ、残電源など）
- ドローン搭載カメラが捉えた画像データ


さて。Macbook PCのTerminalで次のコードを打ち込むことで、TelloEduドローンに、離陸と着陸の操作を行わせることに成功しました。

```Python3:Terminal
>>> tello_new_ip = '192.168.0.9'
>>> tello_new_address = (tello_new_ip , tello_port)
>>> socket.sendto('command'.encode('utf-8'),tello_new_address)
7
>>> socket.sendto('takeoff'.encode('utf-8'),tello_new_address)
7
>>> socket.sendto('land'.encode('utf-8'),tello_new_address)
4
>>> quit()
```

Macbook PCから、「192.168.0.9」という（プライベート）IPアドレスを持つ端末（つまり、TelloEduドローン）に向けて、上記の操作コマンドが送られたことになります。

> tello_new_ip = '192.168.0.9'

ここで１つ、注意すべきことがあります。

なお、Wifiルーターから各端末（子機）に割り振られるプライベートIPアドレスが、一定時間経過後に、動的に切り替わってしまうDHCPのWifiルータを使っている場合、TelloEduドローンに割り振られた（プライベート）IPアドレスは、切り替わってしまいます。

そうなると、MacbookのTerminalから送信される操縦コマンドは、TelloEduドローンに届かなくなり、操縦不能になってしまうため、気をつけてください。

Wifiルーターは、各端末に対して一度割り当てたIPアドレスをいつまでも変えずに、固定してくれるものを使うようにしましょう。 （今回は、Wifiルータから割り振られるプライベートIPアドレスが一定時間ごとに切り替わるDHCPルータを使いました）

###さらなる発展

後は、同じことを2機目、3機目のTelloEduにしていくと、1台のPCから複数機のTelloEduをコントロールできるようなります。

X機のTelloEduドローンと、1台のMacbook PCはすべてWifi子機になります。
Wifiルーターは、唯一のWifi親機になります。

__（ 以下、2機目以降のドローンのプライベートIPアドレスは、架空の文字列です ）__

![スクリーンショット 2021-07-27 0.06.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/ffa78cf7-36ed-1fc6-4abc-509a62ffad1d.png)

###後記

####（ 事象１ ）

一晩置いて、翌朝、Telloに電源を再投入すると、TelloEduとWifiルータとの接続は切れていて、TelloEduは再びWifi親機に戻っていました。

__（ Macbook PC上のWifi AP一覧画面 ）__

elloEduが発信源のWifi AP 「TELLO-9FXXXX」が表示されている。

![スクリーンショット 2021-07-27 10.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754134/7e42b3c9-a674-5f7f-dc2a-d92513d25bec.png)

__（ （Wifiルータに接続中の）iPhone内のFingアプリ上でのIPアドレス検索結果 ）__

'192.168.0.9'の行がグレーアウト（灰色色）になり、非活性に切り替わっている。
このAPは「オフラインです」と表示されている。

####（ 事象2 ）

事象１の体験後にTelloEduの電源を切り、さらに数時間経過後、Telloに電源を再投入すると、TelloEduは再び、Wifiルータにつながっていました。

- Macbook PC上のWifi AP一覧画面: TelloEduが発信源のWifi AP 「TELLO-9FXXXX」がない。
- （Wifiルータに接続中の）iPhone内のFingアプリ上でのIPアドレス検索結果: '192.168.0.9'が黒文字で活性化表示されていて、「オンライン中」になっている。

---

###Terminalに手打ちしたPythonコードを、スクリプトファイル化しました

- TelloEduドローン１機を、Wifiルータに接続させます。
- このスクリプトを実行するMacbook PCは、対象となるTelloEduドローンに、あらかじめWifi接続しておきます。

####__telledu_connect_to_wifi_router.py__

```Python3:telledu_connect_to_wifi_router.py
import socket, argparse    

# WifiルーターのSSIDをコマンドライン引数から受け取る
parser = argparse.ArgumentParser(description='')  
parser.add_argument('-ssid')  

# Wifiルーターのパスワードをコマンドライン引数から受け取る
parser.add_argument('-pw')  

args = parser.parse_args() 
wifi_host_ssid = args.ssid
wifi_host_pw = args.pw

message_1 = "Wifiルータ（SSID）：　" + str(wifi_host_ssid)
message_2 = "Wifiルータ（パスワード）：　" + str(wifi_host_pw)

print(message_1)
print(message_2)

# TelloEduのプラウベートIPアドレスとポート番号は全機体、同じ定数文字列
tello_ip = '192.168.10.1'
tello_port = 8889

# (Wifi client) Macbook -> (Wifi host) TelloEduに接続
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
tello_address = (tello_ip , tello_port)
wifi_host_ap = "ap {0} {1}".format(wifi_host_ssid, wifi_host_pw)
print(wifi_host_ap)
socket.sendto('command'.encode('utf-8'),tello_address)
socket.sendto(wifi_host_ap.encode('utf-8'),tello_address)
```

####（ 使い方 ）

コマンドライン引数として、TelloEduを接続させたいWifi親機（Wifiルーター）のSSIDとパスワードを渡します。

```bash:Terminal
electron@diynoMacBook-Pro ~ % python3 telledu_connect_to_wifi_router.py -ssid aterm-xxxxxxxxxx -pw yyyyyyyyyyy
Wifiルータ（SSID）：　aterm-xxxxxxxxxx
Wifiルータ（パスワード）：　yyyyyyyyyyy
ap aterm-xxxxxxxxxx yyyyyyyyyyy
electron@diynoMacBook-Pro ~ %
``` 

####__telloedu_single_remote_control.py__

- TelloEduドローン１機を、Macbook PCから遠隔操作します。
- コントローラーとなるMacbook PCは、TelloEduドローンと同じWifiルータに接続済みにしておきます。

```Python3:telloedu_single_remote_control.py
import socket, argparse, time    

# WifiルーターのSSIDをコマンドライン引数から受け取る
parser = argparse.ArgumentParser(description='')  
parser.add_argument('-ip')  

args = parser.parse_args() 
tello_ip = args.ip

print("IPアドレス {0} 番のTelloEduドローンに操作コマンドを送ります。".format(tello_ip))

# TelloEduのポート番号は全機体、同じ定数文字列
tello_port = 8889
tello_address = (tello_ip , tello_port)

socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

socket.sendto('command'.encode('utf-8'),tello_address)
time.sleep(3)
socket.sendto('takeoff'.encode('utf-8'),tello_address)
time.sleep(3)
socket.sendto('land'.encode('utf-8'),tello_address)
time.sleep(3)
```

####（ 使い方 ）

コマンドライン引数として、遠隔操作したいTelloEduのプライベートIPアドレスを渡します。

```bash:Terminal
electron@diynoMacBook-Pro ~ % python3 telloedu_single_remote_control.py -ip 192.168.0.9
IPアドレス 192.168.0.9 番のTelloEduドローンに操作コマンドを送ります。
electron@diynoMacBook-Pro ~ %
```