ROS基本概念 文件系統 創建ROS軟件包 ROS中的一些命令
- ROS是什么
- ROS文件系統
- 文件系統工具:rospack、roscd、rosls
- 創建ROS 軟件包
- catkin是什么
- 創建和構建一個catkin工作空間:
- catkin軟件包的結構
- catkin工作空間中存放軟件包的結構
- 創建catkin軟件包-catkin_create_pkg
- 構建一個catkin工作區並生效配置文件
- package.xml文件內容
- ROS一些基本概念
- 節點:
- 客戶端庫:
- roscore:
- rosnode:獲取節點信息的ROS工具
- rosrun:運行給定的軟件包中的節點
- ROS話題:節點之間是通過一個ROS話題來相互通信的
- rqt_graph:顯示當前運行的節點和話題
- rostopic:獲取ROS話題的信息
- rostopic echo:顯示在某個話題上發布的數據
- rostopic list:列出當前已被訂閱和發布的所有話題。
- ROS消息:話題的通信是通過節點間發送ROS消息實現的
- rostopic type:查看所發布話題的消息類型
- rostopic pub:把數據發布到當前某個正在廣播的話題上
- rostopic hz:報告數據發布的速率
- rqt_plot:在滾動時間圖上顯示發布到某個話題上的數據
- ROS服務:節點之間通訊的另一種方式
- rosservice:有許多可用於服務的命令
- rosservice list:顯示節點提供的服務
- rosservice type:查看服務的類型
- rosservice call:調用服務
- rosparam:在ROS參數服務器上存儲和操作數據
- rosparam list:查看參數服務器上都有哪些參數
- rosparam set:改變參數服務器上參數的值
- rosparam get:查看參數服務器上參數的值
- rqt_console:連接ROS的日志框架,顯示節點的輸出信息
- rqt_logger_level:在節點運行時改變輸出信息的詳細級別
- roslaunch:啟動定義在launch(啟動)文件中的節點
- launch XML文件的內容
- 使用roslaunch:運行launch文件
中間件,連接了真正的操作系統和程序,提供了類似操作系統的功能。
它提供了操作系統應有的服務,包括硬件抽象,底層設備控制,常用函數的實現,進程間消息傳遞,以及包管理。
ROS包括:框架+工具+功能+社區
框架:分布式、進程管理、進程間通信
ros采用分布式架構,可以同時運行多個進程,每個進程可以單獨設計,並且組合起來。
ros用節點Node代表進程。
機器人控制是一個Node,激光雷達laser是一個node。ros提供了一套框架管理這些node,並且提供他們之間相互通信的橋梁。
分布式架構,擴展性好,軟件復用率高。如果換一個高級激光雷達,只用修改節點,不需要修改通信。
工具:仿真、數據可視化、圖形界面、數據記錄
提供一些工具 比如:Gazebo、Rviz等
功能:控制、規划、視覺、建圖
有一些功能包
社區:軟件包管理、文檔、教程
軟件包(Packages):包是ROS代碼的軟件組織單元,每個軟件包都可以包含程序庫、可執行文件、腳本或其他構件。
Manifests (package.xml): 清單(Manifest)是對軟件包的描述。它用於定義軟件包之間的依賴關系,並記錄有關軟件包的元信息,如版本、維護者、許可證等。
1.rospack
rospack獲取軟件包的有關信息,rospack find,可以返回軟件包的所在路徑。
用法:
$ rospack find [package_name]
例子:
jym@ubuntu:~$ rospack find roscpp
/opt/ros/noetic/share/roscpp
2.roscd
roscd接切換目錄到某個軟件包或者軟件包集當中。
例子:
jym@ubuntu:~$ roscd roscpp
jym@ubuntu:/opt/ros/noetic/share/roscpp$
roscd只能切換到那些路徑已經包含在ROS_PACKAGE_PATH環境變量中的軟件包。
使用echo $ROS_PACKAGE_PATH查看查看ROS_PACKAGE_PATH中包含的路徑。
jym@ubuntu:~$ echo $ROS_PACKAGE_PATH
/opt/ros/noetic/share
打開這個文件夾,可以找到這些包。

