Skip to content

Instantly share code, notes, and snippets.

@ymt117
Last active June 25, 2025 13:02
Show Gist options
  • Save ymt117/2c67c777747390560bdda209de90cd86 to your computer and use it in GitHub Desktop.
Save ymt117/2c67c777747390560bdda209de90cd86 to your computer and use it in GitHub Desktop.
PythonからフライトコントローラへMSPでコマンドを送る
import serial
import time
# ==== 設定 ====
PORT = 'COM10'
BAUDRATE = 115200
# ==== MSPヘッダー生成 ====
def create_msp_packet(command_id, payload=[]):
header = [ord('$'), ord('M'), ord('<')]
size = len(payload)
checksum = size ^ command_id
for byte in payload:
checksum ^= byte
packet = header + [size, command_id] + payload + [checksum]
return bytearray(packet)
# ==== 応答データを表示 ====
def print_response(response):
if len(response) < 6:
print("応答が不正です(短すぎます)")
return
size = response[3]
command = response[4]
payload = response[5:-1]
print(f"MSP応答: コマンドID={command}, サイズ={size}, ペイロード={payload.hex()}")
# ==== メイン処理 ====
def main():
try:
with serial.Serial(PORT, BAUDRATE, timeout=2) as ser:
print("シリアル接続しました。MSP_STATUSを送信中...")
packet = create_msp_packet(101) # 101 = MSP_STATUS
ser.write(packet)
# 応答待ち
time.sleep(0.1)
if ser.in_waiting > 0:
response = ser.read(ser.in_waiting)
print_response(response)
else:
print("フライトコントローラからの応答がありません。")
except Exception as e:
print(f"エラー: {e}")
if __name__ == "__main__":
main()

接続

フライトコントローラのUART1(TX, RX, GND)にUARTシリアル変換アダプタ経由でPCを接続する。

フライトコントローラ UARTシリアル変換アダプタ
UART1(TX) RX
UART1(RX) TX
GND GND

get_id.pyの実行結果

フライトコントローラのIDが取得できる。

$ python .\get_id.py
シリアル接続しました。MSP_STATUSを送信中...
MSP応答: コマンドID=101, サイズ=11, ペイロード=e903000083000000081000

フライトコントローラとの接続を外すと失敗する。

$ python .\get_id.py
シリアル接続しました。MSP_STATUSを送信中...
フライトコントローラからの応答がありません。

ほかのコマンドを送る

以下のようにMSP_STATUS(=101)からMSP_RC(=105)に変えると実行結果が変わる。

-packet = create_msp_packet(101)
+packet = create_msp_packet(105)
$ python .\get_id.py
シリアル接続しました。MSP_STATUSを送信中...
MSP応答: コマンドID=105, サイズ=36, ペイロード=dc05dc05dc057503dc05dc05dc05dc05dc05dc05dc05dc05dc05dc05dc05dc05dc05dc05
import serial
import time
PORT = 'COM10'
BAUDRATE = 115200
# MSPパケット作成関数
def create_msp_packet(command_id, payload):
header = [ord('$'), ord('M'), ord('<')]
size = len(payload)
checksum = size ^ command_id
for byte in payload:
checksum ^= byte
packet = header + [size, command_id] + payload + [checksum]
return bytearray(packet)
# RCデータ作成関数(1000〜2000の8ch)
def create_rc_payload(channels):
payload = []
for val in channels:
payload.append(val & 0xFF) # 下位バイト
payload.append((val >> 8) & 0xFF) # 上位バイト
return payload
# 実行関数
def main():
try:
with serial.Serial(PORT, BAUDRATE, timeout=2) as ser:
print("送信中:MSP_SET_RAW_RC")
# RC値:Roll, Pitch, Yaw, Throttle, AUX1〜AUX4
rc_values = [1500, 1500, 1500, 1200, 2000, 1000, 1000, 1000]
payload = create_rc_payload(rc_values)
packet = create_msp_packet(200, payload) # 200 = MSP_SET_RAW_RC
# 連続送信(FCは一定間隔でRC受信を要求)
for _ in range(50):
ser.write(packet)
time.sleep(0.05) # 50ms間隔(20Hz)
print("送信完了")
except Exception as e:
print(f"エラー: {e}")
if __name__ == "__main__":
main()

Pythonから制御コマンドを送る

フライトコントローラの設定

  1. INAV Configuratorにフライトコントローラを接続する
  2. 左メニューの「Receiver」を選択する
  3. 「Receiver Mode」をMSPに設定する

send_rc.pyの実行結果

実行すると、INAV Configuratorの「Receiver」画面でThrottleなどの値が変化することが確認できる。

$ python .\send_rc.py
送信中:MSP_SET_RAW_RC
送信完了

Q. 目的地へ自律飛行させるには?

A. ウェイポイントを送信する

以下の情報を送る必要がある。

  • action: 到達後の挙動
  • lat: 緯度
  • lon: 経度
  • alt: 高度
  • param1 - param4: 補足情報
  • flag: オプション

使用するコマンドは以下の2つ。

  • MSP_SET_WP: 245
  • MSP_SET_WP_TOTAL: 246

最初にMSP_SET_WP_TOTALで全ウェイポイントの個数を送信して、そのあとにMSP_SET_WPをそれぞれのウェイポイントを送る。

ウェイポイントはフライトコントローラがアーム状態にならないと設定できない? アーム状態には加速度センサーのキャリブレーションやGPSのFIX、受信機の受信状態などができてないとダメ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment