PX4二次开发快速入门

news2024/9/22 13:29:20

文章目录

  • 前言
  • 一、概述
  • 二、二次开发基础(自定义工作队列,自定义uorb)
  • 三、自定义串口驱动(添加一个毫米波雷达并定高)
  • 四、自定义I2C驱动(驱动一个oled显示屏)
  • 五、自定义参数
  • 六、自定义日志
  • 七、自定义机型
  • 八、自定义mavlink消息和QGC通信
  • 九、自定义mavlink消息和MAVROS通信
  • 十、OFFBAORD控制接口(状态控制 pwm输出)
  • 十一、基于模型开发(替换控制律/基于模型的编队)

前言

交流学习可加文章底部作者微信

本教程的适用对象:
1、零基础或者有较少基础(尚未入门)
2、希望在短时间里(一到两个月)学会对PX4进行二次开发的开源爱好者或工程师

硬件:
pixhawk飞控
超维M系列无人机

软件:
PX4 1.13.3
QGC4.2.4

一、概述

二、二次开发基础(自定义工作队列,自定义uorb)

在modules文件夹下添加work_item文件夹
在这里插入图片描述

添加下面四个文件
在这里插入图片描述

CMakeLists.txt

px4_add_module(
	MODULE modules__work_item
	MAIN work_item_test
	COMPILE_FLAGS
		#-DDEBUG_BUILD   # uncomment for PX4_DEBUG output
		#-O0             # uncomment when debugging
	SRCS
		WorkItemTest.cpp
		WorkItemTest.hpp
	DEPENDS
		px4_work_queue
	)

Kconfig

menuconfig MODULES_WORK_ITEM
	bool "work_item"
	default n
	---help---
		Enable support for work_item

WorkItemTest.cpp

#include "WorkItemTest.hpp"

WorkItemTest::WorkItemTest() :
	ModuleParams(nullptr),
	ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1)
{
}

WorkItemTest::~WorkItemTest()
{
	perf_free(_loop_perf);
	perf_free(_loop_interval_perf);
}

bool WorkItemTest::init()
{
ScheduleOnInterval(100000_us);
	return true;
}

void WorkItemTest::Run()
{
	if (should_exit()) {
		ScheduleClear();
		exit_and_cleanup();
		return;
	}

	perf_begin(_loop_perf);
	perf_count(_loop_interval_perf);

	// Check if parameters have changed
	if (_parameter_update_sub.updated()) {
		// clear update
		parameter_update_s param_update;
		_parameter_update_sub.copy(&param_update);
		updateParams(); // update module parameters (in DEFINE_PARAMETERS)
	}


	PX4_INFO("test workitem");

	perf_end(_loop_perf);
}

int WorkItemTest::task_spawn(int argc, char *argv[])
{
	WorkItemTest *instance = new WorkItemTest();

	if (instance) {
		_object.store(instance);
		_task_id = task_id_is_work_queue;

		if (instance->init()) {
			return PX4_OK;
		}

	} else {
		PX4_ERR("alloc failed");
	}

	delete instance;
	_object.store(nullptr);
	_task_id = -1;

	return PX4_ERROR;
}

int WorkItemTest::print_status()
{
	perf_print_counter(_loop_perf);
	perf_print_counter(_loop_interval_perf);
	return 0;
}

int WorkItemTest::custom_command(int argc, char *argv[])
{
	return print_usage("unknown command");
}

int WorkItemTest::print_usage(const char *reason)
{
	if (reason) {
		PX4_WARN("%s\n", reason);
	}

	PRINT_MODULE_DESCRIPTION(
		R"DESCR_STR(
### Description
Example of a simple module running out of a work queue.

)DESCR_STR");

	PRINT_MODULE_USAGE_NAME("work_item_example", "template");
	PRINT_MODULE_USAGE_COMMAND("start");
	PRINT_MODULE_USAGE_DEFAULT_COMMANDS();

	return 0;
}

extern "C" __EXPORT int work_item_test_main(int argc, char *argv[])
{
	return WorkItemTest::main(argc, argv);
}

WorkItemTest.hpp

