摘要: 刚刚开始学习ROS,打算入机器人的坑了,参考教材是《ROS及其人开发实践》胡春旭编著 机械工业出版社 华章科技出品。本来以为可以按照书上的步骤一步步来,但是,too young to simple啊,程序员的苦逼日子开始了,特地记录如下。
今天居然发现,不是linux没有安装成功,只是没有办法找到boot/efi下的引导文件,充分利用Manjaro • 18.1.0-rc6的u盘启动选项detect efi功能就可以实现U盘引导硬盘上的系统的功能了,也不错,居然还有这样操作哈哈。
一、创建并配置工作空间(workspace)
工作空间是存放工程开发相关文件的文件夹,现在较新版本的ROS默认使用catkin编译系统,该编译系统的空间比较特殊,所以需要特殊的方式创建。
1、创建工作空间
mkdir -p ~/catkin_ws/src #在home目录下创建两级目录,先创建catkin目录,再创建src目录,必须使用-p选项
cd ~/catkin_ws/src #切换到src目录
catkin_init_workspace #初始化工作空间
2、编译工作空间,此时工作空间为空,经过编译会生成很多文件,严格来说是迁移来很多文件
cd ~/catkin_ws/
catkin_make #catkin自己的编译命令
3、初始化环境变量,使环境变量生效
source devel/setup.bash #其实就是运行编译生成的devel目录下的setup.bash文件
4、验证环境变量是否有效
echo $ROS_PACKAGE_PATH #打印当前工作空间的路径,结果如下:,包括刚刚创建的工作空间的目录就对了,否则,要好好找找原因了。
municationk@developk:~/catkin_ws$ echo $ROS_PACKAGE_PATH
/home/municationk/catkin_ws/src:/opt/ros/melodic/share
二、在工作空间创建功能包,ROS系统的实现主要靠功能包实现各个功能
功能包中包含了许多文件和配置信息及编译信息等,现在较新版本的ROS默认使用catkin编译系统,该编译系统对功能包要求比较特殊,所以需要特殊的方式创建。
1、创建功能包,应用catkin_create_pkg命令
cd ~/catkin_ws/src #切换到代码空间,也就是工作空间的src目录
catkin_create_pkg learning_com std_msgs rospy roscpp #创建功能包,并指定有三个功能包依赖
2、再次编译工作空间,并设置环境变量
cd ~/catkin_ws/
catkin_make #编译
source devel/setup.bash #设置环境变量
三、在工作空间创建功能包,实现一个简单的发布、订阅程序:主要是添加两个cpp源码talker.cpp和listener.cpp,修改一个编译配置文件CMakeList.txt,修改一个功能包配置文件package.xml文件
1、talker.cpp在工作空间的代码空间的功能包的代码空间中,本文中为:~/catkin_ws/src/learning_com/src/目录中,内容
1 /** 2 * 该例程将发布chatter话题,消息类型String 3 */ 4 5 #include <sstream> 6 #include "ros/ros.h" 7 #include "std_msgs/String.h" 8 9 int main(int argc, char **argv) 10 { 11 // ROS节点初始化 12 ros::init(argc, argv, "talker"); 13 14 // 创建节点句柄 15 ros::NodeHandle n; 16 17 // 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String 18 ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); 19 20 // 设置循环的频率 21 ros::Rate loop_rate(10); 22 23 int count = 0; 24 while (ros::ok()) 25 { 26 // 初始化std_msgs::String类型的消息 27 std_msgs::String msg; 28 std::stringstream ss; 29 ss << "hello world " << count; 30 msg.data = ss.str(); 31 32 // 发布消息 33 ROS_INFO("%s", msg.data.c_str()); 34 chatter_pub.publish(msg); 35 36 // 循环等待回调函数 37 ros::spinOnce(); 38 39 // 按照循环频率延时 40 loop_rate.sleep(); 41 ++count; 42 } 43 44 return 0; 45 }
2、listener.cpp在工作空间的代码空间的功能包的代码空间中,本文中为:~/catkin_ws/src/learning_com/src/目录中,内容
1 /** 2 * 该例程将订阅chatter话题,消息类型String 3 */ 4 5 #include "ros/ros.h" 6 #include "std_msgs/String.h" 7 8 // 接收到订阅的消息后,会进入消息回调函数 9 void chatterCallback(const std_msgs::String::ConstPtr& msg) 10 { 11 // 将接收到的消息打印出来 12 ROS_INFO("I heard: [%s]", msg->data.c_str()); 13 } 14 15 int main(int argc, char **argv) 16 { 17 // 初始化ROS节点 18 ros::init(argc, argv, "listener"); 19 20 // 创建节点句柄 21 ros::NodeHandle n; 22 23 // 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallback 24 ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); 25 26 // 循环等待回调函数 27 ros::spin(); 28 29 return 0; 30 }
3、CMakeList.txt在工作空间的代码空间的功能包的代码空间中,本文中为:~/catkin_ws/src/learning_com/目录中,内容
1 cmake_minimum_required(VERSION 2.8.3) 2 project(learning_com) 3 4 ## Compile as C++11, supported in ROS Kinetic and newer 5 # add_compile_options(-std=c++11) 6 7 ## Find catkin macros and libraries 8 ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) 9 ## is used, also find other catkin packages 10 find_package(catkin REQUIRED COMPONENTS 11 roscpp 12 rospy 13 std_msgs 14 ) 15 16 ## Specify additional locations of header files 17 ## Your package locations should be listed before other locations 18 include_directories( 19 include 20 ${catkin_INCLUDE_DIRS} 21 ) 22 23 ## Declare a C++ library 24 # add_library(${PROJECT_NAME} 25 # src/${PROJECT_NAME}/learning_communication.cpp 26 # ) 27 28 add_executable(talker src/talker.cpp) 29 target_link_libraries(talker ${catkin_LIBRARIES}) 30 add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp) 31 32 add_executable(listener src/listener.cpp) 33 target_link_libraries(listener ${catkin_LIBRARIES}) 34 add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp) 35 36 ## Mark other files for installation (e.g. launch and bag files, etc.) 37 # install(FILES 38 # # myfile1 39 # # myfile2 40 # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 41 # ) 42 43 ############# 44 ## Testing ## 45 ############# 46 47 ## Add gtest based cpp test target and link libraries 48 # catkin_add_gtest(${PROJECT_NAME}-test test/test_learning_communication.cpp) 49 # if(TARGET ${PROJECT_NAME}-test) 50 # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) 51 # endif() 52 53 ## Add folders to be run by python nosetests 54 # catkin_add_nosetests(test) ~
实际的内容更多,只需要关注:1,2,10~14,18~21,28~34这些行就够了
4、package.xml在工作空间的代码空间的功能包的代码空间中,本文中为:~/catkin_ws/src/learning_com/目录中,内容
1 <?xml version="1.0"?> 2 <package format="2"> 3 <name>learning_com</name> 4 <version>0.0.0</version> 5 <description>The learning_communication package</description> 6 7 <maintainer email="municationk@todo.todo">municationk</maintainer> 8 9 <license>TODO</license> 10 11 <buildtool_depend>catkin</buildtool_depend> 12 <build_depend>roscpp</build_depend> 13 <build_depend>rospy</build_depend> 14 <build_depend>std_msgs</build_depend> 15 <build_export_depend>roscpp</build_export_depend> 16 <build_export_depend>rospy</build_export_depend> 17 <build_export_depend>std_msgs</build_export_depend> 18 <exec_depend>roscpp</exec_depend> 19 <exec_depend>rospy</exec_depend> 20 <exec_depend>std_msgs</exec_depend> 21 22 <export> 23 <!-- Other tools can request additional information be placed here --> 24 25 </export> 26 </package>
同上,内容比较多,有用就这些就够了。
5、编译功能包,并设置环境变量
cd ~/catkin_ws/
catkin_make #编译
source devel/setup.bash #设置环境变量
测试,打开三个终端,在第一终端输入:roscore,第二个终端输入:rosrun learning_com talker 第三个终端输入:rosrun learning_com listener
在第一终端输入:roscore,
municationk@developk:~/catkin_ws$ roscore ... logging to /home/municationk/.ros/log/41d00338-b742-11e9-bb4a-d39af2b318a5/roslaunch-developk-11230.log Checking log directory for disk usage. This may take awhile. Press Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB. started roslaunch server http://developk:45561/ ros_comm version 1.14.3 SUMMARY ======== PARAMETERS * /rosdistro: melodic * /rosversion: 1.14.3 NODES auto-starting new master process[master]: started with pid [11240] ROS_MASTER_URI=http://developk:11311/ setting /run_id to 41d00338-b742-11e9-bb4a-d39af2b318a5 process[rosout-1]: started with pid [11251] started core service [/rosout]
第二个终端输入:rosrun learning_com talker
municationk@developk:~/catkin_ws$ rosrun learning_com talker [ INFO] [1564988563.784974961]: hello world 0 [ INFO] [1564988563.885031740]: hello world 1 [ INFO] [1564988563.985024808]: hello world 2 [ INFO] [1564988564.085013935]: hello world 3 [ INFO] [1564988564.185028269]: hello world 4 [ INFO] [1564988564.285029076]: hello world 5 [ INFO] [1564988564.385029776]: hello world 6 [ INFO] [1564988564.485037478]: hello world 7 [ INFO] [1564988564.585027521]: hello world 8 [ INFO] [1564988564.685035509]: hello world 9 [ INFO] [1564988564.785033638]: hello world 10 [ INFO] [1564988564.885032052]: hello world 11 [ INFO] [1564988564.985045949]: hello world 12 [ INFO] [1564988565.085036609]: hello world 13 [ INFO] [1564988565.185046211]: hello world 14 [ INFO] [1564988565.285035685]: hello world 15 [ INFO] [1564988565.385040617]: hello world 16 [ INFO] [1564988565.485035166]: hello world 17 [ INFO] [1564988565.585033846]: hello world 18 [ INFO] [1564988565.685045276]: hello world 19 [ INFO] [1564988565.785045671]: hello world 20 [ INFO] [1564988565.885033669]: hello world 21 [ INFO] [1564988565.985047584]: hello world 22 [ INFO] [1564988566.085030408]: hello world 23 [ INFO] [1564988566.185034201]: hello world 24 [ INFO] [1564988566.285026831]: hello world 25 [ INFO] [1564988566.385031470]: hello world 26 [ INFO] [1564988566.485012264]: hello world 27 [ INFO] [1564988566.585025410]: hello world 28
第三个终端输入:rosrun learning_com listener
municationk@developk:~/catkin_ws$ rosrun learning_com listener [ INFO] [1564988569.085433644]: I heard: [hello world 53] [ INFO] [1564988569.185483579]: I heard: [hello world 54] [ INFO] [1564988569.285412983]: I heard: [hello world 55] [ INFO] [1564988569.385413951]: I heard: [hello world 56] [ INFO] [1564988569.485403072]: I heard: [hello world 57] [ INFO] [1564988569.585392842]: I heard: [hello world 58] [ INFO] [1564988569.685406999]: I heard: [hello world 59] [ INFO] [1564988569.785430346]: I heard: [hello world 60] [ INFO] [1564988569.885437192]: I heard: [hello world 61] [ INFO] [1564988569.985383334]: I heard: [hello world 62] [ INFO] [1564988570.085448900]: I heard: [hello world 63] [ INFO] [1564988570.185430490]: I heard: [hello world 64] [ INFO] [1564988570.285360554]: I heard: [hello world 65] [ INFO] [1564988570.385351604]: I heard: [hello world 66] [ INFO] [1564988570.485397283]: I heard: [hello world 67] [ INFO] [1564988570.585397681]: I heard: [hello world 68] [ INFO] [1564988570.685402230]: I heard: [hello world 69] [ INFO] [1564988570.785393468]: I heard: [hello world 70] [ INFO] [1564988570.885363100]: I heard: [hello world 71] [ INFO] [1564988570.985392078]: I heard: [hello world 72] [ INFO] [1564988571.085475920]: I heard: [hello world 73] [ INFO] [1564988571.185429095]: I heard: [hello world 74] [ INFO] [1564988571.285393208]: I heard: [hello world 75] [ INFO] [1564988571.385433165]: I heard: [hello world 76] [ INFO] [1564988571.485432988]: I heard: [hello world 77] [ INFO] [1564988571.585488144]: I heard: [hello world 78] [ INFO] [1564988571.685395075]: I heard: [hello world 79] [ INFO] [1564988571.785379391]: I heard: [hello world 80] [ INFO] [1564988571.885424095]: I heard: [hello world 81] [ INFO] [1564988571.985416266]: I heard: [hello world 82]
当在第二个终端中使用ctrl+c将程序中talker的publisher退出:
[ INFO] [1564988684.485031189]: hello world 1207 [ INFO] [1564988684.585041383]: hello world 1208 [ INFO] [1564988684.685035838]: hello world 1209 [ INFO] [1564988684.785028755]: hello world 1210 [ INFO] [1564988684.885037794]: hello world 1211 [ INFO] [1564988684.985037237]: hello world 1212 [ INFO] [1564988685.085037514]: hello world 1213 [ INFO] [1564988685.185037370]: hello world 1214 [ INFO] [1564988685.285035278]: hello world 1215 [ INFO] [1564988685.385038330]: hello world 1216 [ INFO] [1564988685.485038069]: hello world 1217 [ INFO] [1564988685.585033289]: hello world 1218 [ INFO] [1564988685.685036926]: hello world 1219 [ INFO] [1564988685.785037248]: hello world 1220 [ INFO] [1564988685.885031570]: hello world 1221 [ INFO] [1564988685.985032773]: hello world 1222 [ INFO] [1564988686.085030804]: hello world 1223 [ INFO] [1564988686.185031407]: hello world 1224 [ INFO] [1564988686.285031990]: hello world 1225 [ INFO] [1564988686.385032176]: hello world 1226 [ INFO] [1564988686.485039157]: hello world 1227 [ INFO] [1564988686.585043363]: hello world 1228 [ INFO] [1564988686.685048856]: hello world 1229 [ INFO] [1564988686.785040098]: hello world 1230 [ INFO] [1564988686.885051605]: hello world 1231 ^C[ INFO] [1564988686.985104558]: hello world 1232 municationk@developk:~/catkin_ws$
第三个终端中的lisenter的subscriber也无法接受数据:
[ INFO] [1564988683.685365358]: I heard: [hello world 1199] [ INFO] [1564988683.785432435]: I heard: [hello world 1200] [ INFO] [1564988683.885411699]: I heard: [hello world 1201] [ INFO] [1564988683.985359765]: I heard: [hello world 1202] [ INFO] [1564988684.085305814]: I heard: [hello world 1203] [ INFO] [1564988684.185308442]: I heard: [hello world 1204] [ INFO] [1564988684.285348116]: I heard: [hello world 1205] [ INFO] [1564988684.385234823]: I heard: [hello world 1206] [ INFO] [1564988684.485375722]: I heard: [hello world 1207] [ INFO] [1564988684.585385628]: I heard: [hello world 1208] [ INFO] [1564988684.685397073]: I heard: [hello world 1209] [ INFO] [1564988684.785395362]: I heard: [hello world 1210] [ INFO] [1564988684.885395528]: I heard: [hello world 1211] [ INFO] [1564988684.985422434]: I heard: [hello world 1212] [ INFO] [1564988685.085454179]: I heard: [hello world 1213] [ INFO] [1564988685.185441077]: I heard: [hello world 1214] [ INFO] [1564988685.285378556]: I heard: [hello world 1215] [ INFO] [1564988685.385396991]: I heard: [hello world 1216] [ INFO] [1564988685.485434675]: I heard: [hello world 1217] [ INFO] [1564988685.585420842]: I heard: [hello world 1218] [ INFO] [1564988685.685352301]: I heard: [hello world 1219] [ INFO] [1564988685.785442642]: I heard: [hello world 1220] [ INFO] [1564988685.885395217]: I heard: [hello world 1221] [ INFO] [1564988685.985383329]: I heard: [hello world 1222] [ INFO] [1564988686.085378470]: I heard: [hello world 1223] [ INFO] [1564988686.185359547]: I heard: [hello world 1224] [ INFO] [1564988686.285419784]: I heard: [hello world 1225] [ INFO] [1564988686.385437478]: I heard: [hello world 1226] [ INFO] [1564988686.485451254]: I heard: [hello world 1227] [ INFO] [1564988686.585436616]: I heard: [hello world 1228] [ INFO] [1564988686.685407657]: I heard: [hello world 1229] [ INFO] [1564988686.785376388]: I heard: [hello world 1230] [ INFO] [1564988686.885540877]: I heard: [hello world 1231]
正好符合了通信中的,有发送才有接收,发送中断了,接受不到数据了,自然就停下了。ROS中的话题通信主要依赖roccore,因此,无论是先运行终端2或终端3都无所谓,但是,一定要先运行终端1的命令。