马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
PH7 当中的数据总线系统
ss15
PH7 代码框架中的数据总线系统
- 数据总线的使用:使用前在类实现 .cpp 文件中加入文件包含(文件路径根据实际情况确定)
#include "./UseGlobalObject.h"
- 通过bus.xxx.Get 或 bus.xxx.Set 的方式调用函数实现获取或设置总线数值等功能,。这里的xxx为总线数据项(bus item),如 bus.Ahrs 或 bus.sImu.GyrFilted 等。
- 每个数据总线项(bus item) 的实质是一个数据总线模板类对象。模板数据结构可以为如 uint16_t, bool, float 等的基本数据类型;也可为一个结构定义。
- 可以将逻辑上或物理上存在一定关系的多个数据合并为一个结构类型,然后定义该结构类型的模板类对象为总线数据项(bus item),例如先定义数据结构:
struct NAV { Location curr_loc; uint32_t pos_time_ms; float relative_altitude; // 气压场高, unit: m float airspeed; // 原始空速(融合) unit m/s float airspeed_smoothed; // m/s uint32_t airspeed_time_ms; float sink_rate; // 下降速率(气压) m/s }; 再进行总线数据项定义: CBusItem<AHRS> Ahrs;
有的情况下,如果一个结构定义包含了大量数据内容,且里面的数据内容在多个不同位置进行数值设置,那么使用一个庞大的结构类型作为模板数据类型就会很不方便且使用效率较低,这种情况下,可以首先定义一个结构类型,再将该结构的成员定义为模板类对象,这样使用起来就更加灵活和高效,如: struct IMU { CBusItem<Vector3f> GyrRaw; // unit: degree/s CBusItem<Vector3f> GyrFilted; CBusItem<Vector3f> AccRaw; // unit: m/s2 CBusItem<Vector3f> AccFilted; CBusItem<Vector3f> MagRaw; CBusItem<Vector3f> MagAvg; CBusItem<IMU_TEMPERATURE> Temp; }; 通过如下方式使用总线数据项: bus.sImu.GyrFilted.Get() bus.sImu.GyrFilted.Set()
在PH7框架中,数值型数据总线为主要的总线类型,此外,为了便于跨线程间安全使用及下行发送,PH7还设置了状态型数据总线作为补充。 数值型数据总线如各种飞控姿态、控制、运行等数据。是PH7系统中最主要的总线数据类型。其特点为数值变化范围较大,数据更新频率较快(10hz——1000Hz),数据流传输方向一般多为从底层(.drv)向顶层(.app)传递;多为在某一个线程中设置,在多个线程中共享获取。 数值型数据总线采用 bus.xxx.Set( )或bus.xxx.Get() 形式进行使用。若总线数据可能存在线程间共享冲突的时候,需要用 SetSafe()函数进行bus item的属性控制,即普通数据总线及安全数据总线,具体见后。 用户自定义的数值型数据总线需要下行发送时,用户需自行实现发送代码。 状态型数据总线顾名思义,多为状态类数据。其特点为数据变化范围有限,多为 bool类数据。数据变化频率较慢(一般10hz以下),数据传递方向多样,在多个不同线程中多次设置或获取。PH7框架中,目前可使用 64个bool型状态变量和8个uint8_t类型的状态变量。 状态型数据采用全局函数 gSetStatus() 及 gGetStatus() 形式进行使用,具有线程安全性和并发安全性,可在PH7代码中任意使用。 用户自定义的状态型数据总线原生具有下行发送机制,用户只需对数值进行设置即可。
- 设置普通数据总线项的数据,同时将该总线数据项的时间戳设定为当前时刻(单位ms, 精确到小数点后3位,即us)
bool Set(T Value) bool Set(T *pValue)
注意:数据总线项具有普通数据总线及安全数据总线两种属性。当为普通数据总线属性时,可以使用SetSafe(T Value, SET_DAT_PROP eCurrProp) 函数在设置数值的同时将其转换为安全数据总线。而Set函数无法对安全数据总线进行任何设置。 这里引入一个数据设置阶段(SET_DAT_PROP)的概念,一旦一个数据总线项在某一阶段被SetSafe() 函数转换为安全数据总线后,它的数值及时间戳对于其他数据阶段即变为只读,不再会被其他阶段的SetSafe函数所改变。 安全数据总线属性的意义在于为在线程间进行安全的数据共享。
- 将某个数据设置为安全数据总线项,同时将该总线数据项的时间戳设定为当前时刻(单位ms, 精确到小数点后3位,即us)
bool SetSafe(T Value, SET_DAT_PROP eCurrProp)
T Get() T &GetRef() - 获取最近一次总线数据项(CBusItem<T> 对象)调用 Set() 或 SetSafe() 时刻的时间戳(ms)
float GetTimeTag() - 获取总线数据项(CBusItem<T> 对象)两次调用 Set() 或 SetSafe() 函数中间的时间间隔
float GetPrevDt_ms()
- 设置状态型数据总线数值,调用以下全局函数设置/获取bool类型状态数据总线数据:
void gSetStatus(STATUS_BOOL eStatue, bool blValue, bool blForceUpdate) bool gGetStatus(STATUS_BOOL eStatue) 调用如下函数设置/获取多值型状态数据总线数据: void gSetStatus(STATUS_UINT eStatue, uint8_t uValue, bool blForceUpdate) uint8_t gGetStatus(STATUS_UINT eStatue) 上述函数在设置数据时的工作机制不同于数值型总线数据的直接赋值设置方式,其工作机制为向框架的MessageLoop处理中心发出一个设置状态数值Message,然后MessageLoop处理中心对消息进行处理并设置相应的状态数值。这样做的目的是为了使该函数具有线程安全性和并发安全性。 由于上述机制的存在,对于状态数值的设置频率不能高于MessageLoop运行的频率(250Hz),同时,使用gSetStatus()函数设置状态数值时,函数会自动监测当前状态与待设置状态是否相同,若相同,则参数blForceUpdate为false情况(默认状态)下gSetStatus函数不会再次设置相同的状态数值。除非用户令blForceUpdate为true。 bool型状态数据最多为64个,PH7框架自动将其全部通过mavlink协议下行发送。 多值型状态数据最多为8个,用户自行实现其下行发送方式。
|