roscd也可以切換到一個軟件包或軟件包集的子目錄中。
jym@ubuntu:~$ roscd roscpp/cmake
jym@ubuntu:/opt/ros/noetic/share/roscpp/cmake$ pwd
/opt/ros/noetic/share/roscpp/cmake
3.rosls
允許直接按軟件包的名稱執行 ls 命令(而不必輸入絕對路徑)。
jym@ubuntu:~$ rosls roscpp_tutorials
cmake launch package.xml srv
代碼變成可執行文件,叫做編譯(compile);先編譯這個,還是先編譯那個(即編譯的安排),叫做構建(build)。
catkin是ros定制的編譯構建系統。
ros代碼都放在catkin workspace中,這個工作空間需要通過指令catkin_make創建。
jym@ubuntu:~$ source /opt/ros/noetic/setup.bash
jym@ubuntu:~$ mkdir -p ~/catkin_ws/src
jym@ubuntu:~$ cd ~/catkin_ws/
jym@ubuntu:~/catkin_ws$ catkin_make
終端:
jym@ubuntu:~$ source /opt/ros/noetic/setup.bash
jym@ubuntu:~$ mkdir -p ~/catkin_ws/src
jym@ubuntu:~$ cd ~/catkin_ws/
jym@ubuntu:~/catkin_ws$ catkin_make
Base path: /home/jym/catkin_ws
Source space: /home/jym/catkin_ws/src
Build space: /home/jym/catkin_ws/build
Devel space: /home/jym/catkin_ws/devel
Install space: /home/jym/catkin_ws/install
Creating symlink "/home/jym/catkin_ws/src/CMakeLists.txt" pointing to "/opt/ros/noetic/share/catkin/cmake/toplevel.cmake"
####
#### Running command: "cmake /home/jym/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/jym/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/jym/catkin_ws/install -G Unix Makefiles" in "/home/jym/catkin_ws/build"
####
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using CATKIN_DEVEL_PREFIX: /home/jym/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/noetic
-- This workspace overlays: /opt/ros/noetic
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.8.10", minimum required is "3")
-- Using PYTHON_EXECUTABLE: /usr/bin/python3
-- Using Debian Python package layout
-- Found PY_em: /usr/lib/python3/dist-packages/em.py
-- Using empy: /usr/lib/python3/dist-packages/em.py
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/jym/catkin_ws/build/test_results
-- Forcing gtest/gmock from source, though one was otherwise available.
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python3 (found version "3.8.10")
-- Found Threads: TRUE
-- Using Python nosetests: /usr/bin/nosetests3
-- catkin 0.8.10
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jym/catkin_ws/build
####
#### Running command: "make -j2 -l2" in "/home/jym/catkin_ws/build"
####
最終可以在Home-catkin_ws中找到:

接下來source一下新生成的setup.*sh文件:
$ source devel/setup.bash
要保證工作區被安裝腳本正確覆蓋,需確定ROS_PACKAGE_PATH環境變量包含當前的工作空間目錄:
$ echo $ROS_PACKAGE_PATH
jym@ubuntu:~/catkin_ws$ source devel/setup.bash
jym@ubuntu:~/catkin_ws$ echo $ROS_PACKAGE_PATH
/home/jym/catkin_ws/src:/opt/ros/noetic/share
一個包要想稱為catkin軟件包,必須符合以下要求:
1.這個包必須有一個符合catkin規范的package.xml文件
這個package.xml文件提供有關該軟件包的元信息
2.這個包必須有一個catkin版本的CMakeLists.txt文件
如果它是個Catkin元包的話,則需要有一個CMakeList.txt文件的相關樣板
3.每個包必須有自己的目錄
這意味着在同一個目錄下不能有嵌套的或者多個軟件包存在
my_package/
CMakeLists.txt
package.xml
workspace_folder/ -- WORKSPACE
src/ -- SOURCE SPACE
CMakeLists.txt -- 'Toplevel' CMake file, provided by catkin
package_1/
CMakeLists.txt -- CMakeLists.txt file for package_1
package.xml -- Package manifest for package_1
...
package_n/
CMakeLists.txt -- CMakeLists.txt file for package_n
package.xml -- Package manifest for package_n
1.切換到剛才創建的空白catkin工作空間中的源文件空間目錄
$ cd ~/catkin_ws/src
2.使用catkin_create_pkg命令創建一個名為beginner_tutorials的新軟件包,這個軟件包依賴於std_msgs、roscpp和rospy
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
終端:
jym@ubuntu:~/catkin_ws$ cd ~/catkin_ws/src
jym@ubuntu:~/catkin_ws/src$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
Created file beginner_tutorials/package.xml
Created file beginner_tutorials/CMakeLists.txt
Created folder beginner_tutorials/include/beginner_tutorials
Created folder beginner_tutorials/src
Successfully created files in /home/jym/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml.
可以觀察到對應的文件夾:


