【ROS学习二】创建编译自己的功能包

一、准备
需要在电脑上事先安装好ROS

二、创建工作区间
ROS不同于其他软件,需要在特定的工作区间下通过ros编译运行自己的程序。
假设电脑上已经安装好ROS,则

$ source /opt/ros/kinetic/setup.bash  (ros安装的路径)

//echo $ROS_PACKAGE_PATH 查看包的路径
//创建和编译一个 catkin workspace
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/
$ catkin_make

在执行完上述操作后,会在~/目录下,生成catkin_ws文件夹,~/catkin_ws/src下有一个CMakeLists.txt。

文件解说:src文件夹存放自己的源码、cmakelist等文件,devel中有.sh文件
程序编译完后,会在devel/lib/xxx中产生可执行文件,为执行可执行文件,source devel/setup.bash(只执行完代码框里的命令,并不会产生可执行文件,需要自己加入)

三、加入自己的代码

在创建完工作区间后,接下来我们加入自己的代码.
1.在/home/ning/catkin_ws/src路径下打开终端

ning@ning:~/catkin_ws/src$ pwd
/home/ning/catkin_ws/src
ning@ning:~/catkin_ws/src$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp  //catkin_create_pkg 是创建包的命令 beginner_tutorials是包的名称  std_msgs rospy roscpp 是创建这个包所需要的库
Created file beginner_tutorials/package.xml
Created file beginner_tutorials/CMakeLists.txt
Successfully created files in /home/ning/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml.

就可以看到/home/ning/catkin_ws/src下有一个新的文件夹beginner_tutorials,里面有两个文件cmakelist.txt与package.xml


2.将自己的代码复制粘帖到/home/ning/catkin_ws/src/beginner_tutorials/src路径下

程序例子 

beginner_tutorials.cpp

/*
 * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
// %Tag(FULLTEXT)%
// %Tag(ROS_HEADER)%
#include "ros/ros.h"
// %EndTag(ROS_HEADER)%
// %Tag(MSG_HEADER)%
#include "std_msgs/String.h"
// %EndTag(MSG_HEADER)%

#include <sstream>

/**
 * This tutorial demonstrates simple sending of messages over the ROS system.
 */
int main(int argc, char **argv)
{
    /**
     * The ros::init() function needs to see argc and argv so that it can perform
     * any ROS arguments and name remapping that were provided at the command line.
     * For programmatic remappings you can use a different version of init() which takes
     * remappings directly, but for most command-line programs, passing argc and argv is
     * the easiest way to do it.  The third argument to init() is the name of the node.
     *
     * You must call one of the versions of ros::init() before using any other
     * part of the ROS system.
     */
// %Tag(INIT)%
    ros::init(argc, argv, "talker");
// %EndTag(INIT)%

    /**
     * NodeHandle is the main access point to communications with the ROS system.
     * The first NodeHandle constructed will fully initialize this node, and the last
     * NodeHandle destructed will close down the node.
     */
// %Tag(NODEHANDLE)%
    ros::NodeHandle n;
// %EndTag(NODEHANDLE)%

    /**
     * The advertise() function is how you tell ROS that you want to
     * publish on a given topic name. This invokes a call to the ROS
     * master node, which keeps a registry of who is publishing and who
     * is subscribing. After this advertise() call is made, the master
     * node will notify anyone who is trying to subscribe to this topic name,
     * and they will in turn negotiate a peer-to-peer connection with this
     * node.  advertise() returns a Publisher object which allows you to
     * publish messages on that topic through a call to publish().  Once
     * all copies of the returned Publisher object are destroyed, the topic
     * will be automatically unadvertised.
     *
     * The second parameter to advertise() is the size of the message queue
     * used for publishing messages.  If messages are published more quickly
     * than we can send them, the number here specifies how many messages to
     * buffer up before throwing some away.
     */
// %Tag(PUBLISHER)%
    ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
// %EndTag(PUBLISHER)%

// %Tag(LOOP_RATE)%
    ros::Rate loop_rate(10);
// %EndTag(LOOP_RATE)%

    /**
     * A count of how many messages we have sent. This is used to create
     * a unique string for each message.
     */
// %Tag(ROS_OK)%
    int count = 0;
    while (ros::ok())
    {
// %EndTag(ROS_OK)%
        /**
         * This is a message object. You stuff it with data, and then publish it.
         */
// %Tag(FILL_MESSAGE)%
        std_msgs::String msg;

        std::stringstream ss;
        ss << "hello world " << count;
        msg.data = ss.str();
// %EndTag(FILL_MESSAGE)%

// %Tag(ROSCONSOLE)%
        ROS_INFO("%s", msg.data.c_str());
// %EndTag(ROSCONSOLE)%

        /**
         * The publish() function is how you send messages. The parameter
         * is the message object. The type of this object must agree with the type
         * given as a template parameter to the advertise<>() call, as was done
         * in the constructor above.
         */
// %Tag(PUBLISH)%
        chatter_pub.publish(msg);
// %EndTag(PUBLISH)%

// %Tag(SPINONCE)%
        ros::spinOnce();
// %EndTag(SPINONCE)%

// %Tag(RATE_SLEEP)%
        loop_rate.sleep();
// %EndTag(RATE_SLEEP)%
        ++count;
    }


    return 0;
}
// %EndTag(FULLTEXT)%

3.修改CMakeLists.txt文件

我们要对他修改下,修改完之后就变成

cmake_minimum_required(VERSION 3.0.2)
project(beginner_tutorials)
SET(CMAKE_CXX_FLAGS "-std=c++11")
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
)
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs) #此处为编译自己的cpp需要的库
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)
add_executable(beginner_tutorials src/beginner_tutorials.cpp) # 加入自己的程序cpp文件
add_dependencies(beginner_tutorials ${catkin_EXPORTED_TARGETS} )
target_link_libraries(beginner_tutorials ${catkin_LIBRARIES})


4.检查修改package.xml文件
使用gedit或者其他的编辑器打开package.xml文件,检查一下工程名字是否正确,链接的库是否齐全等

<?xml version="1.0"?>
<package format="2">
  <name>beginner_tutorials</name>
  <version>0.0.0</version>
  <description>The beginner_tutorials package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="ubuntu@todo.todo">ubuntu</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 multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, 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 depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

四、编译
进入~/catkin_ws文件夹,打开终端执行命令catkin_make

五、运行
1.新建第一个终端

roscore//如果遇到为找到命令的错误,可以尝试运行source /opt/ros/kinetic/setup.bash (ros安装的路径)

2.新建第二个终端

cd ~/catkin_ws
source devel/setup.bash
build目录下功能包里有可运行程序,直接运行
cd build/beginner_tutorials

./beginner_tutorials

3、新打开一个终端

rostopic list

查看运行的话题topic,程序创建的话题chatter也在列表里

Talk is cheap, show me the code
原文地址:https://www.cnblogs.com/birdBull/p/14537764.html