catalogue
2.5 initiator of creating request and processing response: submit request and process response
1.1} get the parameters in the command
3.1 the added code is before judging the response: client waitForExistence();
1, Implementation of client
1. Create client C + + files
2. Programming
Server implementation: submit two integers and process the response results
technological process:
1. Include header file;
2. Initialize ROS node
3. Create node handle
4. Create customer object
5. Initiator who creates the request and processes the response: submits the request and processes the response
2.1 include header file
//1. Include header file; #include "ros/ros.h" #include "plumbing_server_client/Addints.h"
2.2 initializing ROS nodes
setlocale(LC_ALL,"");//Prevent garbled code //2. Initialize ROS node ros::init(argc,argv,"client");
2.3 create node handle
//3. Create node handle ros::NodeHandle nh;//Equivalent to a renamed NodeHandle = nh
2.4 creating customer objects
This part is different from our previous cognition.
//4. Create customer object ros::ServiceClient client = nh.serviceClient<plumbing_server_client::Addints>("addInts");
You can use this part of the code to make a comparison with the publisher of topic communication and the client of service communication. The comparison is as follows (pay attention to the part marked yellow)
//4. Create subscriber object ros::Subscriber sub = nh.subscribe("chatter",10,doMsg); //4. Create publisher object ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10); //4. Create service object ros::ServiceServer server = nh.advertiseService("addInts",doNums); //4. Create customer object ros::ServiceClient client = nh.serviceClient<plumbing_server_client::Addints>("addInts");
2.5 initiator of creating request and processing response: submit request and process response
I thought that according to the demand, the two integers were submitted by the client object, and the response of the server was also received by the client object. However, I found that the official routine is not the same as my idea. It seems that it allows us to submit and receive data as an object, which can also be explained clearly, After all, your submitted data and received data are declared in the customization file.
//5. Submit request and process response //5.0 creating request and processing response objects plumbing_server_client::Addints ai; //5.1 organization request ai.request.num1 = 100; ai.request.num2 = 200; //5.2 processing response bool flag = client.call(ai); if (flag) { ROS_INFO("Response successful"); ROS_INFO("Response result:= %d",ai.response.sum); }else { ROS_INFO("Processing failed"); }
Partial code interpretation
bool flag = client.call(ai);
The number to be processed is ready, but you have to pass it in. The function of this code is to pass the number in. As long as the server has no problem, there will be a response. The return value of this function is bool, that is, correct or wrong. If there is a response, it is correct. If there is no response, it is an error, that is, the following if instruction and the following if statement, What we need to focus on is AI response. Sum, he is the result of the response.
if (flag) { ROS_INFO("Response successful"); ROS_INFO("Response result:= %d",ai.response.sum); }else { ROS_INFO("Processing failed"); }
3. Disposition
Configure three things, you can see the previous content
4. Compilation and execution
II. Optimization
1. Optimization 1
The above example can only operate on fixed numbers, and our idea is that we input numbers and he operates.
The data we submit is actually in the main function. What we have to do is to change the value of the parameter, an assignment operation.
At this time, you need to use argc and argv in the main function. Argc represents the number of parameters and argv is an array
1.1} get the parameters in the command
Why 3? Because the node name is a parameter, the two values we give are two parameters
int main(int argc, char *argv[]) { setlocale(LC_ALL,"");//Prevent garbled code //Optimization implementation: get the parameters in the command if (argc != 3) { ROS_INFO("Insufficient parameters"); return 1; } //2. Initialize ROS node ros::init(argc,argv,"client");
1.2 assignment
It is equivalent to performing an assignment operation, that is, the first num1 in the argv array and the second num2 and atoi in the argv array
This instruction converts characters to integers. Remember that the type char * argv [] in your main function is character type. And you are counting.
//5. Submit request and process response //5.0 creating request and processing response objects plumbing_server_client::Addints ai; //5.1 organization request ai.request.num1 = atoi(argv[1]); ai.request.num2 = atoi(argv[2]); //5.2 processing response bool flag = client.call(ai);
2. Compilation and execution
3, Optimize
I remember we talked about starting the server before starting the client during service communication, but there are many nodes in the ros, and we can't guarantee the order of nodes. In order to avoid the problem of throwing exceptions when starting the client before starting the server, we have a solution.
Question:
If the client is started first, an exception is requested
Requirements:
If you start the client first, don't throw an exception, but hang up, wait for the server to start, and start normally
solve:
Related functions are built in ROS, which can make the client hang up and wait for the server to start.
3.1 the added code is before judging the response: client waitForExistence();
//5.1 organization request ai.request.num1 = atoi(argv[1]); ai.request.num2 = atoi(argv[2]); //Call the function to judge the status of the server //Function 1 client.waitForExistence(); //5.2 processing response bool flag = client.call(ai); if (flag) { ROS_INFO("Response successful"); ROS_INFO("Response result:= %d",ai.response.sum); }else { ROS_INFO("Processing failed"); }
3.2} results
3.3. The added code is before judging the response: ros::service::waitForService("addInts"); Parameters are topics;
//5. Submit request and process response //5.0 creating request and processing response objects plumbing_server_client::Addints ai; //5.1 organization request ai.request.num1 = atoi(argv[1]); ai.request.num2 = atoi(argv[2]); //Call the function to determine the status of the server //Function 1 //client.waitForExistence(); //Function 2 ros::service::waitForService("addInts"); //5.2 processing response bool flag = client.call(ai); if (flag) { ROS_INFO("Response successful"); ROS_INFO("Response result:= %d",ai.response.sum); }else { ROS_INFO("Processing failed"); } return 0;
3.4 results