在上面已經有介紹過創建和構建一個catkin工作空間,那邊主要目的是創建一個空白的catkin工作空間。
到了這個地方主要目的是構建一個catkin工作空間。
1.在catkin工作區中構建軟件包
$ cd ~/catkin_ws
$ catkin_make
2.工作空間構建完成后,要將這個工作空間添加到ROS環境中,需要source一下生成的配置文件
$ . ~/catkin_ws/devel/setup.bash
jym@ubuntu:~/catkin_ws/src$ cd ~/catkin_ws
jym@ubuntu:~/catkin_ws$ catkin_make
Base path: /home/jym/catkin_ws
Source space: /home/jym/catkin_ws/src
Build space: /home/jym/catkin_ws/build
Devel space: /home/jym/catkin_ws/devel
Install space: /home/jym/catkin_ws/install
####
#### Running command: "cmake /home/jym/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/jym/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/jym/catkin_ws/install -G Unix Makefiles" in "/home/jym/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/jym/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/jym/catkin_ws/devel;/opt/ros/noetic
-- This workspace overlays: /home/jym/catkin_ws/devel;/opt/ros/noetic
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.8.10", minimum required is "3")
-- Using PYTHON_EXECUTABLE: /usr/bin/python3
-- Using Debian Python package layout
-- Using empy: /usr/lib/python3/dist-packages/em.py
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/jym/catkin_ws/build/test_results
-- Forcing gtest/gmock from source, though one was otherwise available.
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python3 (found version "3.8.10")
-- Using Python nosetests: /usr/bin/nosetests3
-- catkin 0.8.10
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~ traversing 1 packages in topological order:
-- ~~ - beginner_tutorials
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'beginner_tutorials'
-- ==> add_subdirectory(beginner_tutorials)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jym/catkin_ws/build
####
#### Running command: "make -j2 -l2" in "/home/jym/catkin_ws/build"
####
jym@ubuntu:~/catkin_ws$ . ~/catkin_ws/devel/setup.bash
描述標簽:內容是描述信息。
<description>The beginner_tutorials package</description>
維護者標簽:它能夠讓其他人聯系到軟件包的相關人員。
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="jym@todo.todo">jym</maintainer>
許可證標簽:些常見的開源許可協議有BSD、MIT、Boost Software License、GPLv2、GPLv3、LGPLv2.1和LGPLv3
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
依賴項標簽:標簽描述了軟件包的依賴關系,這些依賴項分為build_depend、buildtool_depend、run_depend、test_depend。
<?xml version="1.0"?> <package format="2"> <name>beginner_tutorials</name> <version>0.0.0</version> <description>The beginner_tutorials package</description> <!-- One maintainer tag required, multiple allowed, one person per tag --> <!-- Example: --> <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> --> <maintainer email="jym@todo.todo">jym</maintainer> <!-- One license tag required, multiple allowed, one license per tag --> <!-- Commonly used license strings: --> <!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 --> <license>TODO</license> <!-- Url tags are optional, but multiple are allowed, one per tag --> <!-- Optional attribute type can be: website, bugtracker, or repository --> <!-- Example: --> <!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> --> <!-- Author tags are optional, multiple are allowed, one per tag --> <!-- Authors do not have to be maintainers, but could be --> <!-- Example: --> <!-- <author email="jane.doe@example.com">Jane Doe</author> --> <!-- The *depend tags are used to specify dependencies --> <!-- Dependencies can be catkin packages or system dependencies --> <!-- Examples: --> <!-- Use depend as a shortcut for packages that are both build and exec dependencies --> <!-- <depend>roscpp</depend> --> <!-- Note that this is equivalent to the following: --> <!-- <build_depend>roscpp</build_depend> --> <!-- <exec_depend>roscpp</exec_depend> --> <!-- Use build_depend for packages you need at compile time: --> <!-- <build_depend>message_generation</build_depend> --> <!-- Use build_export_depend for packages you need in order to build against this package: --> <!-- <build_export_depend>message_generation</build_export_depend> --> <!-- Use buildtool_depend for build tool packages: --> <!-- <buildtool_depend>catkin</buildtool_depend> --> <!-- Use exec_depend for packages you need at runtime: --> <!-- <exec_depend>message_runtime</exec_depend> --> <!-- Use test_depend for packages you need only for testing: --> <!-- <test_depend>gtest</test_depend> --> <!-- Use doc_depend for packages you need only for building documentation: --> <!-- <doc_depend>doxygen</doc_depend> --> <buildtool_depend>catkin</buildtool_depend> <build_depend>roscpp</build_depend> <build_depend>rospy</build_depend> <build_depend>std_msgs</build_depend> <build_export_depend>roscpp</build_export_depend> <build_export_depend>rospy</build_export_depend> <build_export_depend>std_msgs</build_export_depend> <exec_depend>roscpp</exec_depend> <exec_depend>rospy</exec_depend> <exec_depend>std_msgs</exec_depend> <!-- The export tag contains other, unspecified, tags --> <export> <!-- Other tools can request additional information be placed here --> </export> </package>
可以結合具體情況進行修改 ,修改后的package.xml
<?xml version="1.0"?> <package format="2"> <name>beginner_tutorials</name> <version>0.1.0</version> <description>The beginner_tutorials package</description> <maintainer email="jym@todo.todo">jym</maintainer> <license>BSD</license> <buildtool_depend>catkin</buildtool_depend> <build_depend>roscpp</build_depend> <build_depend>rospy</build_depend> <build_depend>std_msgs</build_depend> <build_export_depend>roscpp</build_export_depend> <build_export_depend>rospy</build_export_depend> <build_export_depend>std_msgs</build_export_depend> <exec_depend>roscpp</exec_depend> <exec_depend>rospy</exec_depend> <exec_depend>std_msgs</exec_depend> <!-- The export tag contains other, unspecified, tags --> <export> <!-- Other tools can request additional information be placed here --> </export> </package>
計算圖(Computation Graph)是一個由ROS進程組成的點對點網絡,它們能夠共同處理數據。
ROS的基本計算圖概念有節點(Nodes)、主節點(Master)、參數服務器(Parameter Server)、消息(Messages)、服務(Services)、話題(Topics)和袋(Bags),它們都以不同的方式向圖(Graph)提供數據。
節點(Nodes):節點是一個可執行文件,它可以通過ROS來與其他節點進行通信。
消息(Messages):訂閱或發布話題時所使用的ROS數據類型。
話題(Topics):節點可以將消息發布到話題,或通過訂閱話題來接收消息。
主節點(Master):ROS的命名服務,例如幫助節點發現彼此。
rosout:在ROS中相當於stdout/stderr(標准輸出/標准錯誤)。
roscore:主節點 + rosout + 參數服務器。
節點實際上只不過是ROS軟件包中的一個可執行文件。ROS節點使用ROS客戶端庫與其他節點通信。節點可以發布或訂閱話題,也可以提供或使用服務。
機器人和遙控器開始工作后,就是兩個節點。機器人是一個節點、遙控器也是一個節點。
遙控器起到了下達指 令的作用;機器人負責監聽遙控器下達的指令,完成相應動作。
節點是一個能執行特定工作任務的工作單元,並且能夠相互通信,從而實現一個機器人系統整體的功能。
ROS客戶端庫可以讓用不同編程語言編寫的節點進行相互通信:
- rospy = Python客戶端庫
- roscpp = C++客戶端庫
roscore = ros+core:主節點(為ROS提供命名服務) + rosout (stdout/stderr) + 參數服務器
roscore是你在運行所有ROS程序前首先要運行的命令。
打開一個新終端,可以使用rosnode看看roscore運行時干了些什么。
要保持以前的終端開着。
rosnode顯示當前正在運行的ROS節點信息。rosnode list命令會列出這些活動的節點。
jym@ubuntu:~$ roscore
... logging to /home/jym/.ros/log/13b5ebe2-3581-11ec-8099-99fb076f9407/roslaunch-ubuntu-4683.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://ubuntu:41325/
ros_comm version 1.15.13
SUMMARY
========
PARAMETERS
* /rosdistro: noetic
* /rosversion: 1.15.13
NODES
auto-starting new master
process[master]: started with pid [4694]
ROS_MASTER_URI=http://ubuntu:11311/
setting /run_id to 13b5ebe2-3581-11ec-8099-99fb076f9407
process[rosout-1]: started with pid [4710]
started core service [/rosout]
jym@ubuntu:~$ rosnode list
/rosout
rosout這個節點用於收集和記錄節點的調試輸出,所以它總是在運行的。
rosnode info命令返回的是某個指定節點的信息。
可以進一步查看rosout的信息, 比如說實際上它是發布了一個/rosout_agg話題。
jym@ubuntu:~$ rosnode info /rosout
--------------------------------------------------------------------------------
Node [/rosout] Publications: * /rosout_agg [rosgraph_msgs/Log] Subscriptions: * /rosout [unknown type] Services: * /rosout/get_loggers * /rosout/set_logger_level contacting node http://ubuntu:45389/ ... Pid: 4710
rosrun可以用包名直接運行軟件包內的節點。
開一個新終端,運行turtlesim包中的turtlesim_node。
rosrun turtlesim turtlesim_node
會看到turtlesim窗口。

