编程是一门实践性很强的技术,个人比较不喜欢光学理论的方式来学习,下面就先用ROS来写个Hello World来让大家对ROS编程有个感性的认识:
切换到用于存放ROS 项目的目录,创建Hello World项目文件夹

mkdir hello_world_tutorial
cd hello_world_tutorial

下面我们要实现一个什么例子呢?就简单得创建一个node然后打印出Hello World Log吧:
创建 hello_world_node.cpp

hello_world_node.cpp

// Include ROS C++ API函数
#include <ros/ros.h>
int main(int argc, char** argv) {
//向ROS master 声明当前程序为 "hello_world_node" node
ros::init(argc, argv, "hello_world_node");
//启动ROS node
ros::start();
//打印一个Log信息
ROS_INFO_STREAM("Hello, world!");
//处理ROS 回调函数,直到收到Ctrl + C 事件
ros::spin();
//退出
ros::shutdown();
return 0;
}

使用g++命令编译,下面的某些地方可能需要根据你安装的ROS版本的不同而修改,比如/opt/ros/indigo/include ,这些地方可以进入opt/ros/查看你电脑上安装的ROS 版本。并替换下面命令中对应的版本,我的树莓派上面安装的是indigo

g++ hello_world_node.cpp -o hello_world_node -I/opt/ros/indigo/include -L/opt/ros/indigo/lib -Wl,-rpath,/opt/ros/indigo/lib -lroscpp -lrosconsole -lrostime

下面是对上面命令的说明:

hello_world_node.cpp 要编译的源码
-o hello_world_node 输出可执行文件的名字
-I/opt/ros/indigo/include 包含的头文件的地址
-L/opt/ros/indigo/lib 静态库的地址
-Wl,-rpath,/opt/ros/indigo/lib 共享库的地址
-lroscpp 链接libroscpp.so 库
-lrosconsole 链接librosconsole.so库
-lrostime 链接librostime.so库

运行完上面的命令你会看到在当前目录下会生成hello_world_node可执行文件,试着运行下:

./hello_world_node

这时候会报如下错误:

ERROR: ROS_MASTER_URI is not defined (Bad Environment)
[FATAL] [1392021564.231775029]: ROS_MASTER_URI is not defined in the
environment. Either type the following or (preferrably) add this to your
~/.bashrc file in order set up your local machine as a ROS master:
export ROS_MASTER_URI=http://localhost:11311
then, type ‘roscore’ in another shell to actually launch the master program.

其实这个错误信息已经十分明显:
这里提示没有ROS_MASTER_URI这个环境变量。其实这个环境变量是在/opt/ros/indigo/setup.sh 中定义的,所以你现在要做的就是运行下面命令,来让它生效。

source /opt/ros/indigo/setup.sh

但是这种方式只对当前的终端有效,如果你退出该终端又会出现上述的问题,所以推荐将其放在.bashrc文件上,这样就不需要每次启动一个终端都source一下。

再次运行hello_world_node将会出现如下提示:

[ERROR] [1392014787.460431497]: [registerPublisher] Failed to contact master at [localhost:11311].  Retrying...

ROS Master 允许ROS 之间能够彼此找到自己,两个ROS 节点如果需要运行必须具备两个条件

  1. ROS Master已经运行
  2. 要进行通信的ROS节点需要在ROS Master上声明

这是由于没有运行roscore,roscore 提供一些功能,这些功能中包含提供ROS Master,有了ROS Master 节点之间才可以相互找到对方并且进行通信。
这时候只需要重新创建一个终端,在终端上运行:

roscore

这时候在原来的那个终端再次运行hello_world_node,如果没有其他以外的话就可以输出如下的消息了:

[ INFO] [1392020655.967763511]: Hello, World!

PS:我在做上面实验的时候还遇到了下面的问题:

c_locale name not valid

遇到这个问题很简单只需要在终端中运行: export LC_ALL=”C” 即可


Contents