#pragma once

#include <px4_platform_common/defines.h>
#include <px4_platform_common/module.h>
#include <px4_platform_common/module_params.h>
#include <px4_platform_common/posix.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>

#include <drivers/drv_hrt.h>
#include <lib/perf/perf_counter.h>

#include <uORB/Publication.hpp>
#include <uORB/Subscription.hpp>
#include <uORB/SubscriptionCallback.hpp>
#include <uORB/topics/orb_test.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_accel.h>
#include <uORB/topics/vehicle_status.h>

using namespace time_literals;

class WorkItemTest : public ModuleBase<WorkItemTest>, public ModuleParams, public px4::ScheduledWorkItem
{
public:
	WorkItemTest();
	~WorkItemTest() override;

	/** @see ModuleBase */
	static int task_spawn(int argc, char *argv[]);

	/** @see ModuleBase */
	static int custom_command(int argc, char *argv[]);

	/** @see ModuleBase */
	static int print_usage(const char *reason = nullptr);

	bool init();

	int print_status() override;

private:
	void Run() override;

	// Publications
	uORB::Publication<orb_test_s> _orb_test_pub{ORB_ID(orb_test)};

	// Subscriptions
	uORB::SubscriptionCallbackWorkItem _sensor_accel_sub{this, ORB_ID(sensor_accel)};        // subscription that schedules WorkItemExample when updated
	uORB::SubscriptionInterval         _parameter_update_sub{ORB_ID(parameter_update), 1_s}; // subscription limited to 1 Hz updates
	uORB::Subscription                 _vehicle_status_sub{ORB_ID(vehicle_status)};          // regular subscription for additional data

	// Performance (perf) counters
	perf_counter_t	_loop_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};
	perf_counter_t	_loop_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval")};

	// Parameters
	DEFINE_PARAMETERS(
		(ParamInt<px4::params::SYS_AUTOSTART>) _param_sys_autostart,   /**< example parameter */
		(ParamInt<px4::params::SYS_AUTOCONFIG>) _param_sys_autoconfig  /**< another parameter */
	)


	bool _armed{false};
};

修改仿真的编译脚本
在这里插入图片描述
添加如下:

CONFIG_MODULES_WORK_ITEM=y

在这里插入图片描述
然后执行

make px4_sitl_default gazbo

启动仿真后执行:

work_item_test start

正常的话会打印下面的信息
在这里插入图片描述

三、自定义串口驱动(添加一个毫米波雷达并定高)

PX4二次开发快速入门(三):自定义串口驱动

四、自定义I2C驱动(驱动一个oled显示屏)

五、自定义参数

在第一节的基础上进一步修改
添加params.c
在这里插入图片描述
params.c内容如下:

PARAM_DEFINE_FLOAT(PARAM_TEST1, 0.2f);
PARAM_DEFINE_INT32(PARAM_TEST2, 0);

CMakeLists.txt

px4_add_module(
	MODULE modules__work_item
	MAIN work_item_test
	COMPILE_FLAGS
		#-DDEBUG_BUILD   # uncomment for PX4_DEBUG output
		#-O0             # uncomment when debugging
	SRCS
		WorkItemTest.cpp
		WorkItemTest.hpp
	DEPENDS
		px4_work_queue
	)

Kconfig

menuconfig MODULES_WORK_ITEM
	bool "work_item"
	default n
	---help---
		Enable support for work_item

WorkItemTest.cpp

#include "WorkItemTest.hpp"

WorkItemTest::WorkItemTest() :
	ModuleParams(nullptr),
	ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1)
{
}

WorkItemTest::~WorkItemTest()
{
	perf_free(_loop_perf);
	perf_free(_loop_interval_perf);
}

bool WorkItemTest::init()
{
ScheduleOnInterval(100000_us);
	return true;
}

