ROS:VScode开发话题(msg)、服务(srv)、动作(action),解决 无法打开源文件

news2024/12/26 2:48:01

 一.解决 无法打开源文件

出错原因:系统没有找到.h文件对应的路径。

在编写完msg、srv、action文件后,要进行编译(catkin_make) .

编译之后,msg、srv、action会生成相应的.h文件

其对应的.h文件目录在devel/include/功能包下,如下:

 解决方法:将.h文件目录加入json文件中即可。

 然后保存json文件,之后关闭VScode,然后重新打开,就好了。

二.话题

1.案例一

talker.cpp

#include "ros/ros.h"
#include <sstream>
#include "std_msgs/String.h"

int main(int argc, char** argv){
    //ROS结点初始化
    ros::init(argc, argv, "talker");
    //创建节点句柄
    ros::NodeHandle nh;
    //创建一个publisher,发布名为chatter的topic,消息类型为std_msgs,队列长度为1000
    ros::Publisher chatter_pub=nh.advertise<std_msgs::String>("chatter",1000);
    //设置循环频率
    ros::Rate loop_Rate(10);
    int count=0;
    while(ros::ok()){
        //初始化std_msgs::String类型的消息
        std_msgs::String msg;
        std::stringstream ss;
        ss<<"hello world:"<<count;
        msg.data=ss.str();
        //发布消息
        ROS_INFO("%s",msg.data.c_str());
        chatter_pub.publish(msg);
        //回调函数:执行一次回调函数,在这里其实没什么用
        ros::spinOnce();
        //按照循环频率延时
        loop_Rate.sleep();
        ++count;
    }
    return 0;
}

listener.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"

//接收到topic后,会进入回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg){
    //打印topic信息
    ROS_INFO("I heard [%s]",msg->data.c_str());
}

int main(int argc,char **argv){
    //初始化ros节点
    ros::init(argc,argv,"listener");
    //创建节点句柄
    ros::NodeHandle nh;
    //创建一个subscribler,订阅topic为“chatter”,注册回调函数chatterCallback
    ros::Subscriber sub=nh.subscribe("chatter",1000,chatterCallback);
    //循环等待执行回调函数
    ros::spin();
    return 0;
}

CMakeList.txt

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

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

2.案例二:自定义msg文件

创建名为msg的文件夹

定义msg文件,name、sex、age是变量,unknow、male、female是常量:

Person.msg

# 变量
string name
uint8 sex
uint8 age
#常量
uint8 unknow=0
uint8 male=1
uint8 female=2

package.xml 添加功能包依赖:

  <!--添加功能包依赖:msg、srv-->
  <build_depend>std_msgs</build_depend>
  <exec_depend>std_msgs</exec_depend>
  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

其中:部分ROS版本中 exec_depend需要改为run_depend

CMakeLists.txt添加编译选项:

find_package(catkin REQUIRED COMPONENTS
  message_generation
)
add_message_files(
  FILES
  Person.msg
)
generate_messages(
  DEPENDENCIES
  std_msgs
)
catkin_package(
 CATKIN_DEPENDS geometry_msgs roscpp std_msgs message_runtime
)

 之后catkin_make

查看自己定义的msg

rosmsg show Person

三.服务

创建名为srv的文件夹

定义srv文件,a、b是请求数据,sum是服务数据,也就是a、b传给服务器,服务器相加sum传给客户端:

AddTwoInts.srv

#客户端
int64 a
int64 b
---
#服务器
int64 sum

package.xml 添加功能包依赖:

  <!--添加功能包依赖:msg、srv-->
  <build_depend>std_msgs</build_depend>
  <exec_depend>std_msgs</exec_depend>
  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

其中:部分ROS版本中 exec_depend需要改为run_depend

CMakeLists.txt添加编译选项:

find_package(catkin REQUIRED COMPONENTS
  message_generation
)
add_service_files(
  FILES
  AddTwoInts.srv
)
catkin_package(
 CATKIN_DEPENDS geometry_msgs roscpp std_msgs message_runtime
)

查看自己定义的srv文件:

rossrv show AddTwoInts.srv 

client.cpp

#include <cstdlib>
#include "ros/ros.h"
#include "robot_setup_tf/AddTwoInts.h"

int main(int argc,char** argv){
    //ROS节点初始化
    ros::init(argc,argv,"add_two_ints_client");
    //从终端命令行获取两个加数
    if(argc!=3){
        ROS_INFO("usage: add_two_ints_client X Y");
        return 1;
    }
    //创建节点句柄
    ros::NodeHandle nh;
    //创建一个client,请求add_two_service
    //service消息类型是robot_setup_tf::AddTwoInts
    ros::ServiceClient client=nh.serviceClient<robot_setup_tf::AddTwoInts>("add_two_ints");
    //创建robot_setup_tf::AddTwoInts类型的消息对象
    robot_setup_tf::AddTwoInts srv;
    srv.request.a=atoll(argv[1]);
    srv.request.b=atoll(argv[2]);
    //发布service请求,等待加法运算
    if(client.call(srv)){
        ROS_INFO("Sum=%ld",(long int)srv.response.sum);
    }else{
        ROS_INFO("Failed to call service add_two_ints");
        return 1;
    }
    return 0;
}

