1. 程式人生 > >octomap中3d-rrt路徑規劃

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

相關推薦

octomap3d-rrt路徑規劃

路徑規劃 在octomap中制定起止點,目標點,使用rrt規劃一條路徑出來,沒有運動學,動力學的限制,只要能避開障礙物。 效果如下(綠線是規劃的路線,紅線是B樣條優化的曲線): #include "ros/ros.h" #include <octomap_msgs/Octomap.h> #i

RRT路徑規劃演算法

%%%%% parameters map=im2bw(imread('map2.bmp')); % input map read from a bmp file. for new maps write the file name here source=[10 10]; % source position

ROS路徑規劃演算法dijkstra和A*

ROS Navigation包裡面的GlobalPlanner自帶是提供了兩種全域性路徑規劃的方法,dijkstra和A* dijkstra 大家都知道了,A*在之前的一篇部落格裡面有介紹 A* 評估函式 為 f(n) = g(n) + h(n) g(

在matlab實踐採用A*演算法模擬AGV路徑規劃-初步

碼字記錄下 今天下午在寫專利,弄了好幾個小時才折騰出一兩百字,主要是寫了把實施過程說明了遍,因為即使寫好了也很可能趕不上在畢業前通過專利初審,所以想盡量早點寫出一篇小論文發表出來,畢竟光軟著沒有卵說服力,所以轉移方向折騰小論文, 疑問:1、路徑規劃怎麼在matlab中模擬,

導航路徑規劃模組與演算法

路徑規劃是導航系統的基本能力之一。 熟悉這個模組的目標: 1. 熟悉導航常用的路徑規劃經典演算法,這個在導航系統開發比較成熟後,使用哪種演算法並不是最重要的,關鍵是能滿足效能需求 2. 熟悉有哪些路徑規劃的衡量指標,是最近,最省時間,最省油... 度量指標要根據實際需求來

python讀取某個路徑文件夾下所有文件--listdir()

文件夾路徑 .com hub 描述 路徑 -a 函數 list bsp 描述:   當需要讀取某個文件下的所有文件時,可以使用listdir()函數,使用該函數之前,需導入模塊:from os import listdir 語法:   listdir(‘file path/

ROS--導航、路徑規劃和SLAM

nbsp del 正方 with ros let slam 規劃 節點 一、用move_base導航走正方形 1、 roscore 2、執行 roslaunch rbx1_bringup fake_turtlebot.launch   然後 rosla

html的相對路徑問題

html bsp src 標簽 nbsp html中 htm 文件 使用 比如html中想使用<img>標簽來引入一個圖片,那圖片的引用src屬性就涉及到一個路徑問題。 相對路徑指的是什麽呢?指的就是相對於當前資源(當前資源現在指的就是html文件的位置)所在目

jsp 包含 一個路徑為變量的文件

包含 base jsp ase body brush 一個 str pre <head> <base href="<%=basePath%>"> <% String fileroot="MyJsp.jsp

Python的絕對路徑和相對路徑

clas tail detail keyword os.path win targe 此外 相對路徑 大牛們應該對路徑都很了解了,這篇文章主要給像我這樣的入門小白普及常識用的,啊哈 下面的路徑介紹針對windows,其他平臺的暫時不是很了解。 在編寫的py文件中打開文件

CSS及HTML、js的資源路徑問題

stat 文件中 bsp ng- 層級 png 目的 指令 php 路徑 分為相對路徑和絕對路徑 一、相對路徑。 相對於文件本身的路徑。 用 ./ 表示同一文件夾下的兄弟文件。 用../ 表示所處文件夾的父文件夾中的文件。 二、絕對路徑。 本機絕對路徑是 例如 E:\ph

[轉載]RPMSPEC常用路徑以及宏變量

source ref odi dst init ould var 代碼 oba 轉自:http://blog.csdn.net/txgc1009/article/details/6833764 通過命令rpm --showrc查看實現代碼。另外直接通過 rpm --eva

JSP、Servlet的相對路徑和絕對路徑

項目 home 路徑問題 流程 localhost -name erp 中轉 所在 1.JSP、Servlet中的相對路徑和絕對路徑 前提:假設你的Http地址為http://192.168.0.1/你的web應用為test,path="/test"那麽你的we

url含有中文路徑時訪問出現404問題

pat find() 訪問 col pub 文字 str static color /** * URL中文字符編碼轉換 * @param url 含中文字符的URL * @return */ public static String getC

Ant Trip(區別於二分匹配最小路徑覆蓋的一筆畫問題)

end src 並且 col group 就是 size http align 題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=3018 題目: Problem Description Ant Country consist

機器人自主移動的秘密:SLAM與路徑規劃有什麽關系?(三)

針對 left 很多 -s 人在 比較 www. 全局 有時 博客轉載自:https://www.leiphone.com/news/201612/lvDXqY82OGNqEiyl.html 雷鋒網(公眾號:雷鋒網)按:本文作者SLAMTEC(思嵐科技公號slamtec-s

java使用相對路徑讀取文件的寫法總結 ,以及getResourceAsStream() (轉)

protected 9.png pre ring details 使用 ide 技術分享 相對 https://blog.csdn.net/my__sun_/article/details/74450241 讀取文件的寫法,相對路徑 在當前的目錄結構中讀取test.txt的

大數據學習哪裏好?0基礎學習大數據的路徑規劃

需求 工程 線上 線下 徹底 招聘 大數據 能源 2018年 隨著移動互聯網和雲計算的快速發展,我國大數據時代已經到來,大數據將徹底顛覆傳統的生產方式生活方式,對不同領域的產業和部門將產生深遠的影響。   大數據的發展前景:  1、人才稀缺:未來3至5年,中國需要200

如何自學人工智能路徑規劃(附資源,百分百親身經驗)

而且 文章 綜述 獨立性 -i 關於 ade sdn 其中 下面的每個資源都是我親身學過的,且是網上公開公認最優質的資源。 下面的每個學習步驟也是我一步步走過來的。希望大家以我為參考,少走彎路。 請大家不要浪費時間找非常多的資料,只看最精華的! 綜述,機器學習的自學簡

centos和pycharm取絕對路徑的差別

art centos7 bin none 項目 har name imp 路徑 pycharm中取執行文件絕對路勁並向上翻兩次,得到項目目錄 import os import sys project_path = os.path.dirname(os.path.dirn