《ROS入门21讲》第15讲《服务数据的定义与使用》主要介绍了ROS中服务数据的定义与使用方法,内容如下:
1. **服务模型**
服务模型由服务端和客户端组成,用于实现节点间的服务调用。
2. **自定义服务数据**
- 可通过`.srv`文件定义自服务数据类型,例如:
```
string name
uint8 age
uint8 sex
```
- 定义完成后,在`package.xml`中添加功能包依赖:
```xml
message_generation
message_runtime
```
- 在`CMakeLists.txt`中添加编译选项:
```cmake
find_package(… message_generation)
add_service_files(FILES Person.srv)
generate_messages(DEPENDENCIES std_msg)
catkin_package(...message_runtime)
```
3. **服务实现**
- **服务器端**
- 初始化ROS节点。
- 创建服务实例并绑定回调函数。
- 在回调函数中处理请求数据并反馈应答。
- 示例代码(C++):
```cpp
#include
#include "learning_service/Person.h"
bool personCallback.learning_service::Person::Request& req,
learning_service::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::init(argc, argv, "person_server");
ros::NodeHandle n;
ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);
ROS_INFO("Ready to show person information.");
ros::spin();
return 0;
}
```
- 示例代码(Python):
```python
import rospy
from learning_service.srv import Person, PersonResponse
def personCallback(req):
rospy.loginfo("Person: name:%s age:%d sex:%d", req.name, req.age, req.sex)
return PersonResponse("OK")
def person_server():
rospy.init_node('person_server')
s = rospy.Service('/show_person', Person, personCallback)
print("Ready to show person information.")
rospy.spin()
if __name__ == '__main__':
person_server()
```
- **客户端**
- 初始化ROS节点。
- 创建服务客户端并调用服务。
- 示例代码(C++):
```cpp
#include
#include "learning_service/Person.h"
int main(int argc, char **argv) {
ros::init(argc, argv, "person_client");
ros::NodeHandle n;
ros::ServiceClient person_client = n.serviceClient("/show_person");
learning_service::Person srv;
srv.request.name = "Tom";
srv.request.age = 20;
srv.request.sex = PersonRequest::male;
person_client.call(srv);
ROS_INFO("Show person result: %s", srv.response.result.c_str());
return 0;
}
```
- 示例代码(Python):
```python
import rospy
from learning_service.srv import Person, PersonRequest
def person_client():
rospy.init_node('person_client')
rospy.wait_for_service('/show_person')
try:
person_client = rospy.ServiceProxy('/show_person', Person)
response = person_client("Tom", 20, PersonRequest.male)
print("Show person result : %s" % response.result)
return response.result
except rospy.ServiceException as e:
print("Service call failed: %s" % e)
return None
if __name__ == '__main__':
person_client()
```
4. **编译与运行**
- 编译时需要在`CMakeLists.txt`中添加:
```cmake
add_executable(person_server src/person_server.cpp)
target_link_libraries(person_server ${catkin_LIBRARIES})
add_dependencies(person_server ${PROJECT_NAME}_gencpp)
```
- 运行命令:
```bash
source devel/setup.bash
roscore
rosrun learning_service person_server
rosrun learning_service person_client
```
总结:本讲详细讲解了ROS服务数据的定义、编译配置及服务器/客户端的实现方法,并通过C++和Python示例展示了服务的调用流程。