昨日、Tello を Python から操作する実験を行っていましたが、離陸後、上手く着陸してくれませんでした。
Tello SDK 1.3 のドキュメントによると、コマンドに対するレスポンスがあるようなので、離陸コマンドや着陸コマンドのレスポンスがどうなっているのか見たいです。
socket への sendto のレスポンスを見ても意味がないと思うので、どうやってレスポンスを受け取るんだろう??
Tello に command を送る方法
これは、昨日の記事でやっていたものになります。
Tello の IP(192.168.10.1) の Port(8889) に command を送ります。
tello から command のレスポンスを受け取る方法
Tello からレスポンスを受け取るには、まず、PC 側に受信ポートを設定 する必要があるようです。
PC 側に受信ポートを設定する
import socket # PC 側の受信ポート(任意の空きポートを指定) LOCAL_PORT = 9000 # ソケットの作成 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('', LOCAL_PORT)) # PC 側のポートをバインド
レスポンスを受信する
そして、レスポンスを受信するためには Socket の recvfrom()
で行うようです。
response, _ = sock.recvfrom(1024) # 最大1024バイトを受信 decoded_response = response.decode('utf-8') print(f'Response: {decoded_response}')
こうすることで、レスポンスを得ることができるようです。
サンプルコードの全体像
import socket TELLO_IP = '192.168.10.1' TELLO_PORT = 8889 # PC 側の受信ポート(任意の空きポートを指定) LOCAL_PORT = 9000 def send_command(sock, command, tello_address): print(f'[SEND] command: {command}') sock.sendto(command.encode('utf-8'), tello_address) try: response, _ = sock.recvfrom(1024) # 最大1024バイトを受信 decoded_response = response.decode('utf-8') print(f'Response: {decoded_response}') except socket.timeout: print("No response (timeout)") def main(sock, tello_address): # コマンドを送れるようにする send_command('command', tello_address) # 離陸 send_command('takeoff', tello_address) # 着陸 send_command('land', tello_address) if __name__ == '__main__': sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('', LOCAL_PORT)) # PC 側のポートをバインド sock.settimeout(5) # タイムアウト設定 main(sock, (TELLO_IP, TELLO_PORT)) sock.close()
このコードでログを監視していたところ、
takeoff
の Response が返る前にタイムアウトしてしまい、そのまま land
を送っていることがわかりました。
タイムアウト設定は 5秒 としているため、レスポンスを得るまで5秒では足りず、Tello 的にはまだ takeoff
の処理中にも関わらず land
を送ったせいで無視された可能性があります。
試しにタイムアウト値を10秒にしてみたところ、普通に
takeoff
のレスポンスは返ってきました
takeoff
のレスポンスを確認したあとに land
を送ることで、
安定して着陸できるようになった気がします。
まとめ
ChatGPT に聞きながらですが、的確に教えてくれるので理解が進みますね!!