Livox Mid-70 + Python
2026年 04月 08日 水曜日
TL;DR
- Livox Mid-70 を購入したので確認
- 公式 SDK は C++ のみだが、plot とかもやりたかったので Python で try
- CRC32 + Handshake の cmd_type でハマったのでそちらも絡めて
背景
Livox Mid-70 の公式 SDK(Livox-SDK)は C/C++ のみ。購入後の動作確認を Python でサクッとやりたかったので、Wiki の Communication Protocol を見ながら UDP 通信を書いてみた。
はまりどころ 1: CRC32
Wiki にはこう書いてある:
crc32 initial value: 0x564F580A
素直にビットシフトで実装すると SDK と異なる値が出る。実際の SDK は CRC-32/ADCCP(標準 CRC32)を使っていて、内部で init ^ 0xFFFFFFFF と result ^ 0xFFFFFFFF が入る。
# NG
def calc_crc32(data: bytes) -> int:
crc = 0x564F580A
for b in data:
crc ^= b
for _ in range(8):
crc = (crc >> 1) ^ 0xEDB88320 if (crc & 1) else (crc >> 1)
return crc & 0xFFFFFFFF
# OK: binascii.crc32 が XOR を自動でやってくれる
import binascii
def calc_crc32(data: bytes) -> int:
return binascii.crc32(data, 0x564F580A) & 0xFFFFFFFFCRC16 は Wiki 通りで問題ない。CRC32 だけ罠。
はまりどころ 2: Handshake の cmd_type
通常コマンドは cmd_type=0x00(Request)だが、Handshake だけは cmd_type=0x01(ACK)で送る。Broadcast への応答という扱いらしい。SDK の実パケットを見て気づいた。
def make_handshake() -> bytes:
ip = bytes(int(x) for x in PC_IP.split("."))
payload = ip + struct.pack("<HHH", DATA_PORT, PC_CMD_PORT, DATA_PORT)
return build_frame(0x00, 0x01, payload, cmd_type=0x01) # ACK動作した接続シーケンス
- Broadcast 受信 — port 55000
- Handshake — cmd_type=0x01, cmd_id=0x01, payload に IP + ポート。ret_code=0x00 を確認
- Heartbeat — cmd_id=0x03 で working_state=1 になるまでポーリング
- Start Sampling — cmd_id=0x04, payload=0x01
- 点群受信 — data_type=2 (Cartesian int32), 14bytes/point
- Heartbeat 維持 — 約 1 秒間隔(止めると LiDAR が再 Broadcast に戻る)
まとめ
Wiki だけだと少し足りないところがあり、特に CRC32 は SDK のソースを見ないと気づきにくい。同じことをやる人の参考になれば。
参考リンク
公式情報
あわせて読むと理解しやすい項目
この記事をシェア