server.cpp 

#include "ros/ros.h"
#include "robot_setup_tf/AddTwoInts.h"

//回调函数,client传进a、b,完成加法后返回给sum
bool add(robot_setup_tf::AddTwoInts::Request  &req, robot_setup_tf::AddTwoInts::Response &res)
{
    res.sum=req.a+req.b;
    ROS_INFO("request: x=%ld, y=%ld",(long int)req.a,(long int)req.b);
    ROS_INFO("response: sum=%ld",(long int)res.sum);
    return true;
}
int main(int argc,char** argv){
    //ROS节点初始化
    ros::init(argc,argv,"add_two_ints_server");
    //创建节点句柄
    ros::NodeHandle nh;
    //创建一个名为"add_two_ints"的server,注册回调函数为add()
    ros::ServiceServer service=nh.advertiseService("add_two_ints",add);
    //循环等待回调函数
    ROS_INFO("Ready to add two ints");
    ros::spin();
    return 0;
}

CMakeList.txt

add_executable(server src/server.cpp)
target_link_libraries(server ${catkin_LIBRARIES})
add_dependencies(server ${PROJECT_NAME}_gencpp)

add_executable(client src/client.cpp)
target_link_libraries(client ${catkin_LIBRARIES})
add_dependencies(client ${PROJECT_NAME}_gencpp)

运行:

roscore
rosrun robot_setup_tf server
rosrun robot_setup_tf client 4 5

四.动作

创建名为action文件夹

创建action文件

DoDishes.action

#goal,定义目标信息,客户端
uint8 dishwasher_id
#Specify which dishwasher we want to use
---
#result,定义结果信息,服务器
uint8 total_dishes_cleaned
---
#feedback,定义周期反馈的消息
float32 percent_complete

package.xml添加功能包依赖

  <!--添加功能包依赖:action-->
  <build_depend>actionlib</build_depend>
  <build_depend>actionlib_msgs</build_depend>
  <exec_depend>actionlib</exec_depend>
  <exec_depend>actionlib_msgs</exec_depend>

CMakeLists.txt添加编译选项:

find_package(catkin REQUIRED COMPONENTS
  actionlib_msgs
  actionlib
)
add_action_files(
  FILES
  DoDishes.action
)
generate_messages(
  DEPENDENCIES
  actionlib_msgs
)

DoDishes_Client.cpp

#include <actionlib/client/simple_action_client.h>
#include "robot_setup_tf/DoDishesAction.h"

typedef actionlib::SimpleActionClient<robot_setup_tf::DoDishesAction> Client;
//当action完成后会调用该回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,const robot_setup_tf::DoDishesResultConstPtr& result){
    ROS_INFO("Yay!The dishes are now clean");
    ros::shutdown();
}
//当action激活后会调用该回调函数一次
void activeCb(){
    ROS_INFO("Goal just went active");
}
//收到feedback后调用该回调函数
void feedbackCb(const robot_setup_tf::DoDishesFeedbackConstPtr& feedback){
    ROS_INFO("percent_complete: %f",feedback->percent_complete);
}
int main(int argc,char** argv){
    ros::init(argc,argv,"do_dishes_client");
    //定义一个客户端
    Client client("do_dishes",true);
    //等待服务器端
    ROS_INFO("Waiting for action server to start.");
    client.waitForServer();
    ROS_INFO("Action server started,sending goal.");
    //创建一个action的goal
    robot_setup_tf::DoDishesGoal goal;
    goal.dishwasher_id=1;
    //发送action的goal给服务器端,并且设置回调函数
    client.sendGoal(goal,&doneCb,&activeCb,&feedbackCb);
    ros::spin();
    return 0;
}

DoDishes_Server.cpp

#include "ros/ros.h"
#include <actionlib/server/simple_action_server.h>
#include "robot_setup_tf/DoDishesAction.h"

typedef actionlib::SimpleActionServer<robot_setup_tf::DoDishesAction> Server;

