欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > Fast Planner规划算法(四)—— Fast Planner程序框架

Fast Planner规划算法(四)—— Fast Planner程序框架

2025/2/25 1:22:55 来源:https://blog.csdn.net/qq_44339029/article/details/132634816  浏览:    关键词:Fast Planner规划算法(四)—— Fast Planner程序框架

   本系列文章用于学习记录Fast-Planner规划算法的相关内容,主要学习资料是深蓝学院的移动机器人运动规划课程

   五、Fast Planner程序框架

   Fast Planner算法相关的程序存放在fast_planner文件夹内

在这里插入图片描述

   fast_planner文件夹下包含八个文件夹,各文件夹的作用如下:

   (1)、bag:脚本文件

   (2)、bspline:非均匀B样条,用于后端时间重分配部分

   (3)、bspline_opt :均匀B样条,用于后端轨迹优化部分

   (4)、path_searching:包含A*算法、Hybrid A * 算法、基于拓扑的PRM算法,三个规划算法,用于前端的路径规划

   (5)、plan_env:用于地图生成,包括栅格地图生成、ESDF生成等

   (6)、plan_manage:主文件夹,主节点所在文件夹,

   (7)、poly_traj:定义了一个多项式的轨迹类

   (8)、traj_utils:可视化相关内容

在这里插入图片描述

   要理解Fast Planner的程序框架,就应该从主节点所在的plan_manage文件夹开始:

   (1)fast_planner_node.cpp

   fast_planner_node.cpp文件是我们通过launch文件启动Fast Planner程序的接口,也是ROS中Fast Planner的主节点,该文件在完成节点初始化后,会根据参数planner的值选择进行kino_replan或者topo_replan的初始化。

在这里插入图片描述

   (2)kino_replan_fsm.cpp

   若参数planner的值为1,则执行kino_replan的初始化,kino_replan的初始化的具体程序在kino_replan_fsm.cpp文件中,这个文件也是ROS跟 Fast Planner程序的接口性程序,包括参数加载、回调、订阅等。

   kino_replan_fsm.cpp文件中的execFSMCallback函数是状态基,用于处理在机器人运行过程中遇到各种情况下,是选择急停、还是重新规划、还是继续执行等。

void KinoReplanFSM::execFSMCallback(const ros::TimerEvent& e)

   kino_replan_fsm.cpp文件中的checkCollisionCallback是用于检查碰撞的函数

void KinoReplanFSM::checkCollisionCallback(const ros::TimerEvent& e)

   kino_replan_fsm.cpp文件中的callKinodynamicReplan函数中,会调用kinodynamicReplan函数,本系列前三篇文章介绍的内容全包含在和这个函数中,即局部的包含前端和后端的规划方法。该函数在planner_manager.cpp文件中。

bool KinoReplanFSM::callKinodynamicReplan()
 bool plan_success =planner_manager_->kinodynamicReplan(start_pt_, start_vel_, start_acc_, end_pt_, end_vel_);

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

   (3)planner_manager.cpp

   kino_replan_fsm.cpp文件通过调用kinodynamicReplan函数来调用该文件。

bool FastPlannerManager::kinodynamicReplan(Eigen::Vector3d start_pt, Eigen::Vector3d start_vel,Eigen::Vector3d start_acc, Eigen::Vector3d end_pt,Eigen::Vector3d end_vel)

   kinodynamicReplan函数中完成一些初始化操作后,首先后使用Hybrid A * 算法进行前端的路径搜索,该部分内容通过调用kinodynamic_astar.cpp中的search函数完成。

 int status = kino_path_finder_->search(start_pt, start_vel, start_acc, end_pt, end_vel, true);
int KinodynamicAstar::search(Eigen::Vector3d start_pt, Eigen::Vector3d start_v, Eigen::Vector3d start_a,Eigen::Vector3d end_pt, Eigen::Vector3d end_v, bool init, bool dynamic, double time_start)

   接下来会将前端得到的路径转换成B样条曲线的形式,作为后端优化的初值,该部分内容在parameterizeToBspline,这个函数的具体程序在non_uniform_bspline.cpp文件中

NonUniformBspline::parameterizeToBspline(ts, point_set, start_end_derivatives, ctrl_pts);
void NonUniformBspline::parameterizeToBspline(const double& ts, const vector<Eigen::Vector3d>& point_set,const vector<Eigen::Vector3d>& start_end_derivative,Eigen::MatrixXd&               ctrl_pts)

   接下来就是后端的使用均匀B样条及优化算法进行轨迹优化了,该部分内容是通过调用BsplineOptimizeTraj函数来完成的,该函数的具体程序在bspline_optimizer.cpp文件中

ctrl_pts = bspline_optimizers_[0]->BsplineOptimizeTraj(ctrl_pts, ts, cost_function, 1, 1);
Eigen::MatrixXd BsplineOptimizer::BsplineOptimizeTraj(const Eigen::MatrixXd& points, const double& ts,const int& cost_function, int max_num_id,int max_time_id)

   最后,就是时间的重分配了,通过调用非均匀的B样条来进行时间的重分配,该部分内容在类NonUniformBspline中完成,该类的具体程序在non_uniform_bspline.cpp文件中

  NonUniformBspline pos = NonUniformBspline(ctrl_pts, 3, ts);double to = pos.getTimeSum();pos.setPhysicalLimits(pp_.max_vel_, pp_.max_acc_);bool feasible = pos.checkFeasibility(false);int iter_num = 0;while (!feasible && ros::ok()) {feasible = pos.reallocateTime();if (++iter_num >= 3) break;}
NonUniformBspline::NonUniformBspline(const Eigen::MatrixXd& points, const int& order,const double& interval) {setUniformBspline(points, order, interval);
}

   上面就是 Fast Planner程序的大概流程,跟前三篇文章 介绍的流程是相同的。

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

   我们现在来看一下上面流程中,比较重要的使用均匀B样条曲线及优化算法进行后端优化的位于bspline_optimizer.cpp文件中的BsplineOptimizeTraj函数

Eigen::MatrixXd BsplineOptimizer::BsplineOptimizeTraj(const Eigen::MatrixXd& points, const double& ts,const int& cost_function, int max_num_id,int max_time_id)

   首先是对优化问题进行一些设置,points是控制点的初值,ts是B样条的时间,setCostFunction(cost_function)是选择在优化过程中加入那些类型的代价,如平滑、无碰撞、距离,等代价函数。

  setControlPoints(points);setBsplineInterval(ts);setCostFunction(cost_function);setTerminateCond(max_num_id, max_time_id);

   然后,执行optimize()函数来进行优化

 optimize();

   在optimize()函数中需要特别注意的是需要最小化的目标函数的设置,即costFunction函数的计算

 opt.set_min_objective(BsplineOptimizer::costFunction, this);

   costFunction函数计算目标函数的具体程序如下:

double BsplineOptimizer::costFunction(const std::vector<double>& x, std::vector<double>& grad,void* func_data) {BsplineOptimizer* opt = reinterpret_cast<BsplineOptimizer*>(func_data);double            cost;opt->combineCost(x, grad, cost);opt->iter_num_++;/* save the min cost result */if (cost < opt->min_cost_) {opt->min_cost_      = cost;opt->best_variable_ = x;}return cost;
}

   具体cost的计算是在其调用的combineCost函数中

void BsplineOptimizer::combineCost(const std::vector<double>& x, std::vector<double>& grad,double& f_combine) 

   在计算cost时,我们传入的是控制点,得到的是目标函数值及其梯度值



   参考资料:

   1、深蓝学院-移动机器人运动规划


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词