void WorkItemTest::Run()
{
	if (should_exit()) {
		ScheduleClear();
		exit_and_cleanup();
		return;
	}

	perf_begin(_loop_perf);
	perf_count(_loop_interval_perf);

	// Check if parameters have changed
	if (_parameter_update_sub.updated()) {
		// clear update
		parameter_update_s param_update;
		_parameter_update_sub.copy(&param_update);
		updateParams(); // update module parameters (in DEFINE_PARAMETERS)
	}
        double param_test1=_param_test1.get();
        int param_test2=_param_test2.get();
        PX4_INFO("param_test1=%lf param_test2=%d\n",param_test1,param_test2);

	PX4_INFO("test workitem");

	perf_end(_loop_perf);
}

int WorkItemTest::task_spawn(int argc, char *argv[])
{
	WorkItemTest *instance = new WorkItemTest();

	if (instance) {
		_object.store(instance);
		_task_id = task_id_is_work_queue;

		if (instance->init()) {
			return PX4_OK;
		}

	} else {
		PX4_ERR("alloc failed");
	}

	delete instance;
	_object.store(nullptr);
	_task_id = -1;

	return PX4_ERROR;
}

int WorkItemTest::print_status()
{
	perf_print_counter(_loop_perf);
	perf_print_counter(_loop_interval_perf);
	return 0;
}

int WorkItemTest::custom_command(int argc, char *argv[])
{
	return print_usage("unknown command");
}

int WorkItemTest::print_usage(const char *reason)
{
	if (reason) {
		PX4_WARN("%s\n", reason);
	}

	PRINT_MODULE_DESCRIPTION(
		R"DESCR_STR(
### Description
Example of a simple module running out of a work queue.

)DESCR_STR");

	PRINT_MODULE_USAGE_NAME("work_item_example", "template");
	PRINT_MODULE_USAGE_COMMAND("start");
	PRINT_MODULE_USAGE_DEFAULT_COMMANDS();

	return 0;
}

extern "C" __EXPORT int work_item_test_main(int argc, char *argv[])
{
	return WorkItemTest::main(argc, argv);
}


WorkItemTest.hpp

#pragma once

#include <px4_platform_common/defines.h>
#include <px4_platform_common/module.h>
#include <px4_platform_common/module_params.h>
#include <px4_platform_common/posix.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>

#include <drivers/drv_hrt.h>
#include <lib/perf/perf_counter.h>

#include <uORB/Publication.hpp>
#include <uORB/Subscription.hpp>
#include <uORB/SubscriptionCallback.hpp>
#include <uORB/topics/orb_test.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_accel.h>
#include <uORB/topics/vehicle_status.h>

using namespace time_literals;

class WorkItemTest : public ModuleBase<WorkItemTest>, public ModuleParams, public px4::ScheduledWorkItem
{
public:
	WorkItemTest();
	~WorkItemTest() override;

	/** @see ModuleBase */
	static int task_spawn(int argc, char *argv[]);

	/** @see ModuleBase */
	static int custom_command(int argc, char *argv[]);

	/** @see ModuleBase */
	static int print_usage(const char *reason = nullptr);

	bool init();

	int print_status() override;

private:
	void Run() override;

	// Publications
	uORB::Publication<orb_test_s> _orb_test_pub{ORB_ID(orb_test)};

	// Subscriptions
	uORB::SubscriptionCallbackWorkItem _sensor_accel_sub{this, ORB_ID(sensor_accel)};        // subscription that schedules WorkItemExample when updated
	uORB::SubscriptionInterval         _parameter_update_sub{ORB_ID(parameter_update), 1_s}; // subscription limited to 1 Hz updates
	uORB::Subscription                 _vehicle_status_sub{ORB_ID(vehicle_status)};          // regular subscription for additional data

	// Performance (perf) counters
	perf_counter_t	_loop_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};
	perf_counter_t	_loop_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval")};

	// Parameters
	DEFINE_PARAMETERS(
		(ParamInt<px4::params::SYS_AUTOSTART>) _param_sys_autostart,   /**< example parameter */
		(ParamInt<px4::params::SYS_AUTOCONFIG>) _param_sys_autoconfig,  /**< another parameter */
	    	(ParamFloat<px4::params::PARAM_TEST1>) _param_test1,   /**< example parameter */
    		(ParamInt<px4::params::PARAM_TEST2>) _param_test2  /**< another parameter */
	)


	bool _armed{false};
};


