ros21講古月居學習筆記無截圖全部跑通


【古月居】ros21講 https://www.bilibili.com/video/BV1zt411G7Vn?from=search&seid=765777793691750397

【代碼】https://github.com/tshooting/ros21guyueju/tree/master

安裝ubuntu https://www.cnblogs.com/rollupbytian/p/14526163.html

安裝ros https://www.cnblogs.com/rollupbytian/p/14528968.html

ros3:命令

3.1命令

cd pwd mkdir ls ll touch mv cp rm  sudo

ros4 C++/Python極簡基礎

4.1 安裝g++ python

sudo apt-get install g++

sudo apt-get install python

ros5 安裝ROS系統

5.1 測試小烏龜

roscore

rosrun turtlesim turtlesim_node

rosrun turtlesim turtle_teleop_key

ros6 ROS是什么

6.1

ros = 通信機制+開發工具+應用功能+生態系統 提高機器人研發中的軟件復用率

通信機制 松耦合分布式通信

開發工具 QT Rviz gazebo TF坐標變換

應用功能 Navigation slam movelt

生態系統:

發行版 軟件源 ROS wiki 郵件列表 ROS answers blog

ros7.ROS中的核心概念

7.1節點 node 執行單元

執行具體任務的進行、獨立運行的可執行文件; 分布式;在系統中的名字唯一

7.2節點管理器 node master 控制中心

為節點提供命名和注冊服務;

跟蹤和記錄話題服務的通信,輔助節點互相查找 建立鏈接;

提供參數服務器,節點使用此服務器存儲和檢索運行時的參數

7.3 話題 topic 異步通信機制

節點間用來傳輸數據的重要總線

使用發布和訂閱模式,數據由發布者傳輸到訂閱者

7.4 消息 message 話題數據

具有一定類型和數據結構,包括ros提供的標准類型和用戶自定義類型

使用編程語言無關的.msg文件定義,編譯過程中生成對應的代碼文件

 7.5 服務通信

服務 service 同步通信機制

使用C/S,請求request和應答response,使用的是.srv文件定義請求和應答數據結構,編譯過程中生成對應的代碼

7.6 參數 parameter 全局共享字典

可以通過網絡訪問的共享、多變量字典

節點使用此服務器來存儲和檢索運行時的參數

適合存儲靜態、非二進制的配置參數,不存儲動態配置的數據

7.7 文件系統

功能包(Package)

ros軟件中的基本單元,包含節點源碼、配置文件、數據定義等。

功能包清單 package manifest

記錄功能包的基本信息,包含作者信息,許可信息,依賴選項、編譯標志等

元功能包 metapackages

組織多個用於同一目的功能包

ros8.ROS命令行工具的使用

8.1 以小海龜為例

roscore 【ros master】

rosrun turtlesim turtlesim_node 【rosrun 功能包的名字 功能包里面的節點】

rosrun turtlesim turtle_teleop_key 【rosrun 功能包的名字 功能包里面的節點】

8.2rqt_graph : 用qt寫的,可以看到系統中的運行圖

顯示兩個節點,仿真器節點和鍵盤控制節點, 和話題

8.3rosnode list  顯示系統中所有的節點,rosout是采集所有節點的日志提交給上面的界面所做顯示

8.4rosnode info /turtlesim 顯示節點的信息

現在這個節點,會發布一些話題,然后訂閱一個話題,提供一些服務

8.5rostopic list 顯示當前所有的話題

發布話題消息 -r是循環 10是每秒10次,話題 消息

8.6rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist "linear:
  x: 1.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 1.0"

8.7rosmsg show geometry_msgs/Twist 可以查看這個消息的類型 有線速度和角速度

8.8rosservice list 查看所有的服務

8.9發布請求服務 生成一個新的海龜

rosservice call /spawn "x: 2.0
y: 4.0
theta: 0.0
name: 'turtle2'"
會有一個response

發現話題多了turtle2有了

8.10話題記錄

rosbag record -a -O ~/Desktop/cmd_record

結束之后按ctrl+s 不要按ctrl+z

先執行上面3個命令,然后再開啟這個話題記錄終端,然后再使用鍵盤讓小烏龜運動,之后按ctrl+s 然后關閉所有的命令roscore之類的

8.11 話題復現

只打開roscore和仿真器節點,然后運行 rosbag play ~/Desktop/cmd_record.bag

ros9.創建工作空間與功能包

9.1工作空間(workspace)是存放工程開發相關文件的文件夾

