Pixhawk 遥控信号处理

生产

RC 信号由 src/drivers/px4io/px4io.cpp#L1653 发布,频率上限只有 50Hz (由 IO_POLL_INTERVAL 限制)。

事实上在同一块代码里发现,对电调的 PWM 输出也是限制在 50Hz。

发布载体为 struct rc_input_valuessensors.cpprc_poll() 流程如下:

  1. 发布流程图表明,无论信号质量怎样, rc_channels 总是会广播。本信息放的是归一化后的各通道数值,限制在 -1~1

    根据 rc_channels 的处理方式,油门的 trim 设置非常重要,一定等于该通道的最小值

  2. 如果信号质量正常,还会广播以 struct manual_control_setpoints_s 为载体的 manual_control_setpoint

    在 manual 控制模式下,本消息会复制到 _v_att_sp 供姿态控制 app 使用

  3. 最后,manual_control_setpoint 会复制到 actuator_controls_3,至于怎么用,需要进一步研究

内部消费

mavlink 模块会发送两种 RC 包,分别为 RC_CHANNELS_RAWRC_CHANNELS

RC_CHANNELS_RAW

RC_CHANNELS_RAW 是为了兼容老的飞控搞的一个消息。生成机制如下:

  • 首先,消息载体 mavlink_rc_channels_raw_t 只能装 8 路信号,然后一位 port 指示这 8 路走哪个端口。事实上好的遥控器很容易就超过 8 路,比如说有 18 路的 Futaba,那么这个载体肯定是不够用的。在这种情况下,port 可以复用来指示是低 8 路,中 8 路或者高 8 路;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct __mavlink_rc_channels_raw_t
    {
    uint32_t time_boot_ms; ///< Timestamp (milliseconds since system boot)
    uint16_t chan1_raw; ///< RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan2_raw; ///< RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan3_raw; ///< RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan4_raw; ///< RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan5_raw; ///< RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan6_raw; ///< RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan7_raw; ///< RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint16_t chan8_raw; ///< RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
    uint8_t port; ///< Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos.
    uint8_t rssi; ///< Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown.
    } mavlink_rc_channels_raw_t;
  • 然后,在 uORB 上实际在走的 rc 载体是 struct rc_input_values,除去 18 路信号外,还包含时间戳,丢包统计之类的东西,参见 drv_rc_input.h#90L;

  • mavlink 发送 RC 包的时候,会循环 3 次,发送 MAVLINK_MSG_ID_RC_CHANNELS_RAW 信息(因为一次只能发 8 路。。。)

RC_CHANNELS

RC_CHANNELS_RAW 消息发送以后,mavlink 会紧跟上发送 RC_CHANNELSRC_CHANNELS 的载体是 mavlink_rc_channels_t,跟 struct rc_input_values 相比,主要是少了丢包信息。

优化

简单地说,RC_CHANNELS_RAW 基本不会用到,发送频率又跟 RC_CHANNELS 绑定,最好的方法是直接注释掉。