Chapter 2. ROS 创建和编译功能包

1. 创建ROS功能包

使用catkin_create_pkg命令来创建一个新的catkin程序包。
首先切换到之前通过创建catkin工作空间教程创建的catkin工作空间中的src目录下:

~/ros_workspace$ cd src

接着使用catkin_create_pkg命令来创建一个名为’beginner_tutorials’的新程序包,这个程序包依赖于std_msgs、roscpp和rospy:

~/ros_workspace/src$ catkin_create_pkg my_demo roscpp rospy std_msgs

创建成功后,提示如下:

Created file my_demo/package.xml
Created file my_demo/CMakeLists.txt
Created folder my_demo/include/my_demo
Created folder my_demo/src
Successfully created files in /home/nic/ros_workspace/src/my_demo. Please adjust the values in package.xml.

这将会创建一个名为my_demo的文件夹,这个文件夹里面包含一个package.xml文件和一个CMakeLists.txt文件,这两个文件都已经自动包含了部分你在执行catkin_create_pkg命令时提供的信息。

catkin_create_pkg命令会要求你输入package_name,如果有需要你还可以在后面添加一些需要依赖的其它程序包:

# This is an example, do not try to run this
# catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

catkin_create_pkg命令也有更多的高级功能,这些功能在catkin/commands/catkin_create_pkg中有描述。

2. 编译ROS功能包

采用CLion开发环境进行编译

CLion的安装及破解请参照此文

(1)创建节点 my_demo
~/ros_workspace/src/my_demo/src$ gedit my_demo.cpp

将一下示例代码复制到my_demo.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)%
(2)配置CLion快捷方式

进入CLion快捷方式所在的目录:

~$ cd /usr/share/applications

打开并编辑快捷方式:

/usr/share/applications$ sudo gedit jetbrains-clion.desktop

按照如下所示修改:

Exec=bash -i -c "/opt/clion-2018.1.6/bin/clion.sh" %f

重新注销系统使之生效。

(3)加载功能包

运行CLion,打开功能包下的CMakeList.txt文件,并作为工程打开,如图:
这里写图片描述

(4)编译节点并运行

打开功能包工程如图,编辑CMakeList.txt文件:

add_executable(my_demo src/my_demo.cpp)
target_link_libraries(my_demo ${catkin_LIBRARIES})

这里写图片描述

点击调试按钮,提示如下:
这里写图片描述

打开新的终端,输入:

~$ roscore

这里写图片描述

在CLion环境中,显示如下:
这里写图片描述

新建一个终端查看执行结果:
这里写图片描述

3. 创建ROS功能包并利用CLion进行编译,至此成功完成!

补充说明

如果采用标准版的QtCreator进行编译,请按以下步骤进行:

a. 参照前面,创建节点 demo_node
b. 设置QtCreator能够在启动时候添加ros环境

查找QtCreator的快捷方式

修改QtCreator的快捷方式

在Exec=处加上 bash -i -c
这里写图片描述
重启QtCreator。

c. 打开QtCreator,通过OpenProject打开工作空间下的CMakeLists.txt文件

这里写图片描述

d. 配置项目

这里写图片描述

e. 修改package中CMakeLists.txt的内容

这里写图片描述

d. 运行结果

这里写图片描述
这里写图片描述

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值