"""send_control.py —— 向吊舱下发单帧 表2-1 控制指令(台架工具,非飞行组件)。 用途:验证吊舱下行链路与各类指令动作(开目标识别/框选跟踪/归中/开电机等), 配合 listen_pod.py 观察遥测状态变化。 用法: python utils/pod_bridge/send_control.py /dev/ttyAMA0 --code TARGET_DETECT_ON --param-x 0 python utils/pod_bridge/send_control.py /dev/ttyAMA0 --code 0x2B # 归中 python utils/pod_bridge/send_control.py --list # 列出全部控制码 控制码可用名字(ControlCode 成员名,如 TARGET_DETECT_ON)或数值(0x07 / 7)。 """ import argparse import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) # utils/ 入 sys.path from pod_bridge.pod_serial import PodSerial # noqa: E402 from pod_bridge.protocol import ControlCode, ControlCommand, encode_control # noqa: E402 def _resolve_code(text: str) -> int: """控制码:支持名字(TARGET_DETECT_ON)或数值(0x07 / 7)。""" name = text.upper() if hasattr(ControlCode, name): return int(getattr(ControlCode, name)) try: return int(text, 0) except ValueError: raise SystemExit(f"无法解析控制码: {text}(用 --list 查看可用名字)") def main() -> int: ap = argparse.ArgumentParser(description="下发单帧吊舱控制指令(表2-1)") ap.add_argument("port", nargs="?", default="/dev/ttyAMA0", help="串口设备号") ap.add_argument("--baud", type=int, default=115200) ap.add_argument("--code", help="控制码名字或数值,如 TARGET_DETECT_ON / 0x2B") ap.add_argument("--param-x", type=int, default=0) ap.add_argument("--param-y", type=int, default=0) ap.add_argument("--param3", type=int, default=0) ap.add_argument("--param-x2", type=int, default=0) ap.add_argument("--param-y2", type=int, default=0) ap.add_argument("--list", action="store_true", help="列出全部控制码后退出") args = ap.parse_args() if args.list: for c in ControlCode: print(f"0x{c.value:02X} {c.name}") return 0 if not args.code: ap.error("需要 --code(或用 --list 查看可用控制码)") code = _resolve_code(args.code) cmd = ControlCommand(code=code, param_x=args.param_x, param_y=args.param_y, param3=args.param3, param_x2=args.param_x2, param_y2=args.param_y2) frame = encode_control(cmd) pod = PodSerial(args.port, args.baud) pod.send(frame) pod.close() print(f"[send] {args.port} 下发 0x{code:02X} → {' '.join(f'{b:02X}' for b in frame)}") return 0 if __name__ == "__main__": sys.exit(main())