src(代碼空間),build(編譯空間),devel(開發空間),install(安裝空間)

9.2創建工作空間

mkdir -p ~/catkin_ws/src【可以只執行這一步】

cd ~/catkin_ws/src

catkin_init_workspace

編譯

cd ~/catkin_ws/

catkin_make[進入這個文件夾去編譯]

設置環境變量

source devel /setup.bash

檢查環境變量

echo $ROS_PACKAGE_PATH

9.3 創建功能包

cd ~/catkin_ws/src

catkin_create_pkg test_pkg std_msgs rospy roscpp

編譯功能包

cd ~/catkin_ws

catkin_make

source ~/catkin_ws/devel/setup.bash【不能在fish下面,要在最初的終端下面】

同一個工作空間下,不允許存在同名功能包,到那時不同工作空間下就允許存在同名的功能包了

使用sudo gedit ~/.bashrc 可以查看

ros10.發布者Publisher的編程實現

10.1創建一個功能包 然后添加依賴

cd ~/catkin_ws/src

catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

10.2 創建發布者代碼

(1)首先創建ros節點

(2)向ros master 注冊節點信息,包括 發布的話題名字和話題中的消息類型 還有就是隊列長度(只保留最新的10個)

(3)創建消息數據

(4)按照一定頻率循環發布消息

調試,在vscode里面寫代碼發現沒有ros/ros.h的路徑,執行下面

https://blog.csdn.net/baidu_38634017/article/details/99875321

https://blog.csdn.net/suoniyusanxing/article/details/107325660?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242

擴展程序會根據當前系統環境配置基本信息,因此有可能配置不完整,這時需要通過生成c_cpp_properties.json文件來配置缺少的信息:

ctrl+shift+P打開Command Palette,運行C/Cpp: Edit configurations...生成c_cpp_properties.json:

在includePath中添加"/opt/ros/kinetic/include/*" ,也就是本地安裝的ros路徑

/**
 * 發布的是turtle1/cmd_vel話題,消息類型geometry_msgs::Twist
 * */

include<ros/ros.h>

include<geometry_msgs/Twist.h>