修改仿真的编译脚本
在这里插入图片描述
添加如下:

CONFIG_MODULES_WORK_ITEM=y

在这里插入图片描述
然后先执行(不执行这一步后面会报错)

make distclean

再执行

make parameters_metadata

最后执行

make px4_sitl_default gazbo

启动仿真后执行(注意要启动work_item_test ,不然地面站搜不到参数):

work_item_test start

在这里插入图片描述
如果在启动work_item_test 之前已经打开了地面站,还需要再刷新一下参数
在这里插入图片描述
就可以搜到添加的参数
在这里插入图片描述

六、自定义日志

七、自定义机型

八、自定义mavlink消息和QGC通信

九、自定义mavlink消息和MAVROS通信

十、OFFBAORD控制接口(状态控制 pwm输出)

十一、基于模型开发(替换控制律/基于模型的编队)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2034436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习笔记:编码器与解码器

目录 介绍 组成结构 代码实现 编码器 解码器 合并编码器-解码器 思考 介绍 在机器翻译中&#xff0c;输入的序列与输出的序列经常是长度不相等的序列&#xff0c;此时&#xff0c;像自然语言处理这种直接使用循环神经网络或是门控循环单元的方法就行不通了。因此&#x…

Qt 窗口:菜单、工具与状态栏的应用

目录 引言&#xff1a; 1. 菜单栏 1.1 创建菜单栏 1.2 在菜单栏中添加菜单 1.3 创建菜单项 1.4 在菜单项之间添加分割线 1.5 综合示例 2.工具栏 2.1 创建工具栏 2.2 设置停靠位置 2.3 设置浮动属性 2.4 设置移动属性 3. 状态栏 3.1 状态栏的创建 3.2 在状态栏中显…

Pytorch_cuda版本的在线安装命令

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 运行效果如下&#xff1a; 这个方法是直接从pytorch官网进行在线下载和安装。 cu121&#xff0c;表示当前您安装的cuda版本是12.1

java基础概念15-字符串