//收到action的goal后调用该回调函数
void execute(const robot_setup_tf::DoDishesGoalConstPtr& goal,Server* as){
    ros::Rate r(1);
    robot_setup_tf::DoDishesFeedback feedback;
    ROS_INFO("Dishwasher %d is working.",goal->dishwasher_id);
    //假设洗盘子的进度,并且按照1hz的频率发布进度feedback
    for(int i=1;i<=10;i++){
        feedback.percent_complete=i*10;
        as->publishFeedback(feedback);
        r.sleep();
    }
    //当action完成后,向客户端返回结果
    ROS_INFO("Dishwasher %d finish working.",goal->dishwasher_id);
    as->setSucceeded();
}
int main(int argc,char** argv){
    ros::init(argc,argv,"do_dishes_server");
    ros::NodeHandle n;
    //定义一个服务器
    Server server(n,"do_dishes",boost::bind(&execute,_1,&server),false);
    //服务器开始运行
    server.start();
    ros::spin();
    return 0;
}

CMakeList.txt

add_executable(DoDishes_Client src/DoDishes_Client.cpp)
target_link_libraries( DoDishes_Client ${catkin_LIBRARIES})
add_dependencies(DoDishes_Client ${${PROJECT_NAME}_EXPORTED_TARGETS})

add_executable(DoDishes_Server src/DoDishes_Server.cpp)
target_link_libraries( DoDishes_Server ${catkin_LIBRARIES})
add_dependencies(DoDishes_Server ${${PROJECT_NAME}_EXPORTED_TARGETS})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/592209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一款可发布236T全球影像,构建“离线版地球”的GIS产品

概述 《水经注地图服务&#xff08;WeServer&#xff09;》是一款可快速发布全国乃至全球海量卫星影像的地图发布服务产品&#xff0c;该产品完全遵循OGC相关协议标准&#xff0c;是一个基于若干项目成功经验总结的产品。它可以轻松发布100TB级海量卫星影像&#xff0c;从而使…

Poco 观察者模式(Observer Pattern) 订阅和发布某个感兴趣的通知, Observer和Notification

Poco 观察者模式&#xff08;Observer Pattern&#xff09; 订阅和发布某个感兴趣的通知&#xff0c; Observer和Notification flyfish 先写一个实例代码 #include "Poco/NotificationCenter.h" #include "Poco/Notification.h" #include "Poco/Ob…

Jetpack Hilt 框架的基本使用

什么是 Hilt&#xff1f; Hilt 是一个功能强大、用法简单的依赖注入框架&#xff0c;于 2020 年加入到 Jetpack 家族中。它是 Android 团队联系了 Dagger2 团队&#xff0c;一起开发出来的一个专门面向 Android 的依赖注入框架。相比于 Dagger2&#xff0c;Hilt 最明显的特征就…

Flutter 笔记 | Flutter 核心原理(四)绘制流程

Vsync 机制 在分析首帧渲染的过程中&#xff0c;可以发现Render Tree的渲染逻辑&#xff08;handleDrawFrame方法&#xff09;是直接执行的&#xff0c;但是后续每一帧的渲染都是Framework的主动调用导致的吗&#xff1f;实际上并非如此&#xff0c;也不能如此。试想一下&…

【017】C++ 指针变量详解,理解指针变量

C 指针变量详解 引言一、内存概述二、指针变量2.1、地址和指针变量的关系2.2、定义指针变量2.3、指针变量的初始化2.4、指针类型2.5、案例2.6、注意事项 三、数组元素的指针3.1、概述3.2、在使用中 [ ] 就是 *()的缩写3.3、指向同一数组的元素的两个指针变量间的关系 四、字符串…

6月销量狂欢季:测评自养号助力,引爆跨境电商销量!

随着夏季的到来&#xff0c;跨境电商卖家们迎来了一个极佳的销售机会。6月作为夏季的重要节点&#xff0c;各种活动和节日都为卖家们提供了引流和销售的良机。然而&#xff0c;要真正实现销量的爆发&#xff0c;单纯依靠传统的营销手段可能难以达到预期的效果。在这篇文章中&am…

AI+边缘,是如何加速制造转型的?

在现代工业中&#xff0c;提起智慧工厂、智能制造有一个经久不衰的话题&#xff0c;那便是IT和OT的融合。 IT&#xff08;Information Technology&#xff09;部门专注于处理数据&#xff0c;整个业务系统需要它来维持运营。而OT&#xff08;Operation Technology&#xff09;…

2023智源大会议程公开 |智能的物质基础专题论坛

6月9日&#xff0c;2023北京智源大会&#xff0c;将邀请这一领域的探索者、实践者、以及关心智能科学的每个人&#xff0c;共同拉开未来舞台的帷幕&#xff0c;你准备好了吗&#xff1f;与会知名嘉宾包括&#xff0c;图灵奖得主Yann LeCun、图灵奖得主Geoffrey Hinton、OpenAI创…

基于OA的采购系统和专业的招标采购管理系统区别