int main(int argc,char ** argv)
{
// ros node init the name of publisher node
ros::init(argc,argv,"velocity_publisher");

</span><span style="color: #008000;">//</span><span style="color: #008000;"> create node handle node master</span>

ros::NodeHandle n;

</span><span style="color: #008000;">//</span><span style="color: #008000;"> create a publisher &amp;&amp; topic name &amp;&amp; msg type &amp;&amp; queue length</span>
ros::Publisher turtle_vel_pub = n.advertise&lt;geometry_msgs::Twist&gt; (<span style="color: #800000;">"</span><span style="color: #800000;">/turtle1/cmd_vel</span><span style="color: #800000;">"</span>,<span style="color: #800080;">10</span><span style="color: #000000;">);

</span><span style="color: #008000;">//</span><span style="color: #008000;">set cycle frequency 10times/sec</span>
ros::Rate loop_rate (<span style="color: #800080;">10</span><span style="color: #000000;">);

</span><span style="color: #0000ff;">int</span> count = <span style="color: #800080;">0</span><span style="color: #000000;">;
</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(ros::ok()){
    </span><span style="color: #008000;">//</span><span style="color: #008000;">init msg </span>

geometry_msgs::Twist vel_msg;
vel_msg.linear.x
= 0.5;//now y and z is zero
vel_msg.angular.z = 0.2;

    </span><span style="color: #008000;">//</span><span style="color: #008000;">publish msg</span>

turtle_vel_pub.publish(vel_msg);

    </span><span style="color: #008000;">//</span><span style="color: #008000;">like cout</span>
    ROS_INFO(<span style="color: #800000;">"</span><span style="color: #800000;">Publish turtle velocity command [%0.2f m/s, %0.2f rad/s]</span><span style="color: #800000;">"</span><span style="color: #000000;">,vel_msg.linear.x,vel_msg.angular.z);

    </span><span style="color: #008000;">//</span><span style="color: #008000;">delay according to cycle frequency  </span>

loop_rate.sleep();
}
return 0;

}

 

10.3 配置發布者代碼編譯規則

在CMakeLists.txt中編譯規則

154行,因為會分區域,build區域,install 區域

add_executable(velocity_publisher src/velocity_publisher.cpp)
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

10.4 編譯並且運行發布者

(1) 先去編譯

cd ~/catkin_ws

catkin_make[編譯]

source devel/setup.bash[以前設置過這一句話,現在就不用再設置了]

(2)啟動命令

roscore [啟動 master]

rosrun turtlesim turtlesim_node[啟動仿真器節點,仿真器節點會訂閱 /turtle1/cmd_vel 話題,我們自己設置的發布者就是發布這個話題的]

rosrun learning_topic velocity_publisher[啟動功能包下面的節點]

就會發現小海龜在動起來了,終端learning_topic velocity_publisher下面會打印rosinfo的信息

對於Python 要注意是讓這個.py的源代碼的屬性變為可以編譯成可執行文件的

 

ros11.訂閱者Subscriber的編程實現

 

 1 /**
 2  * 現在是實現一個訂閱者
 3  * 首先初始化ros節點【這個時候還不知道這個節點的角色,一個節點可以是發布者同時也可以是訂閱者】
 4  * 創建句柄
 5  * 
 6  * 創建訂閱者 讓這個節點去訂閱話題
 7  * 循環等待話題消息,接收到消息后進入回調函數
 8  * 在回調函數中完成消息的處理
 9  * 
10  * */
11  
12 #include<ros/ros.h>
13 #include"turtlesim/Pose.h"
14 void poseCallback(const turtlesim::Pose::ConstPtr & msg)
15 {
16     ROS_INFO("Turtle Pose : x:%0.6f,y:%0.6f",msg->x,msg->y);
17 }
18 int main( int argc,char ** argv){
19     //初始化ros節點
20     ros::init(argc,argv, "pose_subscriber");
21     
22     //創建句柄
23     ros::NodeHandle n;
24 
25     //創建一個訂閱者,訂閱者的名字和隊列長度,注冊回調函數
26     ros::Subscriber pose_sub = n.subscribe("/turtle1/pose",10,poseCallback);
27     
28     //循環等待回調函數
29     ros::spin();
30     
31     return 0;
32 }
33 add_executable(pose_subscriber src/pose_subscriber)
34 target_link_libraries(pose_subscriber ${catkin_LIBRARIES})

ros12.話題消息的定義與使用

12.1

(1)首先定義一個msg文件(在learning_topic下面創建一個msg文件夾,在里面創建)

 string name

uint8 sex

uint8 age

uint8 unknown = 0

uint8 male = 1

uint8 female = 2

(2)然后在Package.xml[learning_topic下面的Package.xml]里面添加功能包編譯依賴和運行依賴

 

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

,最后需要在CMakeLists.txt里面添加編譯選項

find_package( ...... message_generation)
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)
catkin_package(...... message_runtime)

(3)編譯之后會自動生成.h文件,在catkin_ws 下面編譯 catkin_make

 

12.2 然后定義一個發布者和訂閱者測試代碼

 1 /**
 2  * 
 3  * 現在是創建一個話題的發布者
 4  * 1 初始化ros節點
 5  * 2 創建句柄
 6  * 3 創建發布者 話題名字 隊列長隊
 7  * 4 設置發布頻率
 8  * 5 創建循環,設置消息,發送消息,按照頻率進行延遲
 9  * 
10  * */
11 #include<ros/ros.h>
12 #include "learning_topic/Person.h"
13 int main(int argc,char ** argv)
14 {
15     //初始化ros節點
16     ros::init(argc,argv,"person_publisher");
17     //創建句柄
18     ros::NodeHandle n;
19     //創建一個發布者
20     ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info",10);
21     //設置循環頻率
22     ros::Rate loop_rate(1);
23     int count = 0;
24     while(ros::ok()){
25         //初始化learning_topic::Person 類型的消息
26         learning_topic::Person person_msg;
27         person_msg.name = "Tom";
28         person_msg.age = 18;
29         person_msg.sex = learning_topic::Person::male;
30         //發布消息
31         person_info_pub.publish(person_msg);
32         ROS_INFO("Publish Person Info : name : %s  age : %d sex : %d",person_msg.name.c_str(),person_msg.age,person_msg.sex);
33         //按照循環頻率延時
34         loop_rate.sleep();
35 
36     }
37     return 0;
38 }
39 /**
40  * 創建一個訂閱者,需要導入消息的類
41  * 定義回調函數
42  * 初始化ros節點
43  * 創建句柄
44  * 創建訂閱者 
45  * 循環等待回調函數
46  * */
47 #include<ros/ros.h>
48 #include"learning_topic/Person.h"
49 void personInfoCallback(const learning_topic ::Person::ConstPtr & msg){
50     ROS_INFO("Subscribe Person Info : name : %s age : %d sex: %d",msg->name.c_str(),msg->age,msg->male);
51 }
52 int main(int argv,char ** argc){
53     //init node
54     ros::init(argv,argc,"person_subscriber");
55     
56     ros::NodeHandle n;
57 
58     ros::Subscriber person_info_sub = n.subscribe("/person_info",10,personInfoCallback);
59 
60     ros::spin();
61     return 0;
62 }
63 CMakeLists.txt
64 add_executable(person_publisher src/person_publisher.cpp)
65 target_link_libraries(person_publisher ${catkin_LIBRARIES})
66 add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)
67 
68  
69 add_executable(person_subscriber src/person_subscriber.cpp)
70 target_link_libraries(person_subscriber ${catkin_LIBRARIES})
71 add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)
72 
73  

