octomap中3d-rrt路径规划
在octomap中制定起止点,目标点,使用rrt规划一条路径出来,没有运动学,动力学的限制,只要能避开障碍物。
效果如下(绿线是规划的路线,红线是B样条优化的曲线):

#include "ros/ros.h"
#include <octomap_msgs/Octomap.h>
#include <octomap_msgs/conversions.h>
#include <octomap_ros/conversions.h>
#include <octomap/octomap.h>
#include <message_filters/subscriber.h>
#include "visualization_msgs/Marker.h"
#include <trajectory_msgs/MultiDOFJointTrajectory.h>
#include <nav_msgs/Odometry.h>
#include <geometry_msgs/Pose.h>
#include <nav_msgs/Path.h>
#include <geometry_msgs/PoseStamped.h>
#include <ompl/base/spaces/SE3StateSpace.h>
#include <ompl/base/spaces/SE3StateSpace.h>
#include <ompl/base/OptimizationObjective.h>
#include <ompl/base/objectives/PathLengthOptimizationObjective.h>
// #include <ompl/geometric/planners/rrt/RRTstar.h>
#include <ompl/geometric/planners/rrt/InformedRRTstar.h>
#include <ompl/geometric/SimpleSetup.h>
#include <ompl/config.h>
#include <iostream>
#include "fcl/config.h"
#include "fcl/octree.h"
#include "fcl/traversal/traversal_node_octree.h"
#include "fcl/collision.h"
#include "fcl/broadphase/broadphase.h"
#include "fcl/math/transform.h"
namespace ob = ompl::base;
namespace og = ompl::geometric;
// Declear some global variables
//ROS publishers
ros::Publisher vis_pub;
ros::Publisher traj_pub;
class planner {
public:
void setStart(double x, double y, double z)
{
ob::ScopedState<ob::SE3StateSpace> start(space);
start->setXYZ(x,y,z);
start->as<ob::SO3StateSpace::StateType>(1)->setIdentity();
pdef->clearStartStates();
pdef->addStartState(start);
}
void setGoal(double x, double y, double z)
{
ob::ScopedState<ob::SE3StateSpace> goal(space);
goal->setXYZ(x,y,z);
goal->as<ob::SO3StateSpace::StateType>(1)->setIdentity();
pdef->clearGoal();
pdef->setGoalState(goal);
std::cout << "goal set to: " << x << " " << y << " " << z << std::endl;
}
void updateMap(std::shared_ptr<fcl::CollisionGeometry> map)
{
tree_obj = map;
}
// Constructor
planner(void)
{
//四旋翼的障碍物几何形状
Quadcopter = std::shared_ptr<fcl::CollisionGeometry>(new fcl::Box(0.8, 0.8, 0.3));
//分辨率参数设置
fcl::OcTree* tree = new fcl::OcTree(std::shared_ptr<const octomap::OcTree>(new octomap::OcTree(0.15)));
tree_obj = std::shared_ptr<fcl::CollisionGeometry>(tree);
//解的状态空间
space = ob::StateSpacePtr(new ob::SE3StateSpace());
// create a start state
ob::ScopedState<ob::SE3StateSpace> start(space);
// create a goal state
ob::ScopedState<ob::SE3StateSpace> goal(space);
// set the bounds for the R^3 part of SE(3)
// 搜索的三维范围设置
ob::RealVectorBounds bounds(3);
bounds.setLow(0,-5);
bounds.setHigh(0,5);
bounds.setLow(1,-5);
bounds.setHigh(1,5);
bounds.setLow(2,0);
bounds.setHigh(2,3);
space->as<ob::SE3StateSpace>()->setBounds(bounds);
// construct an instance of space information from this state space
si = ob::SpaceInformationPtr(new ob::SpaceInformation(space));
start->setXYZ(0,0,0);
start->as<ob::SO3StateSpace::StateType>(1)->setIdentity();
// start.random();
goal->setXYZ(0,0,0);
goal->as<ob::SO3StateSpace::StateType>(1)->setIdentity();
// goal.random();
// set state validity checking for this space
si->setStateValidityChecker(std::bind(&planner::isStateValid, this, std::placeholders::_1 ));
// create a problem instance
pdef = ob::ProblemDefinitionPtr(new ob::ProblemDefinition(si));
// set the start and goal states
pdef->setStartAndGoalStates(start, goal);
// set Optimizattion objective
pdef->setOptimizationObjective(planner::getPathLengthObjWithCostToGo(si));
std::cout << "Initialized: " << std::endl;
}
// Destructor
~planner()
{
}
void replan(void)
{
std::cout << "Total Points:" << path_smooth->getStateCount () << std::endl;
if(path_smooth->getStateCount () <= 2)
plan();
else
{
for (std::size_t idx = 0; idx < path_smooth->getStateCount (); idx++)
{
if(!replan_flag)
replan_flag = !isStateValid(path_smooth->getState(idx));
else
break;
}
if(replan_flag)
plan();
else
std::cout << "Replanning not required" << std::endl;
}
}
void plan(void)
{
// create a planner for the defined space
og::InformedRRTstar* rrt = new og::InformedRRTstar(si);
//设置rrt的参数range
rrt->setRange(0.2);
ob::PlannerPtr plan(rrt);
// set the problem we are trying to solve for the planner
plan->setProblemDefinition(pdef);
// perform setup steps for the planner
plan->setup();
// print the settings for this space
si->printSettings(std::cout);
std::cout << "problem setting\n";
// print the problem settings
pdef->print(std::cout);
// attempt to solve the problem within one second of planning time
ob::PlannerStatus solved = plan->solve(1);
if (solved)
{
// get the goal representation from the problem definition (not the same as the goal state)
// and inquire about the found path
std::cout << "Found solution:" << std::endl;
ob::PathPtr path = pdef->getSolutionPath();
og::PathGeometric* pth = pdef->getSolutionPath()->as<og::PathGeometric>();
pth->printAsMatrix(std::cout);
// print the path to screen
// path->print(std::cout);
nav_msgs::Path msg;
msg.header.stamp = ros::Time::now();
msg.header.frame_id = "map";
for (std::size_t path_idx = 0; path_idx < pth->getStateCount (); path_idx++)
{
const ob::SE3StateSpace::StateType *se3state = pth->getState(path_idx)->as<ob::SE3StateSpace::StateType>();
// extract the first component of the state and cast it to what we expect
const ob::RealVectorStateSpace::StateType *pos = se3state->as<ob::RealVectorStateSpace::StateType>(0);
// extract the second component of the state and cast it to what we expect
const ob::SO3StateSpace::StateType *rot = se3state->as<ob::SO3StateSpace::StateType>(1);
geometry_msgs::PoseStamped pose;
// pose.header.frame_id = "/world"
pose.pose.position.x = pos->values[0];
pose.pose.position.y = pos->values[1];
pose.pose.position.z = pos->values[2];
pose.pose.orientation.x = rot->x;
pose.pose.orientation.y = rot->y;
pose.pose.orientation.z = rot->z;
pose.pose.orientation.w = rot->w;
msg.poses.push_back(pose);
}
traj_pub.publish(msg);
//Path smoothing using bspline
//B样条曲线优化
og::PathSimplifier* pathBSpline = new og::PathSimplifier(si);
path_smooth = new og::PathGeometric(dynamic_cast<const og::PathGeometric&>(*pdef->getSolutionPath()));
pathBSpline->smoothBSpline(*path_smooth,3);
// std::cout << "Smoothed Path" << std::endl;
// path_smooth.print(std::cout);
//Publish path as markers
nav_msgs::Path smooth_msg;
smooth_msg.header.stamp = ros::Time::now();
smooth_msg.header.frame_id = "map";
for (std::size_t idx = 0; idx < path_smooth->getStateCount (); idx++)
{
// cast the abstract state type to the type we expect
const ob::SE3StateSpace::StateType *se3state = path_smooth->getState(idx)->as<ob::SE3StateSpace::StateType>();
// extract the first component of the state and cast it to what we expect
const ob::RealVectorStateSpace::StateType *pos = se3state->as<ob::RealVectorStateSpace::StateType>(0);
// extract the second component of the state and cast it to what we expect
const ob::SO3StateSpace::StateType *rot = se3state->as<ob::SO3StateSpace::StateType>(1);
geometry_msgs::PoseStamped point;
// pose.header.frame_id = "/world"
point.pose.position.x = pos->values[0];
point.pose.position.y = pos->values[1];
point.pose.position.z = pos->values[2];
point.pose.orientation.x = rot->x;
point.pose.orientation.y = rot->y;
point.pose.orientation.z = rot->z;
point.pose.orientation.w = rot->w;
smooth_msg.poses.push_back(point);
std::cout << "Published marker: " << idx << std::endl;
}
vis_pub.publish(smooth_msg);
// ros::Duration(0.1).sleep();
// Clear memory
pdef->clearSolutionPaths();
replan_flag = false;
}
else
std::cout << "No solution found" << std::endl;
}
private:
// construct the state space we are planning in
ob::StateSpacePtr space;
// construct an instance of space information from this state space
ob::SpaceInformationPtr si;
// create a problem instance
ob::ProblemDefinitionPtr pdef;
og::PathGeometric* path_smooth;
bool replan_flag = false;
std::shared_ptr<fcl::CollisionGeometry> Quadcopter;
std::shared_ptr<fcl::CollisionGeometry> tree_obj;
bool isStateValid(const ob::State *state)
{
// cast the abstract state type to the type we expect
const ob::SE3StateSpace::StateType *se3state = state->as<ob::SE3StateSpace::StateType>();
// extract the first component of the state and cast it to what we expect
const ob::RealVectorStateSpace::StateType *pos = se3state->as<ob::RealVectorStateSpace::StateType>(0);
// extract the second component of the state and cast it to what we expect
const ob::SO3StateSpace::StateType *rot = se3state->as<ob::SO3StateSpace::StateType>(1);
fcl::CollisionObject treeObj((tree_obj));
fcl::CollisionObject aircraftObject(Quadcopter);
// check validity of state defined by pos & rot
fcl::Vec3f translation(pos->values[0],pos->values[1],pos->values[2]);
fcl::Quaternion3f rotation(rot->w, rot->x, rot->y, rot->z);
aircraftObject.setTransform(rotation, translation);
fcl::CollisionRequest requestType(1,false,1,false);
fcl::CollisionResult collisionResult;
fcl::collide(&aircraftObject, &treeObj, requestType, collisionResult);
return(!collisionResult.isCollision());
}
// Returns a structure representing the optimization objective to use
// for optimal motion planning. This method returns an objective which
// attempts to minimize the length in configuration space of computed
// paths.
ob::OptimizationObjectivePtr getThresholdPathLengthObj(const ob::SpaceInformationPtr& si)
{
ob::OptimizationObjectivePtr obj(new ob::PathLengthOptimizationObjective(si));
// obj->setCostThreshold(ob::Cost(1.51));
return obj;
}
ob::OptimizationObjectivePtr getPathLengthObjWithCostToGo(const ob::SpaceInformationPtr& si)
{
ob::OptimizationObjectivePtr obj(new ob::PathLengthOptimizationObjective(si));
obj->setCostToGoHeuristic(&ob::goalRegionCostToGo);
return obj;
}
};
void octomapCallback(const octomap_msgs::Octomap::ConstPtr &msg, planner* planner_ptr)
{
//loading octree from binary
// const std::string filename = "/home/xiaopeng/dense.bt";
// octomap::OcTree temp_tree(0.1);
// temp_tree.readBinary(filename);
// fcl::OcTree* tree = new fcl::OcTree(std::shared_ptr<const octomap::OcTree>(&temp_tree));
// convert octree to collision object
octomap::OcTree* tree_oct = dynamic_cast<octomap::OcTree*>(octomap_msgs::msgToMap(*msg));
fcl::OcTree* tree = new fcl::OcTree(std::shared_ptr<const octomap::OcTree>(tree_oct));
// Update the octree used for collision checking
planner_ptr->updateMap(std::shared_ptr<fcl::CollisionGeometry>(tree));
planner_ptr->replan();
}
void odomCb(const nav_msgs::Odometry::ConstPtr &msg, planner* planner_ptr)
{
planner_ptr->setStart(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z);
}
void startCb(const geometry_msgs::PointStamped::ConstPtr &msg, planner* planner_ptr)
{
planner_ptr->setStart(msg->point.x, msg->point.y, msg->point.z);
}
void goalCb(const geometry_msgs::PointStamped::ConstPtr &msg, planner* planner_ptr)
{
planner_ptr->setGoal(msg->point.x, msg->point.y, msg->point.z);
planner_ptr->plan();
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "octomap_planner");
ros::NodeHandle n;
planner planner_object;
ros::Subscriber octree_sub = n.subscribe<octomap_msgs::Octomap>("/octomap_binary", 1, boost::bind(&octomapCallback, _1, &planner_object));
// ros::Subscriber odom_sub = n.subscribe<nav_msgs::Odometry>("/rovio/odometry", 1, boost::bind(&odomCb, _1, &planner_object));
ros::Subscriber goal_sub = n.subscribe<geometry_msgs::PointStamped>("/goal/clicked_point", 1, boost::bind(&goalCb, _1, &planner_object));
ros::Subscriber start_sub = n.subscribe<geometry_msgs::PointStamped>("/start/clicked_point", 1, boost::bind(&startCb, _1, &planner_object));
// vis_pub = n.advertise<visualization_msgs::Marker>( "visualization_marker", 0 );
vis_pub = n.advertise<nav_msgs::Path>( "visualization_marker", 0 );
// traj_pub = n.advertise<trajectory_msgs::MultiDOFJointTrajectory>("waypoints",1);
traj_pub = n.advertise<nav_msgs::Path>("waypoints",1);
std::cout << "OMPL version: " << OMPL_VERSION << std::endl;
ros::spin();
return 0;
}
octomap中3d-rrt路径规划的更多相关文章
- RRT路径规划算法
传统的路径规划算法有人工势场法.模糊规则法.遗传算法.神经网络.模拟退火算法.蚁群优化算法等.但这些方法都需要在一个确定的空间内对障碍物进行建模,计算复杂度与机器人自由度呈指数关系,不适合解决多自由度 ...
- ROS(indigo)RRT路径规划
源码地址:https://github.com/nalin1096/path_planning 路径规划 使用ROS实现了基于RRT路径规划算法. 发行版 - indigo 算法在有一个障碍的环境找到 ...
- RRT路径规划算法(matlab实现)
基于快速扩展随机树(RRT / rapidly exploring random tree)的路径规划算法,通过对状态空间中的采样点进行碰撞检测,避免了对空间的建模,能够有效地解决高维空间和复杂约束的 ...
- V-rep学习笔记:机器人路径规划1
Motion Planning Library V-REP 从3.3.0开始,使用运动规划库OMPL作为插件,通过调用API的方式代替以前的方法进行运动规划(The old path/motion ...
- 游戏AI之路径规划(3)
目录 使用路径点(Way Point)作为节点 洪水填充算法创建路径点 使用导航网(Navigation Mesh)作为节点 区域分割 预计算 路径查询表 路径成本查询表 寻路的改进 平均帧运算 路径 ...
- PRM路径规划算法
路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法:如人工势场法.单元分解法.随机路标图(PRM)法.快速搜索树(RRT)法等.传统的人工势场.单元分解法需要对空间中的 ...
- iOS高德地图使用-搜索,路径规划
项目中想加入地图功能,使用高德地图第三方,想要实现确定一个位置,搜索路线并且显示的方法.耗了一番功夫,总算实现了. 效果 WeChat_1462507820.jpeg 一.配置工作 1.申请key 访 ...
- 路径规划: PRM 路径规划算法 (Probabilistic Roadmaps 随机路标图)
随机路标图-Probabilistic Roadmaps (路径规划算法) 路径规划作为机器人完成各种任务的基础,一直是研究的热点.研究人员提出了许多规划方法如: 1. A* 2. Djstar 3. ...
- 机器人路径规划其一 Dijkstra Algorithm【附动态图源码】
首先要说明的是,机器人路径规划与轨迹规划属于两个不同的概念,一般而言,轨迹规划针对的对象为机器人末端坐标系或者某个关节的位置速度加速度在时域的规划,常用的方法为多项式样条插值,梯形轨迹等等,而路径规划 ...
随机推荐
- 谈谈一些有趣的CSS题目(十五)-- 奇妙的 background-clip: text
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- npm install fetchmatedata慢的解决办法
最近在开发webpack工程时,第一步npm install这里超级慢,一直停着,显示:"fetchMetadata: sill mapToRegistry uri https://regi ...
- app性能测试【通过loadrunner录制】
随着智能手机近年来的快速增长,从游戏娱乐到移动办公的各式各样的手机APP软件渗透到我们的生活中,对于大型的手机APP测试不仅要关注它的功能性.易用性还要关注它的性能,最近发现LoadRunner12可 ...
- javascript函数作用域及this指向详解
一.先说一个简单的概念--变量提升: 通过function+函数名的方式,声明的函数,可以在代码中的任何位置调用: 通过var定义变量的方式,声明的函数,则必须在声明之后进行调用,原因就是在变量定义之 ...
- Java学习笔记--链表
心在山东身在吴,飘蓬江海漫嗟吁. 他时若遂凌云志, 敢笑黄巢不丈夫. --水浒传 先上源代码,LinkedList类: private static class Node<E> { E i ...
- MySql5.7环境搭建
1. 安装mysql的linux系统 [root@grewan ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [root@grewan ...
- 高性能网站架构设计之缓存篇(1)- Redis C#客户端
一.什么 RedisREmote DIctionary Server,简称 Redis,是一个类似于Memcached的Key-Value存储系统.相比Memcached,它支持更丰富的数据结构,包括 ...
- 面试(4)-spring-Spring面试题和答案
1:69道Spring面试题和答案 转自:http://ifeve.com/spring-interview-questions-and-answers/ 目录 Spring 概述 依赖注入 Spri ...
- css样式自动换行/强制换行
写样式时遇到的英文字符超出容器问题,度娘后了解下列知识,与大家分享,同时以便自己日后回顾. 一.自动换行问题 正常字符的换行是比较合理的,而连续的数字和英文字符常常将容器撑大. 下面介绍的是CSS如何 ...
- 如何编写Hexo主题
完成一个Hexo的主题其实很简单,和写静态页面差不多,只是内容部分通过Hexo的变量去获取,而且Hexo还内置了一些辅助函数帮你快速方便地完成繁琐的处理. 起步 在写代码之前要先把项目结构搭建好,一个 ...