3 ROS1通讯编程提高(1)
创始人
2025-06-01 22:40:10
0

3 ROS1通讯编程提高

  • 3.1 使用VS Code编译ROS1
    • 3.1.1 VS Code的安装和配置
      • 3.1.1.1 VS Code以及插件安装
      • 3.1.1.2 VS Code配置ROS1工作空间
      • 3.1.1.3 VS Code运行ROS1的方法
      • 3.1.1.3 参考资料
    • 3.1.2 使用VScode编译C++文件
    • 3.1.3使用VScode编译Python文件
  • 3.2 ROS1动作编程
    • 3.2.1 动作编程模型
    • 3.2.2 动作编程基础示例
      • 3.2.2.1 使用VS Code创建动作编程项目
      • 3.2.2.2 配置action动作文件
      • 3.2.2.3 C++实现action基本编程
      • 3.2.2.4 Python实现action基本编程\
    • 3.2.3 动作编程总结
      • 3.2.3.1 动作编程的顺序流程
      • 3.2.3.2 动作编程逻辑
    • 3.2.4 参考

  • 其他ROS1学习笔记: ROS1学习笔记
  • 代码仓库:Github连接地址
  • 欢迎各位互相学习交流

3.1 使用VS Code编译ROS1

3.1.1 VS Code的安装和配置

3.1.1.1 VS Code以及插件安装

  1. VS Code的下载安装:

VS Code的下载链接:VS Code 官网连接;历史版本下载链接:VS Code历史版本,选择合适的版本,对于Linux系统下载deb文件双击运行,或者输入命令sudo dpkg -i vscode安装包名.deb即可。

  1. VS Code的插件配置:
    1. VS Code编译ROS需要的插件主要包括:ROS、C/C++、Python、CMake、CMake Tools以及中文汉化插件Chinese(simplified) Language Pack for Visual Studio Code,如图所示:

在这里插入图片描述

    1. 其中Python可能需要设置解析器的位置即usr/bin/python2.7,重启VS Code,配置好的插件环境如图所示:

在这里插入图片描述

3.1.1.2 VS Code配置ROS1工作空间

  1. VS Code打开工作空间:
    1. 在终端进入到工作空间即cd catkin_ws
    1. 输入命令code .直接在VS Code打开工作空间,如图所示

在这里插入图片描述

  1. 配置工作空间下的json文件:在VS Code打开的工作空间,会出现一个.vscode文件夹,里面存放了三个json文件,用于配置C++和Python编译ROS,下面依次介绍:
    1. task.json文件:用于配置C++和Python编译ROS任务,配置好之后,可基本上后续不需要进行改动。
// /home/ubuntu/catkin_ws/.vscode/tasks.json
{"version": "2.0.0","tasks": [{"type": "shell","args": ["--directory","/home/ubuntu/catkin_ws"],"problemMatcher": ["$catkin-gcc"],"command":"catkin_make","group": "build","label": "catkin_make: build_by_vscode","presentation": {"reveal": "always"}}]
}
    1. c_cpp_properties.json:用于配置C++编译ROS时的一些C++特有的路径和代码规范,配置本次配置好,后续可能出现修改地方主要在于这些路径位置。
