PX4+Offboard模式+代码控制无人机起飞(Gazebo)

该文指导读者如何通过ROS和mavros包控制PX4无人机在offboard模式下起飞和降落。首先创建ROS工作空间和功能包,编写C++代码并设置订阅器、发布者和服务客户端来处理起飞和模式切换。然后在Gazebo仿真环境中测试代码,最终实现无人机的自动起飞和降落功能。
摘要由CSDN通过智能技术生成

参考PX4自动驾驶用户指南
https://docs.px4.io/main/zh/ros/mavros_offboard_cpp.html

我的另一篇博客写了 键盘控制PX4无人机飞行
PX4无人机 - 键盘控制飞行代码

可以先借鉴本篇博客,实现代码控制无人机起飞,熟悉offboard模式

新建ros项目工程

mkdir -p px4_offboard_ws/src

接着进入文件编译一下

cd px4_offboard_ws
catkin_make

进入src目录,创建ros功能包

catkin_create_pkg t1_offboard_takeoff rospy roscpp

在src目录下新建offboard.cpp文件
并将以下代码复制进去

/**
 * @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 = 2;

    //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;
}

在src目录下的CMakeLists.txt文件中,在Build的最后(Install的上面)添加下面两行代码

add_executable(t1_offboard_takeoff src/offboard.cpp)
 
target_link_libraries(t1_offboard_takeoff ${catkin_LIBRARIES})

再回到px4_offboard_ws下进行编译

cd ~/px4_offboard_ws
catkin_make

编译成功后运行先px4仿真

roslaunch px4 mavros_posix_sitl.launch

px4仿真的教程在我上一篇博客中Ubuntu20.04+MAVROS+PX4+Gazebo保姆级安装教程
接着运行ros功能包

cd ~/px4_offboard_ws
source devel/setup.bash
rosrun t1_offboard_takeoff t1_offboard_takeoff

可以看到gazebo中的无人机已经起飞

在这里插入图片描述想要无人机降落可以通过代码控制,也可以在运行px4的终端中输入 commander land
(需要先终止ros程序 ctrl+c)
在这里插入图片描述可以看到无人机已经降落

要通过mavros控制无人机进行向上飞行,需要使用C++编写一个ROS节点,并且使用mavros提供的API接口来发送控制指令。 以下是一个简单的示例代码,可以让无人机起飞后向上飞行一定的距离: ``` c++ #include <ros/ros.h> #include <mavros_msgs/CommandBool.h> #include <mavros_msgs/CommandTOL.h> #include <mavros_msgs/SetMode.h> #include <mavros_msgs/State.h> #include <geometry_msgs/PoseStamped.h> #include <std_msgs/Float64.h> // 飞行高度设定为5米 double target_height = 5.0; // 订阅当前无人机状态 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, "upward_flight_node"); ros::NodeHandle nh; // 订阅无人机状态,用于判断是否连接到飞控 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::Publisher target_height_pub = nh.advertise<std_msgs::Float64>("target_height", 10); // 用于修改无人机模式 ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>("mavros/cmd/arming"); ros::ServiceClient takeoff_client = nh.serviceClient<mavros_msgs::CommandTOL>("mavros/cmd/takeoff"); ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>("mavros/set_mode"); // 等待连接到飞控 while(ros::ok() && !current_state.connected){ ros::spinOnce(); ros::Rate(20); } // 设置目标高度 std_msgs::Float64 target_height_msg; target_height_msg.data = target_height; target_height_pub.publish(target_height_msg); // 等待一段时间,让高度值发送到飞控 ros::Rate(2.0); for(int i = 0; i < 10; i++){ ros::spinOnce(); ros::Rate(2.0); } // 设置起飞模式 mavros_msgs::SetMode takeoff_mode; takeoff_mode.request.custom_mode = "AUTO.TAKEOFF"; set_mode_client.call(takeoff_mode); // 等待起飞完成 while(ros::ok() && current_state.mode != "AUTO.TAKEOFF"){ ros::spinOnce(); ros::Rate(20); } // 向上飞行 geometry_msgs::PoseStamped pose; pose.pose.position.x = 0; pose.pose.position.y = 0; pose.pose.position.z = target_height; local_pos_pub.publish(pose); // 等待飞行完成 while(ros::ok() && current_state.mode == "AUTO.TAKEOFF"){ ros::spinOnce(); ros::Rate(20); } return 0; } ``` 需要注意的是,这段代码仅仅是一个示例,实际使用时还需要根据具体的情况进行修改和完善。同时,为了能够与mavros正常通信,还需要启动mavros节点,具体方法可以参考mavros的官方文档。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值