再開一個新終端,輸入rosnode list,會看到下面的輸出信息:
jym@ubuntu:~$ rosnode list
/rosout
/turtlesim
停止節點:關閉turtlesim窗口以停止節點(或回到rosrun turtlesim的終端並按Ctrl+C)。
改變節點名稱:使用重映射參數來改變節點名稱:
$ rosrun turtlesim turtlesim_node __name:=my_turtle
測試節點是否正常運行:ping,來測試它是否正常。
rosnode ping my_turtle
jym@ubuntu:~$ rosnode ping my_turtle
rosnode: node is [/my_turtle]
pinging /my_turtle with a timeout of 3.0s
xmlrpc reply from http://ubuntu:45307/ time=0.414848ms
xmlrpc reply from http://ubuntu:45307/ time=1.438141ms
xmlrpc reply from http://ubuntu:45307/ time=1.352310ms
xmlrpc reply from http://ubuntu:45307/ time=0.378132ms
xmlrpc reply from http://ubuntu:45307/ time=0.369549ms
xmlrpc reply from http://ubuntu:45307/ time=0.383854ms
xmlrpc reply from http://ubuntu:45307/ time=0.408173ms
^Cping average: 0.677858ms
三個終端輸入:
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun turtlesim turtle_teleop_key
選中turtle_teleop_key的終端窗口以確保按鍵輸入能夠被捕獲。
可以使用鍵盤上的方向鍵來控制turtle運動了。
turtlesim_node節點和turtle_teleop_key節點之間是通過一個ROS話題來相互通信的。
turtle_teleop_key在話題上發布鍵盤按下的消息,turtlesim則訂閱該話題以接收消息。
使用rqt_graph來顯示當前運行的節點和話題。
打開一個新終端:
$ rosrun rqt_graph rqt_graph
會看到一個窗口:
如果把鼠標放在/turtle1/command_velocity上方,相應的ROS節點(這里是藍色和綠色)和話題(這里是紅色)就會高亮顯示。可以看到,turtlesim_node和turtle_teleop_key節點正通過一個名為/turtle1/command_velocity的話題來相互通信。

