ROS(Robot Operating System)機器人操作系統實際上是提供了多節點協同機制,使用了話題、服務、參數服務器、action等通信機制,同時ROS還提供了Gazebo、rviz、rqt、rosbag等工具,這些工具的本質也是對通信消息的收發。
ROS本身提供了點對點網絡,共同處理數據,它的基本概念包括節點、主節點、參數服務器、消息、服務、話題、包等等。
分別使用
rospack-獲取軟件包有關信息:查看軟件包依賴,
roscd-切換到軟件包目錄
rosls-查看軟件包包含文件
rosnode-查看ros節點相關信息:查看節點列表,查看節點消息屬性
rosrun-運行軟件包-某一節點功能:rqt-graph
rostopic-獲取話題相關信息
rosservice-獲取服務相關信息
rosparam-獲取參數相關信息
roslaunch-啟動launch文件
rosmsg-查看消息有關信息
可以使用Tab補全代碼
整個ROS程序的完整結構是
workspace_folder/ -- WORKSPACEsrc/ -- SOURCE SPACECMakeLists.txt -- 'Toplevel' CMake file, provided by catkinpackage_1/CMakeLists.txt -- CMakeLists.txt file for package_1package.xml -- Package manifest for package_1...package_n/CMakeLists.txt -- CMakeLists.txt file for package_npackage.xml -- Package manifest for package_n
初始化工作空間
mkdir -p my_workspace/src
cd my_workspace/src
創建軟件包 catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
創建catkin工作區,生效配置文件
使用catkin_make,即在CMAKE標準工作流中依次調用了cmake和make。
cd ..
catkin_make
catkin_make install# 等價于在CMAKE工作空間下執行:
# mkdir build | cd build | cmake .. | make | make install
運行軟件包和查看系統結構
運行鍵盤控制小烏龜運動的示例功能,在多個終端窗口分辨運行下面指令
roscore
rosrun turtlesim turtlesim_node __name:=my_turtle
rosrun turtlesim turtle_teleop_key
檢查通信的層次方向
rosrun rqt_graph rqt_graph
rostopic 指令詳述
(1)echo-接收話題消息數據-rostopic echo <topic_name>
(2)pub-發布話題消息數據-rostopic pub <topic_name> <msgs_type> [args]
# 發布一次小烏龜速度話題消息數據
rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
# 以1Hz的頻率持續發布小烏龜速度話題數據
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
(3)hz-查看數據發布速率-``
rosservice 指令詳述
(1)rosservice list 獲取服務列表
(2)rosservice call
rosparam 指令詳述
#(1)rosparam list 獲取參數列表
#(2)rosparam get [param_name] 獲取參數值
#(3)rosparam set [param_name] [args] 設置參數值
#(4)rosparam load [yaml_name] ([namespace]) 從文件中加載參數(載入新的命名空間)
#(5)rosparam sump [yaml_name] ([namespace]) 向文件中轉儲參數(載入新的命名空間)
#(6)rosparam delete [param_name] 刪除參數
rqt 指令詳述
(1)查看節點傳遞消息層次:rosrun rqt_graph rqt_graph
(2)查看數據圖:rosrun rqt_plot rqt_plot
(3)查看日志框架:rosrun rqt_console rqt_console
(4)查看信息的詳細級別:rosrun rqt_logger_level rqt_logger_levelroslaunch
在軟件包(如beginner_tutorials)文件夾內創建launch文件家,用于保存launch文件。
<launch><!--創建兩個分組,命名空間分別為turtlesim1,turtlesim2它們都包含名為sim的turtlesim節點,--><group ns="turtlesim1"><node pkg="turtlesim" name="sim" type="turtlesim_node"/></group><group ns="turtlesim2"><node pkg="turtlesim" name="sim" type="turtlesim_node"/></group><!--啟動模仿節點,模仿的輸入和輸出分別為turtlesim1和turtlesim2--><node pkg="turtlesim" name="mimic" type="mimic"><remap from="input" to="turtlesim1/turtle1"/><remap from="output" to="turtlesim2/turtle1"/></node></launch>
在終端窗口運行launch文件和發布話題消息
roslaunch beginner_tutorials turtlemimic.launch
rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
其中消息傳遞的層次是
13. rosed 操作詳述
rosed是rosbash套件的一部分,可以用來編輯包中文件
設置默認編輯器
詳細操作見:http://wiki.ros.org/cn/ROS/Tutorials/UsingRosEd
10.創建ROS消息和服務
(1)基本介紹
消息(.msg)和服務(.srv)都是文本文件,一般分別放置在軟件功能包中的msg和srv文件夾中(與launch平級),用于為不同語言編寫的消息生成源代碼,msg只有一個部分,而服務分為請求和響應。
(2)類型格式
可用類型:
- int8, int16, int32, int64 (以及 uint*)
- float32, float64
- string
- time, duration
- 其他msg文件
- variable-length array[] 和 fixed-length array[C]
.srv文件用一條---將請求和響應兩部分上下分開,如:
int64 A
int64 B
---
int64 Sum
(3)創建消息或服務
為保證能夠轉換成為C++、python或者其他語言的源代碼(即若需要自己構建消息類型),需要在package.xml、CMakeLists.txt中添加相關代碼:
對于消息
package.xml
<build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>
CMakeLists.txt
- find_package中添加message_generation
- catkin_package取消注釋,并在CATKIN_DEPENDS后面添加message_runtime
- add_message_files取消注釋,并添加message_name.msg
- generate_messages取消注釋
對于服務
package.xml
<build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>
CMakeLists.txt
- find_package中添加message_generation
- catkin_package取消注釋,并在CATKIN_DEPENDS后面添加message_runtime
- add_service_files取消注釋,并添加service_name.srv
- generate_messages取消注釋
添加完成后,退回工作空間,使用catkin_make重新編譯ROS包,編譯完成后,自行創建的消息類型就被加載到rosmaster中了,可以通過rosmsg show <message_name>或rossrv show <service_name>查看消息詳細信息。
11.編寫簡單的發布者和訂閱者
C++
(1).cpp文件添加
在前面創建的pkg/src中添加talker.cpp文件,在其中初始化名為talker_init的節點。(talker.cpp和listenter.cpp的代碼見節尾)
(2)CMakeLists.txt添加
在CMakeLists.txt的末尾添加
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)
代碼解釋
add_executable(<exable file_name> <relative file_path>)
target_link_libraries(<exable file_name> ${catkin_LIBRARIES})
add_dependencies(<exable file_name> ${${PROJECT_NAME}_EXPORTED_TARGETS})
(3)編譯和運行
在workspace執行catkin_make編譯指令,可以調用rosrun <pkg_name> <exable file_name>,即rosrun beginner_tutorials talker。
/*talker.cpp*/
#include "ros/ros.h"
#include "std_msgs/String.h"#include <sstream>int main(int argc, char **argv)
{// 初始化ROS,指定節點名,此處的節點名必須是唯一的ros::init(argc, argv, "talker_initname");// 創建進程句柄ros::NodeHandle n;// 創建話題發布者,定義其名字和消息類型,以及最多緩存的消息條數ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);// 指定循環頻率ros::Rate loop_rate(10);int count = 0;/* 若沒有出現:(1)Ctrl+C;(2)被同名節點提出網絡;(3)ros::shutdown()被程序另一部分調用;(4)ros::NodeHandles都被銷毀。則ros::ok()返回true*/while(ros::ok()){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;
}
/*listener.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, "listener_initname");ros::NodeHandle n;// 創建訂閱者,指定可以累積接收的消息數,指定回調函數ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);// 自循環函數,一旦ros::ok()返回false,將自動退出ros::spin();return 0;
}
python
(1)添加.py文件
一般習慣在前面創建的pkg中創建scripts文件夾,在其中添加talker.py文件,在其中初始化名為talker_init_py的節點。右擊.py文件的屬性,將其設置為可以作為程序執行。(talker.py和listenter.py的代碼見節尾)
(2)在CMakeList.txt中添加(可以不做這一步)
catkin_install_python(PROGRAMS scripts/talker.py scripts/listener.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
(3)運行
若進行了第二步,需切換到工作空間目錄執行catkin_make。
使用rosrun <pkg_name> <filename.py>運行。
"""talker.py"""
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# license removed for brevityimport rospy
from std_msgs.msg import String
# 創建發布者函數
def talker():# 創建話題發布者對象,指定其名字,消息類型,最大累積隊列長度pub = rospy.Publisher('chatter', String, queue_size=10)# 初始化節點,指定節點名,anonymous = True會讓名稱末尾添加隨機數,來確保節點具有唯一的名稱。rospy.init_node('talker_init_py', anonymous=True)# 設置發布頻率rate = rospy.Rate(10)# 如果節點沒有被關閉while not rospy.is_shutdown():hello_str = "hello world %s" % rospy.get_time()# ros消息框rospy.loginfo(hello_str)# 發布消息pub.publish(hello_str)# 睡眠指定時間rate.sleep()if __name__ == '__main__':try:talker()except rospy.POSInterruptException:pass
"""listener.py"""
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
from std_msgs.msg import String# 創建回調函數
def callback(data):# 在ros窗口顯示消息rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)def listener():# 初始化節點rospy.init_node('listener_init_py', anonymous=True)# 指定訂閱者對象rospy.Subscriber("chatter", String, callback)# 自循環函數rospy.spin()if __name__ == '__main__':listener()
進階庫學習
navigate 導航模塊
首先跑通一個demo對navigate模塊建立整體的認識,下載中國大學慕課《機器人操作系統入門》的代碼(視頻和代碼鏈接見文末),根據其中的md文件配置ros工作空間和編譯,
slam例子
分別輸入指令:
roscore
# roslaunch slam_sim_demo <launchfilename>
roslaunch slam_sim_demo gmapping_demo.launch
roslaunch slam_sim_demo view_slam.launch
在rviz環境中使用2D Nav Goal指定目標點
跑通的gmapping_demo層次結構如圖:
navigation本身是一個metapackage,是一個功能包的集合。
是一個二維的導航功能包。
灰色(可替代)
藍色(必須提供)
move_base的功能包括全局規劃、局部規劃、處理異常行為,可以把它看做有三個接口,如下圖所示,針對每個接口,都可以指定相應的程序,而這三個接口插件都集成了nav_core這個接口類。
cost_map是move_base的一個插件,與map不同的是,cost_map用于路徑規劃,是有多個層疊加的結果,如static layer(靜態)、obstacle layer(動態和三維)、inflation layer(膨脹信息)。
map_server提供一直地圖的信息,發布的topic為占用柵格數值和地圖信息,提供靜態地圖服務,提供frame的參數服務器。
amcl為蒙特卡洛自適應定位方法,輸入的參數有/tf、/scan和/map,輸出的參數為/tf、/amcl_pose和/map,相較于傳統的純里程計(odom)定位,會將里程計的漂移補到odom計和map之間。
navigation例子
roscore
ROS資料:
ROS wiki cn:http://wiki.ros.org/cn/ROS/TutorialsROS導航官方庫:【奧特學院】ROS機器人入門課程《ROS理論與實踐》零基礎教程:https://www.bilibili.com/video/BV1Ci4y1L7ZZ,課程文檔:http://www.autolabor.com.cn/book/ROSTutorials/中國大學慕課,課程代碼:https://github.com/GetOverMassif/ROS-Academy-for-Beginners,課程文檔:https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/