寫完之后進行編譯

cd ~/catkin_ws

catkin_make

roscore

rosrun learning_topic person_publisher

rosrun learning_topic person_subscriber

ros 13.客戶端Client的編程實現

(1)創建一個節點

(2)發現某個服務之后,創建一個客戶端, (請求的數據類型也要知道)

(3)初始化請求數據

  (4)請求服務調用,會有響應顯示調用的結果

catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim

 1 /**
 2  * 創建一個客戶端,請求/spawn,服務的數據類型是 turtlesim::Spawn
 3  * 初始化ros節點
 4  * 發現服務創建一個客戶端實例
 5  * 設置請求服務數據,發布請求
 6  * 等待server處理之后的應答結果
 7  * */
 8 #include<ros/ros.h>
 9 #include<turtlesim/Spawn.h>
10 int main(int argc, char ** argv)
11 {
12     //初始化節點 創建句柄
13     ros::init(argc,argv,"turtle_spawn");
14     ros::NodeHandle node;
15     //發現服務 創建客戶端
16     ros::service::waitForService("/spawn");
17     ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn> ("/spawn");
18     //初始化turtlesim::Spwn 的請求數據
19     turtlesim::Spawn srv;
20     srv.request.x = 2.0;
21     srv.request.y = 2.0;
22     srv.request.name = "turtle2";
23     //請求服務調用
24     ROS_INFO("Call service to spawn turtle [x : %0.6f,y:%0.6f ,name :%s]",srv.request.x,srv.request.y,srv.request.name);
25     add_turtle.call(srv);
26 
27     //顯示服務調用結果
28     ROS_INFO("Spawn turtle successfully [name :%s]",srv.response.name.c_str());
29 
30     return 0;
31 }
32 add_executable(turtle_spawn src/turtle_spawn.cpp)
33 target_link_libraries(turtle_spawn ${catkin_LIBRARIES})

 rosrun turtlesim turtlesim_node

 rosrun learning_service turtle_spawn

 

ros14.服務端Server的編程實現

(1)創建一個節點【可以再節點里面注冊發布者,注冊服務】

(2)創建server實例

(3)循環等待服務請求,進入回調函數

(4)在回調函數中完成服務功能的處理,並反饋應答數據

 1 /**
 2  * 現在要實現的就是一個服務器
 3  * 初始化ros節點
 4  * 創建服務端
 5  * 循環等待服務請求,進入回調函數響應請求
 6  * 在回調函數中完成服務功能的處理並反饋給客戶端應答數據
 7  * 
 8  * */
 9 
10 #include<ros/ros.h>
11 #include<geometry_msgs/Twist.h>
12 #include<std_srvs/Trigger.h>
13 ros::Publisher turtle_vel_pub;
14 bool pubCommand = false;
15 bool commandCallback(std_srvs::TriggerRequest & req, std_srvs::TriggerResponse & res){
16 
17     pubCommand =  !pubCommand;
18     //顯示請求數據
19     ROS_INFO ("publish turtle velocity command [%s]", pubCommand == true ? "Yes":"No");
20     //設置反饋數據
21     res.success = true;
22     res.message = "Change turtle command state!";
23 
24 }
25 int main(int argc,char ** argv )
26 {
27     //初始化創建句柄
28     ros::init(argc,argv,"turtle_command_server");
29     ros::NodeHandle n;
30     //創建一個服務 注冊回調函數
31     ros::ServiceServer command_service = n.advertiseService("/turtle_command",commandCallback);
32     //創建一個發布者 設置循環發布消息
33     turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);
34     //循環等待回調函數 因為這是一個服務段,要一直等待響應客戶端的請求
35     ROS_INFO("Ready to receive turtle command.");
36     //設置循環頻率
37     ros::Rate loop_rate(10);
38     while(ros::ok()){
39         //查看一次回調函數隊列
40         ros::spinOnce();
41         //如果標志為true,則發布速度指令
42         if(pubCommand){
43             geometry_msgs::Twist vel_msg;
44             vel_msg.linear.x = 0.5;
45             vel_msg.angular.z = 0.2;
46             turtle_vel_pub.publish(vel_msg);
47         }
48         //按照循環頻率延時
49         loop_rate.sleep();
50     }
51 
52     return 0;
53 }
54 add_executable(turtle_command_server src/turtle_command_server.cpp)
55 target_link_libraries(turtle_command_server ${catkin_LIBRARIES})

