ROS 创建msg和srv 编写发布者和订阅者节点 编写服务端和客户端节点(python版本)
ROS 創(chuàng)建msg和srv 編寫發(fā)布者和訂閱者節(jié)點(diǎn) 編寫服務(wù)端和客戶端節(jié)點(diǎn)-python版本
- rosed
- msg和srv
- 創(chuàng)建msg
- 使用rosmsg
- 創(chuàng)建srv
- 使用rossrv
- 重新make一下軟件包
- 編寫發(fā)布者節(jié)點(diǎn)
- 發(fā)布者節(jié)點(diǎn)代碼解析
- 編寫訂閱者節(jié)點(diǎn)
- 訂閱者節(jié)點(diǎn)代碼解析
- 構(gòu)建節(jié)點(diǎn)
- 運(yùn)行發(fā)布者和訂閱者節(jié)點(diǎn)
- 編寫服務(wù)節(jié)點(diǎn)
- 編寫客戶端節(jié)點(diǎn)
- 運(yùn)行服務(wù)端和客戶端節(jié)點(diǎn)
rosed
利用它可以直接通過軟件包名編輯包中的文件,而無需鍵入完整路徑。
$ rosed roscpp Logger.msg編輯roscpp軟件包中的Logger.msg文件。退出vim,按下鍵盤上的Esc,然后分別按下:q!
Tap補(bǔ)全,在不知道準(zhǔn)確文件名的情況下,你也可以輕松地查看和編輯包中的所有文件。
$ rosed roscpp <tab><tab> jym@ubuntu:~$ rosed roscpp Empty.srv roscpp.cmake genmsg_cpp.py roscppConfig.cmake gensrv_cpp.py roscppConfig-version.cmake GetLoggers.srv roscpp-msg-extras.cmake Logger.msg roscpp-msg-paths.cmake msg_gen.py SetLoggerLevel.srv package.xmlmsg和srv
msg(消息):msg文件就是文本文件,用于描述ROS消息的字段。它們用于為不同編程語言編寫的消息生成源代碼。
srv(服務(wù)):一個srv文件描述一個服務(wù)。它由兩部分組成:請求(request)和響應(yīng)(response)。
創(chuàng)建msg
在之前創(chuàng)建的軟件包里定義一個新的消息。直接使用roscd beginner_tutorials,會報(bào)錯。顯示:
roscd: No such package/stack 'beginner_tutorials'因?yàn)閞oscd只能切換到那些路徑已經(jīng)包含在ROS_PACKAGE_PATH環(huán)境變量中的軟件包。
工作空間構(gòu)建完成后,要將這個工作空間添加到ROS環(huán)境中,需要source一下生成的配置文件。
然后用roscd beginner_tutorials就沒問題了。
jym@ubuntu:~$ roscd beginner_tutorials roscd: No such package/stack 'beginner_tutorials' jym@ubuntu:~$ . ~/catkin_ws/devel/setup.bash jym@ubuntu:~$ roscd beginner_tutorials jym@ubuntu:~/catkin_ws/src/beginner_tutorials$然后輸入:
$ mkdir msg $ echo "int64 num" > msg/Num.msg那么就在msg文件夾里面生成了Num.msg文件。
然后打開package.xml,確保有以下兩行代碼,沒有的話加上。
確保msg文件能被轉(zhuǎn)換為C++、Python和其他語言的源代碼。
<build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>在構(gòu)建時,只需要message_generation,而在運(yùn)行時,只需要message_runtime。
輸入下面指令可以直接打開CMakeLists.txt文件
$ beginner_tutorials CMakeLists.txt按esc后再按i,可以進(jìn)入編輯。
1.在CMakeLists.txt文件中,為已經(jīng)存在里面的find_package調(diào)用添加message_generation依賴項(xiàng)
添加message_generation后的find_package如下所示。
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation )2.還要確保導(dǎo)出消息的運(yùn)行時依賴關(guān)系:
找到catkin_package添加CATKIN_DEPENDS message_runtime
catkin_package(...CATKIN_DEPENDS message_runtime ......)3.找到如下代碼塊:
# add_message_files( # FILES # Message1.msg # Message2.msg # )刪除#符號來取消注釋,然后將Message*.msg替換為你的.msg文件名,就像下邊這樣:
add_message_files(FILESNum.msg )手動添加.msg文件后,我們要確保CMake知道何時需要重新配置項(xiàng)目。
4.現(xiàn)在必須確保generate_messages()函數(shù)被調(diào)用:
取消下面幾行的注釋:添加任意你的消息用到的包含.msg文件的軟件包(本例中為std_msgs)
# generate_messages( # DEPENDENCIES # std_msgs # )以上是創(chuàng)建消息的所有步驟。
使用rosmsg
通過rosmsg show命令看看ROS能否識別創(chuàng)建的消息。
輸入:rosmsg show beginner_tutorials/Num
可看到:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ rosmsg show beginner_tutorials/Num int64 num上面的例子中,消息類型包含兩部分:
- beginner_tutorials – 定義消息的軟件包
- Num – 消息的名稱Num
如果不記得msg在哪個包中,也可以省略包名稱。$ rosmsg show Num
可看到:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ rosmsg show Num [beginner_tutorials/Num]: int64 num創(chuàng)建srv
可從另一個包復(fù)制現(xiàn)有的srv定義,而不是手動創(chuàng)建新的srv。
roscp是一個實(shí)用的命令行工具,用于將文件從一個包復(fù)制到另一個包。
從rospy_tutorials包中復(fù)制一個服務(wù):
$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv剩下的和創(chuàng)建msg類似:
1.打開package.xml,確保有以下兩行代碼:
<build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>2.在CMakeLists.txt文件中,為已經(jīng)存在里面的find_package調(diào)用添加message_generation依賴項(xiàng)。
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation )3.在package.xml中修改服務(wù)字段。
刪除#符號來取消注釋,然后將Service*.srv替換為你的.srv文件名,就像下邊這樣:
add_service_files(FILESAddTwoInts.srv )以上就是創(chuàng)建服務(wù)的所有步驟。
使用rossrv
通過rossrv show命令看看ROS能否識別創(chuàng)建的服務(wù)。
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ rossrv show beginner_tutorials/AddTwoInts int64 a int64 b --- int64 sum也可以在不指定包名的情況下找到這樣的服務(wù)。
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ rossrv show AddTwoInts [rospy_tutorials/AddTwoInts]: int64 a int64 b --- int64 sum[beginner_tutorials/AddTwoInts]: int64 a int64 b --- int64 sum第一個是剛剛在beginner_tutorials包中創(chuàng)建的,第二個是之前rospy_tutorials包中已經(jīng)存在的。
重新make一下軟件包
現(xiàn)在我們已經(jīng)創(chuàng)建了一些新消息,所以需要重新make一下軟件包:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ roscd beginner_tutorials jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ cd ../.. jym@ubuntu:~/catkin_ws$ catkin_makejym@ubuntu:~/catkin_ws$ cd - /home/jym/catkin_ws/src/beginner_tutorials jym@ubuntu:~/catkin_ws/src/beginner_tutorials$msg目錄中的任何.msg文件都將生成所有支持語言的代碼。
C++消息的頭文件將生成在~/catkin_ws/devel/include/beginner_tutorials/。Python腳本將創(chuàng)建在~/catkin_ws/devel/lib/python3/dist-packages/beginner_tutorials/msg。而Lisp文件則出現(xiàn)在~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/。
類似地,srv目錄中的任何.srv文件都將生成支持語言的代碼。對于C++,頭文件將生成在消息的頭文件的同一目錄中。對于Python和Lisp,會在msg目錄旁邊的srv目錄中。
編寫發(fā)布者節(jié)點(diǎn)
“節(jié)點(diǎn)”是連接到ROS網(wǎng)絡(luò)的可執(zhí)行文件。
這里將創(chuàng)建talker(發(fā)布者)節(jié)點(diǎn),該節(jié)點(diǎn)將不斷廣播消息。
1.將目錄切換到創(chuàng)建的beginner_tutorials包中:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ roscd beginner_tutorials2.創(chuàng)建一個scripts目錄來存放Python腳本:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ mkdir scripts jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ cd scripts3.在scripts目錄下創(chuàng)建talker.py文件:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ vim talker.py輸入:
#!/usr/bin/env python # license removed for brevity import rospy from std_msgs.msg import Stringdef talker():pub = rospy.Publisher('chatter', String, queue_size=10)rospy.init_node('talker', anonymous=True)rate = rospy.Rate(10) # 10hzwhile not rospy.is_shutdown():hello_str = "hello world %s" % rospy.get_time()rospy.loginfo(hello_str)pub.publish(hello_str)rate.sleep()if __name__ == '__main__':try:talker()except rospy.ROSInterruptException:pass然后給它執(zhí)行權(quán)限:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ chmod +x talker.py可以通過下面的命令查看和編輯這個文件:
$ rosed beginner_tutorials talker.py4.將以下內(nèi)容添加到CMakeLists.txt文件
catkin_install_python(PROGRAMS scripts/talker.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )確保正確安裝Python腳本,并使用合適的Python解釋器。
發(fā)布者節(jié)點(diǎn)代碼解析
#!/usr/bin/env python每個Python ROS節(jié)點(diǎn)的最開頭都有這個聲明。第一行確保腳本作為Python腳本執(zhí)行。
import rospy from std_msgs.msg import String如果要編寫ROS節(jié)點(diǎn),則需要導(dǎo)入rospy。std_msgs.msg的導(dǎo)入則是為了使我們能夠重用std_msgs/String消息類型(即一個簡單的字符串容器)來發(fā)布。
pub = rospy.Publisher('chatter', String, queue_size=10)rospy.init_node('talker', anonymous=True)這部分代碼定義了talker與其他ROS部分的接口。
pub = rospy.Publisher("chatter", String, queue_size=10)聲明該節(jié)點(diǎn)正在使用String消息類型發(fā)布到chatter話題。
這里的String實(shí)際上是std_msgs.msg.String類。
queue_size參數(shù)是在ROS Hydro及更新版本中新增的,用于在訂閱者接收消息的速度不夠快的情況下,限制排隊(duì)的消息數(shù)量。
下一行的rospy.init_node(NAME, ...)非常重要,因?yàn)樗言摴?jié)點(diǎn)的名稱告訴了rospy。
只有rospy掌握了這一信息后,才會開始與ROS主節(jié)點(diǎn)進(jìn)行通信。
在本例中,節(jié)點(diǎn)使用talker名稱。注意:名稱必須是基本名稱,不能包含任何斜杠。
anonymous = True會讓名稱末尾添加隨機(jī)數(shù),來確保節(jié)點(diǎn)具有唯一的名稱。
rate = rospy.Rate(10) # 10hz此行創(chuàng)建一個Rate對象rate。借助其方法sleep(),它提供了一種方便的方法,來以你想要的速率循環(huán)。它的參數(shù)是10,即表示希望它每秒循環(huán)10次。
while not rospy.is_shutdown():hello_str = "hello world %s" % rospy.get_time()rospy.loginfo(hello_str)pub.publish(hello_str)rate.sleep()這個循環(huán)是一個相當(dāng)標(biāo)準(zhǔn)的rospy結(jié)構(gòu):檢查rospy.is_shutdown()標(biāo)志,然后執(zhí)行代碼邏輯。
查看is_shutdown()以檢查程序是否應(yīng)該退出(例如有Ctrl+C或其他)。
在本例中,代碼邏輯即對public .publish(hello_str)的調(diào)用,它將一個字符串發(fā)布到chatter話題。
循環(huán)的部分還調(diào)用了rate.sleep(),它在循環(huán)中可以用剛剛好的睡眠時間維持期望的速率。
此循環(huán)還調(diào)用了rospy.loginfo(str),它有3個任務(wù):打印消息到屏幕上;把消息寫入節(jié)點(diǎn)的日志文件中;寫入rosout。
rosout是一個方便的調(diào)試工具:可以使用rqt_console來拉取消息,而不必在控制臺窗口找節(jié)點(diǎn)的輸出。
try:talker()except rospy.ROSInterruptException:pass除了標(biāo)準(zhǔn)的Python __main__檢查,它還會捕獲一個rospy.ROSInterruptException異常,當(dāng)按下Ctrl+C或節(jié)點(diǎn)因其他原因關(guān)閉時,這一異常就會被rospy.sleep()和rospy.Rate.sleep()拋出。
編寫訂閱者節(jié)點(diǎn)
1.將目錄切換到scripts目錄中:
$ roscd beginner_tutorials/scripts/2.創(chuàng)建listener.py文件
$ vim listener.py輸入:
#!/usr/bin/env python import rospy from std_msgs.msg import Stringdef callback(data):rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)def listener():# In ROS, nodes are uniquely named. If two nodes with the same# name are launched, the previous one is kicked off. The# anonymous=True flag means that rospy will choose a unique# name for our 'listener' node so that multiple listeners can# run simultaneously.rospy.init_node('listener', anonymous=True)rospy.Subscriber("chatter", String, callback)# spin() simply keeps python from exiting until this node is stoppedrospy.spin()if __name__ == '__main__':listener()3.給它執(zhí)行權(quán)限
$ chmod +x listener.py4.編輯你CMakeLists.txt中的catkin_install_python()調(diào)用
可以用rosed打開CMakeLists.txt
rosed beginner_tutorials CMakeLists.txt然后添加
catkin_install_python(PROGRAMS scripts/talker.py scripts/listener.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )訂閱者節(jié)點(diǎn)代碼解析
listener.py的代碼類似于talker.py,只不過我們?yōu)橛嗛喯⒁肓艘环N新的基于回調(diào)的機(jī)制。
rospy.init_node('listener', anonymous=True)rospy.Subscriber("chatter", String, callback)# spin() simply keeps python from exiting until this node is stoppedrospy.spin()這聲明節(jié)點(diǎn)訂閱了chatter話題,類型是std_msgs.msgs.String。當(dāng)接收到新消息時,callback函數(shù)被調(diào)用,消息作為第一個參數(shù)。
稍微更改了對rospy.init_node()的調(diào)用。添加了anonymous=True關(guān)鍵字參數(shù)。
ROS要求每個節(jié)點(diǎn)都有一個唯一的名稱,如果出現(xiàn)具有相同名稱的節(jié)點(diǎn),則會與前一個節(jié)點(diǎn)發(fā)生沖突,這樣一來,出現(xiàn)故障的節(jié)點(diǎn)很容易地被踢出網(wǎng)絡(luò)。
anonymous=True標(biāo)志會告訴rospy為節(jié)點(diǎn)生成唯一的名稱,這樣就很容易可以有多個listener.py一起運(yùn)行。
rospy.spin()只是不讓節(jié)點(diǎn)退出,直到節(jié)點(diǎn)被明確關(guān)閉。
與roscpp不同,rospy.spin()不影響訂閱者回調(diào)函數(shù),因?yàn)樗鼈冇凶约旱木€程。
構(gòu)建節(jié)點(diǎn)
使用CMake作為構(gòu)建系統(tǒng)。即使是Python節(jié)點(diǎn)也必須使用它。這是為了確保能為創(chuàng)建的消息和服務(wù)自動生成Python代碼。
回到catkin工作空間,然后運(yùn)行catkin_make:
$ cd ~/catkin_ws $ catkin_make運(yùn)行發(fā)布者和訂閱者節(jié)點(diǎn)
開三個終端:
第一個輸入:
$ roscore第二個:
運(yùn)行talker發(fā)布者節(jié)點(diǎn)
$ cd ~/catkin_ws $ source ./devel/setup.bash $ rosrun beginner_tutorials talker.py第三個:
$ cd ~/catkin_ws $ source ./devel/setup.bash $ rosrun beginner_tutorials listener.py可以通過
$ rosrun rqt_graph rqt_graph看到當(dāng)前運(yùn)行的節(jié)點(diǎn)和話題
發(fā)布者節(jié)點(diǎn)發(fā)出:
[INFO] [1635421895.494006]: hello world 1635421895.4938853 [INFO] [1635421895.594515]: hello world 1635421895.5943954 [INFO] [1635421895.694447]: hello world 1635421895.6943207 [INFO] [1635421895.793802]: hello world 1635421895.7936826 [INFO] [1635421895.893810]: hello world 1635421895.893687 [INFO] [1635421895.993590]: hello world 1635421895.9934704 [INFO] [1635421896.094563]: hello world 1635421896.0942173 [INFO] [1635421896.194204]: hello world 1635421896.1938524 [INFO] [1635421896.294536]: hello world 1635421896.2941887 [INFO] [1635421896.394086]: hello world 1635421896.3939602 [INFO] [1635421896.493973]: hello world 1635421896.4936652 [INFO] [1635421896.594645]: hello world 1635421896.5942914 [INFO] [1635421896.694563]: hello world 1635421896.6942132 [INFO] [1635421896.794407]: hello world 1635421896.7942781 [INFO] [1635421896.894170]: hello world 1635421896.8938253 ^Cjym@ubuntu:~/catkin_ws$訂閱者節(jié)點(diǎn)收到:
[INFO] [1635421896.198918]: /listener_8151_1635421497025I heard hello world 1635421896.1938524 [INFO] [1635421896.299254]: /listener_8151_1635421497025I heard hello world 1635421896.2941887 [INFO] [1635421896.397918]: /listener_8151_1635421497025I heard hello world 1635421896.3939602 [INFO] [1635421896.498270]: /listener_8151_1635421497025I heard hello world 1635421896.4936652 [INFO] [1635421896.599628]: /listener_8151_1635421497025I heard hello world 1635421896.5942914 [INFO] [1635421896.698885]: /listener_8151_1635421497025I heard hello world 1635421896.6942132 [INFO] [1635421896.795746]: /listener_8151_1635421497025I heard hello world 1635421896.7942781 [INFO] [1635421896.898501]: /listener_8151_1635421497025I heard hello world 1635421896.8938253可以看到在發(fā)布者節(jié)點(diǎn)添加ctrl+c之后,訂閱者節(jié)點(diǎn)也不接收消息了。
編寫服務(wù)節(jié)點(diǎn)
前面已經(jīng)創(chuàng)建了需要的服務(wù)AddTwoInts.srv。
接下來:
在beginner_tutorials包中創(chuàng)建scripts/add_two_ints_server.py文件并粘貼以下內(nèi)容進(jìn)去:
#!/usr/bin/env pythonfrom __future__ import print_functionfrom beginner_tutorials.srv import AddTwoInts,AddTwoIntsResponse import rospydef handle_add_two_ints(req):print("Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b)))return AddTwoIntsResponse(req.a + req.b)def add_two_ints_server():rospy.init_node('add_two_ints_server')s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)print("Ready to add two ints.")rospy.spin()if __name__ == "__main__":add_two_ints_server()然后將以下內(nèi)容添加到CMakeLists.txt文件。確保正確安裝Python腳本,并使用合適的Python解釋器。
catkin_install_python(PROGRAMS scripts/add_two_ints_server.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )以上流程在linux上輸入的指令代碼:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials$ roscd beginner_tutorials/scripts/ jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ vim add_two_ints_server.py jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ chmod +x add_two_ints_server.py jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ rosed beginner_tutorials CMakeLists.txt使用rospy編寫服務(wù)。使用init_node()聲明我們的節(jié)點(diǎn),然后再聲明我們的服務(wù):
s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)這聲明了一個名為add_two_ints的新服務(wù),其服務(wù)類型為AddTwoInts。所有的請求(request)都傳遞給了handle_add_two_ints函數(shù)。handle_add_two_ints被AddTwoIntsRequest的實(shí)例調(diào)用,返回AddTwoIntsResponse實(shí)例。
就像訂閱者中的例子一樣,rospy.spin()可以防止代碼在服務(wù)關(guān)閉之前退出。
編寫客戶端節(jié)點(diǎn)
在beginner_tutorials包中創(chuàng)建scripts/add_two_ints_client.py文件并粘貼以下內(nèi)容進(jìn)去:
#!/usr/bin/env pythonfrom __future__ import print_functionimport sys import rospy from beginner_tutorials.srv import *def add_two_ints_client(x, y):rospy.wait_for_service('add_two_ints')try:add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)resp1 = add_two_ints(x, y)return resp1.sumexcept rospy.ServiceException as e:print("Service call failed: %s"%e)def usage():return "%s [x y]"%sys.argv[0]if __name__ == "__main__":if len(sys.argv) == 3:x = int(sys.argv[1])y = int(sys.argv[2])else:print(usage())sys.exit(1)print("Requesting %s+%s"%(x, y))print("%s + %s = %s"%(x, y, add_two_ints_client(x, y)))同樣將以下內(nèi)容添加到CMakeLists.txt文件。
catkin_install_python(PROGRAMS scripts/add_two_ints_server.py scripts/add_two_ints_client.pyDESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )以上流程在linux上輸入的指令代碼:
jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ roscd beginner_tutorials/scripts/ jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ vim add_two_ints_client.py jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ chmod +x add_two_ints_client.py jym@ubuntu:~/catkin_ws/src/beginner_tutorials/scripts$ rosed beginner_tutorials CMakeLists.txt客戶端(用來調(diào)用服務(wù))的代碼分析:
對于客戶端來說不需要調(diào)用init_node()。首先調(diào)用:
rospy.wait_for_service('add_two_ints')這是一種很方便的方法,可以讓在add_two_ints服務(wù)可用之前一直阻塞。
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)這里為服務(wù)的調(diào)用創(chuàng)建了一個句柄(handle)。
resp1 = add_two_ints(x, y)return resp1.sum然后可以使用這個句柄,就像普通的函數(shù)一樣調(diào)用它。
因?yàn)橐呀?jīng)將服務(wù)的類型聲明為AddTwoInts,它會生成AddTwoIntsRequest對象 (you’re free to pass in your own instead)。如果調(diào)用失敗,rospy.ServiceException將會拋出,所以應(yīng)該弄一個合適的try/except部分。
使用CMake作為構(gòu)建系統(tǒng)。為了確保能為創(chuàng)建的消息和服務(wù)自動生成Python代碼。
切換當(dāng)前目錄到catkin工作空間,然后運(yùn)行catkin_make:
$ cd ~/catkin_ws $ catkin_make現(xiàn)在已經(jīng)編寫了一個簡單的服務(wù)和客戶端
運(yùn)行服務(wù)端和客戶端節(jié)點(diǎn)
開三個終端:
第一個輸入:
$ roscore第二個:
運(yùn)行talker發(fā)布者節(jié)點(diǎn)
$ cd ~/catkin_ws $ source ./devel/setup.bash $ rosrun beginner_tutorials add_two_ints_server.py第三個:
$ cd ~/catkin_ws $ source ./devel/setup.bash $ rosrun beginner_tutorials add_two_ints_client.py 1 3服務(wù)節(jié)點(diǎn)運(yùn)行效果:
jym@ubuntu:~/catkin_ws$ rosrun beginner_tutorials add_two_ints_server.py Ready to add two ints. Returning [1 + 3 = 4]客戶端節(jié)點(diǎn)運(yùn)行效果:
jym@ubuntu:~/catkin_ws$ rosrun beginner_tutorials add_two_ints_client.py 1 3 Requesting 1+3 1 + 3 = 4總結(jié)
以上是生活随笔為你收集整理的ROS 创建msg和srv 编写发布者和订阅者节点 编写服务端和客户端节点(python版本)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux替换windows回车,转载
- 下一篇: 基于深度学习的手写数字识别、python