无人机 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型的参数与测试。

相关推荐
云卓SKYDROID3 小时前
无人机DSP处理器工作要点!
人工智能·无人机·科普·云卓科技
云卓SKYDROID12 小时前
无人机磁力传感器与信号传输解析!
人工智能·科技·无人机·科普·云卓科技
云卓SKYDROID12 小时前
无人机监视系统工作原理与运行要点!
无人机·科普·遥控器·高科技·云卓科技
云卓SKYDROID18 小时前
无人机测控系统运行设置与职责!
人工智能·科技·无人机·科普·云卓科技
GIS数据转换器1 天前
在机器人和无人机时代,测绘人的出路在哪里?
大数据·人工智能·信息可视化·机器人·自动驾驶·汽车·无人机
月阳羊1 天前
无人机,云台参数设置,PWM输出控制云台俯仰
无人机
lida20031 天前
Ardupilot开源无人机之Geek SDK进展2025Q2
开源·无人机·穿越机·jetson-fpv
金戈鐡馬1 天前
Ubuntu下编译PX4原生飞控固件
无人机·飞控·px4
IT猿手2 天前
基于烟花算法(Fireworks Algorithm,FWA)及三次样条的机器人路径规划,50个场景任意选择,完整MATLAB代码
开发语言·算法·机器学习·matlab·机器人·无人机
创小董3 天前
无人机中继传输数据链技术,(无人机+自组网)远距离传输技术实现详解
无人机