rosrun turtlesim turtlesim_node

rosrun learning_service turtle_command_server

rosservice call /turtle_command "{}"

 

 

ros15.服務數據的定義與使用

自己創建一個服務端一個客戶端,自己編寫服務數據類型

15.1自定義服務數據

(1)創建服務數據文件

Person.srv

string name

uint8 age

unit8 sex

uint8 unknown = 0

unit8 male = 1

uint8 female = 2

---

string result

(2)在Package.xml 里面添加功能包依賴

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

(3)在CMakeLists.tst 添加編譯選項

find_package( ...... message_generation)
add_service_files(FILES Person.srv)
generate_messages(DEPENDENCIES std_msgs)

catkin_package(
# INCLUDE_DIRS include
# LIBRARIES learning_service
CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
# DEPENDS system_lib
)
現在就去編譯 catkin_make
就會發現這個文件下面 有了Person.h了
/home/tian/catkin_ws/devel/include/learning_service

15.2創建服務端和客戶端

問題:在vscode里面,會出現找不到.h的情況這個時候在c_cpp_properties.json 設置

"includePath": [
"${workspaceFolder}/**",
"/opt/ros/kinetic/include/*",
"/home/tian/catkin_ws/devel/include/*"
],

 

 15.2.1實現一個服務端

初始化節點

創建服務端,注冊回調函數

循環等待回調函數

客戶端

創建節點

發現服務 然后創建客戶端

設置數據

調用服務

查看返回結果

 1 /**
 2  * 創建一個服務端 執行/show_person 服務,參數類型是learning_service::Person
 3  * 初始化節點
 4  * 創建服務端,注冊回調函數 
 5  * 循環等待回調函數
 6  * 
 7  * */
 8 #include<ros/ros.h>
 9 #include "learning_service/Person.h"
10 bool personCallback(learning_service::Person::Request & req,
11     learning_service::Person::Response & res)
12 {
13     ROS_INFO("Person : name : %s age : %d sex : %d",req.name.c_str(),req.age,req.male);
14     //設置反饋數據
15     res.result = "OK";
16 
17 }
18 int main(int argc,char ** argv)
19 {
20     ros::init(argc,argv,"person_server");
21     ros::NodeHandle n;
22     ros::ServiceServer person_service = n.advertiseService("/show_person",personCallback);
23     //循環等待回調函數
24     ROS_INFO("Ready to show person information.");
25     ros::spin();
26     return 0;
27 }
28 /**
29  * 現在是客戶端代碼
30  * 初始化節點
31  * 發現服務然后創建客戶端
32  * 初始化數據 發送請求
33  * 請求響應的結果
34  * 
35  * */
36 #include<ros/ros.h>
37 #include "learning_service/Person.h"
38 int main(int argc,char ** argv)
39 {
40     //初始化
41     ros::init(argc,argv,"person_client");
42     ros::NodeHandle node;
43     //等待服務 創建客戶端
44     ros::service::waitForService("/show_person");
45     ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");
46     //初始化learning_service::Person
47     learning_service::Person srv;
48     srv.request.name = "Tom";
49     srv.request.age = 20;
50     srv.request.sex = learning_service::Person::Request::male;
51     //請求服務調用
52     ROS_INFO("Call service to show person [name :%s,age : %d,sex:%d]",
53         srv.request.name.c_str(),srv.request.age,srv.request.sex
54     );
55     //調用服務
56     person_client.call(srv);
57     //顯示服務調用結果
58     ROS_INFO("show person result : %s ",srv.response.result.c_str());
59 
60 
61     return 0;
62 }
63 add_executable(person_publisher src/person_publisher.cpp)
64 target_link_libraries(person_publisher ${catkin_LIBRARIES})
65 add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)
66 
67  
68 add_executable(person_subscriber src/person_subscriber.cpp)
69 target_link_libraries(person_subscriber ${catkin_LIBRARIES})
70 add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)