// /home/ubuntu/catkin_ws/.vscode/c_cpp_properties.json
{"configurations": [{"browse": {"databaseFilename": "","limitSymbolsToIncludedHeaders": true},"includePath": ["/opt/ros/melodic/include/**","${workspaceFolder}/devel/include/**",//配置成自身工作空间的devel文件夹的路径;//目的是指向自定义msg/action/srv等路径."/usr/include/**"],"name": "ROS","cppStandard":"c++17","intelliSenseMode": "gcc-x64","compilerPath": "/usr/bin/gcc","cStandard": "c11"}],"version": 4
}
    1. settings.json:用于配置Python编译ROS时的一些Python包路径和规范,配置好之后,可能出现变换的地方也在这些路径位置。
// /home/ubuntu/catkin_ws/.vscode/settings.json
{"python.autoComplete.extraPaths": ["/opt/ros/melodic/lib/python2.7/dist-packages","${workspaceFolder}/devel/lib/python2.7/dist-packages"// 如果是高版本ROS可能是Python3,按照自定义消息一样查看中间文件位置确定],"cmake.configureOnOpen": true,"cmake.sourceDirectory": "${workspaceFolder}/src"
}

3.1.1.3 VS Code运行ROS1的方法

  1. 编译运行:
  • 方法一:使用快捷键或者在VS Code的编译器【终端】–【运行生成任务】即Crtl+Shift+B,点击之后选择catkin_make: build_by_vscode(在task.json的label名字)即可编译整个工作空间。
  • 方法二:在VS Code下面的终端(或者在【终端】–【新终端】即Crtl+Shift+`)cd 到catkin_ws下进行catkin_make编译

3.1.1.3 参考资料

  1. 参考文献:
    VS Code的tast.json查考文件;
    VS Code的C++查考文件;
    VS Code的Python查考文件;
    【奥特学园】ROS机器人入门课程《ROS理论与实践》零基础教程

3.1.2 使用VScode编译C++文件

  1. catkin_ws/src/目录下右键create catkin package创建包,然后按照提示命名如test,然后输入依赖项roscpp rospy std_msgs

  2. catkin_ws/src/test/src下右键新建test_c.cpp文件,编辑test_c.cpp文件。

// test_c.cpp文件用于测试ROS1环境
#include "ros/ros.h"
int main(int argc, char* argv[])
{ros::init(argc,argv,"i_am_nodename");ROS_INFO("HELLO");return 0;
}
  1. 配置catkin_ws/src/test/src/CMakeLists.txt文件,然后编译运行。
    1. 在136行,取消 add_executable(${PROJECT_NAME}_node src/test_node.cpp)的注释,修改为 add_executable(i_am_nodename src/test_c.cpp)
    1. 其次在149-151行的target_link_libraries(${PROJECT_NAME}_node…) 修改为 target_link_libraries(i_am_nodename…)即可
    1. 编译运行(直接在VScode的终端下的+号新建终端,输入roscore,新建终端输入rosrun test i_am_nodename即可查看INFO的消息)。

3.1.3使用VScode编译Python文件

  1. 之前同编译C++是Step1-Step3,此时在catkin_ws/src/test/文件夹下创建Python文件夹scripts,在scripts文件夹里新建Python文件test_p.py
  2. 编写Python程序,赋予可执行权限,然后运行客户端roscore,最后rosrun test test_p.py即可。
#! /usr/bin/env python
import rospy
if __name__ =='__main__':rospy.init_node("test_p")rospy.loginfo("ok")

Tips:
在Ubuntu20.04版本的ROS需要配置CMakeLists文件,大约在161行处,类似C++一样添加Python文件的位置。同时对于高版本的Python编译ROS在Python文件头部是没有#!/usr/bin/env
python,采用命令:sudo ln -s /usr/bin/python3 /usr/bin/python创建Python的连接。

3.2 ROS1动作编程

3.2.1 动作编程模型

在任何ROS的大型系统中,如果向节点发送请求以执行某些任务,最后收到对请求的回复,这一操作主要是通过ROS的服务编程实现,但是如果服务需要很长时间来执行,用户可能希望能够在执行期间取消请求或获得有关请求进展情况的定期反馈,基本的服务编程的应答模式是满足不了的,因此ROS提供actionlib即动作编程完成这些操作。

  • 动作编程的作用:针对服务编程的应答模式的提升,在服务端执行过程中能够取消或者获得服务器状态,动作编程一般适用于耗时的请求响应场景,用以获取连续的状态反馈。

  • 动作编程的例子:如巡检机器人导航过程中,从A到B的导航过程,应该是一个动作编程,即目标是B,在A到B时,提供导航状态。

在这里插入图片描述
在动作编程中,客户端发送目标(goal)或者取消指令(cancel)给服务端,服务端提供状态(status)、实时反馈(feedback)和结果(result)。

官方以移动机器人为例解释goal、feedback和result,即

  • 1)目标(goal):为了使用动作完成任务,引入了可以由 ActionClient 发送到 ActionServer 的目标的概念。在移动基地的情况下,目标是 PoseStamped 消息,其中包含有关机器人应移动到世界何处的信息,在官方洗碗例子中对目标的描述也是需要选择的那个洗碗工是谁。
  • 2)回馈(feedback):服务器持续反馈 ActionClient目标的增量进度。对于移动机器人,这可能是机器人沿路径的当前位置。
  • 3)结果(result):目标完成后,结果从 ActionServer 发送到 ActionClient,这与反馈不同,因为它只发送一次。当客户端请求的目的(goal)是提供某种信息时,这就非常有用。对于移动机器人,结果不是很重要,但它可以是机器人的最终位置(不代表就是目的地)。

3.2.2 动作编程基础示例

动作编程的基本思想和自定义的消息话题编程是一致的。

动作编程内容:洗盘子动作编程,两个节点,一个为客户端一个为服务端,客户端发送数字1(代码实现)给给服务端,作为选择哪个洗碗工,服务端接收到之后持续反馈进度给客户端,最后发送数字100(代码实现)作为结果返回。

3.2.2.1 使用VS Code创建动作编程项目

(一)使用VS Code新建功能包:

  1. 打开VS Code和工作空间,新建动作编程功能包并创建ROS文件夹结构。
    1. 打开VS Code和工作空间,在工作空间catkin_ws下输入命令code .打开VS Code,打开后如果出现提示Select a kit for catkin_ws,则选择第一项Scan for kit即可。

在这里插入图片描述

    1. 新建动作编程功能包,右键工作空间catkin_ws的src目录,选择create catkin package然后在VS Code的提示下输入包名action_communication,回车之后输入依赖项roscpp rospy std_msgs即可

在这里插入图片描述

    1. 新建ROS结构的文件夹,即在功能包下新建action文件夹和scripts文件夹。

3.2.2.2 配置action动作文件

(二)定义action动作文件:

  1. 定义动作文件。在action_communication/action下创建自定义动作文件.action,这里为DoDishes.action文件。其中的内容分为三个部分:
  • 第一部分goal对应目标数据,即客户端发布数据。
  • 第二部分result定义结果,服务端应答给客户端的结果。
  • 第三部分是反馈部分,服务端反馈一些信息给客户端。
# catkin_ws/src/action_communication/action/DoDishes.action
# Define the goal
uint32 dishwasher_id  # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message
float32 percent_complete

(三)配置action文件

  • 配置msg文件包括在package.xml和CMakeList.txt配置两部分。
  1. 在package.xml添加依赖项actionlib和actionlib_msgs四项,二者都是依赖项和执行依赖项。
// /catkin_ws/src/action_communication/package.xmlactionlibactionlib_msgsactionlibactionlib_msgs
  1. 在功能包的CmakeLists.txt添加编译选项,包括四部分。
    1. 添加编译依赖项功能包:find_package(catkin REQUIRED COMPONENTS ..+ 依赖项功能包),大约在第10行,添加actionlibactionlib_msgs两项:
# /catkin_ws/src/action_communication/CMakeLists.txt
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsactionlibactionlib_msgs
)
    1. 添加自定义action文件:add_action_files(FILES 文件名),大约在第66行,如此时的文件名为DoDishes.action
# /catkin_ws/src/action_communication/CMakeLists.txt
add_action_files(FILESDoDishes.action
)
    1. 添加action的编译依赖项std_msgsactionlib_msgs:generate_messages(DEPENDENCIES 依赖项名),大约在第71行,即表示在编译msg时候得依赖于std_msgs
# /catkin_ws/src/action_communication/CMakeLists.txt
generate_messages(DEPENDENCIESstd_msgsactionlib_msgs
)
    1. 添加执行时的依赖:catkin_package的关键字CATKIN_DEPENDS后+包,大约在106行,添加actionlib和actionlib_msgs如:
# /catkin_ws/src/action_communication/CMakeLists.txt
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES action_communicationCATKIN_DEPENDS roscpp rospy std_msgs actionlib actionlib_msgs
#  DEPENDS system_lib
)

(四)编译action文件,查看中间文件:

  1. 在工作空间下编译,此时在工作空间的devel目录会多出几个文件,如C++的中间文件在/home/ubuntu/catkin_ws/devel/include/功能包名/文件夹下,Python的中间文件在/home/ubuntu/catkin_ws/devel/lib/python2.7/dist-packages/功能包名/msg

3.2.2.3 C++实现action基本编程

(五)C++实现action基本编程:

  1. 实现动作服务器
    1. 首先在工作空间的根目录的src文件夹里创建服务程序DoDishes_server_cpp.cpp
# catkin_ws/src/action_communication/src/DoDishes_server_cpp.cpp
#include 
#include 
#include "action_communication/DoDishesAction.h"typedef actionlib::SimpleActionServer Server;// 收到action的goal后调用该回调函数
void callback(const action_communication::DoDishesGoalConstPtr& goal, Server* server)
{ros::Rate r(1);action_communication::DoDishesFeedback feedback;ROS_INFO("收到客户端的goal,洗碗工 %d 开始洗盘子.", goal->dishwasher_id);// 假设洗盘子的进度,并且按照1hz的频率发布进度feedbackfor(int i=1; i<=10; i++){feedback.percent_complete = i * 10;server->publishFeedback(feedback);ROS_INFO("feedback ing ...");r.sleep();}// 当action完成后,向客户端返回结果ROS_INFO("洗碗工完成了工作,发送result(100个)给客户端.");action_communication::DoDishesResult res;res.total_dishes_cleaned = 100;server->setSucceeded(res);
}int main(int argc, char** argv)
{setlocale(LC_ALL,"");ros::init(argc, argv, "do_dishes_server");ros::NodeHandle nh;// 定义一个服务器Server server(nh, "do_dishes", boost::bind(&callback, _1, &server), false);// 服务器开始运行ROS_INFO("action服务端启动,等待指令");server.start();ros::spin();return 0;
}
    1. 创建客户端文件DoDishes_client_cpp.cpp
# catkin_ws/src/l_t/src/DoDishes_client_cpp.cpp
#include 
#include "action_communication/DoDishesAction.h"typedef actionlib::SimpleActionClient Client;// 当action完成后会调用该回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,const action_communication::DoDishesResultConstPtr& result){ROS_INFO("result:洗碗工把盘子已经洗完啦!洗了%d个",result->total_dishes_cleaned);ros::shutdown();
}// 当action激活后会调用该回调函数一次
void activeCb(){ROS_INFO("服务器已经打开,可以执行任务");
}// 收到feedback后调用该回调函数
void feedbackCb(const action_communication::DoDishesFeedbackConstPtr& feedback)
{ROS_INFO("feedback:洗盘子的进度:%f", feedback->percent_complete);
}int main(int argc, char** argv)
{setlocale(LC_ALL,"");ros::init(argc, argv, "do_dishes_client");// 定义一个客户端Client client("do_dishes", true);// 等待服务器端client.waitForServer();ROS_INFO("goal:选择员工1洗盘子:");// 创建一个action的goalaction_communication::DoDishesGoal goal;goal.dishwasher_id = 1;// 发送action的goal给服务器端,并且设置回调函数client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);ros::spin();return 0;
}
    1. 配置动作的服务端和客户端代码的编译选项。在功能包的目录下,打开其CMakeLists.txt文件。
# catkin_ws/src/action_communication/CMakeLists.txt
add_executable(dodisher_server_cpp src/DoDishes_server_cpp.cpp)
add_executable(dodisher_client_cpp src/DoDishes_client_cpp.cpp)add_dependencies(dodisher_server_cpp ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(dodisher_client_cpp ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})target_link_libraries(dodisher_server_cpp ${catkin_LIBRARIES})
target_link_libraries(dodisher_client_cpp ${catkin_LIBRARIES})
    1. 在工作空间的根目录下进行编译操作。
    1. 运行服务编程。首先打开一个终端输入roscore,打开ROS,再新建一个终端输入rosrun action_communication DoDishes_server运行服务程序。最后新建终端输入rosrun action_communication DoDishes_client即运行客户端并执行动作操作。

在这里插入图片描述

3.2.2.4 Python实现action基本编程\

(六)Python实现action基本编程:

  1. 在scripts文件夹创建Python服务端文件
    1. DoDishes_server_py.py,代码见注释

#!/usr/bin/env python
# -*- coding: utf-8 -*-# catkin_ws/src/action_communication/scripts/DoDishes_server_py.pyimport rospy
import actionlib
from action_communication.msg import *class myActionServer:def __init__(self):# 1.创建服务器,执行服务器回调函数self.server = actionlib.SimpleActionServer("dodishes", DoDishesAction, self.serverCb, False)self.server.start()rospy.loginfo("服务端启动")def serverCb(self,goal):id = goal.dishwasher_idrospy.loginfo("收到来自客户端的goal,洗碗工 %d 开始工作",id)rate = rospy.Rate(1)for i in range(1, 10):rospy.loginfo("feedback ing...")feedBack_obj = DoDishesFeedback()feedBack_obj.percent_complete = iself.server.publish_feedback(feedBack_obj)rate.sleep()res = DoDishesResult()res.total_dishes_cleaned = 100rospy.loginfo("洗碗工完成了工作,发送result(100个)给客户端.")self.server.set_succeeded(res)if __name__ == "__main__":rospy.init_node("action_server_py")server = myActionServer()rospy.spin()
    1. 编写客户端DoDishes_client_py.py文件
#!/usr/bin/env python
# -*- coding: utf-8 -*-# catkin_ws/src/action_communication/scripts/DoDishes_client_py.pyimport rospy
import actionlib
from action_communication.msg import *def result_cb(state,result):if state == actionlib.GoalStatus.SUCCEEDED:rospy.loginfo("result:洗碗工把盘子已经洗完啦!洗了%d个",result.total_dishes_cleaned)def active_cb():rospy.loginfo("服务被激活....")def feedback_cb(f):rospy.loginfo("当前进度:%.2f",f.percent_complete)if __name__ == "__main__":# 2.初始化 ROS 节点rospy.init_node("action_client_py")# 3.创建 action Client 对象client = actionlib.SimpleActionClient("dodishes",DoDishesAction)# 4.等待服务client.wait_for_server()# 5.组织目标对象并发送goal_obj = DoDishesGoal()goal_obj.dishwasher_id = 1rospy.loginfo("goal:选择员工1洗盘子:")client.send_goal(goal_obj,result_cb,active_cb,feedback_cb)# 6.编写回调, 激活、连续反馈、最终响应# 7.spinrospy.spin()
    1. 给Python文件赋予可执行权限,在script文件夹下输入命令sudo chmod +x *.py即可赋予所有Python可执行权限。
    1. 运行py文件

在这里插入图片描述

3.2.3 动作编程总结

3.2.3.1 动作编程的顺序流程

  1. 动作编程的顺序流程:
    1. 在action文件夹编写自定义action文件,配置package.xml文件包括actionlib和actionlib_msg,分别包括四项;
    1. 配置CMakeList.txt文件包括
      1. 添加编译依赖项功能包find_package
      1. 添加自定义action文件add_action_files
      1. 添加action的编译依赖项generate_messages里添加std_msgs和actionlib_msgs
      1. 添加执行时的依赖catkin_package里添加actionlib actionlib_msgs
    1. C++代码:
      1. 添加头文件(头文件为功能包名字/自定义动作.h)
      1. 正常编写代码;
      1. CMakeList.txt进行配置(不仅有add_executable和target_link_libraries还包括add_dependencies);
      1. 编译运行;
    1. Python代码:
      1. 添加包from 功能包名.msg import *
      1. 正常代码编写;②CMakeList.txt进行配置(目前配置不配置影响不大);
      1. 赋予py文件可执行权限
      1. 编译运行。

3.2.3.2 动作编程逻辑

  1. 编程逻辑顺序:

在这里插入图片描述

3.2.4 参考

  • ROS-WIKI:actionlib package summary(DoDishes)
  • 高级action教程-ROS-WIKI:cn/actionlib_tutorials/Tutorials
  • B站视频:【奥特学园】ROS机器人入门课程《ROS理论与实践》零基础教程

相关内容

热门资讯

海昌海洋公园跌超14%,公司拟... 6月3日,港股海昌海洋公园跌超14%,公司拟折让约46.43%发行51亿股,净筹约22.84亿港元。
从不“内卷”的添可,找到了“对... 每年618大促,都是观察消费趋势的绝佳窗口,而家电市场又是风向标一样的存在。今年尤为明显的是,经历了...
拿捏两位影帝的她,怎么变成了唯... 林志玲一直都是自信优雅的代名词,无论是走红毯抬头挺胸的优雅,还是综艺节目里的从容应对,她的每个动作都...
创新药概念异动拉升,华海药业等... 6月3日,创新药概念异动拉升,华海药业、万邦德、海南海药涨停,冠昊生物涨逾10%,千红制药、联化科技...
车圈大佬掀桌子,赔本赚吆喝的“... 这番言论在社交网络迅速发酵,一石激起千层浪,多家车企连续三个股市交易日股价下跌。大家都在猜测魏建军到...
国际金价再次站上3400美元,... 6月2日晚,受国际政治经济形势影响,COMEX黄金再次站上3400美元/盎司。6月3日A股开盘后,沪...
经销商要“分手”,“极核”厂家... 最近,盐城市民王先生向我们荔枝新闻中心求助说,去年他加盟销售一款品牌电动车,后来由于销量惨淡,他自行...
A股低开:稳定币概念股活跃,翠...   中新经纬6月3日电 3日早盘,A股三大指数小幅低开。上证指数跌0.22%,报3340.07点;深...
恒生指数开盘涨0.53%,恒生... 6月3日,恒生指数开盘涨0.53%,恒生科技指数涨0.54%。翰森制药涨近4%,与Regeneron...
科创板人工智能ETF(5889... 6月3日,三大指数集体低开,科技方向震荡走高。截至发稿,相关ETF方面,科创板人工智能ETF(588...
烧掉一半净利润,拼多多想培育怎... 当外部不确定性日益增加,为中小商家提供“避风港”和“助推器”,助力其度过周期波动,这种“授人以渔”的...
“苏超”霸屏,中国可以靠江苏搞... 01 经济独立,城市人格独立最近一段时间,无相君的朋友圈和微信群都被“苏超”霸屏了。几乎每天一个热搜...
【开盘】A股三大股指集体低开,... 6月3日,A股三大股指集体低开。其中,沪指跌0.22%报3340.07点,深成指跌0.34%报100...
刚刚!深交所宣布:调整→ 深交... 6月3日,深交所发布公告,根据指数编制规则,深圳证券交易所和深圳证券信息有限公司决定于2025年6月...
两宗券商“老鼠仓”曝光→ 股市... 地方证监局最新披露的罚单,让两起券商从业人员“老鼠仓”案件浮出水面,2家龙头券商中信证券、华泰证券牵...
大热IP经济难“包治百病”,明... 近日,IP经济、黄金概念股表现活跃,明牌珠宝股价涨停。5月29日,明牌珠宝发布公告称,公司股票连续两...
银河证券:港股市场情绪仍需观察... 银河证券发布港股策略研报称,港股市场情绪仍需观察关税政策走向。近期国际贸易局势反复无常,前景仍然不明...
银河证券:短期内A股市场或仍维... 银河证券发布A股策略研报称,近期板块轮动速度加快,行情震荡格局尚未改变,市场成交额未出现明显放量,仍...
哪吒汽车,注定掉队 哪吒汽车,... 定焦One(dingjiaoone)原创特约作者 | 胡锟编辑 | 魏佳从登顶新势力销量冠军,到几乎...
牛市早报|端午假期预计全社会跨... 【市场数据】截至5月30日收盘,上证综指跌0.47%,报3347.49点;科创50指数跌0.94%,...