当前采购信息化百家争鸣&#xff0c;既有初级版的审批和记录电子化&#xff0c;也有中级版的业务全流程电子化&#xff0c;还有升级版的数智化创新形式&#xff08;如电商平台、智能评标、供应商风险评估、专家行为画像、大数据统计分析等&#xff09;。 近年来&#xff0c;招标…

Zotero文献在word中的引用

前提 确保你的word中有Zotero插件。如下图示&#xff1a; 具体操作 Step01 Zeroto中下载样式 在Zotero中添加相应的文献样式&#xff0c;具体如下&#xff1a; 打开Zotero“编辑”中的首选项&#xff0c;打开“引用”&#xff0c;从“获取更多样式”中搜寻你想要的文献样…

JAVA开发(手工处理数据库表数据的一些示例算法)

背景&#xff1a; 在项目开发中&#xff0c;有时候需要手动处理一下数据库表的数据。涉及到数据得到备份、恢复&#xff0c;清洗&#xff0c;计算&#xff0c;合并等操作。 举例记录一下最近对数据的一些处理过程。 1、对数据表进行数据量统计 select count(*) from table…

API接口的重要性和好处|附加淘宝api接口展示案例|商品数据采集演示

随着互联网的发展&#xff0c;API接口已经成为许多企业进行信息交流和数据管理的重要工具。通过API接口&#xff0c;企业之间能够快速、可靠地进行数据传输和信息共享&#xff0c;从而提高了企业的生产效率和服务质量。以下是API接口的重要性和好处的文章&#xff1a; 1.提高生…

Zabbix从入门到精通以及案例实操系列

1、Zabbix入门 1.1、Zabbix概述 Zabbix是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix使用灵活的通知机制&#xff0c;允许用户为几乎任何事件配置基于邮件的告警。这样可以快速反馈服务器的问题。基于已存储的数据&#xff0c;Zabbix提供了出色的报告和…

5.2.2 IP地址的分配和使用

5.2.2 IP地址的分配和使用 我们已经学习了分类的IP地址&#xff0c;我们就来一起学习一下在实际的应用中IP地址是如何分配和使用的。在最初的IP地址编址方案中&#xff0c;因特网的每个物理网络都必须被分配一个唯一的网络地址&#xff0c;该网络上的主机每个主机都使用该网络…

Jenkins——maven 插件配置

文章目录 一、Maven 的集成二、在执行job的机器上安装好maven三、下载 maven 插件四、配置全局工具五、Maven 相关使用1、新建 job2、自由风格 job 中命令行使用 mvn 命令3、构建操作 一、Maven 的集成 在 Jenkins 上构建 Java 项目时需要使用 Maven 来进行构建打包 二、在执…

【笔记】微机原理及接口技术2 -- 存储器与IO接口技术

目录 存储器存储器分类存储器常用性能指标半导体存储器随机存取存储器 RAM动态随机存储器 DRAM三态缓冲器只读存储器 ROM存储器与 CPU 链接存储空间扩展方式内存寻址方法&#xff08;片选方式&#xff09;存储器小节思考题 I/O 接口技术IO 接口概述IO 端口编址寻址输入输出控制…

让仓库“零误差”,WMS仓库管理系统助力供应链升级

现代供应链的核心是以消费者和库存管理为中心&#xff0c;通过降低库存来提高产品的流通速度和供应链效率。而在信息技术快速发展的今天&#xff0c;企业的库存管理也面临着新的挑战&#xff1a; 1.仓库货品种类多&#xff0c;数量多&#xff0c;且摆放混乱&#xff0c;加大了查…

RWKV – transformer 与 RNN 的强强联合

在 NLP (Natural Language Processing, 自然语言处理) 领域&#xff0c;ChatGPT 和其他的聊天机器人应用引起了极大的关注。每个社区为构建自己的应用&#xff0c;也都在持续地寻求强大、可靠的开源模型。自 Vaswani 等人于 2017 年首次提出 Attention Is All You Need 之后&am…

SAP-MM-发票行项目格式

目的&#xff1a;SAP提供标准事物代码屏幕变式&#xff0c;但因各个公司运用的方式不同&#xff0c;可采用屏幕变式进行自定义&#xff0c;方便最终用户使用&#xff1b; 方案&#xff1a;采用屏幕变式T-CODE&#xff1a;OLMRLIST对相应事物代码进行调整&#xff1a; 案例&am…

ASCII Unicode UTF-8等等编码介绍

目录 背景 Unicode UTF-8 ISO-8859-1 GB2312和GBK ANSI UTF-16LE 和UTF-16BE UTF-16 LE 和BE是什么 如何处理字节序问题 "带有BOM的UTF-8"又是什么&#xff1f; 背景 由于计算机是美国人发明的&#xff0c;因此最早只有127个字母被编码到计算机中&#x…