rosrun learning_service person_server

rosrun learning_service person_client

ros16.參數的使用與編程方法

16.1 ros master 里面有一個parameter server【全局字典】 里面有各種參數以及對應的值

啟動roscore

啟動 rosrun turtlesim turtlesim_node

(1)rosparam list [列出當前參數]

/background_b
/background_g
/background_r
/rosdistro
/roslaunch/uris/host_tian_nl__39943
/rosversion
/run_id

(2)顯示某一個參數

rosparam get /background_b

(3)設置某個參數值

osparam set /background_b 0

為了顯示已經改變了參數的值,可以刷新一下顯示小烏龜的背景

rosservice call /clear "{}"

(4)保存參數到文件 文件后綴是.yaml

rosparam dump now_param.yaml

(5)從文件讀取參數

rosparam load now_param.yaml

rosservice call /clear "{}"

(6) 刪除參數

rosparam delete param_key

16.2 參數編程

初始化ros節點

get 函數獲取參數

set函數設置參數

 1 /**
 2  * 設置海龜歷程中的參數
 3  * */
 4 #include<string>
 5 #include<ros/ros.h>
 6 #include<std_srvs/Empty.h>
 7 int main(int argc,char ** argv)
 8 {
 9     int red,green , blue;
10     //ros 初始化和創建句柄
11     ros::init(argc,argv,"parameter_config");
12     ros::NodeHandle node;
13     //讀取背景顏色
14     ros::param::get("/background_r",red);
15     ros::param::get("/background_g",green);
16     ros::param::get("/background_b",blue);
17     //輸出讀取的背景顏色
18     ROS_INFO("Get Background Color [%d ,%d,%d]",red,green,blue);
19     //設置背景顏色參數
20     ros::param::set("/background_r",255);   
21     ros::param::set("/background_g",255);   
22     ros::param::set("/background_b",255);   
23     ROS_INFO("Get Background Color [255,255,255]");
24     //因為已經被修改了 再讀取背景顏色
25     ros::param::get("/background_r",red);
26     ros::param::get("/background_g",green);
27     ros::param::get("/background_b",blue);
28     ROS_INFO("Re-get Background Color [%d ,%d,%d]",red,green,blue);
29     //調用服務,刷新背景顏色 等待服務 服務找到之后就設置參數 調用服務
30     ros::service::waitForService("/clear");
31     ros::ServiceClient clear_background = node.serviceClient<std_srvs::Empty>("/clear");
32     std_srvs::Empty srv;
33     clear_background.call(srv);
34     sleep(1);
35     return 0;
36 }
37 add_executable(parameter_config src/parameter_config.cpp)
38 target_link_libraries(parameter_config ${catkin_LIBRARIES})

啟動roscore

啟動 rosrun turtlesim turtlesim_node

啟動 rosrun learning_parameter parameter_config

ros17.ROS中的坐標系管理系統

17.1坐標變化 就是 P2 = R(P1)+t

17.2 TF 功能包能干什么

5秒鍾以前,機器人頭部的坐標系相對於全局坐標系的關系是怎么樣的

機器人夾取的物體相對於機器人中心坐標系的位置在哪里

機器人中心坐標相對於全局坐標的位置在哪里

TF坐標變換是如何實現的

廣播TF變換

監聽 TF變換

17.3 演示

sudo apt-get install ros-melodic-turtle-tf

roslaunch turtle_tf turtle_tf_demo.launch [烏龜2會追着烏龜1 ,不要求他們的頭指向同一方向,但是身子要重疊]
rosrun turtlesim turtle_teleop_key

rosrun tf view_frames【會在當前目錄下生成 frames.pdf】

rosrun tf  tf_echo turtle1 turtle2[可以看到兩個小烏龜的位姿]
rosrun rviz rviz -d `rospack find turtle_tf` /rviz/turtle_rviz.rviz 【在Fixed Frame 變成world  || Add-> TF】

ros18.tf坐標系廣播與監聽的編程實現

roscore

rosrun turtlesim turtlesim_node

rosrun learning_tf turtle_tf_broadcaster __name:=turtle1_tf_broadcaster /turtle1【turtle1_tf_broadcaster 會替換掉代碼里面設置的節點名字 arg[1] = trutle1】
rosrun learning_tf turtle_tf_broadcaster __name:=turtle2_tf_broadcaster /turtle2

