虚拟机编写ROS第一个程序(话题:发布者) - (ROS学习笔记3)
运行环境:Ubuntu 16.04 64位虚拟机
学习笔记3源码-话题发布者案例程序,提取码:vdzg
创建工作空间
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace
编译工作空间
$ cd ~/catkin_ws/
$ catkin_make

设置环境变量
$ source ~/catkin_ws/devel/setup.bash
检查环境变量

创建功能包
“catkin_create_pkg”命令在创建用户功能包时会生成catkin 构建系统所需的CMakeLists.txt和package.xml文件的包目录。
要创建的功能包名称是“my_first_ros_pkg”。ROS中的功能包名称全部是小写字母,不能包含空格。格式规则是将每个单词用下划线(_)而不是短划线( - )连接起来。
执行下面命令
$ cd ~/catkin_ws/src

创建一个名为my_first_ros_pkg的功能包
$ catkin_create_pkg my_first_ros_pkg std_msgs roscpp


nclude → include目录
src → 源代码目录
CMakeLists.txt → 构建配置文件
package.xml → 功能包配置文件
当前src源代码目录是空的。
修改功能包配置文件(package.xml)
必要的ROS配置文件之一的package.xml是一个包含功能包信息的XML文件,包括功能包名称、作者、许可证和依赖功能包。
文件打开如下:

如果采用C++编程,基本上也没啥可以改的,我这里也就改了下版本号和版权许可证。

然后保存退出。
修改构建配置文件(CMakeLists.txt)
ROS的构建系统catkin基本上使用CMake,并在功能包目录中的CMakeLists.txt文件中描述构建环境。在这个文件中设置可执行文件的创建、依赖包优先构建、连接器(linker)的创建等等。

修改内容如下:
cmake_minimum_required(VERSION 2.8.3)
project(my_first_ros_pkg)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES my_first_ros_pkg
CATKIN_DEPENDS roscpp std_msgs
# DEPENDS system_lib
)
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
add_executable(hello_world_node src/hello_world_node.cpp)
target_link_libraries(hello_world_node
${catkin_LIBRARIES}
)
修改完之后,保存退出。
编写源代码(话题:发布者)
在上述CMakelists.txt文件的可执行文件创建部分(add_executable)中,进行了以下设置。
add_executable(hello_world_node src/hello_world_node.cpp)
换句话说,是引用功能包的src目录中的hello_world_node.cpp源代码来生成hello_world_node可执行文件。由于这里没有hello_world_node.cpp源代码,我们来写一个简单的例子。
首先,用cd命令转到功能包目录中包含源代码的目录(src),并创建hello_world_node.cpp文件。这个例子使用gedit编辑器,但是您可以使用自己的编辑器,比如vi、gedit、qtcreator、vim或者emacs。
$ cd ~/catkin_ws/src/my_first_ros_pkg/src/
$ gedit hello_world_node.cpp
之后如下修改代码:
#include <ros/ros.h>
#include <std_msgs/String.h>
#include <sstream>
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "hello_world_node");
// 创建节点句柄
ros::NodeHandle nh;
// 创建一个Publisher,发布名为say_hello_world的topic,消息类型为std_msgs::String
ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("say_hello_world", 1000);
// 设置循环的频率
ros::Rate loop_rate(10);
int count = 0;
while (ros::ok())
{
// 初始化std_msgs::String类型的消息
std_msgs::String msg;
std::stringstream ss;
ss << "hello world!" << count;
msg.data = ss.str();
// 发布消息
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
// 循环等待回调函数
ros::spinOnce();
// 安装循环频率延时
loop_rate.sleep();
++count;
}
return 0;
}


该代码的功能为话题编程中的实现一个发布者功能,该功能主要为:
初始化ROS节点
向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型;
安装一定频率循环发布消息。
构建功能包与运行节点
构建功能包
所有构建功能包的准备工作都已完成。在构建之前,使用以下命令更新ROS功能包的配置文件。这是一个将之前创建的功能包反映在ROS功能包列表的命令,这并不是必选操作,但在创建新功能包后更新的话使用时会比较方便。
$ rospack profile

下面是catkin构建。移动到catkin工作目录后进行catkin构建。
$ cd ~/catkin_ws && catkin_make

运行节点
如果构建无误,那么将在“~/catkin_ws/devel/lib/my_first_ros_pkg”中生成“hello_world_node”文件。

下一步是运行该节点,打开一个终端窗口(Ctrl + Alt + t)并在运行该节点之前先运行roscore。请注意,运行roscore后,ROS中的所有节点都可用,除非退出了roscore,否则只需运行一次。
注意:如果在执行roscore时出现如下错误,那是因为.bashrc文件中的配置的IP地址与本机的IP地址不一致到导致的,修改下.bashrc文件即可。修改指令如下:
$ source ~/.bashrc
export ROS_HOSTNAME=xxx.xxx.xxx.xxx
$ gedit ~/.bashrc

修改后再次执行

最后,打开一个新的终端窗口(Ctrl + Alt + t)并使用以下命令运行节点。这是在名为my_first_ros_pkg的功能包中运行名为hello_world_node的节点的命令。
$ rosrun my_first_ros_pkg hello_world_node

当您运行这个节点的时候,您可以在终端窗口中看到以hello world!0,1,2,3 ... 作为字符串发送的消息。这不是一个实际的消息传递,但可以看作是本节讨论的构建系统的结果。