服务器篇--客户端程序
1 int main(int argc, char *argv[]) 2 { 3 ros::init(argc, argv, "add_tow_ints_client"); //节点初始化,节点名称 4 5 if (argc != 3) 6 { 7 ROS_INFO("usage:add_two_ints_client X Y"); 8 return 1; 9 }
argc不会计入”rosrun [package_name]”,只会从节点名开始算起,argv[0]=”node_name”。
1 //ROS_INFO("%d",argc); 2 ros::NodeHandle n; 3 ros::ServiceClient client = n.serviceClient<learning_communication::addtwo>("add_two_ints"); 4 learning_communication::addtwo srv; 5 srv.request.a = atoll(argv[1]); 6 srv.request.b = atoll(argv[2])
ServiceClient是客户端类,定义在service_client.h中,而此头文件又包含在node_handle.h中,里面实际有用的就是一个数据就是impl_用来和服务器进行关联。
n.serviceClient方法内建一个关联服务器的Client返回出来。
对于addtwo类型,关联的还有两个类型,addtwo::Request和addtwo::Response。
而addtwo类型的对象,还有两个数据,[addtwo].request数据(Request类型)和[addtwo].response(Response类型)。注意大小写,类型是大写,数据是小写。
1 if (client.call(srv)) 2 { 3 ROS_INFO("Sum:%ld", (long int)srv.response.sum); 4 } 5 else 6 { 7 ROS_ERROR("Failed to call service add_two_ints"); 8 return 1; 9 }
ServiceClient对象的call方法简单理解说就是通过用自身的impl_利用指针去调用服务器的反馈程序,接收反馈程序的返回值,所以服务器的反馈程序的类型是bool,一定要在那个程序中写明返回值。
1 return 0; 2 }
服务器程序
1 int main(int argc, char *argv[]) 2 { 3 ros::init(argc,argv,"add_tow_ints_server");//节点初始化,节点名称 4 ros::NodeHandle n; 5 ros::ServiceServer service = n.advertiseService("add_two_ints",add); 6 ROS_INFO("Ready to add two ints."); 7 ros::spin(); 8 return 0; 9 }
ServiceServer类定义在service_server.h中,关键成员数据也是impl_。
advertiseService返回一个关联了名字和处理函数的ServiceServer对象。
1 bool add(learning_communication::addtwo::Request &req,learning_communication::addtwo::Response &res) 2 { 3 res.sum=req.a+req.b; 4 ROS_INFO("a=%ld b=%ld sum=%ld/n",req.a,req.b,res.sum); 5 return true; 6 }
处理函数要有两个实参,一个request,一个response,最后一定要返回true。
这种创造服务器和客户端的方法还属于较为底层,service.h和service.cpp中还定义了一些整合的函数。