Gazebo筆記(三)

Chien-lin.Tseng
My learning note
Published in
13 min readJul 16, 2019

2019年7月16日(二)

目錄:

一、參考網站

二、一些小發現、心得

三、建立發布節點 (使用 python)

四、建立接受器節點 (使用 python)

一、參考網站

(1) Tutorial: ROS Control

二、一些小發現、心得

(1) 發布消息到 /rrbot/joint1_position_controller/command ,使手臂動作

/rrbot/joint1_position_controller/command 是話題名稱。
std_msgs/Float64 是消息類型。
'0' 是發布的資料。

(2) 印在螢幕上

rospy.loginfo("%f\n",speed_linear)

(3) 話題上的消息類型

/rrbot/joint1_position_controller/command

rostopic type /rrbot/joint1_position_controller/command
----------------------------------------------------
std_msgs/Float64
(分隔線)rosmsg show std_msgs/Float64
---------------------------------------------------
float64 data
(分隔線)rostopic hz /rrbot/joint1_position_controller/command
----------------------------------------------------
average rate: 15.307
min: 0.000s max: 0.162s std dev: 0.03397s window: 168
所以 頻率約是 15Hz

/rrbot/joint1_position_controller/state

rostopic type /rrbot/joint1_position_controller/state
--------------------------------------------------------
control_msgs/JointControllerState
(分隔線)rosmsg show control_msgs/JointControllerState
--------------------------------------------------------
std_msgs/Header header
uint32 seq
time stamp
string frame_id
float64 set_point
float64 process_value
float64 process_value_dot
float64 error
float64 time_step
float64 command
float64 p
float64 i
float64 d
float64 i_clamp
bool antiwindup

/turtle1/cmd_vel

rostopic type /turtle1/cmd_vel
------------------------------------------------
geometry_msgs/Twist
(分隔線)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

(4) 刪掉 package

rm -r name

(5) 依賴項之後補加的加法

三、建立發布節點 (使用 python)

(1) 注意事項

* 是 usr ,而不是 user

(2) 建立 my_rrbot package,並加上依賴項(可以放消息類型相關、rospy)。
std_msgs、control_msgs 都和消息有關。
rospy 和 python 有關。

cd ~/catkin_ws/src
catkin_create_pkg my_rrbot std_msgs control_msgs rospy

之後,my_rrbot pkg裡面自動會有src資料夾,把程式放在這裡就可以。

(3) 建立 rrbot_pub.py

功能: 這個程式可以發布 -1 ~ 1 的 sin波消息,讓 rrbot的joint1 去轉動。

分析:

(a) python 相關檔案要加上這樣的開頭:

#!/usr/bin/env python

(b) import 和消息類型有關的東西:

因為我們想要對 /rrbot/joint1_position_controller/command 話題發布消息,而它使用的消息類型是 std_msgs/Float64 ,所以需要如下的 import:

from std_msgs.msg import Float64

(c) 宣告 節點名稱:

宣告這個節點名稱為 rrbot_command,且其後會附加隨機亂數,確保該節點為獨一無二的。

rospy.init_node("rrbot_command", anonymous=True)

(d) 發布消息到話題 /rrbot/joint1_position_controller/command

消息類型為 Float64 : (注意:rospy.Publisher 是大寫!!)

move_publisher = rospy.Publisher("/rrbot/joint1_position_controller/command", Float64, queue_size=10)

(e) 宣告消息變數的方法

move_msg = Float64()

(f) 設定發布頻率:

經由用rostopic hz 測量 rqt_gui的發布頻率,發現其發布頻率是 15 hz,所以我這裡的發布器頻率也設為 15 hz。 ( rospy.Rate 是大寫)

rate = rospy.Rate(15)  #15 hz

在loop中的 rate.sleep()

(g) 設定消息值

由之前的 rosmsg show ,我們可以觀察到:

rosmsg show std_msgs/Float64
---------------------------------------------------
float64 data

可以使用以下方式,來設定消息值( .data ):

move_msg.data = angle

(e) 剩下就是一直發布消息了

(4) 執行 rrbot_pub.py

chmod +x rrbot_pub.py
rosrun my_rrbot rrbot_pub.py

以下的指令是,執行所有的程式:

roslaunch rrbot_gazebo rrbot_world.launch     //開啟 rrbot
roslaunch rrbot_control rrbot_control.launch //開啟 controller
rosrun my_rrbot rrbot_pub.py //發布轉動命令到topic

這時候,rrbot的 joint 1會開始來回轉動( -1 ~ 1 間)。