rostopic命令工具能讓你獲取ROS話題的信息。
使用幫助選項查看可用的rostopic的子命令
rostopic -h
jym@ubuntu:~$ rostopic -h
rostopic is a command-line tool for printing information about ROS Topics.
Commands:
rostopic bw display bandwidth used by topic
rostopic delay display delay of topic from timestamp in header
rostopic echo print messages to screen
rostopic find find topics by type
rostopic hz display publishing rate of topic
rostopic info print information about active topic
rostopic list list active topics
rostopic pub publish data to topic
rostopic type print topic or field type
Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'
接下來,將使用其中的一些子命令來了解turtlesim
rostopic echo可以顯示在某個話題上發布的數據。
打開新終端輸入:
rostopic echo /turtle1/cmd_vel
可以通過按下鍵盤方向鍵讓turtle_teleop_key節點發布數據。
然后按下向上鍵時可以看到:
jym@ubuntu:~$ rostopic echo /turtle1/cmd_vel
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
此時再看一下rqt_graph:

rostopic echo現在也訂閱了turtle1/command_velocity話題。
rostopic list能夠列出當前已被訂閱和發布的所有話題。
開一個新終端:查看一下list子命令需要的參數
rostopic list -h
jym@ubuntu:~$ rostopic list -h
Usage: rostopic list [/namespace]
Options:
-h, --help show this help message and exit
-b BAGFILE, --bag=BAGFILE
list topics in .bag file
-v, --verbose list full details about each topic
-p list only publishers
-s list only subscribers
--host group by host name
在rostopic list中使用verbose選項:
$ rostopic list -v
會列出所有發布和訂閱的主題及其類型的詳細信息。
jym@ubuntu:~$ rostopic list -v
Published topics:
* /rosout_agg [rosgraph_msgs/Log] 1 publisher
* /rosout [rosgraph_msgs/Log] 4 publishers
* /turtle1/pose [turtlesim/Pose] 1 publisher
* /turtle1/color_sensor [turtlesim/Color] 1 publisher
* /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher
Subscribed topics:
* /rosout [rosgraph_msgs/Log] 1 subscriber
* /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers
* /statistics [rosgraph_msgs/TopicStatistics] 1 subscriber
話題的通信是通過節點間發送ROS消息實現的。為了使發布者(turtle_teleop_key)和訂閱者(turtulesim_node)進行通信,發布者和訂閱者必須發送和接收相同類型的消息。這意味着話題的類型是由發布在它上面消息的類型決定的。使用rostopic type命令可以查看發布在話題上的消息的類型。
rostopic type命令用來查看所發布話題的消息類型。
運行:
$ rostopic type /turtle1/cmd_vel
可以使用rosmsg查看消息的詳細信息
$ rosmsg show geometry_msgs/Twist
jym@ubuntu:~$ rostopic type /turtle1/cmd_vel
geometry_msgs/Twist
jym@ubuntu:~$ rosmsg show geometry_msgs/Twist
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
現在已經知道了turtlesim節點想要的消息類型,然后就可以發布命令給turtle了。
rostopic pub可以把數據發布到當前某個正在廣播的話題上。
$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
以上命令會發送一條消息給turtlesim,告訴它以2.0大小的線速度和1.8大小的角速度移動。
jym@ubuntu:~$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
publishing and latching message for 3.0 seconds
- rostopic pub命令將消息發布到指定的話題
- -1 這一選項會讓rostopic只發布一條消息,然后退出
- /turtle1/cmd_vel是要發布到的話題的名稱
- geometry_msgs/Twist是發布到話題時要使用的消息的類型
- – 這一選項(兩個破折號)用來告訴選項解析器,表明之后的參數都不是選項。如果參數前有破折號(-)比如負數,那么這是必需的。
- 如前所述,一個turtlesim/Velocity消息有兩個浮點型元素:
linear和angular。在本例中,'[2.0, 0.0, 0.0]'表示linear的值為x=2.0,y=0.0,z=0.0,而'[0.0, 0.0, 1.8]'是說angular的值為x=0.0,y=0.0,z=1.8
這行命令發出后,turtle移動了一下就停了。這是因為turtle需要一個穩定的頻率為1Hz的指令流才能保持移動狀態。我們可以使用rostopic pub -r命令來發布源源不斷的命令:
$ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
將以1 Hz的速度發布velocity指令到velocity話題上。
rqt_graph中。可以看到rostopic pub節點正在與rostopic echo節點進行通信:

