BetaFlight模块设计之八:GPS任务分析

Posted lida2003

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BetaFlight模块设计之八:GPS任务分析相关的知识,希望对你有一定的参考价值。

BetaFlight模块设计之八:GPS任务分析

基于BetaFlight开源代码框架简介的框架设计,逐步分析内部模块功能设计。

GPS任务

描述:主要从GPS硬件获取GPS数据,并通知相关任务。

注:这里发现一个BetaFlight的问题,基本上都是全局变量(查询)在做通知,而没有像Paparazzi有内部总线(消息机制)。从设计耦合度的角度,全局变量是一种强依赖,而消息就已经解耦。

 ├──> 初始化
 │   ├──> [v]硬件初始化gpsInitHardware
 │   └──> [v]业务初始化gpsInit
 ├──> 任务
 │   ├──> [x]实时任务
 │   ├──> [x]事件任务
 │   └──> [v]时间任务[TASK_GPS] = DEFINE_TASK("GPS", NULL, NULL, gpsUpdate, TASK_PERIOD_HZ(TASK_GPS_RATE), TASK_PRIORITY_MEDIUM),
 ├──> 驱动
 │   ├──> [v]查询serialRxBytesWaiting/serialRead
 │   └──> [x]中断
 └──> 接口
     ├──> bool gpsIsHealthy()
     ├──> void gpsEnablePassthrough(serialPort_t *gpsPassthroughPort)
     ├──> void GPS_reset_home_position(void)
     ├──> 支持NMEA协议
     └──> 支持UBLOX协议

gpsUpdate函数分析

任务主函数,从结构化的角度看,如果能引入消息机制和组件模块化设计,程序结构上可能会更加便于理解和阅读。

gpsUpdate
 ├──> <GPS data from gpsPort>
 │   ├──> <serialRxBytesWaiting>
 │   │   ├──> <cmpTimeUs(micros(), currentTimeUs) > GPS_MAX_WAIT_DATA_RX>
 │   │   │   ├──> rescheduleTask(TASK_SELF, TASK_PERIOD_HZ(TASK_GPS_RATE_FAST));
 │   │   │   └──> return
 │   │   └──> gpsNewData(serialRead(gpsPort));
 │   └──> rescheduleTask(TASK_SELF, TASK_PERIOD_HZ(TASK_GPS_RATE));
 ├──> <GPS data from MSP, no serial port>
 │   ├──> gpsSetState(GPS_STATE_RECEIVING_DATA); // Never timeout
 │   ├──> onGpsNewData();
 │   └──> GPS_update &= ~GPS_MSP_UPDATE;
 ├──> <gpsData.state>
 │   ├──> <GPS_STATE_UNKNOWN><GPS_STATE_INITIALIZED>
 │   │   └──> break;
 │   ├──> <GPS_STATE_INITIALIZING><GPS_STATE_CHANGE_BAUD><GPS_STATE_CONFIGURE>
 │   │   └──> gpsInitHardware
 │   ├──> <GPS_STATE_LOST_COMMUNICATION>
 │   │   ├──> gpsData.timeouts++;
 │   │   ├──> <gpsConfig()->autoBaud>
 │   │   │   └──> Loop config baudrate
 │   │   └──> Init state config // gpsSol.numSat = 0; DISABLE_STATE(GPS_FIX); gpsSetState(GPS_STATE_INITIALIZING);
 │   └──> <GPS_STATE_RECEIVING_DATA>
 │       ├──> <Timeout check>
 │       │   └──> gpsSetState(GPS_STATE_LOST_COMMUNICATION);
 │       └──> <USE_GPS_UBLOX>
 │           └──> <gpsConfig()->autoConfig == GPS_AUTOCONFIG_ON>
 │               └──> <gpsData.state_position>
 │                   ├──> <0>
 │                   ├──> <!isConfiguratorConnected()>
 │                   │   ├──> [gpsData.ubloxUseSAT配置CLASS_NAVMSG_SAT or MSG_SVINFO]
 │                   │   └──> gpsData.state_position = 1;
 │                   ├──> <1>
 │                   │   ├──> <STATE(GPS_FIX) && (gpsConfig()->gps_ublox_mode == UBLOX_DYNAMIC)>
 │                   │   │   ├──> ubloxSendNAV5Message(true);
 │                   │   │   └──> gpsData.state_position = 2;
 │                   │   └──> <isConfiguratorConnected()>
 │                   │       └──> gpsData.state_position = 2;
 │                   └──> <2>
 │                       └──> <isConfiguratorConnected()>
 │                           ├──> [gpsData.ubloxUseSAT配置CLASS_NAVMSG_SAT or MSG_SVINFO]
 │                           └──>gpsData.state_position = 0;
 ├──> 状态执行时间更新
 ├──> <sensors(SENSOR_GPS)>
 │   └──> updateGpsIndicator(currentTimeUs);
 ├──> <!ARMING_FLAG(ARMED) && !gpsConfig()->gps_set_home_point_once>
 │   └──> uDISABLE_STATE(GPS_FIX_HOME);
 ├──> <USE_GPS_RESCUE><gpsRescueIsConfigured>
 │   ├──> updateGPSRescueState
 │   └──> minSats = gpsRescueConfig()->minSats;
 └──> <STATE(GPS_FIX)><gpsIsHealthy() && gpsSol.numSat >= minSats && !hasFix>
     └──>beeper(BEEPER_READY_BEEP);

gpsNewData函数分析

除了任务处理相关GPS状态,告警等处理外,gpsUpdate中真正GPS数据处理在这里完成。

gpsNewData
 ├──> <!gpsNewFrame(c)>
 │   └──> return
 ├──> <gpsData.state == GPS_STATE_RECEIVING_DATA>
 │   ├──> gpsData.lastLastMessage = gpsData.lastMessage;
 │   ├──> gpsData.lastMessage = millis();
 │   └──> sensorsSet(SENSOR_GPS);
 ├──> GPS_update ^= GPS_DIRECT_TICK;
 └──> onGpsNewData

gpsNewFrame函数分析

这里可以看出GPS大体两种协议格式:NEMA和UBLOX,其他不支持。

gpsNewFrame
 ├──> <GPS_NMEA><USE_GPS_NMEA>
 │   └──> gpsNewFrameNMEA
 ├──> <GPS_UBLOX><USE_GPS_UBLOX>
 │   └──> gpsNewFrameUBLOX
 └──> <other excep>
     └──> return false

onGpsNewData 函数分析

这里有GPS数据更新主要有两个大体用途:距离告警和GPS安全救援。

onGpsNewData
 ├──> <!(STATE(GPS_FIX) && gpsSol.numSat >= 5)>
 │   └──> return 
 ├──> [Delta Time in milliseconds for navigation computations, updated with every good GPS read]
 ├──> GPS_calculateDistanceAndDirectionToHome
 ├──> <ARMING_FLAG(ARMED)>
 │   └──> GPS_calculateDistanceFlownVerticalSpeed(false);
 └──> <USE_GPS_RESCUE>
     └──> rescueNewGpsData

以上是关于BetaFlight模块设计之八:GPS任务分析的主要内容,如果未能解决你的问题,请参考以下文章

BetaFlight模块设计之一:系统任务模块分析

BetaFlight模块设计之二:SERIAL任务分析

BetaFlight模块设计之十二:电传任务分析

BetaFlight模块设计之二十七:姿态更新任务分析

BetaFlight模块设计之二十八:MainPidLoop任务分析

BetaFlight模块设计之十三:Gyro过滤任务分析