EGO-Planner学习笔记

4 篇文章 0 订阅

前言

对于一般无人机设计,可以将无人机的飞行控制过程分为感知层,运动规划层以及控制层,框图如下
在这里插入图片描述
感知层对无人机的状态信息进行解析获取,结合状态信息以及任务需求对无人机i的期望运动状态进行规划,并生成对应的轨迹,最后通过控制层输出可由无人机直接执行的控制指令,由此实现闭环控制。

感知层

感知层一般由传感器作为硬件构成,如加速度计、磁力计、陀螺仪等外部传感器以及摄像头、激光、GPS等外部传感器,通过对各类传感器的数据进行获取并融合可以得到无人机的状态信息,如位置、速度、加速度以及姿态角信息。

硬件部分

在使用EGO_Planner算法时,需要使用外部视觉传感器对室内环境进行感知,使用IMU模块进行融合定位。

算法部分

该算法使用VINS-Fusion对各类定位数据进行融合,包括由视觉里程计计算得到位姿信息以及IMU积分得到的位姿信息。经融合后可以得到无人机准确的位姿信息及速度等状态量。同时根据感知到的环境信息实时构建地图,以完成对障碍物的探测等任务。

运动规划层

运动规划层将结合环境信息、无人机的状态信息以及飞行任务综合生成一条合理的路径,并交由控制层执行。

路径的表示方法

路径一般为曲线,表示方法由很多种,如样条曲线以及多项式曲线。考虑到样条曲线的控制点只对临近的曲线造成影响,该算法使用样条曲线作为最后的路径输出。

路径搜索

通过判断任务需求得到飞行任务的目标点,通过路径搜多算法生成一条从当前点到目标点的一条合理路径,该路径应避开当前可探测的障碍物。该算法使用A*算法对可行路径进行初步搜索。

轨迹优化

轨迹是有时间维度的路径,及可以在某个时间可以到达某个位置。
由于A*算法依据栅格地图的看空白处获得,所得到的路径为折线,考虑飞行的连贯性以及代价,路径应为光滑连续的曲线。故需要对该路径进行优化。
首先由初始路径生成一条由若干控制点组成的光滑的样条曲线,在优化过程中通过改变控制点在空间中的位置实现对路径的修改。
该算法采用基于梯度下降的优化算法,通过对当前对极构造代价函数,该代价函数应综合考虑总消耗,最终得到消耗最小的轨迹。其中总消耗包括飞行过程中的速度变化、加速变化以及角速度变化、力矩变化等,这里的状态量由得到期望路径后使用微分平坦算法得到,并作为期望值参与代价函数的计算。
优化过程中首先判断该路径是否会发生碰撞,若发生碰撞,应对路径进行搜索,得到一条无碰撞的路径。
在此基础上进行微分平坦得到控制量,并结合控制量以及其他惩罚项得到代价函数值,通过梯度下降对轨迹进行修改,最后得到最优的轨迹,并生成控制指令供控制层执行。

控制层

该算法使用pid控制,得到期望姿态角以及期望推力后传递至飞行控制板执行。
至此完成闭环。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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的代码框架,其中路径规划算法需要根据具体情况进行选择和实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值