无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整

0 前言

之前文章添加了一个自定义的模块,本篇文章在之前的自定义模块中,添加两个自定义参数

使用QGC显示出来,并通过QGC调整参数值,代码实现参数更新

新增的参数放在 jone_demo_params.c文件里面

之前定义的模块中,一直在终端打印一个消息,本节中设置一个bool型参数,为1 打印一个消息,为0 打印另一个消息

并且设置一个float型参数,将该参数值打印出来

1 PX4 添加自定义参数方法

PX4定义参数 在具体模块的 **_params.c文件中进行

通过函数 PARAM_DEFINE**(),例如:

  • PARAM_DEFINE_INT32 定义整型参数
  • PARAM_DEFINE_FLOAT 定义浮点型参数

目前只有这两种类型

PARAM_DEFINE**() 函数的上面有注释

[!NOTE]

注意:注释是有格式要求的,不能随意写,为了在QGC中进行显示,与参数的自动化处理

注释的格式如下:

/** 第一行

*短注释

*长注释

*标签

PARAM_DEFINE**()

标签以@为开头,标签的内根据参数的类型来定,具体有:

  • @unit 单位16

  • @min 最小值16

  • @max 最大值

  • @value 各值代表的不同含义

  • @boolean 布尔型参数
  • @decimal 指定参数值的小数位数
  • @increment 参数的调整步长。
  • @group 分组

PARAM_DEFINE**() 函数的 参数,第一个为定义的参数名称,第二个为默认值:

  • 参数名称

[!NOTE]

注意参数的名字不能超过16个字符

  • 默认值

下面是原有PX4定义好的参数的例子

浮点型参数

c 复制代码
/**
 * VTOL Takeoff relative loiter altitude.
 *
 * Altitude relative to home at which vehicle will loiter after front transition.
 *
 * @unit m
 * @min 20
 * @max 300
 * @decimal 1
 * @increment 1
 * @group VTOL Takeoff
 */
PARAM_DEFINE_FLOAT(VTO_LOITER_ALT, 80);

整型参数

c 复制代码
/**
 * Maximum number of search attempts
 *
 * Maximum number of times to search for the landing target if it is lost during the precision landing.
 *
 * @min 0
 * @max 100
 * @group Precision Land
 */
PARAM_DEFINE_INT32(PLD_MAX_SRCH, 3);

具体的参数自动处理代码在Tools/module_config 下面的几个python文件中,例如 generate_params.py 中的核心代码:

c 复制代码
                # get the type and extract all tags
                tags = '@group {:}'.format(param_group)
                if param['type'] == 'enum':
                    param_type = 'INT32'
                    for key in param['values']:
                        tags += '\n * @value {:} {:}'.format(key, param['values'][key])
                elif param['type'] == 'bitmask':
                    param_type = 'INT32'
                    for key in param['bit']:
                        tags += '\n * @bit {:} {:}'.format(key, param['bit'][key])
                    max_val = max(key for key in param['bit'])
                    tags += '\n * @min 0'
                    tags += '\n * @max {:}'.format((1<<(max_val+1)) - 1)
                elif param['type'] == 'boolean':
                    param_type = 'INT32'
                    tags += '\n * @boolean'
                elif param['type'] == 'int32':
                    param_type = 'INT32'
                elif param['type'] == 'float':
                    param_type = 'FLOAT'
                else:
                    raise Exception("unknown param type {:}".format(param['type']))

2 代码实践

2.1 定义参数

定义一个bool型变量,来控制打印消息a还是b

分组为 demo

c 复制代码
/**
 * print msg a or b
 *
 * Control print msg a or b
 *
 * @boolean
 * @group demo
 */
PARAM_DEFINE_INT32(PRINT_MSG_A_EN, 1);

定义一个float型变量,在打印时,打印该值

单位 随便定义为s

最小值为0.2 ,最大值为1.0

小数精度为2

增量步长为0.01

分组为demo

c 复制代码
/**
 * print number
 *
 * Print number value
 *
 * @unit s
 * @min 0.2
 * @max 1.0
 * @decimal 2
 * @increment 0.01
 * @group demo
 */
PARAM_DEFINE_FLOAT(PRINT_NUM_VALUE, 0.4f);

2.2 使用参数

下面是如何使用上面定义的两个参数