public static void main(String[] args) {String name "张三";name "李四";System.out.println(name);// 李四} name变量是一个引用变量&#xff0c;它存储的是对字符串对象的引用&#xff08;即内存地址&#xff09;&#xff0c;而不是字符串对象本身的…

【Git】远程仓库新建分支后,拉到本地开发

1. 在远程仓库上创建分支 2. git fetch origin&#xff1a;在本地同步远程仓库的分支&#xff08;获取远程仓库所有分支的所有修改&#xff09; 3. git remote -a&#xff1a;查看所有分支&#xff08;远程&#xff0b;本地&#xff09; 4. git checkout -b 本地名 远程仓库…

华夏erp2.3代码审计

1 sql注入代码 该项目使用的是Mybits的数据库,直接在*.xml文件中全局搜索 ${我们选一个比较有可能有注入的 UserMapperEx.xml 进行查 看 回溯到UserMapperEx.java。 继续回溯到UserService.java。 继续回溯可以看到UserComponent.java中userName的值是从search中获取的。 在s…

CodeWave--创建实体与枚举

一、实体的创建 可视化开发左侧边栏选择数据模块&#xff0c;在实体菜单下&#xff0c;选择2处的“” &#xff0c;即可创建一个默认的实体类&#xff0c;修改3处的实体名称&#xff0c;再在实体页签中&#xff0c;添加所需的字段即可。 注&#xff1a;id是自动生成的主键&…

域名是什么?1分钟快速了解

任何一个互联网上的设备&#xff0c;包括服务器或我们的个人电脑设备&#xff0c;都有一个对应的地址&#xff0c;即IP地址&#xff0c;&#xff08;比如&#xff0c;192.168.1.1)。所有设备&#xff0c;都通过这个独立唯一的IP地址来互相访问。 由于IP地址不容易被记忆&#…

仅需三步,轻松制作电脑系统安装盘!

系统安装在现在可谓是必不可少的技能。自己系统坏了,不用到电脑安装,省了不少大洋,在朋友面前也可以装装大神,百利无一害呀,还不赶快学起来! 按照以前常规方式,每个电脑系统都会配有一个光盘,然后放到光驱里面读取安装,但随着笔记本越做越薄,光驱慢慢被取消了。所以…

广州网站建设运营团队

广州是中国南部的一座国际化大都市&#xff0c;拥有众多创新科技企业和互联网公司。随着数字经济的快速发展&#xff0c;网站建设和运营已经成为企业发展和推广的重要手段。作为一支专业的网站建设运营团队&#xff0c;我们深知在这个信息化时代&#xff0c;拥有一个优质的网站…

React 学习——react项目中加入echarts图

实现的代码如下&#xff1a; import * as echarts from echarts import { useEffect, useRef } from react; const Home ()>{const chartRef useRef(null);useEffect(()>{// const chartDom document.getElementById(main);//使用id获取节点const chartDom chartRef…

Linux系统驱动(十六)platform驱动

文章目录 一、简介&#xff08;一&#xff09;device、bus、driver模型&#xff08;二&#xff09;platform驱动原理 二、platform总线驱动的API&#xff08;一&#xff09;设备信息端&#xff08;二&#xff09;设备驱动端&#xff08;三&#xff09;驱动中获取设备信息函数&a…

【子豪兄】精讲CS231N斯坦福计算机视觉公开课学习笔记

wx 搜索 gzh 司南锤&#xff0c;回复 子豪兄231笔记 可获取笔记文件&#xff08;pdfdoc) 文章目录 学习链接:- 斯坦福大学公开课- 计算机视觉发展历史- 图像分类算法- 线性分类、损失函数与梯度下降- 神经网络与反向传播- 卷积神经网络- 可视化卷积神经网络- 训练神经网络 &…

关于WMS仓储管理系统的开发与应用

在当今这个全球化与数字化交织并进的时代&#xff0c;高效的仓储管理已经跃升为企业运营效能与市场竞争力提升的关键驱动力。仓库&#xff0c;这一供应链体系中的核心枢纽&#xff0c;其角色已远远超越了简单的货物存储功能&#xff0c;而是成为了推动货物流转效率与精准度的战…

软件测试之面试常见问题大全

软件测试之常见软件测试面试题 面试题解读&#xff0c;轻轻松松过面试&#xff0c;我以一个过来人的身份&#xff0c;写下这篇面试常见问题 1. 最常见的就是&#xff0c;为什么想进本公司&#xff0c;你了解本公司的业务吗&#xff1f; 再回答这个问题的时候是灵活的&#x…

DHCP学习笔记

1.DHCP快速配置 1.1配置接口IP R1: sysname R1 undo info-center enable interface Ethernet0/0/0 ip address 192.168.1.1 255.255.255.0 quit 1.2开启DHCP服务&#xff0c;接着在R1的e0/0/0配置DHCP Server功能 dhcp enable #全局下开启DHCP服务 interface Ethernet…

深度强化学习,模型改进

深度强化学习&#xff1a;DQN、PPO、DDPG、A3C、TD3、SAC、Rainbow、MADDPG、模仿学习&#xff0c;提供创新点&#xff0c;实验对比&#xff0c;代文章、润色 代码不收敛 菲涅尔模型 python深度学习算法模型定制

事务消息使用及方案选型思考

1. 事务消息概念与重要性 1.1 分布式系统中的事务问题 在分布式系统中&#xff0c;事务的一致性是一个核心问题。以电商登录送积分活动为例&#xff0c;用户登录成功后&#xff0c;系统需要执行两个关键操作&#xff1a;记录登录日志和发放积分。这两个操作需要保持一致性&am…

高性能的 C++ Web 开发框架 CPPCMS + WebSocket 模拟实现聊天与文件传输案例。

1. 项目结构 2. config.json {"service": {"api": "http","port": 8080,"ip": "0.0.0.0"},"http": {"script": "","static": "/static"} }3. CMakeLists.txt…

html+css+js网页设计 电商模版4个页面

htmlcssjs网页设计 电商模版4个页面 带js 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&…