rosrun learning_tf turtle_tf_listener

rosrun turtlesim turtle_teleop_key rostopic list

rosnode list

  1 roscore
  2 
  3 rosrun turtlesim turtlesim_node
  4 
  5 rosrun learning_tf turtle_tf_broadcaster __name:=turtle1_tf_broadcaster /turtle1【turtle1_tf_broadcaster 會替換掉代碼里面設置的節點名字 arg[1] = trutle1】
  6 rosrun learning_tf turtle_tf_broadcaster __name:=turtle2_tf_broadcaster /turtle2
  7 
  8 rosrun learning_tf turtle_tf_listener
  9 
 10 rosrun turtlesim turtle_teleop_key rostopic list
 11 
 12 rosnode list
 13 
 14 
 15 /**
 16  * 現在是實現一個tf廣播器
 17  * 創建坐標變換值
 18  * 發布坐標變換
 19  * 
 20  * */
 21 #include<ros/ros.h>
 22 #include<tf/transform_broadcaster.h>
 23 #include<turtlesim/Pose.h>
 24 std::string turtle_name;
 25 void poseCallback(const turtlesim::PoseConstPtr & msg){
 26     //創建tf的廣播器
 27     static tf::TransformBroadcaster br;
 28     //初始化tf的數據
 29     tf::Transform transform;
 30     //平移
 31     transform.setOrigin(tf::Vector3(msg->x,msg->y,0));
 32     //四元數
 33     tf::Quaternion q;
 34     q.setRPY(0,0,msg->theta);
 35     transform.setRotation(q);
 36     
 37     //廣播world與海龜坐標系之間的tf數據
 38     br.sendTransform(
 39         tf::StampedTransform(
 40             transform,
 41             ros::Time::now(),
 42             "world",
 43             turtle_name
 44         )
 45     );
 46 
 47 }
 48 int main(int argc,char ** argv){
 49     ros::init(argc,argv,"my_tf_broadcaster");
 50     if(argc!=2){
 51         ROS_ERROR("need turtle name as argument");
 52         return -1;
 53     }
 54     turtle_name = argv[1];
 55     //訂閱海龜的位子話題
 56     ros::NodeHandle node;
 57     ros::Subscriber sub = node.subscribe(turtle_name+"/pose",10,&poseCallback);
 58     //循環等待回調函數
 59     ros::spin();
 60     return 0;
 61 }
 62 /**
 63  * 定義tf監聽器
 64  * 查找坐標變換
 65  * */
 66 #include<ros/ros.h>
 67 #include<tf/transform_listener.h>
 68 #include<geometry_msgs/Twist.h>
 69 #include<turtlesim/Spawn.h>
 70 int main(int argc,char ** argv){
 71     //初始化ros節點和句柄 請求產生烏龜
 72     ros::init(argc,argv,"my_tf_listener");
 73     ros::NodeHandle node;
 74     ros::service::waitForService("/spawn");
 75     ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
 76     turtlesim::Spawn srv;
 77     add_turtle.call(srv);
 78     //創建發布turtle速度控制指令的發布者
 79     ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel",10);
 80     //創建tf的監聽器
 81     tf::TransformListener listener;
 82     ros::Rate rate(10.0);
 83     while (ros::ok())
 84     {
 85         //獲取兩個海龜坐標系之間的tf數據
 86         tf::StampedTransform transform;
 87         try
 88         {
 89             listener.waitForTransform("/turtle2","/turtle1",ros::Time(0),ros::Duration(3.0));
 90             listener.lookupTransform("/turtle2","/turtle1",ros::Time(0),transform);
 91 
 92         }
 93         catch(tf::TransformException &ex)
 94         {
 95             ROS_ERROR("%s",ex.what());
 96             // ros::Duration(1.0)這里代表時長
 97             ros::Duration(1.0).sleep();
 98             continue;
 99         }
100         //根據兩個烏龜之間的位置關系,發布turtle的速度控制指令
101         geometry_msgs::Twist vel_msg;
102         //arctan(y/x);
103         vel_msg.angular.z = 4.0 * atan2(
104             transform.getOrigin().y(),
105             transform.getOrigin().x()
106         );
107         vel_msg.linear.x = 0.5* sqrt(
108             pow(transform.getOrigin().x(),2) +
109             pow(transform.getOrigin().y(),2)
110         );
111 
112         turtle_vel.publish(vel_msg);
113     }
114     
115     return 0;
116 }
117 add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
118 target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})
119 
120 add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
121 target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})

 ros19.launch啟動文件[xml]的使用方法

