• ROS(indigo)RRT路径规划


    源码地址:https://github.com/nalin1096/path_planning

    路径规划


    使用ROS实现了基于RRT路径规划算法。

    发行版 - indigo 

    算法在有一个障碍的环境找到优化的路径。算法可视化在RVIZ完成,代码是用C ++编写。 

    包有两个可执行文件:

    ros_node 
    env_node



    RVIZ参数: 

    Frame_id =“path_planner” 
    marker_topic =“path_planner_rrt” 

    说明: 

    1. 打开终端,输入 
    1. $ roscore 
    1. 打开新的终端并转到catkin工作区:
    1. $ catkin_make 
    1. $ source ./devel/setup.bash 
    1. $ rosrun path_planning env_node
    1. 打开新的终端 
    1. $ rosrun rviz rviz 
    1. 在RVIZ窗口,更改: 
    1. 在全局选项固定框架“path_planner” 
    1. 添加标记和标记改变主题,以“path_planner_rrt” 
    1. 打开新的终端 
    1. rosrun path_planning rrt_node


    如果想修改环境environment,如下

    #include <ros/ros.h>
    #include <visualization_msgs/Marker.h>
    #include <path_planning/rrt.h>
    #include <path_planning/obstacles.h>
    #include <geometry_msgs/Point.h>
    
    #include <iostream>
    #include <cmath>
    #include <math.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <vector>
    
    using namespace rrt;
    
    void initializeMarkers(visualization_msgs::Marker &boundary,
        visualization_msgs::Marker &obstacle)
    {
        //init headers
    	boundary.header.frame_id    = obstacle.header.frame_id    = "path_planner";
    	boundary.header.stamp       = obstacle.header.stamp       = ros::Time::now();
    	boundary.ns                 = obstacle.ns                 = "path_planner";
    	boundary.action             = obstacle.action             = visualization_msgs::Marker::ADD;
    	boundary.pose.orientation.w = obstacle.pose.orientation.w = 1.0;
    
        //setting id for each marker
        boundary.id    = 110;
    	obstacle.id   = 111;
    
    	//defining types
    	boundary.type  = visualization_msgs::Marker::LINE_STRIP;
    	obstacle.type = visualization_msgs::Marker::LINE_LIST;
    
    	//setting scale
    	boundary.scale.x = 1;
    	obstacle.scale.x = 0.2;
    
        //assigning colors
    	boundary.color.r = obstacle.color.r = 0.0f;
    	boundary.color.g = obstacle.color.g = 0.0f;
    	boundary.color.b = obstacle.color.b = 0.0f;
    
    	boundary.color.a = obstacle.color.a = 1.0f;
    }
    
    vector<geometry_msgs::Point> initializeBoundary()
    {
        vector<geometry_msgs::Point> bondArray;
    
        geometry_msgs::Point point;
    
        //first point
        point.x = 0;
        point.y = 0;
        point.z = 0;
    
        bondArray.push_back(point);
    
        //second point
        point.x = 0;
        point.y = 100;
        point.z = 0;
    
        bondArray.push_back(point);
    
        //third point
        point.x = 100;
        point.y = 100;
        point.z = 0;
    
        bondArray.push_back(point);
    
        //fourth point
        point.x = 100;
        point.y = 0;
        point.z = 0;
        bondArray.push_back(point);
    
        //first point again to complete the box
        point.x = 0;
        point.y = 0;
        point.z = 0;
        bondArray.push_back(point);
    
        return bondArray;
    }
    
    vector<geometry_msgs::Point> initializeObstacles()
    {
        vector< vector<geometry_msgs::Point> > obstArray;
    
        vector<geometry_msgs::Point> obstaclesMarker;
    
        obstacles obst;
    
        obstArray = obst.getObstacleArray();
    
        for(int i=0; i<obstArray.size(); i++)
        {
            for(int j=1; j<5; j++)
            {
                obstaclesMarker.push_back(obstArray[i][j-1]);
                obstaclesMarker.push_back(obstArray[i][j]);
            }
    
        }
        return obstaclesMarker;
    }
    
    int main(int argc,char** argv)
    {
        //initializing ROS
        ros::init(argc,argv,"env_node");
    	ros::NodeHandle n;
    
    	//defining Publisher
    	ros::Publisher env_publisher = n.advertise<visualization_msgs::Marker>("path_planner_rrt",1);
    
    	//defining markers
        visualization_msgs::Marker boundary;
        visualization_msgs::Marker obstacle;
    
        initializeMarkers(boundary, obstacle);
    
        //initializing rrtTree
        RRT myRRT(2.0,2.0);
        int goalX, goalY;
        goalX = goalY = 95;
    
        boundary.points = initializeBoundary();
        obstacle.points = initializeObstacles();
    
        env_publisher.publish(boundary);
        env_publisher.publish(obstacle);
    
        while(ros::ok())
        {
            env_publisher.publish(boundary);
            env_publisher.publish(obstacle);
            ros::spinOnce();
            ros::Duration(1).sleep();
        }
    	return 1;
    }
    

    障碍物obstacles,可修改调整障碍物个数等:

    #include <path_planning/obstacles.h>
    #include <geometry_msgs/Point.h>
    
    
    vector< vector<geometry_msgs::Point> > obstacles::getObstacleArray()
    {
        vector<geometry_msgs::Point> obstaclePoint;
        geometry_msgs::Point point;
    
        //first point
        point.x = 50;
        point.y = 50;
        point.z = 0;
    
        obstaclePoint.push_back(point);
    
        //second point
        point.x = 50;
        point.y = 70;
        point.z = 0;
    
        obstaclePoint.push_back(point);
    
        //third point
        point.x = 80;
        point.y = 70;
        point.z = 0;
    
        obstaclePoint.push_back(point);
    
        //fourth point
        point.x = 80;
        point.y = 50;
        point.z = 0;
        obstaclePoint.push_back(point);
    
        //first point again to complete the box
        point.x = 50;
        point.y = 50;
        point.z = 0;
        obstaclePoint.push_back(point);
    
        obstacleArray.push_back(obstaclePoint);
    
        return obstacleArray;
    
    }
    

    RRT:

    #include <path_planning/rrt.h>
    #include <math.h>
    #include <cstddef>
    #include <iostream>
    
    using namespace rrt;
    
    /**
    * default constructor for RRT class
    * initializes source to 0,0
    * adds sorce to rrtTree
    */
    RRT::RRT()
    {
        RRT::rrtNode newNode;
        newNode.posX = 0;
        newNode.posY = 0;
        newNode.parentID = 0;
        newNode.nodeID = 0;
        rrtTree.push_back(newNode);
    }
    
    /**
    * default constructor for RRT class
    * initializes source to input X,Y
    * adds sorce to rrtTree
    */
    RRT::RRT(double input_PosX, double input_PosY)
    {
        RRT::rrtNode newNode;
        newNode.posX = input_PosX;
        newNode.posY = input_PosY;
        newNode.parentID = 0;
        newNode.nodeID = 0;
        rrtTree.push_back(newNode);
    }
    
    /**
    * Returns the current RRT tree
    * @return RRT Tree
    */
    vector<RRT::rrtNode> RRT::getTree()
    {
        return rrtTree;
    }
    
    /**
    * For setting the rrtTree to the inputTree
    * @param rrtTree
    */
    void RRT::setTree(vector<RRT::rrtNode> input_rrtTree)
    {
        rrtTree = input_rrtTree;
    }
    
    /**
    * to get the number of nodes in the rrt Tree
    * @return tree size
    */
    int RRT::getTreeSize()
    {
        return rrtTree.size();
    }
    
    /**
    * adding a new node to the rrt Tree
    */
    void RRT::addNewNode(RRT::rrtNode node)
    {
        rrtTree.push_back(node);
    }
    
    /**
    * removing a node from the RRT Tree
    * @return the removed tree
    */
    RRT::rrtNode RRT::removeNode(int id)
    {
        RRT::rrtNode tempNode = rrtTree[id];
        rrtTree.erase(rrtTree.begin()+id);
        return tempNode;
    }
    
    /**
    * getting a specific node
    * @param node id for the required node
    * @return node in the rrtNode structure
    */
    RRT::rrtNode RRT::getNode(int id)
    {
        return rrtTree[id];
    }
    
    /**
    * return a node from the rrt tree nearest to the given point
    * @param X position in X cordinate
    * @param Y position in Y cordinate
    * @return nodeID of the nearest Node
    */
    int RRT::getNearestNodeID(double X, double Y)
    {
        int i, returnID;
        double distance = 9999, tempDistance;
        for(i=0; i<this->getTreeSize(); i++)
        {
            tempDistance = getEuclideanDistance(X,Y, getPosX(i),getPosY(i));
            if (tempDistance < distance)
            {
                distance = tempDistance;
                returnID = i;
            }
        }
        return returnID;
    }
    
    /**
    * returns X coordinate of the given node
    */
    double RRT::getPosX(int nodeID)
    {
        return rrtTree[nodeID].posX;
    }
    
    /**
    * returns Y coordinate of the given node
    */
    double RRT::getPosY(int nodeID)
    {
        return rrtTree[nodeID].posY;
    }
    
    /**
    * set X coordinate of the given node
    */
    void RRT::setPosX(int nodeID, double input_PosX)
    {
        rrtTree[nodeID].posX = input_PosX;
    }
    
    /**
    * set Y coordinate of the given node
    */
    void RRT::setPosY(int nodeID, double input_PosY)
    {
        rrtTree[nodeID].posY = input_PosY;
    }
    
    /**
    * returns parentID of the given node
    */
    RRT::rrtNode RRT::getParent(int id)
    {
        return rrtTree[rrtTree[id].parentID];
    }
    
    /**
    * set parentID of the given node
    */
    void RRT::setParentID(int nodeID, int parentID)
    {
        rrtTree[nodeID].parentID = parentID;
    }
    
    /**
    * add a new childID to the children list of the given node
    */
    void RRT::addChildID(int nodeID, int childID)
    {
        rrtTree[nodeID].children.push_back(childID);
    }
    
    /**
    * returns the children list of the given node
    */
    vector<int> RRT::getChildren(int id)
    {
        return rrtTree[id].children;
    }
    
    /**
    * returns number of children of a given node
    */
    int RRT::getChildrenSize(int nodeID)
    {
        return rrtTree[nodeID].children.size();
    }
    
    /**
    * returns euclidean distance between two set of X,Y coordinates
    */
    double RRT::getEuclideanDistance(double sourceX, double sourceY, double destinationX, double destinationY)
    {
        return sqrt(pow(destinationX - sourceX,2) + pow(destinationY - sourceY,2));
    }
    
    /**
    * returns path from root to end node
    * @param endNodeID of the end node
    * @return path containing ID of member nodes in the vector form
    */
    vector<int> RRT::getRootToEndPath(int endNodeID)
    {
        vector<int> path;
        path.push_back(endNodeID);
        while(rrtTree[path.front()].nodeID != 0)
        {
            //std::cout<<rrtTree[path.front()].nodeID<<endl;
            path.insert(path.begin(),rrtTree[path.front()].parentID);
        }
        return path;
    }
    

    RRT节点:

    #include <ros/ros.h>
    #include <visualization_msgs/Marker.h>
    #include <geometry_msgs/Point.h>
    #include <path_planning/rrt.h>
    #include <path_planning/obstacles.h>
    #include <iostream>
    #include <cmath>
    #include <math.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <vector>
    #include <time.h>
    
    #define success false
    #define running true
    
    using namespace rrt;
    
    bool status = running;
    
    void initializeMarkers(visualization_msgs::Marker &sourcePoint,
        visualization_msgs::Marker &goalPoint,
        visualization_msgs::Marker &randomPoint,
        visualization_msgs::Marker &rrtTreeMarker,
        visualization_msgs::Marker &finalPath)
    {
        //init headers
    	sourcePoint.header.frame_id    = goalPoint.header.frame_id    = randomPoint.header.frame_id    = rrtTreeMarker.header.frame_id    = finalPath.header.frame_id    = "path_planner";
    	sourcePoint.header.stamp       = goalPoint.header.stamp       = randomPoint.header.stamp       = rrtTreeMarker.header.stamp       = finalPath.header.stamp       = ros::Time::now();
    	sourcePoint.ns                 = goalPoint.ns                 = randomPoint.ns                 = rrtTreeMarker.ns                 = finalPath.ns                 = "path_planner";
    	sourcePoint.action             = goalPoint.action             = randomPoint.action             = rrtTreeMarker.action             = finalPath.action             = visualization_msgs::Marker::ADD;
    	sourcePoint.pose.orientation.w = goalPoint.pose.orientation.w = randomPoint.pose.orientation.w = rrtTreeMarker.pose.orientation.w = finalPath.pose.orientation.w = 1.0;
    
        //setting id for each marker
        sourcePoint.id    = 0;
    	goalPoint.id      = 1;
    	randomPoint.id    = 2;
    	rrtTreeMarker.id  = 3;
        finalPath.id      = 4;
    
    	//defining types
    	rrtTreeMarker.type                                    = visualization_msgs::Marker::LINE_LIST;
    	finalPath.type                                        = visualization_msgs::Marker::LINE_STRIP;
    	sourcePoint.type  = goalPoint.type = randomPoint.type = visualization_msgs::Marker::SPHERE;
    
    	//setting scale
    	rrtTreeMarker.scale.x = 0.2;
    	finalPath.scale.x     = 1;
    	sourcePoint.scale.x   = goalPoint.scale.x = randomPoint.scale.x = 2;
        sourcePoint.scale.y   = goalPoint.scale.y = randomPoint.scale.y = 2;
        sourcePoint.scale.z   = goalPoint.scale.z = randomPoint.scale.z = 1;
    
        //assigning colors
    	sourcePoint.color.r   = 1.0f;
    	goalPoint.color.g     = 1.0f;
        randomPoint.color.b   = 1.0f;
    
    	rrtTreeMarker.color.r = 0.8f;
    	rrtTreeMarker.color.g = 0.4f;
    
    	finalPath.color.r = 0.2f;
    	finalPath.color.g = 0.2f;
    	finalPath.color.b = 1.0f;
    
    	sourcePoint.color.a = goalPoint.color.a = randomPoint.color.a = rrtTreeMarker.color.a = finalPath.color.a = 1.0f;
    }
    
    vector< vector<geometry_msgs::Point> > getObstacles()
    {
        obstacles obst;
        return obst.getObstacleArray();
    }
    
    void addBranchtoRRTTree(visualization_msgs::Marker &rrtTreeMarker, RRT::rrtNode &tempNode, RRT &myRRT)
    {
    
    geometry_msgs::Point point;
    
    point.x = tempNode.posX;
    point.y = tempNode.posY;
    point.z = 0;
    rrtTreeMarker.points.push_back(point);
    
    RRT::rrtNode parentNode = myRRT.getParent(tempNode.nodeID);
    
    point.x = parentNode.posX;
    point.y = parentNode.posY;
    point.z = 0;
    
    rrtTreeMarker.points.push_back(point);
    }
    
    bool checkIfInsideBoundary(RRT::rrtNode &tempNode)
    {
        if(tempNode.posX < 0 || tempNode.posY < 0  || tempNode.posX > 100 || tempNode.posY > 100 ) return false;
        else return true;
    }
    
    bool checkIfOutsideObstacles(vector< vector<geometry_msgs::Point> > &obstArray, RRT::rrtNode &tempNode)
    {
        double AB, AD, AMAB, AMAD;
    
        for(int i=0; i<obstArray.size(); i++)
        {
            AB = (pow(obstArray[i][0].x - obstArray[i][1].x,2) + pow(obstArray[i][0].y - obstArray[i][1].y,2));
            AD = (pow(obstArray[i][0].x - obstArray[i][3].x,2) + pow(obstArray[i][0].y - obstArray[i][3].y,2));
            AMAB = (((tempNode.posX - obstArray[i][0].x) * (obstArray[i][1].x - obstArray[i][0].x)) + (( tempNode.posY - obstArray[i][0].y) * (obstArray[i][1].y - obstArray[i][0].y)));
            AMAD = (((tempNode.posX - obstArray[i][0].x) * (obstArray[i][3].x - obstArray[i][0].x)) + (( tempNode.posY - obstArray[i][0].y) * (obstArray[i][3].y - obstArray[i][0].y)));
             //(0<AM⋅AB<AB⋅AB)∧(0<AM⋅AD<AD⋅AD)
            if((0 < AMAB) && (AMAB < AB) && (0 < AMAD) && (AMAD < AD))
            {
                return false;
            }
        }
        return true;
    }
    
    void generateTempPoint(RRT::rrtNode &tempNode)
    {
        int x = rand() % 150 + 1;
        int y = rand() % 150 + 1;
        //std::cout<<"Random X: "<<x <<endl<<"Random Y: "<<y<<endl;
        tempNode.posX = x;
        tempNode.posY = y;
    }
    
    bool addNewPointtoRRT(RRT &myRRT, RRT::rrtNode &tempNode, int rrtStepSize, vector< vector<geometry_msgs::Point> > &obstArray)
    {
        int nearestNodeID = myRRT.getNearestNodeID(tempNode.posX,tempNode.posY);
    
        RRT::rrtNode nearestNode = myRRT.getNode(nearestNodeID);
    
        double theta = atan2(tempNode.posY - nearestNode.posY,tempNode.posX - nearestNode.posX);
    
        tempNode.posX = nearestNode.posX + (rrtStepSize * cos(theta));
        tempNode.posY = nearestNode.posY + (rrtStepSize * sin(theta));
    
        if(checkIfInsideBoundary(tempNode) && checkIfOutsideObstacles(obstArray,tempNode))
        {
            tempNode.parentID = nearestNodeID;
            tempNode.nodeID = myRRT.getTreeSize();
            myRRT.addNewNode(tempNode);
            return true;
        }
        else
            return false;
    }
    
    bool checkNodetoGoal(int X, int Y, RRT::rrtNode &tempNode)
    {
        double distance = sqrt(pow(X-tempNode.posX,2)+pow(Y-tempNode.posY,2));
        if(distance < 3)
        {
            return true;
        }
        return false;
    }
    
    void setFinalPathData(vector< vector<int> > &rrtPaths, RRT &myRRT, int i, visualization_msgs::Marker &finalpath, int goalX, int goalY)
    {
        RRT::rrtNode tempNode;
        geometry_msgs::Point point;
        for(int j=0; j<rrtPaths[i].size();j++)
        {
            tempNode = myRRT.getNode(rrtPaths[i][j]);
    
            point.x = tempNode.posX;
            point.y = tempNode.posY;
            point.z = 0;
    
            finalpath.points.push_back(point);
        }
    
        point.x = goalX;
        point.y = goalY;
        finalpath.points.push_back(point);
    }
    
    int main(int argc,char** argv)
    {
        //initializing ROS
        ros::init(argc,argv,"rrt_node");
    	ros::NodeHandle n;
    
    	//defining Publisher
    	ros::Publisher rrt_publisher = n.advertise<visualization_msgs::Marker>("path_planner_rrt",1);
    
    	//defining markers
        visualization_msgs::Marker sourcePoint;
        visualization_msgs::Marker goalPoint;
        visualization_msgs::Marker randomPoint;
        visualization_msgs::Marker rrtTreeMarker;
        visualization_msgs::Marker finalPath;
    
        initializeMarkers(sourcePoint, goalPoint, randomPoint, rrtTreeMarker, finalPath);
    
        //setting source and goal
        sourcePoint.pose.position.x = 2;
        sourcePoint.pose.position.y = 2;
    
        goalPoint.pose.position.x = 95;
        goalPoint.pose.position.y = 95;
    
        rrt_publisher.publish(sourcePoint);
        rrt_publisher.publish(goalPoint);
        ros::spinOnce();
        ros::Duration(0.01).sleep();
    
        srand (time(NULL));
        //initialize rrt specific variables
    
        //initializing rrtTree
        RRT myRRT(2.0,2.0);
        int goalX, goalY;
        goalX = goalY = 95;
    
        int rrtStepSize = 3;
    
        vector< vector<int> > rrtPaths;
        vector<int> path;
        int rrtPathLimit = 1;
    
        int shortestPathLength = 9999;
        int shortestPath = -1;
    
        RRT::rrtNode tempNode;
    
        vector< vector<geometry_msgs::Point> >  obstacleList = getObstacles();
    
        bool addNodeResult = false, nodeToGoal = false;
    
        while(ros::ok() && status)
        {
            if(rrtPaths.size() < rrtPathLimit)
            {
                generateTempPoint(tempNode);
                //std::cout<<"tempnode generated"<<endl;
                addNodeResult = addNewPointtoRRT(myRRT,tempNode,rrtStepSize,obstacleList);
                if(addNodeResult)
                {
                   // std::cout<<"tempnode accepted"<<endl;
                    addBranchtoRRTTree(rrtTreeMarker,tempNode,myRRT);
                   // std::cout<<"tempnode printed"<<endl;
                    nodeToGoal = checkNodetoGoal(goalX, goalY,tempNode);
                    if(nodeToGoal)
                    {
                        path = myRRT.getRootToEndPath(tempNode.nodeID);
                        rrtPaths.push_back(path);
                        std::cout<<"New Path Found. Total paths "<<rrtPaths.size()<<endl;
                        //ros::Duration(10).sleep();
                        //std::cout<<"got Root Path"<<endl;
                    }
                }
            }
            else //if(rrtPaths.size() >= rrtPathLimit)
            {
                status = success;
                std::cout<<"Finding Optimal Path"<<endl;
                for(int i=0; i<rrtPaths.size();i++)
                {
                    if(rrtPaths[i].size() < shortestPath)
                    {
                        shortestPath = i;
                        shortestPathLength = rrtPaths[i].size();
                    }
                }
                setFinalPathData(rrtPaths, myRRT, shortestPath, finalPath, goalX, goalY);
                rrt_publisher.publish(finalPath);
            }
    
    
            rrt_publisher.publish(sourcePoint);
            rrt_publisher.publish(goalPoint);
            rrt_publisher.publish(rrtTreeMarker);
            //rrt_publisher.publish(finalPath);
            ros::spinOnce();
            ros::Duration(0.01).sleep();
        }
    	return 1;
    }
    

    头文件定义类如下:

    obstacles:

    #ifndef OBSTACLES_H
    #define OBSTACLES_H
    #include <geometry_msgs/Point.h>
    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    class obstacles
    {
        public:
            /** Default constructor */
            obstacles() {}
            /** Default destructor */
            virtual ~obstacles() {}
    
            vector< vector<geometry_msgs::Point> > getObstacleArray();
    
        protected:
        private:
            vector< vector<geometry_msgs::Point> > obstacleArray;
    };
    
    #endif // OBSTACLES_H
    

    rrt:

    #ifndef rrt_h
    #define rrt_h
    
    #include <vector>
    using namespace std;
    namespace rrt {
    	class RRT{
    
            public:
    
                RRT();
                RRT(double input_PosX, double input_PosY);
    
                struct rrtNode{
                    int nodeID;
                    double posX;
                    double posY;
                    int parentID;
                    vector<int> children;
                };
    
                vector<rrtNode> getTree();
                void setTree(vector<rrtNode> input_rrtTree);
                int getTreeSize();
    
                void addNewNode(rrtNode node);
                rrtNode removeNode(int nodeID);
                rrtNode getNode(int nodeID);
    
                double getPosX(int nodeID);
                double getPosY(int nodeID);
                void setPosX(int nodeID, double input_PosX);
                void setPosY(int nodeID, double input_PosY);
    
                rrtNode getParent(int nodeID);
                void setParentID(int nodeID, int parentID);
    
                void addChildID(int nodeID, int childID);
                vector<int> getChildren(int nodeID);
                int getChildrenSize(int nodeID);
    
                int getNearestNodeID(double X, double Y);
                vector<int> getRootToEndPath(int endNodeID);
    
            private:
                vector<rrtNode> rrtTree;
                double getEuclideanDistance(double sourceX, double sourceY, double destinationX, double destinationY);
    	};
    };
    
    #endif
    

    其他代码:

    CMakeLists:

    cmake_minimum_required(VERSION 2.8.3)
    project(path_planning)
    
    ## Find catkin macros and libraries
    ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
    ## is used, also find other catkin packages
    find_package(catkin REQUIRED COMPONENTS
      roscpp
      std_msgs
      visualization_msgs
    )
    
    ## System dependencies are found with CMake's conventions
    # find_package(Boost REQUIRED COMPONENTS system)
    
    
    ## Uncomment this if the package has a setup.py. This macro ensures
    ## modules and global scripts declared therein get installed
    ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
    # catkin_python_setup()
    
    ################################################
    ## Declare ROS messages, services and actions ##
    ################################################
    
    ## To declare and build messages, services or actions from within this
    ## package, follow these steps:
    ## * Let MSG_DEP_SET be the set of packages whose message types you use in
    ##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
    ## * In the file package.xml:
    ##   * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
    ##   * If MSG_DEP_SET isn't empty the following dependencies might have been
    ##     pulled in transitively but can be declared for certainty nonetheless:
    ##     * add a build_depend tag for "message_generation"
    ##     * add a run_depend tag for "message_runtime"
    ## * In this file (CMakeLists.txt):
    ##   * add "message_generation" and every package in MSG_DEP_SET to
    ##     find_package(catkin REQUIRED COMPONENTS ...)
    ##   * add "message_runtime" and every package in MSG_DEP_SET to
    ##     catkin_package(CATKIN_DEPENDS ...)
    ##   * uncomment the add_*_files sections below as needed
    ##     and list every .msg/.srv/.action file to be processed
    ##   * uncomment the generate_messages entry below
    ##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
    
    ## Generate messages in the 'msg' folder
    # add_message_files(
    #   FILES
    #   Message1.msg
    #   Message2.msg
    # )
    
    ## Generate services in the 'srv' folder
    # add_service_files(
    #   FILES
    #   Service1.srv
    #   Service2.srv
    # )
    
    ## Generate actions in the 'action' folder
    # add_action_files(
    #   FILES
    #   Action1.action
    #   Action2.action
    # )
    
    ## Generate added messages and services with any dependencies listed here
    # generate_messages(
    #   DEPENDENCIES
    #   std_msgs#   visualization_msgs
    # )
    
    ###################################
    ## catkin specific configuration ##
    ###################################
    ## The catkin_package macro generates cmake config files for your package
    ## Declare things to be passed to dependent projects
    ## INCLUDE_DIRS: uncomment this if you package contains header files
    ## LIBRARIES: libraries you create in this project that dependent projects also need
    ## CATKIN_DEPENDS: catkin_packages dependent projects also need
    ## DEPENDS: system dependencies of this project that dependent projects also need
    catkin_package(
      INCLUDE_DIRS include
      LIBRARIES path_planning
      CATKIN_DEPENDS roscpp std_msgs visualization_msgs
      DEPENDS system_lib
    )
    
    ###########
    ## Build ##
    ###########
    
    ## Specify additional locations of header files
    ## Your package locations should be listed before other locations
    # include_directories(include)
    include_directories(include
      ${catkin_INCLUDE_DIRS}
    )
    
    ## Declare a cpp library
    add_library(path_planning
    	src/rrt.cpp
    	src/obstacles.cpp
    )
    
    ## Declare a cpp executable
    # add_executable(path_planning_node src/path_planning_node.cpp)
    
    add_executable(rrt_node src/rrt_node.cpp)
    add_dependencies(rrt_node path_planning)
    target_link_libraries(rrt_node path_planning ${catkin_LIBRARIES} )
    
    add_executable(env_node src/environment.cpp)
    add_dependencies(env_node path_planning)
    target_link_libraries(env_node path_planning ${catkin_LIBRARIES} )
    
    ## Add cmake target dependencies of the executable/library
    ## as an example, message headers may need to be generated before nodes
    # add_dependencies(path_planning_node path_planning_generate_messages_cpp)
    
    ## Specify libraries to link a library or executable target against
    # target_link_libraries(path_planning_node
    #   ${catkin_LIBRARIES}
    # )
    
    #############
    ## Install ##
    #############
    
    # all install targets should use catkin DESTINATION variables
    # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
    
    ## Mark executable scripts (Python etc.) for installation
    ## in contrast to setup.py, you can choose the destination
    # install(PROGRAMS
    #   scripts/my_python_script
    #   DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    # )
    
    ## Mark executables and/or libraries for installation
    # install(TARGETS path_planning path_planning_node
    #   ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    #   LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    #   RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
    # )
    
    ## Mark cpp header files for installation
    # install(DIRECTORY include/${PROJECT_NAME}/
    #   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
    #   FILES_MATCHING PATTERN "*.h"
    #   PATTERN ".svn" EXCLUDE
    # )
    
    ## Mark other files for installation (e.g. launch and bag files, etc.)
    # install(FILES
    #   # myfile1
    #   # myfile2
    #   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
    # )
    
    #############
    ## Testing ##
    #############
    
    ## Add gtest based cpp test target and link libraries
    # catkin_add_gtest(${PROJECT_NAME}-test test/test_path_planning.cpp)
    # if(TARGET ${PROJECT_NAME}-test)
    #   target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
    # endif()
    
    ## Add folders to be run by python nosetests
    # catkin_add_nosetests(test)
    
    package:

    <?xml version="1.0"?>
    <package>
      <name>path_planning</name>
      <version>1.0.0</version>
      <description>A path planning algorithm using RRT visualized in RVIZ</description>
    
      <!-- One maintainer tag required, multiple allowed, one person per tag --> 
      <!-- Example:  -->
      <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
      <maintainer email="nalin00796@gmail.com">Nalin Gupta</maintainer>
    
    
      <!-- One license tag required, multiple allowed, one license per tag -->
      <!-- Commonly used license strings: -->
      <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
      <license>TODO</license>
    
    
      <!-- Url tags are optional, but mutiple are allowed, one per tag -->
      <!-- Optional attribute type can be: website, bugtracker, or repository -->
      <!-- Example: -->
      <!-- <url type="website">http://wiki.ros.org/path_planning</url> -->
    
    
      <!-- Author tags are optional, mutiple are allowed, one per tag -->
      <!-- Authors do not have to be maintianers, but could be -->
      <!-- Example: -->
      <!-- <author email="jane.doe@example.com">Jane Doe</author> -->
    
    
      <!-- The *_depend tags are used to specify dependencies -->
      <!-- Dependencies can be catkin packages or system dependencies -->
      <!-- Examples: -->
      <!-- Use build_depend for packages you need at compile time: -->
      <!--   <build_depend>message_generation</build_depend> -->
      <!-- Use buildtool_depend for build tool packages: -->
      <!--   <buildtool_depend>catkin</buildtool_depend> -->
      <!-- Use run_depend for packages you need at runtime: -->
      <!--   <run_depend>message_runtime</run_depend> -->
      <!-- Use test_depend for packages you need only for testing: -->
      <!--   <test_depend>gtest</test_depend> -->
      <buildtool_depend>catkin</buildtool_depend>
      <build_depend>roscpp</build_depend>
      <build_depend>std_msgs</build_depend>
      <build_depend>visualization_msgs</build_depend>
      <run_depend>roscpp</run_depend>
      <run_depend>std_msgs</run_depend>
      <run_depend>visualization_msgs</run_depend>
    
    
      <!-- The export tag contains other, unspecified, tags -->
      <export>
        <!-- You can specify that this package is a metapackage here: -->
        <!-- <metapackage/> -->
    
        <!-- Other tools can request additional information be placed here -->
    
      </export>
    </package>




  • 相关阅读:
    LeetCode#34 Search for a Range
    Multiplication algorithm
    LeetCode#31 Next Permutation
    Spring boot之Hello World
    spring boot 简介
    分布式-网络通信-线程
    分布式-网络通信-协议
    分布式-架构图
    9.leetcode70-climbing stairs
    8.Leetcode69 Sqrt(x) 笔记
  • 原文地址:https://www.cnblogs.com/liang123/p/6324843.html
Copyright © 2020-2023  润新知