无人机路径规划3:ego-planner三维运动规划实现

XTDrone实现ego-planner三维运动规划

编译ego-palnner

cp -r  ~/XTDrone/motion_planning/3d/ego_planner ~/catkin_ws/src/
cd ~/catkin_ws/
catkin_make #或catkin build
  • 遇到报错,安装各种依赖库,把显示未安装的全部安装一遍
apt search occupancy
  • eigen3报错

eigen/double重载出错,经探索是版本问题,卸载eigen3

sudo updatedb
locate eigen3
#手动卸载
sudo rm -rf /usr/local/include/eigen3

重装eigen3.3.7

mkdir build
cd build
cmake ..
sudo make
sudo make install
#复制Eigen库到 /usr/local/include 中 (这一步很重要,一定要执行,否则后面编译一些程序,会提示没有Eigen库)
sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include
sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include 
sudo cp -r /usr/local/include/eigen3 /usr/include/eigen3
  • 解决ceres和eigen版本冲突问题

https://zhuanlan.zhihu.com/p/149775218?from_voters_page=true

XTDrone仿真实现

启动仿真程序,注意launch文件中使用的是iris_stereo_camera.sdf

cd PX4_Firmware
roslaunch px4 indoor1.launch
cd catkin_ws
bash scripts/xtdrone_run_vio.sh

由于VINS-Fusion发布的是Odometry类型的话题,我们要将其对应转为PX4所需的话题

cd ~/XTDrone/sensing/slam/vio
python vins_transfer.py iris 0

启动rtabmap仿真。注意把仿真launch文件的iris_stereo_camera换成iris_realsense_camera,这样才能有深度图数据。

roslaunch vins rtabmap_vins.launch

建立通信

cd ~/XTDrone/communication
python multirotor_communication.py iris 0 

键盘控制起飞(将飞机用键盘控制起飞后悬停,关闭键盘控制)

cd ~/XTDrone/control/keyboard
python multirotor_keyboard_control.py iris 1 vel

键盘起飞改为自动悬停的脚本

cd /home/tju/catkin_ws/src/offboard/scripts
python hover.py iris 1 vel

转换相机位姿的坐标系方向

cd ~/XTDrone/motion_planning/3d
python ego_transfer.py iris 0

启动rviz

cd ~/XTDrone/motion_planning/3d
rviz -d ego_rviz.rviz

启动ego_planner

roslaunch ego_planner single_uav.launch 

效果展示
请添加图片描述

建立自己的仿真环境

修改empty.world文件,其中注意引用同一个sdf模型时,要不同命名否则报错
请添加图片描述

编写plan.sh脚本一起启动

#!/bin/bash
gnome-terminal -x bash -c  "cd ~/PX4_Firmware; roslaunch px4 indoor1.launch"
sleep 5
gnome-terminal -x bash -c  "cd ~/catkin_ws; bash scripts/xtdrone_run_vio.sh"
sleep 5
gnome-terminal -x bash -c  "cd ~/XTDrone/sensing/slam/vio; python vins_transfer.py iris 0"
sleep 2
gnome-terminal -x bash -c  "roslaunch vins rtabmap_vins.launch "
sleep 5
gnome-terminal -x bash -c  "cd ~/XTDrone/communication; python multirotor_communication.py iris 0"
sleep 2
gnome-terminal -x bash -c  "cd /home/tju/catkin_ws/src/offboard/scripts; python hover.py iris 1 vel"
sleep 2
gnome-terminal -x bash -c  "cd ~/XTDrone/motion_planning/3d; python ego_transfer.py iris 0"
sleep 2
gnome-terminal -x bash -c  "cd ~/XTDrone/motion_planning/3d; rviz -d ego_rviz.rviz"
sleep 5
gnome-terminal -x bash -c  "roslaunch ego_planner single_uav.launch"
wait
exit 0

请添加图片描述
效果展示请添加图片描述
hover.py 自动悬停脚本

# encoding = utf-8
from time import sleep
import rospy
from geometry_msgs.msg import Twist
import sys, select, os
import tty, termios
from std_msgs.msg import String


MAX_LINEAR = 20
MAX_ANG_VEL = 3
LINEAR_STEP_SIZE = 0.01
ANG_VEL_STEP_SIZE = 0.01

cmd_vel_mask = False
ctrl_leader = False