angle在-1 ~ 1 之間。

看一下 rqt_graph:

可以看到我們的 rrbot_command節點,發布了消息到 /rrbot/joint1_position_controller/command 話題,進行joint的轉動。

(5) 講述如何補上依賴項,要實際操作

待……補 (先別看)

更改Cmakelist、package.xml的內容

待……補

(6) 同時發布 two joint 轉動 (做好玩的)

這個程式可以使兩個 joint 同時轉動,程式如下:

rosrun my_rrbot rrbot_two_pub.py

看一下 rqt_graph:

Nodes only
nodes/topics (all) (抄左上角欄位的)

觀察第二張 rqt 圖。可以看到 rrbot_command節點,發布消息到兩個話題。

四、建立接受器節點 (使用 python)

(1) 建立 rrbot_sub.py (都是放在 /catkin_ws/src/my_rrbot/src)

程式功能:在 rrbot_pub.py 運行的情況下,執行這個程式。這個節點可以訂閱 /rrbot/joint1_position_controller/command 話題,接收到 command的值。

程式:

分析:

(a) 宣告節點

宣告這個節點名稱為 rrbot_command_sub。

rospy.init_node('rrbot_command_sub', anonymous=True)

(b) 訂閱話題

訂閱 /rrbot/joint1_position_controller/command 話題,接收消息類型為 Float64的消息。若接收到消息,則呼叫 callback 函式。
(注意 Subscriber大寫)

rospy.Subscriber('/rrbot/joint1_position_controller/command', Float64, callback)

(c) rospy.spin()

確保節點不會退出,直到該節點被終止。

rospy.spin() simply keeps your node from exiting until the node has been shutdown. (tutorial的)

rospy.spin()

(d) call back 函式

用 subdata.data,就像 rrbot_pub.py 中的寫法那樣。

def callback(subdata):    
rospy.loginfo("command is %f", subdata.data)

(2) 執行 rrbot_sub.py

roscore
rosrun my_rrbot rrbot_pub.py
rosrun my_rrbot rrbot_sub.py

執行結果如下:
左為 rrbot_pub.py,右為 rrbot_sub.py。用螢幕截圖,可以發現它接收的非常精準。

結果圖

(3) 建立 rrbot_two_sub.py

程式功能:rrbot_two_sub.py 的節點可以訂閱兩個話題,分別是 /rrbot/joint1_position_controller/command 話題和 /rrbot/joint1_position_controller/state 話題。訂閱第一個話題,可以得到發布的目標位置。訂閱第二個話題,可以得到 joint的實際位置

程式:

分析:

(a) 宣告節點

宣告這個節點的名稱為 rrbot_command_sub

rospy.init_node('rrbot_command_sub', anonymous=True)

(b) 訂閱話題

rospy.Subscriber('/rrbot/joint1_position_controller/command', Float64, callback)

(c) 訂閱話題

訂閱 /rrbot/joint1_position_controller/state 話題。由之前的測量(二、一些小發現、心得),可知道這個 topic 使用 JointControllerState 消息類型。若有接收到消息,則呼叫 callbackstate 函式。

rospy.Subscriber('/rrbot/joint1_position_controller/state', JointControllerState, callbackstate)

(d) callbackstate 函式

我們的目標是讀取出 process_value,因為這個是 joint的實際位置讀值。

由之前的測量(二、一些小發現、心得),可以推論出為什麼要寫subdata_state.process_value 。

def callbackstate(subdata_state):
rospy.loginfo("process value is %f", subdata_state.process_value)

(4) 執行 rrbot_two_sub.py

執行所有程式:

roslaunch rrbot_gazebo rrbot_world.launch
roslaunch rrbot_control rrbot_control.launch
rosrun my_rrbot rrbot_pub.py
rosrun my_rrbot rrbot_two_sub.py

執行結果:
註: 如果 command的值和process_value的值差一些些,可以開啟 rqt_gui,去調整他的PID,像我就是把P調成20000。
如果 command的值和process_value的值差很多(差不多6.28),則可以去調整rrbot_pub.py 的發布值,把它加6.28或減6.28即可。

左邊是發布器,右邊是接收器。

看一下rqt_graph:

注意左上角。
注意左上角。

我們可以看到,rrbot_command_sub節點訂閱了兩個話題!
rrbot_command節點發布了消息到一個話題!

(5) rospy.spin() 的擺放位置

spin要放在最後面。
如果把程式放在spin後面的話,程式就不會執行到那邊。

以下是正確的程式( rrbot_two_sub_test.py):

--

--