摘要: 剛剛開始學習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的命令。