无人机仿真—PX4编译,gazebo仿真及简单off board控制模式下无人机起飞
前言
- 在上篇记录中,已经对整体的PX4仿真环境有了一定的了解,现如今就要开始对无人机进行起飞等仿真环境工作,在整体虚拟环境中如果程序能够安稳起飞降落,即可对无人机进行实飞操作。
- 需要做的是,通过PX4官网提供的基本程序包,在ROS工作空间下新建程序包对其进行运行,再打开仿真环境即可
PX4编译
利用ROS启动仿真环境(正式)
-
老规矩先加载ROS,运行命令
-
-
在PX4文件夹内用mavros连接到本地ros,运行以下命令打开gazebo仿真环境
编写外部程序包
首先需要在ROS工作空间下,在src目录下新建功能包
cd ~/catkin_ws/src
catkin_create_pkg offboard roscpp mavros geometry_msgs
//catkin_create_pkg 是ROS命令,新建一个功能包
//offboard 功能包名字
//roscpp mavros geometry_msgs功能包依赖
//命令格式catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
在offboard功能包src目录下新建cpp文件,将外部程序控制文件写入保存
-
新建cpp文件
-
touch offboard_node.cpp
-
将以下程序写入到cpp文件,此程序参考的是PX4官网给出的例程。
-
/**
* @file offb_node.cpp
* @brief Offboard control example node, written with MAVROS version 0.19.x, PX4 Pro Flight
* Stack and tested in Gazebo SITL
*/
#include <ros/ros.h>
#include <geometry_msgs/PoseStamped.h>
#include <mavros_msgs/CommandBool.h>
#include <mavros_msgs/SetMode.h>
#include <mavros_msgs/State.h>
mavros_msgs::State current_state;
void state_cb(const mavros_msgs::State::ConstPtr& msg){
current_state = *msg;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "offb_node");
ros::NodeHandle nh;
//订阅mavros状态
ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>
("mavros/state", 10, state_cb);
//发布无人机位姿信息
ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>
("mavros/setpoint_position/local", 10);
//定义起飞服务客户端(起飞,降落)
ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>
("mavros/cmd/arming");
//定义设置模式服务客户端(设置offboard模式)
ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>
("mavros/set_mode");
//the setpoint publishing rate MUST be faster than 2Hz
ros::Rate rate(20.0);
// wait for FCU connection
while(ros::ok() && !current_state.connected){
ros::spinOnce();
rate.sleep();
}
geometry_msgs::PoseStamped pose;
pose.pose.position.x = 0;
pose.pose.position.y = 0;
pose.pose.position.z = 10;
//send a few setpoints before starting
for(int i = 100; ros::ok() && i > 0; --i){
local_pos_pub.publish(pose);
ros::spinOnce();
rate.sleep();
}
mavros_msgs::SetMode offb_set_mode;
offb_set_mode.request.custom_mode = "OFFBOARD";
mavros_msgs::CommandBool arm_cmd;
arm_cmd.request.value = true;
ros::Time last_request = ros::Time::now();
while(ros::ok()){
if( current_state.mode != "OFFBOARD" &&
(ros::Time::now() - last_request > ros::Duration(5.0))){
if( set_mode_client.call(offb_set_mode) &&
offb_set_mode.response.mode_sent){
ROS_INFO("Offboard enabled");
}
last_request = ros::Time::now();
} else {
if( !current_state.armed &&
(ros::Time::now() - last_request > ros::Duration(5.0))){
if( arming_client.call(arm_cmd) &&
arm_cmd.response.success){
ROS_INFO("Vehicle armed");
}
last_request = ros::Time::now();
}
}
local_pos_pub.publish(pose);
ros::spinOnce();
rate.sleep();
}
return 0;
}
-
在offboard目录下找到Cmakelists.txt文件,并设置程序运行节点,不然rosrun命令无法找到该节点,从而报错
-
-
输入以下除蓝色字体的命令 - 编辑好后即可进行编译
编译
小结
- 之所以要记录本次的过程,是因为自己对ROS工作模式的进一步了解,当然,实验这篇前需要去了解一下ROS语法,这里推荐古月居博主,可以在B站和csdn上都可以搜到。
- 踩坑总结:
- 在已经 建立工作空间的情况下,如果需要新建程序包,不要在工作空间目录(catkin_ws)下新建,而是要了解ros环境后在src目录下使用命令新建程序包,不然编译就会出错
- 运行程序包的命令,不需要添加文件后缀名
- 之所以会产生各种错误,是基于自己并不了解ros的工作模式和原理,实际上,只要自己有了经验,有了教训,下一次的建立会相比较第一次都会顺手很多。
- 错误的不断产生让我一度以为自己的ros环境产生了怀疑,认为自己的环境搭建出错,但一切的根源就是自己的工作路径添加错误,对系统产生的错误需要自己一点点去啃。
- 因为ROS系统产生错误显示的是英文,对于一些不常见的错误,可以利用有道词典的划词功能,对错误进行翻译,只有自己真正了解到这个错误,最终才能够有根据的去寻求答案。
- 最后送句话给自己吧。“海压竹枝低复举,风吹山角晦还明”
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)