新終端中通過rostopic echo命令來查看turtlesim所發布的數據:rostopic echo /turtle1/pose
---
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: -1.8
---
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: -1.8
---
rostopic hz報告數據發布的速率。
看一下turtlesim_node發布/turtle/pose得有多快:
$ rostopic hz /turtle1/pose
jym@ubuntu:~$ rostopic hz /turtle1/pose
subscribed to [/turtle1/pose]
average rate: 62.521
min: 0.014s max: 0.018s std dev: 0.00067s window: 63
average rate: 62.479
min: 0.014s max: 0.018s std dev: 0.00056s window: 125
average rate: 62.486
min: 0.014s max: 0.018s std dev: 0.00057s window: 188
可以知道,turtlesim正以大約60Hz的頻率發布有關烏龜的數據。
rqt_plot命令可以在滾動時間圖上顯示發布到某個話題上的數據。這里我們將使用rqt_plot命令來繪制正被發布到/turtle1/pose話題上的數據。
新終端輸入rosrun rqt_plot rqt_plot
可以在左上角的文本框里面添加任何想要繪制的話題。在里面輸入/turtle1/pose/x后,之前不能按下的加號按鈕將會變亮。按一下該按鈕,並對/turtle1/pose/y重復相同的過程。現在你會在圖中看到turtle的x-y位置。