if __name__=="__main__":

    settings = termios.tcgetattr(sys.stdin)

    multirotor_type = sys.argv[1]
    multirotor_num = int(sys.argv[2])
    control_type = sys.argv[3]
    
    if multirotor_num == 18:
        formation_configs = ['waiting', 'cuboid', 'sphere', 'diamond']
    elif multirotor_num == 9:
        formation_configs = ['waiting', 'cube', 'pyramid', 'triangle']
    elif multirotor_num == 6:
        formation_configs = ['waiting', 'T', 'diamond', 'triangle']
    
    cmd= String()
    twist = Twist()   
    
    rospy.init_node('hover')
        
        
    if control_type == 'vel':
        multi_cmd_vel_flu_pub = [None]*multirotor_num
        multi_cmd_pub = [None]*multirotor_num
        for i in range(multirotor_num):
            multi_cmd_vel_flu_pub[i] = rospy.Publisher('/xtdrone/'+multirotor_type+'_'+str(i)+'/cmd_vel_flu', Twist, queue_size=10)
            multi_cmd_pub[i] = rospy.Publisher('/xtdrone/'+multirotor_type+'_'+str(i)+'/cmd',String,queue_size=10)
        leader_cmd_vel_flu_pub = rospy.Publisher("/xtdrone/leader/cmd_vel_flu", Twist, queue_size=10)
        leader_cmd_pub = rospy.Publisher("/xtdrone/leader/cmd", String, queue_size=10)
 
    else:
        multi_cmd_accel_flu_pub = [None]*multirotor_num
        multi_cmd_pub = [None]*multirotor_num
        for i in range(multirotor_num):
            multi_cmd_accel_flu_pub[i] = rospy.Publisher('/xtdrone/'+multirotor_type+'_'+str(i)+'/cmd_accel_flu', Twist, queue_size=10)
            multi_cmd_pub[i] = rospy.Publisher('/xtdrone/'+multirotor_type+'_'+str(i)+'/cmd',String,queue_size=10)
        leader_cmd_accel_flu_pub = rospy.Publisher("/xtdrone/leader/cmd_accel_flu", Twist, queue_size=10)
        leader_cmd_pub = rospy.Publisher("/xtdrone/leader/cmd", String, queue_size=10)
    
    forward  = 0.0
    leftward  = 0.0
    upward  = 0.0
    angular = 0.0

    icount = 0
    while(1):  
        icount +=1
        # print(icount)
        if icount == 1:
            upward = 1.0
            print(upward)

        elif icount == 2:
            cmd = 'OFFBOARD'
            print(upward)
            print(cmd)
            sleep(1)
        elif icount == 3:
            cmd = 'ARM'
            print(upward)
            print(cmd)
            sleep(1)
        elif icount == 4:
            forward   = 0.0
            leftward   = 0.0
            upward   = 0.0
            angular  = 0.0
            cmd = 'HOVER'
            print(upward)
            print(cmd)
            sleep(3)
        else:
            m = icount
            sleep(5)
            
            
        twist.linear.x = forward; twist.linear.y = leftward ; twist.linear.z = upward
        twist.angular.x = 0.0; twist.angular.y = 0.0;  twist.angular.z = angular
        
        print(twist)
        
        for i in range(multirotor_num):
            if ctrl_leader:
                if control_type == 'vel':
                    leader_cmd_vel_flu_pub.publish(twist)
                else:
                    leader_cmd_aceel_flu_pub.publish(twist)
                leader_cmd_pub.publish(cmd)
            else:
                if not cmd_vel_mask:
                    if control_type == 'vel':
                        multi_cmd_vel_flu_pub[i].publish(twist)   
                    else:
                        multi_cmd_accel_flu_pub[i].publish(twist)
                multi_cmd_pub[i].publish(cmd)
                
        cmd = ''

    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)

  • 18
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
Ego-Planner是一个基于ROS的路径规划器,它可以在给定的地图和起点、终点信息下,生成一条可行的路径。以下是Ego-Planner的代码框架: 1. 首先需要定义一个EgoPlanner类,其中包含了一些必要的成员变量和函数。 ```c++ class EgoPlanner { private: ros::NodeHandle nh_; ros::Subscriber sub_map_; ros::Subscriber sub_pose_; ros::Subscriber sub_goal_; ros::Publisher pub_path_; nav_msgs::OccupancyGrid map_; geometry_msgs::PoseStamped start_; geometry_msgs::PoseStamped goal_; public: EgoPlanner(); // 构造函数 ~EgoPlanner(); // 析构函数 void mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg); // 地图回调函数 void poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg); // 当前位置回调函数 void goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg); // 目标位置回调函数 void plan(); // 路径规划函数 }; ``` 2. 在构造函数中,需要完成ROS节点的初始化、订阅和发布话题的设置。 ```c++ EgoPlanner::EgoPlanner() { nh_ = ros::NodeHandle("~"); sub_map_ = nh_.subscribe("map", 1, &EgoPlanner::mapCallback, this); sub_pose_ = nh_.subscribe("pose", 1, &EgoPlanner::poseCallback, this); sub_goal_ = nh_.subscribe("goal", 1, &EgoPlanner::goalCallback, this); pub_path_ = nh_.advertise<nav_msgs::Path>("path", 1); } ``` 3. 在地图、当前位置和目标位置的回调函数中,需要将接收到的信息保存到对应的成员变量中。 ```c++ void EgoPlanner::mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg) { map_ = *msg; } void EgoPlanner::poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { start_ = *msg; } void EgoPlanner::goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { goal_ = *msg; } ``` 4. 在路径规划函数中,需要调用路径规划算法,生成一条可行的路径,并将路径发布出去。 ```c++ void EgoPlanner::plan() { // 调用路径规划算法,生成一条可行的路径 std::vector<geometry_msgs::PoseStamped> path = pathPlanning(map_, start_, goal_); // 将路径发布出去 nav_msgs::Path path_msg; path_msg.header.frame_id = "map"; path_msg.header.stamp = ros::Time::now(); path_msg.poses = path; pub_path_.publish(path_msg); } ``` 5. 在主函数中,创建EgoPlanner对象,并进入ROS循环。 ```c++ int main(int argc, char** argv) { ros::init(argc, argv, "ego_planner"); EgoPlanner planner; ros::Rate rate(10); while (ros::ok()) { planner.plan(); ros::spinOnce(); rate.sleep(); } return 0; } ``` 以上就是Ego-Planner的代码框架,其中路径规划算法需要根据具体情况进行选择和实现
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值