BetaFlight代码解析(17)—遥测系统

本文档介绍了Betaflight的遥测系统架构,该系统使飞行控制器能够将飞行数据、传感器读数和状态信息传输到外部接收器、地面站和屏幕显示(OSD)系统。遥测系统支持多种协议,并管理数据调度、格式化和传输。

系统架构

遥测系统为多种遥测协议提供了一个统一的框架,每种协议都针对特定的接收机生态系统和应用场景而设计。该系统负责协议初始化、从各种飞行控制器子系统收集数据、根据协议规范进行数据格式化以及传输调度。

支持的协议

该遥测系统支持六种主要协议,每种协议都针对不同的接收器生态系统和带宽要求进行了优化:

协议文件波特率用例主要特点
FrSky SmartPortsmartport.c57600FrSky接收机传感器轮询,MSP 支持
CRSF(Crossfire)crsf.c420000+ExpressLRS,TBS高带宽,MSP隧道
格劳普纳HoTThott.c19200格劳普纳系统双向文本模式
MAVLinkmavlink.c多变的地面站完整飞行数据
光遥测(LTM)ltm.c1200-2400低带宽 OSD最小数据集
FlySky iBusibus.c115200FlySky接收器传感器框架

协议初始化模式

每个协议都遵循由中央遥测系统管理的统一初始化模式:

CRSF遥测实施

CRSF(Crossfire)代表了 Betaflight 中最先进的遥测实现,支持高带宽数据传输、MSP 命令隧道以及波特率协商等高级功能。

CRSF帧调度

CRSF 使用轮询调度器来确定每个周期要发送的遥测帧:

// Scheduling array populated during initialization
static uint8_t crsfSchedule[CRSF_SCHEDULE_COUNT_MAX];
static uint8_t crsfScheduleIndex = 0;

// Frame types are scheduled based on sensor availability
if (sensors(SENSOR_ACC) && telemetryIsSensorEnabled(SENSOR_PITCH | SENSOR_ROLL | SENSOR_HEADING)) {
    crsfSchedule[index++] = BIT(CRSF_FRAME_ATTITUDE_INDEX);
}

SmartPort遥测实现

SmartPort遥测技术采用轮询协议,接收器通过ID请求特定的传感器数据。飞行控制器在收到轮询请求后,会返回请求的数据。

SmartPort传感器管理

SmartPort维护着一个已启用传感器及其对应数据ID的表格:

// Sensor initialization adds enabled sensors to the table
#define ADD_SENSOR(dataId) frSkyDataIdTableInfo.table[frSkyDataIdTableInfo.index++] = dataId

static void initSmartPortSensors(void) {
    if (telemetryIsSensorEnabled(SENSOR_VOLTAGE)) {
        ADD_SENSOR(FSSP_DATAID_VFAS);
    }
    if (telemetryIsSensorEnabled(SENSOR_CURRENT)) {
        ADD_SENSOR(FSSP_DATAID_CURRENT);
    }
    // Additional sensors...
}

通过遥测技术实现的MSP

多种遥测协议支持 MSP(MultiWii 串行协议)隧道,允许配置工具通过遥测链路与飞行控制器通信。

MSP帧处理

通过遥测技术接收到的MSP帧会被缓冲并异步处理:

// MSP frame buffering for CRSF
bool bufferCrsfMspFrame(uint8_t *frameStart, int frameLength) {
    if (mspRxBuffer.len + CRSF_MSP_LENGTH_OFFSET + frameLength > CRSF_MSP_BUFFER_SIZE) {
        return false;
    }
    uint8_t *p = mspRxBuffer.bytes + mspRxBuffer.len;
    *p++ = frameLength;
    memcpy(p, frameStart, frameLength);
    mspRxBuffer.len += CRSF_MSP_LENGTH_OFFSET + frameLength;
    return true;
}

配置和传感器管理

遥测系统可对传输哪些传感器数据进行精细控制,使用户能够优化带宽使用并自定义发送给接收器的数据。

