Files
Vision/docs/云台通信协议指南.md
T

4.8 KiB
Raw Blame History

云台通信协议指南

串口配置

参数 值
波特率 921600
数据位 8
停止位 1
校验位 None

帧格式总览

所有帧通过帧头 (SOF) 区分类型,checksum = 帧头到数据末尾前一字节的所有字节累加和取低 8 位。

帧头 长度 用途
0xA5 10 自动/视觉追踪数据
0xA6 11 手动控制数据
0xA7 3 命令
0xA8 50 调试调参数据

1. 自动/视觉追踪数据帧 0xA5 (10 字节)

用途: 视觉识别完成后持续发送跟踪误差。

[SOF:0xA5][error_x:4][error_y:4][checksum:1]
偏移 长度 类型 含义
0 1 uint8 帧头 0xA5
1 4 float 归一化 X 轴误差
5 4 float 归一化 Y 轴误差
9 1 uint8 checksum

Python 写入示例:

import struct

def send_auto_tracking(ser, error_x: float, error_y: float):
    data = bytearray()
    data.append(0xA5)
    data.extend(struct.pack('<ff', error_x, error_y))
    checksum = sum(data) & 0xFF
    data.append(checksum)
    ser.write(data)

2. 手动控制数据帧 0xA6 (10 字节)

用途: 手动模式下发送角速度目标值。

[SOF:0xA6][yaw_velocity:4][pitch_velocity:4][checksum:1]
偏移 长度 类型 含义
0 1 uint8 帧头 0xA6
1 4 float Yaw 角速度 (degrees/s)
5 4 float Pitch 角速度 (degrees/s)
9 1 uint8 checksum

Python 写入示例:

def send_manual_control(ser, yaw_deg_per_s: float, pitch_deg_per_s: float):
    data = bytearray()
    data.append(0xA6)
    data.extend(struct.pack('<ff', yaw_deg_per_s, pitch_deg_per_s))
    checksum = sum(data) & 0xFF
    data.append(checksum)
    ser.write(data)

3. 命令帧 0xA7 (3 字节)

用途: 切换模式和控制激光。

[SOF:0xA7][cmd:1][checksum:1]
cmd 值 含义
0x01 切换到自动/视觉追踪模式
0x02 切换到手动模式
0x05 切换到调试模式 (失能所有电机)
0x03 激光开
0x04 激光关

Python 写入示例:

CMD_AUTO  = 0x01
CMD_MANUAL = 0x02
CMD_LASER_ON  = 0x03
CMD_LASER_OFF = 0x04
CMD_DEBUG = 0x05

def send_command(ser, cmd: int):
    data = bytearray([0xA7, cmd])
    checksum = sum(data) & 0xFF
    data.append(checksum)
    ser.write(data)

4. 调试调参帧 0xA8 (50 字节)

用途: 在调试模式下发送 PID 参数进行调参。发送后固件会立即生效。

[SOF:0xA8]
[vision_yaw_Kp:4][vision_yaw_Ki:4][vision_yaw_Kd:4]
[vision_pitch_Kp:4][vision_pitch_Ki:4][vision_pitch_Kd:4]
[motor_yaw_Kp:4][motor_yaw_Ki:4][motor_yaw_Kd:4]
[motor_pitch_Kp:4][motor_pitch_Ki:4][motor_pitch_Kd:4]
[checksum:1]
偏移 长度 类型 含义
0 1 uint8 帧头 0xA8
1 4 float 视觉环 Yaw Kp
5 4 float 视觉环 Yaw Ki
9 4 float 视觉环 Yaw Kd
13 4 float 视觉环 Pitch Kp
17 4 float 视觉环 Pitch Ki
21 4 float 视觉环 Pitch Kd
25 4 float 电机角度环 Yaw Kp
29 4 float 电机角度环 Yaw Ki
33 4 float 电机角度环 Yaw Kd
37 4 float 电机角度环 Pitch Kp
41 4 float 电机角度环 Pitch Ki
45 4 float 电机角度环 Pitch Kd
49 1 uint8 checksum

Python 写入示例:

def send_debug_tune(ser,
                    v_yaw_kp, v_yaw_ki, v_yaw_kd,
                    v_pitch_kp, v_pitch_ki, v_pitch_kd,
                    m_yaw_kp, m_yaw_ki, m_yaw_kd,
                    m_pitch_kp, m_pitch_ki, m_pitch_kd):
    data = bytearray()
    data.append(0xA8)
    data.extend(struct.pack('<fff', v_yaw_kp, v_yaw_ki, v_yaw_kd))
    data.extend(struct.pack('<fff', v_pitch_kp, v_pitch_ki, v_pitch_kd))
    data.extend(struct.pack('<fff', m_yaw_kp, m_yaw_ki, m_yaw_kd))
    data.extend(struct.pack('<fff', m_pitch_kp, m_pitch_ki, m_pitch_kd))
    checksum = sum(data) & 0xFF
    data.append(checksum)
    ser.write(data)

调试流程

  1. 上位机发送命令帧 (0xA7, cmd=0x05) 切换到调试模式
  2. 固件收到后失能 yaw 和 pitch 电机,日志指示进入调试模式
  3. 通过 0xA8 帧写入 PID 参数,参数会实时生效:
    • 视觉环 PID → 直接写入选中的视觉 PID 实例
    • 电机角度环 PID → 通过话题推送到 gimbal 更新电机角度 PID
  4. 调试完毕后,发送命令帧 (0xA7, cmd=0x02 手动 或 0x01 自动) 切出调试模式,电机会自动使能

校验和计算

def calc_checksum(data: bytes) -> int:
    return sum(data) & 0xFF  # 所有字节累加取低 8 位

校验和覆盖范围:帧头到数据末尾前一字节的全部字节。接收端在收到数据后也应计算并比对校验和。