1 .msg文件夾定義數據類型及 變量名
文件位置如圖,在PX4-Autopilot/msg文件夾下,筆者創建的文件名為gps_msg.msg
gps_msg.msg內容如下?
uint64 timestamp ? ?# 時間戳
float32 latitude ? ??
float32 longitude ?
float32 altitude ? ??
同時,在CMakeLists.txt中添加gps_msg.msg?
2 .編譯
終端打開PX4-Autopilot,運行命令
make px4_fmu-v3_default
開始編譯,用于生成.h頭文件
編譯結束
?
?一開始用的fmu-v3發現沒有生成.h文件?
換成了
make px4_fmu-v4_default
生成的gps_msg.h位置和內容如圖
3. 創建新模塊
在PX4的src/modules
目錄下創建一個新文件夾,比如筆者此處命名為alxx 。
在alxx文件夾下創建CMakeList.txt文件,內容如下
px4_add_module(
#下面添加文件夾名字
MODULE examples__alxx
#下面添加線程名字
MAIN x
SRCS
#添加文件夾里面.cpp文件
01gps_msg.cpp
DEPENDS
)
將自己的模塊名(筆者的是alxx)添加進default.cmake文件下,筆者使用的是fmu-v4編譯的,所以到PX4-Autopilot/boards/px4/fmu-v4里面的default.cmake文件中進行添加
4.cpp文件內容的編寫
#include <uORB/uORB.h>
#include <uORB/topics/gps_msg.h> // 引入想要發布的消息類型的頭文件
#include <drivers/drv_hrt.h>//包含函數hrt_absolute_time()
#include <uORB/Publication.hpp> //用于創建一個 uORB 發布器
#include <systemlib/mavlink_log.h> //使用mavlink_log_critical()函數
using namespace std;
extern "C" __EXPORT int x_main(int argc, char *argv[]);//主函數 ?告訴編譯器使用 C 語言的方式來處理特定的函數或代碼塊。
int x_thread(int argc, char *argv[]);//線程
static bool thread_running = false;//線程運行標志
static bool thread_should_exit = false;//線程結束標志
static orb_advert_t mavlink_log_pub = 0; ?//使用 &mavlink_log_pub
static int daemon_task;
class main_task01//主函數命名
{
public:
void run();
private:
};
void main_task01::run()
{
// 創建一個 gps_msg_s 結構體并初始化消息數據
gps_msg_s gps_msg{};
gps_msg.timestamp = hrt_absolute_time();
gps_msg.latitude = 37.7749;
gps_msg.longitude = -122.4194;
gps_msg.altitude = 11.0f;
// 創建一個 uORB 發布器,發布 gps_msg 消息
uORB::Publication<gps_msg_s> gps_msg_pub{ORB_ID(gps_msg)};
PX4_INFO("alxx使用C++發布了Uorb消息");//終端打印消息
while (true) {
// 發布消息
gps_msg_pub.publish(gps_msg);
}
}
int x_main(int argc, char *argv[])
{
/*檢查傳遞給程序的命令行參數數量,如果參數數量小于2,使用 mavlink_log_critical 函數向 mavlink_log_pub
發布一條關于“[lxx]mission command”的嚴重級別日志消息。*/
if (argc < 2) {
mavlink_log_critical(&mavlink_log_pub, "[lxx]mission command");
}
if (!strcmp(argv[1], "start")) {
if (thread_running) {
/*檢查 thread_running 是否為真,如果是,它會發布一條關于 "[lxx]already running" 的嚴重級別日志消息。*/
mavlink_log_critical(&mavlink_log_pub, "[lxx]already running");
}
thread_should_exit = false; //表示線程不應該退出。
thread_running = true; //表示線程正在運行
daemon_task = px4_task_spawn_cmd("x",
SCHED_DEFAULT,
SCHED_PRIORITY_MAX - 5,
3000,
x_thread, //啟動一個新任務(x_thread),可能是為了執行特定的線程函數,并傳遞其他參數。
&argv[2]);
return 0;
}
if (!strcmp(argv[1], "stop")) {
thread_should_exit = true;
}
mavlink_log_critical(&mavlink_log_pub, "unrecognized command");
return 0;
}
int x_thread(int argc, char *argv[])
{
main_task01 x;
x.run();
return 0;
}
?
終端打開PX4-Autopilot,再編譯
make px4_fmu-v4_default
5.運行
運行仿真語句
make px4_sitl_default jmavsim
?報錯,因為make前面多打了空格
重新輸入后
可以打開仿真
?鼠標光標定位到終端最下方,輸入“help”
?
還有PX4-Autopilot/boards/px4/sitl里面的default.cmake 也要添加alxx
再編譯
make px4_fmu-v4_default?
啟動仿真
make px4_sitl_default jmavsim
運行
help??
?筆者定義的線程是x,在最后
運行
x start?
輸出.msg文件里定義的數據
listener gps_msg
6.添加自啟動?
文件所在位置:PX4-Autopilot/ROMFS/px4fmu_common/init.d?
?
打開文件 rc.mc_apps
翻至最下方,在最下方添加? 自己的線程名 start? ,筆者定義的線程是x,所以在最下方添加的內容如下
保存文件。終端打開px4源碼,先清空之前編譯的內容。
? ? ? ? 在Linux中,make clean 是一個常用于管理源代碼編譯過程的命令。這個命令通常定義在Makefile文件中,是make工具的一個標準目標。make clean的主要作用是清除之前編譯過程中產生的所有編譯和鏈接產物,比如對象文件(.o文件)、編譯生成的可執行文件以及其他中間文件。這樣做的目的是為了確保下一次編譯是從一個干凈的狀態開始,避免由于舊的編譯產物導致的潛在問題。
? ? ? ? 在進行源代碼的編譯時,尤其是在進行多次編譯或者修改了源代碼后,使用make clean可以保證新的編譯不會受到之前編譯產物的影響,從而減少編譯錯誤和問題。然而,需要注意的是,執行make clean后,之前編譯生成的所有文件都會被刪除,所以在執行這個命令之前要確保不再需要這些文件。
make clean
編譯
make px4_fmu-v4_defaulr
?
啟動仿真
make px4_sitl_default jmavsim
?線程已經啟動了,打印了消息
觀察數據
listener gps_msg?
?