本节的概要内容之前在《PH47代码框架二次开发极简教程》已经进行过初步讲解,阅读过之前内容的读者,可粗略了解本节内容,查缺补漏即可。
概述
数据总线系统为整个PH47代码框架及用户代码体系提供了设置、获取、交换数据的方法和途径。以及获取诸如设置获取数据时间戳,数据设置时间间隔,数据权限控制等功能。数据总线系统是PH47代码框架最常用和最重要的功能模块之一。
数据总线系统由一系列总线数据项(Bus item)构成,总线数据项构成方式可以是包含了一个数据简单类型(如 uint8_t,int32,float等)的数据项,也多个具有相关性的数据构成的复杂类型数据项,如结构变量。
目前PH47框架已经预置了大量针对小型固定翼及多旋翼飞行器飞行控制的总线数据,具体名称及对应数据可参见“附录2:PH47代码框架总线数据项说明”。
在整个PH47代码框架内,都可以使用全局引用对象bus来引用整个数据总线系统内的总线数据项,进而调用数据总线的功能函数。
基本使用步骤
加入UseGlobalObject.h文件包含
如果是在二次开发代码中首次使用数据总线功能,那么只需要在二次开发代码的.cpp文件顶部加入如下文件包含即可:
#include"../../Frame/UseGlobalObject.h"//文件包含路径根据实际情况确定
若是在PH47框架文件中(如应用层)使用数据总线,一般情况下都已经进行过必要的文件包含了,无需再次包含(以下均同)。
通过全局引用对象bus来调用总线系统功能函数
一般按照如下形式使用数据总线各种功能函数:
bus.BusItem.Function();
通过上述简单的两个步骤,即可完成对PH47代码框架中数据总线功能的使用。
简明使用指南
设置总线数据项数值(简称为设置数据总线yyy)
| 函数 | bool Set(T Value)bool Set(T *pValue) |
|---|---|
| 功能 | 通过模板类型变量或指针设置当前普通总线数据项数值(普通总线数据项相对于安全总线数据项,安全总线数据项由 SetSafe() 设定)。函数在设置总线数值的同时,还将当前函数执行时刻(精确到us)设置为当前总线数据的时间戳。 |
| 返回值 | 设置成功返回 true,否则false |
| 所属类 | CbusItem |
| 实现文件 | \DevStudio\Frame\BusItem.h |
// Demo
// 设置差分气压总线数据项fAspdDiffPress的数值为2.13(pa)
bus.fAspdDiffPress.Set(2.13f);
// 设置sImu.AccRaw的数值,总线AccRaw的时间戳默认为该语句执行时刻
Vector3i vAccRaw; vAccRaw.x = 0.12; vAccRaw.y = -0.02; vAccRaw.z = 9.82; bus.sImu.AccRaw.Set(&vAccRaw)
// 设置sImu.AccRaw的数值,并将强制设定该数值的设置时间戳为10062.107ms bus.sImu.AccRaw.Set(&vAccRaw,10062,107);
获取总线数据项的数值(简称读取总线yyy数值)
| 函数 | T Get()T &GetRef() |
|---|---|
| 功能 | 直接获取总线数据项数值,或获取总线数据项的引用 |
| 返回值 | 返回当前总线数据项数值 |
| 所属类 | CbusItem |
| 实现文件 | \DevStudio\Frame\BusItem.h |
// Demo
Vector3i vAccRaw = bus.sImu.AccRaw.Get();
Matrix3f dcm = bus.sAhrs.dcm.GetRef();
获取总线数据项AccFilted最近一次赋值时刻的ms时间计数
| 函数 | uint32_t GetTimeStamp_ms() |
|---|---|
| 功能 | 获取总线数据项最近一次赋值时刻的 ms 时间计数。 |
| 返回值 | ms 时间计数 |
| 所属类 | CBusItem |
| 实现文件 | \DevStudio\Frame\BusItem.h |
// 例如上一次赋值时刻为196603.874ms,则函数返回196603(ms)
uint32_t uTmTag_ms = bus.sImu.AccFilted.GetTimeStamp_ms();
获取总线数据项真实设置时刻与距离其最近的ms时刻间的us时间
| 函数 | uint32_t GetTimeStamp_us() |
|---|---|
| 功能 | 获取总线数据项最近一次赋值时刻的 us 时间计数。 |
| 返回值 | us 时间计数 |
| 所属类 | CBusItem |
| 实现文件 | \DevStudio\Frame\BusItem.h |
| 示例 |
// 例如上一次赋值时刻为196603.874ms,则函数返回874(us)
uint16_t uTmpTm_us = bus.sImu.AccFilted.GetTmStampDec_us();
获取总线数据项AccFilted最近两次设置时的时间间隔(ms)
| 函数 | uint32_t GetDt2Prev_ms() |
|---|---|
| 功能 | 获取总线数据项最近两次设置时的时间间隔(ms) |
| 返回值 | ms时间间隔 |
| 所属类 | CBusItem |
| 实现文件 | \DevStudio\Frame\BusItem.h |
uint32_t uSetInv_ms = bus.sImu.AccFilted.GetDt2Prev_ms();
获取总线数据项AccFilted最近两次设置时的时间间隔(us)
| 函数 | uint32_t GetDt2Prev_us() |
|---|---|
| 功能 | 功能同上,但时间单位为us |
| 返回值 | ms时间间隔 |
uint32_t uSetInv_us = bus.sImu.AccFilted.GetDt2Prev_us();
总线数据项的构成方式
本节及下一节内容为在二次开发过程中创建新的总线数据项必备知识。初学者在不涉及创建新的总线数据项时可粗略了解本节及下一节内容。
PH47代码框架的总线系统实质是通过模板类定义方式来实现总线数据项,定义模板类的类型即为总线数据项的类型。由此,总线数据项的构成可以有如下3种方式:
以单个数据的类型做为模板参数定义模板类对象,即数据总线项
CBusItem<float> fAspdDiffPress;
多个数据聚合成结构后,以结构类型作为模板参数定义模板类对象,即总线数据项bus item
// step1:定义结构
struct HOMEINFO
{
LocationLoc; floatBaroAlt;
};
// step2:以结构类型声明模板类对象(bus item)
CBusItem<HOMEINFO> Home;
以单个数据定义模板类对象后,再将多个模板类对象聚合成一个结构
// step1:定义结构
struct HOMEINFO
{
LocationLoc;
floatBaroAlt;
};
// step2:以结构类型声明模板类对象(bus item)
CBusItem<HOMEINFO> Home;
上述三种总线数据项定义方式中,推荐使用第一、第三种方式,在实际编程中比较方便。
加入用户自定义总线数据项
简单类型总线数据项加入
在需要使用总线的.cpp文件头部加入对数据总线的文件包含:
#include"../../Frame/UseGlobalObject.h"//文件包含路径根据实际情况确定
在\DevStudio\BoardConfig\Board_xxx\DataBus_xxx.h文件中注释为"用户自定义设置区域"内加入自有总线数据的定义(注意!不要对该区域以外的总线数据声明进行任何修改或删除!!!),之后就可以使用总线相关函数实现各种功能了.
CBusItem<float> fAspdDiffPress;// float类型的bus item
复杂类型总线数据项加入
第一步:在需要使用总线的.cpp文件头部加入对数据总线的文件包含:
#include"../../Frame/UseGlobalObject.h"
第二步:在文件\DevStudio\BoardConfig\Board_xxx\BusItemDef4User.h中加入对复杂类型的结构声明如下:
structBUS_ITEM_DEMO
{
CBusItem<uint8_t>Item_A;
CBusItem<float>Item_B;
};
第三步:在\DevStudio\BoardConfig\Board_xxx\DataBus_xxx.h文件的“用户自定义参数设置区域”加入总线数据的定义:
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
// 用户自定义参数设置区域, 不得对该区域之外的任何内容进行修改
BUS_ITEM_DEMO sBusItemDemo;
// <=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>=<=>
模板变量本身就是一个结构变量的总线数据项
复杂类型总线数据项还有一种形式,即用于定义总线数据项的模板变量本身就是一个结构变量,此方式的典型例子为总线数据项bus.OptiFlowTof_MTF01,具体描述位于"实战教程--添加光流传感器.h"的"4.在PH47代码框架中添加专用新传感器的数据总线"中有详细解释。
全局状态变量
概述
全局状态变量是一种特殊的总线数据项,其数据赋值具有线程安全性和并发安全性。PH47框架已经封装实现全局状态变量的下行传输机制,该变量的数值通过 mavlink 的 STATUS_EXT_HIGH 消息 以 5Hz 的频率下行传输,用户无需自己实现下行机制。
全局状态变量具有 bool, uint8_t 两种类型,bool 型全局状态变量最多可设置 48 个,uint8_t型共有8个,留给用户自定义使用的 6 个
设置bool 型全局状态变量数值
| 函数 | void gSetStatus(STATUS_BOOL eStatue, bool blValue, bool blForceUpdate = false); | |
|---|---|---|
| 功能 | 设置 bool 类型的全局状态变量。本函数具有线程安全性和并发安全性, 同时在 PH47 代码框架中已经预置了全局状态的下行传输机制, 用户无需自己实现。 注意,本函数的重复调用频率不能超过250Hz | |
| 参数 | eStatue | 全局变量 id |
| blValue: | 全局变量状态 | |
| blForceUpdate | 是否强制更新状态。为false时, 若设置状态与变量当前状态相同, 则不对当前状态进行更新。 | |
| 所属类 | 全局函数 | |
| 实现文件 | D:\Stm32H7 prog\PH47\DevStudio\Frame\GlobalFun.h | |
| 示例 |
获取bool型全局状态变量数值。
| 函数 | bool gGetStatus(STATUS_BOOL eStatue) |
|---|---|
| 功能 | 获取 bool 类型的全局状态变量数值 |
| 参数 | eStatue 全局变量 id |
| 返回值 | bool 类型的全局变量状态 |
| 所属类 | 全局函数 |
| 实现文件 | D:\Stm32H7 prog\PH47\DevStudio\Frame\GlobalFun.h |
| 示例 |
_sFlags.initialized = gGetStatus(S_AHRS_INITED);
设置 uint8_t型全局状态变量数值
// 设置 bool 型全局状态变量 S_FAILURE_TELE 数值为 true,
// 且不论之前数值是什么,均强制进行更新
gSetStatus(S_FAILURE_TELE, true);
获取uint8_t型全局状态变量eStatue的状态
uint8_t gGetStatus(STATUS_UINT eStatue);
创建用户自定义全局状态变量
相关文件
DevStudio\BoardConfig\Board_BBP\StateVarDef_BBP.h对全局状态变量的ID进行了定义,此文件中的enumSTATUS_BOOL及enumSTATUS_UINT枚举分别定义了bool及uint8_t类型的全局状态变量ID。
与自定义总线数据类似,自定义全局状态变量必须位于标注“用户自定义参数设置区域”的区域内。二次开发永不能对该区域意外的任何内容进行删除或修改。
- 步骤1:加入UseGlobalObject.h文件包含
在需要使用全局状态变量的.cpp文件头部加入文件包含:
#include"../../Frame/UseGlobalObject.h" //文件包含路径根据实际情况确定
-
步骤2:加入自定义全局变量ID
以确定是否开始惯性制导的标志变量S_INSNAV_START为例,在DevStudio\BoardConfig\Board_XXX\StateVarDef_XXX.h文件的enum STATUS_BOOL声明的用户自定义部分加入S_INSNAV_START声明。
之后在程序中需要的地方就可以通过gSetStatus(S_INSNAV_START,true); 或gSetStatus(S_INSNAV_START); 设置获取状态。
更多内容见CSDN博客专栏:无人机飞控
https://blog.csdn.net/ss15/category_9690939.html?spm=1001.2014.3001.5482相关资源:PH47: PH47运动控制代码框架.
https://gitee.com/ss15/ph47

1300

被折叠的 条评论
为什么被折叠?