服務(Services)是節點之間通訊的另一種方式。服務允許節點發送一個請求(request)並獲得一個響應(response)。
rosservice可以很容易地通過服務附加到ROS客戶端/服務器框架上。rosservice有許多可用於服務的命令,如下所示:
rosservice list 輸出活躍服務的信息
rosservice call 用給定的參數調用服務
rosservice type 輸出服務的類型
rosservice find 按服務的類型查找服務
rosservice uri 輸出服務的ROSRPC uri
jym@ubuntu:~$ rosservice list
/clear
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/teleop_turtle/get_loggers
/teleop_turtle/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/get_loggers
/turtlesim/set_logger_level
使用rosservice type命令進一步查看clear(清除)服務:
jym@ubuntu:~$ rosservice type /clear
std_srvs/Empty
服務的類型為empty(空),這表明調用這個服務時不需要參數(即,它在發出請求時不發送數據,在接收響應時也不接收數據)。
查看有參服務:
$ rosservice type /spawn | rossrv show
jym@ubuntu:~$ rosservice type /spawn | rossrv show
float32 x
float32 y
float32 theta
string name
---
string name
這個服務能讓我們可以在給定的位置和角度生成一只新的烏龜。name字段是可選的。
調用無參服務:
$ rosservice call /clear
清除了turtlesim_node背景上的軌跡。
調用有參服務:
jym@ubuntu:~$ rosservice call /spawn 2 2 2 ""
name: "turtle2"
該調用返回了新產生的烏龜的名字。然后turtlesim里面出現了個新烏龜。
rosparam能在ROS參數服務器(Parameter Server)上存儲和操作數據。參數服務器能夠存儲整型(integer)、浮點(float)、布爾(boolean)、字典(dictionaries)和列表(list)等數據類型。
rosparam使用YAML標記語言的語法。一般而言,YAML的表述很自然:1是整型,1.0是浮點型,one是字符串,true是布爾型,[1, 2, 3]是整型組成的列表,{a: b, c: d}是字典。
rosparam有很多命令可以用來操作參數,如下所示:
rosparam set 設置參數
rosparam get 獲取參數
rosparam load 從文件中加載參數
rosparam dump 向文件中轉儲參數
rosparam delete 刪除參數
rosparam list 列出參數名
jym@ubuntu:~$ rosparam list
/rosdistro
/roslaunch/uris/host_ubuntu__36577
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r
修改背景顏色的紅色通道值:
$ rosparam set /turtlesim/background_r 150
上述指令修改了參數的值,現在我們需要調用clear服務使得參數的修改能生效:
$ rosservice call /clear
查看參數服務器上其他參數的值。獲取背景的綠色通道的值:
$ rosparam get /turtlesim/background_g
也可以用rosparam get /來顯示參數服務器上的所有內容:
$ rosparam get /
jym@ubuntu:~$ rosparam get /
rosdistro: 'noetic
'
roslaunch:
uris:
host_ubuntu__36577: http://ubuntu:36577/
rosversion: '1.15.13
'
run_id: 7f07518e-3585-11ec-8099-99fb076f9407
turtlesim:
background_b: 255
background_g: 86
background_r: 150
rqt_console連接到了ROS的日志框架,以顯示節點的輸出信息。
rqt_logger_level允許我們在節點運行時改變輸出信息的詳細級別,包括Debug、Info、Warn和Error`。
接下來,看一下turtlesim在rqt_console中輸出的信息,同時在使用turtlesim時切換rqt_logger_level中的日志級別。
在啟動turtlesim之前先在兩個新終端中運行rqt_console和rqt_logger_level:
$ rosrun rqt_console rqt_console
$ rosrun rqt_logger_level rqt_logger_level
在另一個新終端中啟動turtlesim:
$ rosrun turtlesim turtlesim_node
因為默認的日志級別是Info,所以你會看到turtlesim啟動后發布的所有信息。
把烏龜撞到牆上,rqt_console上會顯示:

日志級別的優先級按以下順序排列:
Fatal (致命)
Error (錯誤)
Warn (警告)
Info (信息)
Debug (調試)
Fatal是最高優先級,Debug是最低優先級。通過設置日志級別,你可以獲得所有優先級級別,或只是更高級別的消息。比如,將日志級別設為Warn時,你會得到Warn、Error和Fatal這三個等級的日志消息。

roslaunch可以用來啟動定義在launch(啟動)文件中的節點。
首先,按照創建catkin工作空間后面的步驟使環境變量生效
然后,切換到之前創建和構建的beginner_tutorials軟件包目錄下
然后,創建一個launch目錄
jym@ubuntu:~$ cd ~/catkin_ws
jym@ubuntu:~/catkin_ws$ source devel/setup.bash
jym@ubuntu:~/catkin_ws$ roscd beginner_tutorials
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ mkdir launch
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ cd launch
jym@ubuntu:~/catkin_ws/src/beginner_tutorials/launch$
創建一個名為turtlemimic.launch的launch文件
$ gedit turtlemimic.launch
然后粘貼進去
<launch> <group ns="turtlesim1"> <node pkg="turtlesim" name="sim" type="turtlesim_node"/> </group> <group ns="turtlesim2"> <node pkg="turtlesim" name="sim" type="turtlesim_node"/> </group> <node pkg="turtlesim" name="mimic" type="mimic"> <remap from="input" to="turtlesim1/turtle1"/> <remap from="output" to="turtlesim2/turtle1"/> </node> </launch>
<launch>
首先用launch標簽開頭,以表明這是一個launch文件。
<group ns="turtlesim1">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<group ns="turtlesim2">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
此處我們創建了兩個分組,並以命名空間(namespace)標簽來區分,其中一個名為turtulesim1,另一個名為turtlesim2,兩個分組中都有相同的名為sim的turtlesim節點。這樣可以讓我們同時啟動兩個turtlesim模擬器,而不會產生命名沖突。
<node pkg="turtlesim" name="mimic" type="mimic">
<remap from="input" to="turtlesim1/turtle1"/>
<remap from="output" to="turtlesim2/turtle1"/>
</node>
在這里我們啟動模仿節點,話題的輸入和輸出分別重命名為turtlesim1和turtlesim2,這樣就可以讓turtlesim2模仿turtlesim1了。
</launch>
這一行使得launch文件的XML標簽閉合。
通過roslaunch命令來運行launch文件:
$ roslaunch beginner_tutorials turtlemimic.launch
現在將會有兩個turtlesim被啟動,然后我們在一個新終端中使用rostopic命令發送:
$ rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
兩個turtlesims同時開始移動,雖然發布命令只發送給了turtlesim1。

實現過程中,有三個終端:
第一個:輸入roscore
jym@ubuntu:~$ roscore
... logging to /home/jym/.ros/log/bd42545e-3598-11ec-8099-99fb076f9407/roslaunch-ubuntu-10960.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://ubuntu:43275/
ros_comm version 1.15.13
SUMMARY
========
PARAMETERS
* /rosdistro: noetic
* /rosversion: 1.15.13
NODES
auto-starting new master
process[master]: started with pid [10968]
ROS_MASTER_URI=http://ubuntu:11311/
第二個:運行launch文件
jym@ubuntu:~$ cd ~/catkin_ws
jym@ubuntu:~/catkin_ws$ source devel/setup.bash
jym@ubuntu:~/catkin_ws$ roscd beginner_tutorials
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ roslaunch beginner_tutorials turtlemimic.launch
... logging to /home/jym/.ros/log/bd42545e-3598-11ec-8099-99fb076f9407/roslaunch-ubuntu-11191.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://ubuntu:36829/
SUMMARY
========
PARAMETERS
* /rosdistro: noetic
* /rosversion: 1.15.13
NODES
/
mimic (turtlesim/mimic)
/turtlesim1/
sim (turtlesim/turtlesim_node)
/turtlesim2/
sim (turtlesim/turtlesim_node)
ROS_MASTER_URI=http://localhost:11311
process[turtlesim1/sim-1]: started with pid [11205]
process[turtlesim2/sim-2]: started with pid [11206]
process[mimic-3]: started with pid [11208]
第三個終端:使用rostopic命令發送
jym@ubuntu:~$ rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
