PX4 您所在的位置:网站首页 pix飞控调参中文对照表 PX4

PX4

2022-06-10 05:14| 来源: 网络整理| 查看: 265

参数是PX4飞控中掉电保存的变量,用于存储飞控的设置、校准系数等数据。

PX4有一套完善的参数框架,对于用户而言只需要非常简单的几个语句就可以完成参数的添加、读取和写入操作。

这一篇我们简单聊一下PX4的参数机制,这部分内容不是所有同学都会用的到,不过有一个框架性的认识对于熟悉PX4的框架也有一定的帮助。

我们以1.11.3版本为例,简单的描述一下PX4的参数操作流程:

代码构建

在编译构建时PX4执行src/lib/parameters/CMakeLists.txt 中脚本文件 px_process_params.py ,这个脚本会历遍所有的源码目录,找到xxx_params.c文件,根据这个文件生成parameters.xml文件。这个文件自动创建在build/xxx/parameters.xml中。

然后执行 px_generate_params.py 脚本,根据parameters.xml文件生成参数头文件和c文件,生成的文件在build/xxx/src/lib/parameters目录下。

稍微阅读这几个文件,里面主要定义了所有参数的名称、数据类型和默认值。

载入参数文件

在PX4启动脚本(ROMFS/px4fmu_common/init.d/rcS)中执行参数载入操作从存储器中读取参数

# Set the parameter file if mtd starts successfully. if mtd start then set PARAM_FILE /fs/mtd_params fi # Load parameters. param select $PARAM_FILE if ! param load then param reset fi

加载参数文件后,会更新build/xxx/src/lib/parameters/px4_parameters.c文件在中px4_parameters结构体的数据,这就是PX4所有参数的参数表了,在文件尾部显示了参数总数,有近千个参数。

应用加载参数

应用中使用参数比较简单,添加几条语句就可以,我们以代码比较简单的src/drivers/heater/heater.cpp模块为例。

参数变量定义

在头文件中通过参数宏结构进行参数变量的定义

DEFINE_PARAMETERS( (ParamFloat) _param_sens_imu_temp_i, (ParamFloat) _param_sens_imu_temp_p, (ParamInt) _param_sens_temp_id, (ParamFloat) _param_sens_imu_temp )

更新参数

在源文件中添加变量更新函数,检测变量是否发生变化,更新变量

void Heater::update_params(const bool force) { // check for parameter updates if (_parameter_update_sub.updated() || force) { // clear update parameter_update_s pupdate; _parameter_update_sub.copy(&pupdate); // update parameters from storage ModuleParams::updateParams(); } }

应用加载与更新参数的机制

在应用的头文件中,通过 DEFINE_PARAMETERS 宏完成参数变量类的定义,我们可以看一下这个宏的内容:

#define _DEFINE_SINGLE_PARAMETER(x) \ do_not_explicitly_use_this_namespace::PAIR(x); #define _CALL_UPDATE(x) \ STRIP(x).update(); #define _DEFINE_PARAMETER_UPDATE_METHOD(...) \ protected: \ void updateParamsImpl() final { \ APPLY_ALL(_CALL_UPDATE, __VA_ARGS__) \ } \ private: #define DEFINE_PARAMETERS(...) \ APPLY_ALL(_DEFINE_SINGLE_PARAMETER, __VA_ARGS__) \ _DEFINE_PARAMETER_UPDATE_METHOD(__VA_ARGS__)

从内容我们可以大致了解,这里使用命名空间 do_not_explicitly_use_this_namespace中参数类定义参数变量,并且定义了应用中所有参数的更新类updateParamsImpl,这个函数在上一部分的ModuleParams::updateParams()中调用,里面的实现为

class ModuleParams { virtual void updateParams() { for (const auto &child : _children) { child->updateParams(); } updateParamsImpl(); } }

在参数更新时,使用STRIP(x).update() 方法更新应用中每个使用到的参数,这个方法定义在do_not_explicitly_use_this_namespace中:

bool update() { int32_t value_int; int ret = param_get(handle(), &value_int); if (ret == 0) { _val = value_int != 0; return true; } return false; }

这些宏定义中值得注意的是APPLY_ALL()方法,这个宏定义使代码中展开复杂的结构,为应用的头文件中定义的所有变量展开变量定义和update()方法,其目的是使代码更加简洁。

这样的宏定义方式大家感兴趣也可以参考一下,减少重复性代码可以使自己的代码结构更加简洁清晰。

参数更新消息

可以发现PX4使用了uORB机制向所有使用参数的应用广播参数的变化,每个使用参数的应用都会订阅 uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)}; 消息。在检测到参数更新时去更新应用使用到的参数值。

这样的设计有好处是处理方式统一,结构简洁。

当然它的代价是在一个参数发生更新时,所有的应用都会收到更新通知去检查更新自己使用的参数。

总结

以上是PX4的参数系统的大致机制,当然还有很多非常有意思的细节信息没有展开。这些信息对于使用而言没有作用不大,对于希望磨砺自己代码能力的同学却是不错的参考,里面使用到的宏定义、模板类、代码生成等等都是不错的学习参考。

往期分享:

AcmeGCS-9-目标框选跟踪

AcmeIot-2-基于PX4硬件的Nuttx开发环境

PX4-6-串口设备驱动

这里会不定期更新一些我整理的无人机相关知识,欢迎关注。

在公众号的主页菜单中有所有分享的分类整理。

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有