遥测配置结构

typedef struct telemetryConfig_s {
    int16_t gpsNoFixLatitude;
    int16_t gpsNoFixLongitude;
    uint8_t telemetry_inverted;
    uint8_t halfDuplex;
    uint8_t frsky_coordinate_format;
    uint8_t frsky_unit;
    uint8_t frsky_vfas_precision;
    uint8_t hottAlarmSoundInterval;
    uint8_t pidValuesAsTelemetry;
    uint8_t report_cell_voltage;
    uint8_t flysky_sensors[IBUS_SENSOR_COUNT];
    uint16_t mavlink_mah_as_heading_divisor;
    uint32_t disabledSensors; // bit flags
    uint8_t mavlink_min_txbuff;
} telemetryConfig_t;

传感器启用/禁用系统

遥测系统使用位标志来控制哪些传感器处于活动状态:

// Sensor enumeration
typedef enum {
    SENSOR_VOLTAGE         = 1 << 0,
    SENSOR_CURRENT         = 1 << 1,
    SENSOR_FUEL            = 1 << 2,
    SENSOR_MODE            = 1 << 3,
    SENSOR_ACC_X           = 1 << 4,
    SENSOR_ACC_Y           = 1 << 5,
    SENSOR_ACC_Z           = 1 << 6,
    SENSOR_PITCH           = 1 << 7,
    SENSOR_ROLL            = 1 << 8,
    SENSOR_HEADING         = 1 << 9,
    SENSOR_ALTITUDE        = 1 << 10,
    SENSOR_VARIO           = 1 << 11,
    SENSOR_LAT_LONG        = 1 << 12,
    SENSOR_GROUND_SPEED    = 1 << 13,
    SENSOR_DISTANCE        = 1 << 14,
    ESC_SENSOR_CURRENT     = 1 << 15,
    ESC_SENSOR_VOLTAGE     = 1 << 16,
    ESC_SENSOR_RPM         = 1 << 17,
    ESC_SENSOR_TEMPERATURE = 1 << 18,
    SENSOR_TEMPERATURE     = 1 << 19,
    SENSOR_CAP_USED        = 1 << 20,
} sensor_e;

// Sensor checking function
bool telemetryIsSensorEnabled(sensor_e sensor) {
    return ~(telemetryConfig()->disabledSensors) & sensor;
}

港口共享和国家管理

遥测系统在共享串行端口时必须与接收器协议协调,特别是对于 CRSF 和 iBus 等协议,因为相同的物理连接既处理 RC 输入又处理遥测输出。

端口共享逻辑

bool telemetryCheckRxPortShared(const serialPortConfig_t *portConfig, const SerialRXType serialrxProvider) {
    if (portConfig->functionMask & FUNCTION_RX_SERIAL && 
        portConfig->functionMask & TELEMETRY_SHAREABLE_PORT_FUNCTIONS_MASK &&
        (serialrxProvider == SERIALRX_SPEKTRUM1024 ||
         serialrxProvider == SERIALRX_SPEKTRUM2048 ||
         serialrxProvider == SERIALRX_SBUS ||
         serialrxProvider == SERIALRX_SUMD ||
         serialrxProvider == SERIALRX_SUMH ||
         serialrxProvider == SERIALRX_XBUS_MODE_B ||
         serialrxProvider == SERIALRX_XBUS_MODE_B_RJ01 ||
         serialrxProvider == SERIALRX_IBUS)) {
        return true;
    }
    return false;
}

遥测状态确定

bool telemetryDetermineEnabledState(portSharing_e portSharing) {
    bool enabled = portSharing == PORTSHARING_NOT_SHARED;
    
    if (portSharing == PORTSHARING_SHARED) {
        if (isModeActivationConditionPresent(BOXTELEMETRY))
            enabled = IS_RC_MODE_ACTIVE(BOXTELEMETRY);
        else
            enabled = ARMING_FLAG(ARMED);
    }
    
    return enabled;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值