【ROS】 ubuntu16.04下vs code实现ros下服务数据的定义和使用


一、工作空间的创建和注意事项


本章节主要内容是以服务数据的定义与使用为主,使用的IDE是vs code,关于ubuntu系统下vs code的安装可以参考我的另一篇博客,链接如下

https://blog.csdn.net/weixin_45417246/article/details/115444048.

新建文件夹catkin_person_server,并在文件夹下新建src文件夹,这里可以不进行工作空间的初始化,并用vs code打开catkin_person_server文件,按住Ctrl+Tab+~键,在vs code中打开终端,在/fjy/catkin_person_server路径下进行编译,并添加环境变量

cd ~/fjy/catkin_person_server //转到catkin_person路径下
catkin_make //编译
source devel/setup.bash //设置环境变量

在这里插入图片描述

按住Fn+F1,在搜索栏中输入C/C++编辑配置,点击C/C++编辑配置,会在左边产生一个.vscode文件夹,单击该文件夹下的c_cpp_properties.json文件,并添加路径,按Ctrl+s保存,路径如下

“/opt/ros/kinetic/include” //使头文件包含合理

在这里插入图片描述

在这里插入图片描述

二、服务数据的定义与生成

在/fjy/catkin_person_server/src路径下创建功能包person_server,博主这边通过终端命令行进行创建

catkin_create_pkg person_server roscpp std_msgs

然后在/fjy/catkin_person_server/src/person_server路径下建立一个srv文件夹,并在srv文件夹下创建Person.srv,单击该msg文件,并编写相应的代码

mkdir srv //创建msg文件
cd srv //进入srv文件夹
touch Person.srv // 创建Person.srv
string name 
uint8  age
uint8  sex

uint8  unknown = 0
uint8 male    = 1
uint8  female  = 2
---
string result

在这里插入图片描述

编写完Person.srv文件后,需要更改CMakeLists.txt和package.xml文件下的内容
首先需要在package.xml中添加

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

在这里插入图片描述

然后在CMakeLists.txt文件夹中添加以下相关该内容
1、在该文件的find_package中添加功能包message_generation,如图所示

在这里插入图片描述

2、添加如下的把srv文件配置成不同的程序文件的配置项,添加到如下图所示位置

add_service_files(FILES Person.srv) //将Person.srv作为消息接口,可编译
generate_messages(DEPENDENCIES std_msgs) //添加依赖

在这里插入图片描述

3、在catkin_package里面去创建运行的依赖,需要将如下所示的该行代码的注释取消掉,然后在他后面添加message_runtime

在这里插入图片描述

完成以上配置后,回到/fjy/catkin_person_server路径下,对catkin_person_server的工作空间进行编译,我们会发现在/fjy/catkin_person_server/devel/include/person_server的路径下产生了关于Person.srv文件转换而来的相关头文件
在这里插入图片描述

在这里插入图片描述

三、Client和Server的程序编写

在/fjy/catkin_person_server/src/person_server/src路径下创建person_client.cpp文件和person_server.cpp文件

touch person_client.cpp
touch person_server.cpp

并单击打开该person_client文件进行程序的编写,程序如下

//包含ros相关的API头文件
#include <ros/ros.h>
//包含peoson_server这个库里的Person消息这个头文件
#include "person_server/Person.h"

int main(int argc, char** argv)
{
    // 创建一个节点,初始化ROS节点
	ros::init(argc, argv, "person_client");
    // 创建节点句柄,用于管理节点的信息
	ros::NodeHandle node;
    // 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
	ros::service::waitForService("/show_person"); //阻塞型函数,等待服务
	ros::ServiceClient person_client = node.serviceClient<person_sever::Person>("/show_person");
    // 初始化person_server::Person的请求数据
	person_server::Person srv; //注意要跟srv的文件名相同
	srv.request.name = "Tom";
	srv.request.age  = 20;
	srv.request.sex  = person_server::Person::Request::male;
    // 请求服务调用
	ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]", 
		 srv.request.name.c_str(), srv.request.age, srv.request.sex);
         person_client.call(srv);
	// 显示服务调用结果
	ROS_INFO("Show person result : %s", srv.response.result.c_str());
	return 0;
};

在编写程序的过程中,会发现找不到person_server/Person.h,这个问题与找不到ros/ros.h一样,都是缺乏头文件路径导致的,打开c_cpp_properties.json文件,添加该头文件的路径,如下,这样就解决了头文件缺失的问题

在这里插入图片描述

单击打开该person_server文件进行程序的编写,程序如下

//包含ros相关的API文件
#include <ros/ros.h>
//包含peoson—_server这个库里的Person消息这个头文件
#include "person_server/Person.h"

// service回调函数,输入参数req,输出参数res
bool personCallback(person_server::Person::Request  &req, person_server::Person::Response &res)
{
    // 显示请求数据
    ROS_INFO("Person: name:%s  age:%d  sex:%d", req.name.c_str(), req.age, req.sex);
    // 设置反馈数据
    res.result = "OK";

    return true;
}
int main(int argc, char **argv)
{
    // 创建一个节点,ROS节点初始化
    ros::init(argc, argv, "person_server");
    // 创建节点句柄,用于管理节点的信息
    ros::NodeHandle n;
    // 创建一个名为/show_person的server,注册回调函数personCallback
    ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);
    // 循环等待回调函数
    ROS_INFO("Ready to show person informtion.");
    ros::spin();

    return 0;
}

完成发布和订阅程序的编写后,需在CMakeLists.txt文件中添加相关代码,代码如下

add_executable(person_server src/person_server.cpp) //生成可执行文件
target_link_libraries(person_server ${catkin_LIBRARIES}) //连接库
add_dependencies(person_server ${PROJECT_NAME}_generate_messages_cpp) //产生动态依赖关系
add_executable(person_client src/person_client.cpp) //生成可执行文件
target_link_libraries(person_client ${catkin_LIBRARIES}) //连接库
add_dependencies(person_client ${PROJECT_NAME}_generate_messages_cpp) //产生动态依赖关系

在这里插入图片描述

然后回到/fjy/catkin_person_server路径下,对工作空间进行编译,编译完成后,打开一个新的终端,启动roscore,再打开一个新的终端到/fjy/catkin_person_server路径下,设置环境变量,运行person_server

cd ~/fjy/catkin_person_server
source devel/setup.bash
rosrun person_server person_server

然后在vs code终端中运行person_publisher,运行结果如下所示

rosrun person_server person_client

在这里插入图片描述

关于服务数据的定义和使用就到这里结束了,大家有什么疑问的地方可以在底下留言