19.1launch 文件語法

 1 <launch>
 2     <node pkg = "learning_topic" type = "person_subscriber" name="talker" output="screen"/>
 3     <node pkg = "learning_topic" type = "person_publisher" name="listener" output="screen"/>
 4     
 5 </launch>
 6 <!-- 
 7     node:啟動節點
 8     pkg:節點所在的功能包名稱
 9     type: 節點的可執行文件名稱
10     name:節點運行時的名稱 【相當於我雖然寫了一個cpp 里面我也確實初始化了一個節點
11     並且這個節點也有名字,但是現在我用name來代替我一開始寫的節點的名字
12     這樣我多幾個name就多了幾個節點但是只寫了一份代碼
13 14     output: 打印在哪里
15     創建一個功能包 不添加任何依賴 learning_launch 在下面添加launch文件夾 把.xml launch文件 放入到文件下面
16     roslaunch learning_launch simple.launch 
17     rostopic list
18 -->

 

 1 <launch>
 2     <param name = "/turtle_number" value = "2"/>
 3     <node pkg="turtlesim" type="turtlesim_node" name="turtlesim_node">
 4         <param name = "turtle_name1" value = "Tom"/>
 5         <param name = "turtle_name2" value = "Jerry"/>
 6         <rosparam 
 7             file = "$(find learning_launch)/config/param.yaml"
 8             command = "load"
 9         />
10     </node>
11 
12     <node 
13         pkg="turtlesim" 
14         type="turtle_teleop_key"
15         name = "turtle_teleop_key" 
16         output = "screen"
17     
18     />
19 </launch>
20 <!-- 
21     設置ros系統中運行的參數,存儲在參數服務器中
22     
23     param:
24         name:
25         value:
26     加載參數文件中的多個參數
27     rosparam
28         file
29         command
30         ns="params"
31     roslaunch learning_launch turtlesim_parameter_config.launch
32     rosparam list
33  -->

 

 1 <launch>
 2     <node 
 3         pkg="turtlesim" 
 4         type="turtlesim_node"
 5         name = "sim" 
 6     />
 7     <node 
 8         pkg="turtlesim" 
 9         type="turtle_teleop_key"
10         name = "teleop" 
11         output = "screen"
12     />
13     <node 
14         pkg="learning_tf" 
15         type="turtle_tf_broadcaster"
16         name = "turtle1_tf_broadcaster" 
17         args="/turtle1"
18     />
19     <node 
20         pkg="learning_tf" 
21         type="turtle_tf_broadcaster"
22         name = "turtle2_tf_broadcaster" 
23         args="/turtle2"
24     />
25     <node 
26         pkg="learning_tf" 
27         type="turtle_tf_listener"
28         name = "listener" 
29          
30     /> 
31     
32     
33 </launch>
34 <!-- 
35     roslaunch learning_launch start_tf_demo_c++.launch
36  -->

 

 1 <launch>
 2     
 3     <include file="$(find learning_launch)/launch/simple.launch"/>
 4     <node pkg="turtlesim" type = "turtlesim_node" name="turtlesim_node">
 5         <remap from="/turtle1/cmd_vel" to="/cmd_vel"/>
 6     </node>
 7 </launch>
 8 <!-- 
 9     remap 重映射 ros計算圖資源的命名
10     roslaunch learning_launch turtlesim_remap.launch 
11     rostopic list
12     rostopic pub /cmd_vel geometry_msgs/Twist "linear:
13     x: 5.0
14     y: 0.0
15     z: 0.0
16     angular:
17     x: 0.0
18     y: 0.0
19     z: 2.0" 
20  -->
21  

ros20.常用可視化工具的使用

20.1rqt_console 【 日志輸出工具 對日志信息進行篩選 】

rqt_graph [計算圖可視化工具]

rqt_plot[ 數據繪圖工具 把信息繪制成圖 在topic那里選擇訂閱的話題]

rqt_image_view [圖形渲染工具 鏈接圖像]

rqt 集成了ros qt的所有的工具,可以把很多的工具就行堆疊

20.2

rosrun rviz rviz

3D視圖區 工具欄 顯示項列表 視覺設置區 時間顯示區

如果先看什么就點擊add 但是都需要訂閱對應的話題

gazebo

roslaunch gazebo_ros willowgarage_world.launch


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM