参考《ROS机器人程序设计》(原书第2版):但是发现其中的一些命令并不能实现正确的结果,且由于版本的问题,一些配置信息不能满足当前的需要。
my system : 在virtualBox下导入的RosIndigo32Bits集成环境,内核为Ubuntu 14.04 LTS
在这个系统默认的只安装了vi,使用之前需要先安装vim,不然后期将无法使用vim打开CMakeLists.txt文件。当然也可以安装其他编译器。
首先建立工作空间:
$mkdir -p ~/dev/catkin_ws/src //建立文件夹,-p的目的是建立所述路径中所有的文件路径
$cd ~/dev/catkin_ws/src
$catkin_init_workspace //定义当前路径为工作空间
当我们创建工作空间之后,里面并没有功能包,只有CMakeLists.txt文件。现在进行工作空间的编译:
$cd ~/dev/catkin_ws
$catkin_make
此时,打开当前文件目录,将会看到新增加了两个文件夹Build和devel,注册程序和添加路径:
$source devel/setup.bash
$echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
创建ROS功能包和综合功能包:
$cd ~/dev/catkin_ws/src
$catkin_create_pkg chapter2_tutorials std_msgs roscpp //此处创建的是使用c++实现的程序文件夹
在功能包下创建两个文件example1_a.cpp和example1_b.cpp,example1_a.cpp将会发送带有节点名称的数据,example1_b.cpp将会把这些命令显示在窗口中。创建文件.cpp可以通过两种形式,1、通过命令$vim example1_a打开。2、直接像在window下建立文件一样建立文件。
在example1_a.cpp中写入程序如下:
#include"ros/ros.h"
#include"std_msgs/String.h"
#include"sstream"
int main(int argc,char **argv)
{
ros::init(argc,argv,"example1_a");
ros::NodeHandle n;
ros::Publisher chatter_pub=n.advertise("message",1000);
ros::Rate loop_rate(10);
while(ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss<<"I am the example1_a node";
msg.data=ss.str();
//ROS_INFO("%s",msg.data.c_str());
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.Sleep();
}
return 0;
}
在example1_b.cpp中写入程序如下:
#include"ros/ros.h"
#include"std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]",msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc,argv,"example1_b");
ros::NodeHandle n;
ros::Subscriber sub=n.subscribe("message",1000,chatterCallback);
ros::spin();
return 0;
}
接下来就是编译节点,但是在编译节点之前需要自行编译CMakeLists.txt文件。
(说明:1、CMakeLists.txt是chapter2_tutorials项目下的文件。2、如果没有安装vim将无法打开CMakeLists.txt文件。)
$rosed chapter2_tutorials CMakeLists.txt
将下面的命令写入到文件的末尾(注意:一直往下拉,知道右下角显示100%,注释后面还是有程序的。)
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(chap2_example1_a src/example1_a.cpp)
add_executable(chap2_example1_b src/example1_b.cpp)
add_dependencies(chap2_example1_a chapter2_tutorials_generate_messages_cpp)
add_dependencies(chap2_example1_b chapter2_tutorials_generate_messages_cpp)
target_link_libraries(chap2_example1_a ${catkin_LIBRARIES})
target_link_libraries(chap2_example1_b ${catkin_LIBRARIES})
现在使用catkin_make工具来编译全部的功能包和节点:
$cd ~/dev/catkin_ws/
$catkin_make
如果编译成功则会出现下面的截图:
至此,一个完整的节点程序就完成了,最后,检查正确性:
首先启动ROS(如果之前没有启动的话):
$roscore
打开新的终端找到功能包路径和注册程序
$cd ~/dev/catkin_ws
$source devel/setup.bash
$catkin_make
(说明:一定要执行以上命令 否则将找不到功能包)
运行 :
$ rosrun chapter2_tutorials chap2_example1_a
注意:我们之前在CMakeLists.txt文件里面添加的命令为:
......
add_executable(chap2_example1_a src/example1_a.cpp)
add_executable(chap2_example1_b src/example1_b.cpp)
......
因此当你执行命令
$ rosrun chapter2_tutorials example1_a
会报错,如下截图:
再次打开一个新的终端:同样的操作执行example1_b文件,观察example1_b运行窗口,你将会看到以下信息:
至此,简单的节点之间的通信完成了。
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
一点小插曲:
1、在打开CMakeLists.txt文件的时候由于没有安装vim,导致错误,提示让我安装vim,可是当执行安装命令
的时候却又不能安装,各种奇葩的错误都有,根据网上提供的一些资料,尝试了更新库甚至替换库,但是没有解决,最后在超级用户模式下解决了。
2、之前由于example1_a.cpp和example1_b.cpp程序输错了,导致catkin_make的时候报错,还纠结了许久,才发现报错原因就是程序本身的问题,截图如下:
希望有遇到类似问题的伙伴注意看错误原因分析,一般从第一个错误处开始分析,从第一个错误或者警告开始一行行的改。