首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

PX4 Mixer 機制深度解析:以 UAVCAN ESC 為例

     編輯:Java 綜合教學

PX4 Mixer 機制深度解析:以 UAVCAN ESC 為例

PX4 固件中,mixer 是一個系統命令(位於 Firmware/src/systemcmds/mixer),負責將混控定義文件(.mix)解析並加載到具體輸出設備(如 UAVCAN ESC,設備節點 /dev/uavcan/esc)。設備驅動中的 MixerGroup 負責解析並執行混控邏輯。

三種 Mixer 類型

類型用途
NullMixer佔位未分組的輸出通道
SimpleMixer0~N 個輸入線性組合為 1 個輸出
MultirotorMixer將 ROLL/PITCH/YAW/THROTTLE 按預定義幾何矩陣映射為多輸出(多旋翼電調)

混控文件加載流程

  1. 讀取文件:mixer_load.c 中 load_mixer_file() 讀取 .mix 文件,過濾非法行(長度<2、首字符非大寫、第二字符非 ':'),將合法行存入緩衝區。
  2. IOCTL 傳遞:調用 ioctl(dev, MIXERIOCLOADBUF, buf) 將緩衝區傳給設備驅動。
  3. 驅動解析:以 UAVCAN 為例,uavcan_main.cpp 的 ioctl() 處理 MIXERIOCLOADBUF,調用 MixerGroup::load_from_buf() 逐行解析。

關鍵數據結構

// 單通道縮放參數(對應 O: 後 5 個整數 / 10000.0f)
struct mixer_scaler_s {
    float negative_scale;  // 負向縮放
    float positive_scale;  // 正向縮放
    float offset;          // 偏移
    float min_output;      // 最小輸出
    float max_output;      // 最大輸出
};

// 輸入控制源(對應 S: 後 7 個整數)
struct mixer_control_s {
    uint8_t control_group;  // 輸入組號
    uint8_t control_index;  // 組內索引
    struct mixer_scaler_s scaler;  // 縮放參數
};

// SimpleMixer 定義
struct mixer_simple_s {
    uint8_t control_count;           // 輸入數量
    struct mixer_scaler_s output_scaler; // 輸出縮放
    struct mixer_control_s controls[0];  // 柔性數組,大小由 control_count 決定
};

解析邏輯:MixerGroup::load_from_buf()

遍歷緩衝區,根據行首字符分發:

  • Z → NullMixer::from_text()
  • M → SimpleMixer::from_text()
  • R → MultirotorMixer::from_text()

解析成功則 add_mixer(m) 加入組,更新剩餘緩衝長度。

SimpleMixer 詳細解析

1. 讀取輸入數量

sscanf(buf, "M: %u%n", &inputs, &used);  // M: 3
buf = skipline(buf, buflen);  // 移至下一行

2. 分配內存

mixinfo = malloc(MIXER_SIMPLE_SIZE(inputs));
// MIXER_SIMPLE_SIZE = sizeof(mixer_simple_s) + inputs * sizeof(mixer_control_s)

3. 解析輸出縮放

int parse_output_scaler(const char* buf, unsigned& buflen, mixer_scaler_s& scaler) {
    buf = findtag(buf, buflen, 'O');  // 找到 O: 行
    int s[5];
    sscanf(buf, "O: %d %d %d %d %d %n", &s[0], &s[1], &s[2], &s[3], &s[4], &n);
    scaler.negative_scale = s[0] / 10000.0f;
    scaler.positive_scale = s[1] / 10000.0f;
    scaler.offset         = s[2] / 10000.0f;
    scaler.min_output     = s[3] / 10000.0f;
    scaler.max_output     = s[4] / 10000.0f;
    return 0;
}

4. 循環解析每個輸入

for (unsigned i = 0; i < inputs; i++) {
    parse_control_scaler(buf, buflen,
        mixinfo->controls[i].scaler,
        mixinfo->controls[i].control_group,
        mixinfo->controls[i].control_index);
}
// S: group index neg_scale pos_scale offset min max

.mix 文件示例

M: 2          # 2 個輸入
O: 10000 10000 0 -10000 10000  # 輸出縮放
S: 0 0 10000 10000 0 -10000 10000  # 輸入 0: 組0 索引0
S: 0 1 10000 10000 0 -10000 10000  # 輸入 1: 組0 索引1

總結

Mixer 機制將控制分配邏輯從飛控核心剝離,通過文本文件配置,實現了靈活的輸出映射。理解其數據結構與解析流程,有助於開發自定義混控、調試輸出異常、移植新硬件平台。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved