1.编写 Service 节点(C++)
进入目录
cd ~/catkin_ws/src/beginner_tutorials/src
然后vim server.cpp
复制代码粘贴,shift+insert 粘贴 ,然后按Esc 键,然后输入:wq 就可以保存退出了
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
bool add(beginner_tutorials::AddTwoInts::Request &req,beginner_tutorials::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("sending back response: [%ld]", (long int)res.sum);
return true;
}
int main(int argc, char **argv){
ros::init(argc, argv, "add_two_ints_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("add_two_ints",add);
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
代码解释:
这段代码是一个 ROS (Robot Operating System) 的服务端程序,它提供了一个名为
add_two_ints
的服务,用于对两个整数进行加法运算。具体来说,程序首先包含了 ROS 的头文件和
beginner_tutorials
包中的AddTwoInts
服务文件,然后定义了一个名为add
的回调函数,用于实现加法运算。回调函数的输入参数是beginner_tutorials::AddTwoInts::Request
类型的req
和beginner_tutorials::AddTwoInts::Response
类型的res
,分别表示请求和响应。在回调函数中,程序将输入参数a
和b
相加,并将结果存储到res.sum
中,然后打印出请求和响应的信息。接着,程序定义了一个
main
函数,其中包含了 ROS 的初始化和节点句柄的创建。节点句柄是 ROS 中用于管理节点、订阅主题、发布消息和提供服务的重要组件。接着,程序调用n.advertiseService
函数创建了一个名为add_two_ints
的服务,并将其回调函数设置为add
。最后,程序通过调用ros::spin()
进入 ROS 的事件循环,等待客户端的请求。当程序接收到客户端的请求时,回调函数
add
会被自动调用,并将请求和响应作为参数传递给它。回调函数会执行加法操作,并将结果存储到响应中,最后将响应发送给客户端。整个程序的作用是创建一个 ROS 服务,用于提供加法运算的功能。其他 ROS 节点可以通过调用该服务,实现对两个整数的加法运算。
2.编写 Client 节点(C++)
复制代码粘贴,shift+insert 粘贴 ,然后按Esc 键,然后输入:wq 就可以保存退出了
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>
int main(int argc, char **argv){
ros::init(argc, argv, "add_two_ints_client");
if (argc != 3){
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
beginner_tutorials::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
if (client.call(srv)){
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
代码解释:
这段代码是一个 ROS 的客户端程序,用于调用
add_two_ints
服务,实现对两个整数进行加法运算。具体来说,程序首先包含了
beginner_tutorials
包中的AddTwoInts
服务文件和 ROS 的头文件,然后在main
函数中进行了初始化,并检查命令行参数是否正确。如果命令行参数不正确,程序会打印一条用法信息并返回1
。接着,程序创建了一个节点句柄,并使用该节点句柄创建了一个
add_two_ints
服务的客户端对象。然后,程序创建了一个beginner_tutorials::AddTwoInts
类型的服务请求对象srv
,并将其成员变量a
和b
分别设置为命令行参数中的两个整数。接下来,程序调用
client.call(srv)
向服务端发送服务请求,并等待服务端的响应。如果服务调用成功,程序会打印出服务端返回的结果,即两个整数的和;否则,程序会打印一条错误信息并返回1
。整个程序的作用是创建一个 ROS 客户端,用于调用
add_two_ints
服务,实现对两个整数进行加法运算。用户可以在命令行中输入两个整数,然后运行该客户端程序,程序会自动将这两个整数发送给add_two_ints
服务,然后等待服务返回结果并将结果打印出来。
3.编辑CMakeLists.txt 文件
add_executable(server src/server.cpp)
target_link_libraries(server ${catkin_LIBRARIES})
add_dependencies(server beginner_tutorials_gencpp)
add_executable(client src/client.cpp)
target_link_libraries(client ${catkin_LIBRARIES})
add_dependencies(client beginner_tutorials_gencpp)
输入cd .. 回到begineer_tutorials 目录下面,然后vim CMakeLists.txt 文件,粘贴,然后按esc ,输入:wq 保存退出
执行命令:
cd ~/catkin_ws/ && catkin_make -j1
编译成功:
测试我们写的代码:
启动三个终端,分别运行3个命令
roscore
rosrun beginner_tutorials server
rosrun beginner_tutorials client 1 3
好了。我们c++的代码就完成了
-------------------------------------------------下面开始python版本-----------------------------
4.编写 Service 节点(python)
进入目录
cd ~/catkin_ws/src/beginner_tutorials/scripts/
输入vim server.py
复制代码 shift+insert 粘贴,然后按esc 输入:wq 保存退出
#!/usr/bin/env python
from __future__ import print_function
from beginner_tutorials.srv import AddTwoInts,AddTwoIntsResponse
import rospy
def 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()
代码解释:
这段代码是一个 ROS 的服务端程序,它提供了一个名为
add_two_ints
的服务,用于对两个整数进行加法运算。具体来说,代码首先导入了
beginner_tutorials.srv
模块中的AddTwoInts
服务和AddTwoIntsResponse
响应类型,以及 ROS 的 Python 接口模块rospy
。然后,程序定义了一个名为handle_add_two_ints
的回调函数,用于实现加法运算。回调函数的输入参数是req
,表示请求,包含两个整数a
和b
。在回调函数中,程序将这两个整数相加,并将结果打印出来,然后将结果存储到AddTwoIntsResponse
类型的响应对象中,并返回它。接着,程序定义了一个名为
add_two_ints_server
的函数,用于初始化 ROS 节点并创建服务。在函数中,程序首先调用rospy.init_node
初始化 ROS 节点,并设置节点名称为add_two_ints_server
。然后,程序使用rospy.Service
函数创建了一个名为add_two_ints
的服务,服务类型为AddTwoInts
,回调函数为handle_add_two_ints
。最后,程序输出一条提示信息并调用rospy.spin()
进入 ROS 的事件循环,等待客户端的请求。最后,程序通过判断
__name__
是否等于"__main__"
,来确定是否需要执行add_two_ints_server()
函数。如果将该脚本作为模块导入到其他 Python 脚本中时,__name__
的值为模块名,此时不会执行add_two_ints_server()
函数。如果直接运行该脚本时,__name__
的值为"__main__"
,此时会执行add_two_ints_server()
函数,启动 ROS 服务端程序。整个程序的作用是创建一个 ROS 服务,用于提供加法运算的功能。其他 ROS 节点可以通过调用该服务,实现对两个整数的加法运算。此外,该程序编写使用了 Python 语言,是 ROS 中 Python 语言的服务端编写示例。
给文件执行权限
chmod +x server.py
回到上一级目录,编写输入vim CMakeLists.txt 文件,编写文件
catkin_install_python(PROGRAMS scripts/server.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
复制粘贴代码。按esc 输入:wq 保存退出
继续:
5.编写 Client 节点(python)
进入刚刚的scripts 目录下面,输入vim client.py
复制代码粘贴,按esc 输入:wq 保存
#!/usr/bin/env python
from __future__ import print_function
import 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.sum
except 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)))
代码解释:
这段代码是一个 ROS 的客户端程序,用于调用
add_two_ints
服务,实现对两个整数进行加法运算。具体来说,代码首先导入了 ROS 的 Python 接口模块
rospy
和beginner_tutorials.srv
模块中的AddTwoInts
服务类型。然后,程序定义了一个名为add_two_ints_client
的函数,用于向add_two_ints
服务发送请求,并返回服务端返回的结果。在函数中,程序使用rospy.wait_for_service
函数等待add_two_ints
服务的出现,然后使用rospy.ServiceProxy
函数创建一个名为add_two_ints
的服务代理,并将输入参数x
和y
传递给服务代理。最后,程序返回服务端返回的结果,即两个整数的和。接着,程序定义了一个名为
usage
的函数,用于打印用法信息。如果用户在命令行中没有输入两个整数,程序会调用usage
函数打印用法信息并退出。最后,程序通过判断
__name__
是否等于"__main__"
,来确定是否需要执行客户端程序。如果将该脚本作为模块导入到其他 Python 脚本中时,__name__
的值为模块名,此时不会执行客户端程序。如果直接运行该脚本时,__name__
的值为"__main__"
,此时会执行客户端程序,先从命令行参数中获取两个整数x
和y
,然后调用add_two_ints_client
函数向add_two_ints
服务发送请求,并将服务端返回的结果打印出来。
整个程序的作用是创建一个 ROS 客户端,用于调用
add_two_ints
服务,实现对两个整数进行加法运算。用户可以在命令行中输入两个整数,然后运行该客户端程序,程序会自动将这两个整数发送给add_two_ints
服务,然后等待服务返回结果并将结果打印出来。该程序编写使用了 Python 语言,是 ROS 中 Python 语言的客户端编写示例。
给文件执行权限
chmod +x client.py
回到上一级目录,输入vim CMakeLists.txt 文件
复制代码,粘贴(shift+insert),按esc 输入:wq 保存退出 ,这里自己看着修改
catkin_install_python
(
PROGRAMS scripts/server.py scripts/client.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
编译节点:
cd ~/catkin_ws/ && catkin_make -j1
编译成功:
分别建立三个终端,分别运行代码:
roscore
rosrun beginner_tutorials server.py
rosrun beginner_tutorials client.py 1 3
好了。教程结束。记得虚拟机拍摄快照,以后弄坏了,可以回来到这个