iNavFlight之RC遥控MSP协议
- 1. RC摇杆MSP协议
- 2. 地面站配置 & MSP遥控器
- 2.1 iNav地面站-配置
- 2.2 iNav地面站-MSP遥控器
- 3. RC摇杆总体逻辑框架
- 4. RC摇杆代码设计框架
- 5. MSP摇杆代码设计
- 5.1 rxMspInit
- 5.2 rxMspFrameStatus
- 5.3 rxMspReadRawRC
- 5.4 rxMspFrameReceive
- 6. 整体Rx业务逻辑处理(processRx)
- 7. 参考资料
1. RC摇杆MSP协议
iNav在地面站配置工具中,有一个MSP遥控器。该遥控器模拟了一个RC遥控器,通过MSP协议将RC摇杆信息的发送给飞控。
因此,这里也就给第三方提供了遥控控制MSP协议接口,通过这个链路将可以给飞控发送RC摇杆信息。
2. 地面站配置 & MSP遥控器
2.1 iNav地面站-配置
使能MSP遥控器的方法,需要在iNav地面站配置软件里面选择接受模式为MSP。
2.2 iNav地面站-MSP遥控器
通过iNav地面站提供的遥控器UI界面,我们可以基本操作飞机。当然相对来说不是很方便 :)
但是不管如何,我们可以基于MSP协议,通过MSP遥控器来操作飞机。当然如果换成自己的接收机就可以控制飞机了(无需修改任何开源代码)。
3. RC摇杆总体逻辑框架
以RC摇杆信息为中心,从逻辑角度,需要三个步骤:
- 摇杆信息获取
- 摇杆信息处理
- 摇杆处理初始化
taskHandleSerial //摇杆信息获取
└──> mspFcProcessCommand
└──> mspFcProcessInCommand //case MSP_SET_RAW_RC
└──> rxMspFrameReceive
#define MSP_SET_RAW_RC 200
taskUpdateRxMain //摇杆信息处理
└──> processRx
└──> calculateRxChannelsAndUpdateFailsafe
main //摇杆处理初始化
└──> init
└──> rxInit
4. RC摇杆代码设计框架
鉴于摇杆信息从使用场景上看,主要是两种类型和十三种串行遥控器协议。所以,从整体上设计上需要考虑这些种类的摇杆信息输入。
typedef enum {
RX_TYPE_NONE = 0,
RX_TYPE_SERIAL,
RX_TYPE_MSP
} rxReceiverType_e;
typedef enum {
SERIALRX_SPEKTRUM1024 = 0,
SERIALRX_SPEKTRUM2048,
SERIALRX_SBUS,
SERIALRX_SUMD,
SERIALRX_IBUS,
SERIALRX_JETIEXBUS,
SERIALRX_CRSF,
SERIALRX_FPORT,
SERIALRX_SBUS_FAST,
SERIALRX_FPORT2,
SERIALRX_SRXL2,
SERIALRX_GHST,
SERIALRX_MAVLINK,
} rxSerialReceiverType_e;
经过整理和抽象以后,每种摇杆信息的使用过程无不离开如下五个步骤:
- rcInit
- rcFrameStatus
- rcProcessFrame
- rcReadRaw
- rcFrameReceive
5. MSP摇杆代码设计
本章重点介绍MSP摇杆的代码设计,当然我们依然按照逻辑思路和抽象化设计概念走。
- rcInit ==> rxMspInit
- rcFrameStatus ==> rxMspFrameStatus
- rcProcessFrame ==> 无,这里不展开,因为有些rc摇杆信息要做CRC校验等等之类操作。
- rcReadRaw ==> rxMspReadRawRC
- rcFrameReceive ==> rxMspFrameReceive
5.1 rxMspInit
基于MSP协议的RC摇杆初始化
- 将rxMspReadRawRC和rxMspFrameStatus两个处理函数挂上统一处理框架
- 支持18个RC摇杆通道
- 支持200ms超时处理
void rxMspInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig)
{
UNUSED(rxConfig);
rxRuntimeConfig->channelCount = MAX_SUPPORTED_RC_CHANNEL_COUNT;
rxRuntimeConfig->rxSignalTimeout = DELAY_5_HZ;
rxRuntimeConfig->rcReadRawFn = rxMspReadRawRC;
rxRuntimeConfig->rcFrameStatusFn = rxMspFrameStatus;
}
#define MAX_SUPPORTED_RC_CHANNEL_COUNT 18
#define DELAY_5_HZ (1000000 / 5)
5.2 rxMspFrameStatus
这个不难理解,无非就是MSP协议的RC摇杆只有两种状态:PENDING or COMPLETE
static uint8_t rxMspFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
{
UNUSED(rxRuntimeConfig);
if (!rxMspFrameDone) {
return RX_FRAME_PENDING;
}
rxMspFrameDone = false;
return RX_FRAME_COMPLETE;
}
5.3 rxMspReadRawRC
获取当前某个通道的摇杆值。
static uint16_t rxMspReadRawRC(const rxRuntimeConfig_t *rxRuntimeConfigPtr, uint8_t chan)
{
UNUSED(rxRuntimeConfigPtr);
return mspFrame[chan];
}
5.4 rxMspFrameReceive
收到报文直接进行复制,且报文数据按照0 - MAX_SUPPORTED_RC_CHANNEL_COUNT 依次排列。
注:
void rxMspFrameReceive(uint16_t *frame, int channelCount)
{
for (int i = 0; i < channelCount; i++) {
mspFrame[i] = frame[i];
}
// Any channels not provided will be reset to zero
for (int i = channelCount; i < MAX_SUPPORTED_RC_CHANNEL_COUNT; i++) {
mspFrame[i] = 0;
}
rxMspFrameDone = true;
}
6. 整体Rx业务逻辑处理(processRx)
略:详见void processRx(timeUs_t currentTimeUs)
注:这里就不再将代码一一罗列出来,看一遍加注释了。如果真有朋友有兴趣,请评论留言,我有机会一一整理。
7. 参考资料
【1】Multiwii Serial Protocol Version 2
【2】BetaFlight模块设计之三十二:MSP协议模块分析
【3】iNavFlight之MSP Sensor报文格式