在 JoneDemo.hpp 文件中的类声明中的私有变量区加入如下内容

c 复制代码
	DEFINE_PARAMETERS(
		(ParamFloat<px4::params::PRINT_NUM_VALUE>)         _param_print_num_value,
		(ParamBool<px4::params::PRINT_MSG_A_EN>)           _param_print_msg_a_enable,
	);

DEFINE_PARAMETERS 就是固定使用之前参数文件定义的参数的函数方法,按照这个格式写

px4::params::+定义参数名称 后面跟 代码中对应的变量

[!NOTE]

注意:参数对应的变量不能直接使用,在使用该值的时候需要使用.get()函数,更改值的时候使用.set()函数.

否则编译报错

在 JoneDemo.cpp 的Run()函数中加入 使用该两个变量的代码

c 复制代码
	if(_param_print_msg_a_enable.get())
	{
	   printf("MSG a print  value : %f \r\n",(double)_param_print_num_value.get());
	}else{
	   printf("hello jone\r\n");
	}

2.3 参数更新

参数更新

如果不进行下面的参数更新的操作,那么在使用的时候QGC里改了参数,代码里不会改

涉及到的函数:parameters_update(bool force)

在里面加入内容:

c 复制代码
	// 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();
		SuperBlock::updateParams();
		
		printMsgAEnable = _param_print_msg_a_enable.get();
		printNumValue = _param_print_num_value.get();

	}

前面四行是固定的,检测的参数更新时进行更新

最后两行则是新定义了两个变量,对应更新到的参数,这样更新后就被赋值了,不用在后面执行是一直执行get()函数

_parameter_update_sub 变量需要在JoneDemo.hpp文件声明

c 复制代码
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};

在构造函数中,加入强制执行参数更新一次,这样上电,变量就会获得参数

c 复制代码
parameters_update(true);

然后再后面的Run函数中,之前本身就有parameters_update(false); 也就是检测到参数变化了才会更新一次

在JoneDemo.hpp文件中的私有区,定义这两个变量就行

c 复制代码
	float printNumValue;
	bool printMsgAEnable;

对应的JoneDemo.cpp 文件中的cpp函数,则改为使用这两个变量

c 复制代码
	if(printMsgAEnable)
	{
	   printf("MSG a print  value : %f \r\n",(double)printNumValue);
	}else{
	   printf("hello jone\r\n");
	}

3 测试

删除掉原来的build文件夹下的px4_sitl_default

然后再编译

c 复制代码
make px4_sitl_default 

再执行

c 复制代码
make px4_sitl_default gazebo

终端打印出了应该输出的内容

打开QGC,打开参数列表,先点击刷新

然后搜索定义的那两个变量名

第1个bool变量PRINT_MSG_A_EN

可以看到再选择值里面可以选择 Enabled和Disabled,就是因为参数定义时,声明了标签:@boolean

同样可以看到长注释:Control print msg a or b

此时将 该变量改为Disabled

终端按照代码逻辑输出了:hello jone

第二个看那个float型参数:PRINT_NUM_VALUE

数字后面有个s,就是单位的标签

有最小值和最大值的标签,小数点后面有两位,就是@decimal 2的标签

此时将 该变量改为0.26,则终端对应打印的数据也进行改变

这样就完成了在PX4中,添加自定义bool型、float型的参数与测试。

相关推荐
深蓝学院2 小时前
突破极限!!!20米每秒的端到端无人机自主导航
无人机
视觉语言导航2 小时前
无人机如何自主侦察?UEAVAD:基于视觉的无人机主动目标探测与导航数据集
无人机
真想骂*1 天前
无人机图传模块:深入理解其工作原理与实际效用
无人机
大山同学1 天前
RACER:基于去中心化多无人机系统的快速协同探索
去中心化·区块链·无人机
黄交大彭于晏2 天前
无人机核心项目开发系列:从设计到实现的完整解析
学习·无人机
创小董3 天前
无人机的应用场景有哪些?
无人机
AI技术控3 天前
计算机视觉算法实战——无人机检测
算法·计算机视觉·无人机
白嫖叫上我5 天前
Ceisum无人机巡检直播视频投射
无人机·cesium·webgis
创小董6 天前
无人机+无人车+无人船+机器狼:无人装备技术优势详解
无人机