Let's now create a service server so you can practice as soon as possible.
And we will start with Python.
We will create a service server that will take two numbers as a request and return the sum as a response.
I'm using this example so we can use an existing interface that's already installed.
And we will see how to create custom interfaces in the next section.
Okay.
So before we write any code let's focus on the interface.
Because a service is defined by a name and an interface, the interface we will use.
So you can do Ros2 interface show is also in the example interfaces package.
But then so for topics you had MSG for services you have serve.
And then we have Add.
So you can find the add to interface.
That's the service interface that we will be using.
And let's press enter.
And this is the interface the first big important thing that you can notice.
And that's the most important.
Here you can see we have three dashes here.
Why do we have three dashes?
Because as I told you previously, a service will contain two messages.
It will contain a request.
So that's what's going from the client to the server.
And then it will contain a response.
And that's the response from the server to the client.
This here those three dashes is the separation between the request and the response.
So you can see that as basically two different messages together with a separation here.
And what do we have in the request.
We have two fields here.
So you see that this time we have two fields two integer numbers named a and b.
So we need to send a and b as a request from the client.
And then the response is a integer number.
Which name is some.
All right.
So from the client you need to send a and b.
And then you receive that in the server you process the service and then you return the response with
a sum field.
All right.
And now let's see how we can actually use that inside our code.
Let's go back to our workspace.
And I'm still going to go to my Python package that was already set up in this.
We already have all the previous nodes from the previous sections.
I'm going to add a new file for the server.
So the name of the interface is add to int.
I'm just going to name it add to int server dot pi.
And later on we're going to also create the add to int client.py.
So like this.
Let's make it executable okay.
And we have the file right here.
Now let's open vs code from the source folder of the workspace with code dot okay let's go back to This
package and the file.
And no surprise here we will start with the template.
Okay.
Because we're creating a new node.
So I'm just going to take the code from here and add it to add to in server.
And I'm going to name this add to int seven node for example like that.
And let's name the node add to int um with with server.
Let's remove that and that and that one.
Great.
And now how to import a service interface.
Well that's the same thing as we did for topics.
We're going to just import that.
But you see the difference here is that we don't have an MSG folder.
It's an SV.
So we are going to do from example interfaces Dot and you see we have s r v and then import add to ints.
Okay.
You can see it's found here.
And as you can see we're going to use that later.
We have added to INTs request and add to ints response.
So let's import add to it.
Now we are using the example interfaces package.
We've already set the dependency in the package dot XML, but make sure that it's here.
Okay so nothing more to do with that.
And let's create a service server.
Where do we create service server.
We're going to do that in the constructor of the node.
Okay.
So just like we did for publishers and subscribers you're going to create your service servers inside
the constructor.
And so let's do self server.
Let's name it server.
Okay.
We're going to save it as an attribute of the class.
And how to create a server.
Well it's quite easy you do self so you get access to the node functionalities.
Create Service.
When you do create service, it's going to create a service server.
The first thing you need to provide is the service type which is that one.
So add two ints.
The second thing you need to provide is the name.
Okay, so that's very similar to what we did with publishers and subscribers.
You need to provide a type and a name.
What is the name.
So the name you choose it when you create the service.
So you choose it here I'm going to use add to int okay.
Because we are adding two ints and one very important thing.
It's quite an important tip here.
I would recommend to use a verb okay for a service name.
Why?
Because service will be used for mainly two things when you need to do some actions.
So do something.
Enable motor, disable motor, turn on LED okay that kind of stuff or a computation.
So add to ints compute area.
Compute inverse kinematics.
Okay.
Those are things that you can use services for.
And because it's an action so action or computation you are going to use a verb.
Great.
So now we have the type name and we need to provide a callback.
Why is that.
Because well when you create a server the server is not going to do anything on its own.
You need.
Then you need a client to send a request to the server.
So we are going to process the request as we receive them.
And for that we need a callback.
So I'm going to create a callback here.
Let's call it callback add two ints.
So what I do usually to name the callbacks for the service servers I use something similar as I do for
subscribers is I start with callback, and then I put the name of the service and we have self.
And then what do we receive as parameters?
We are going to receive two parameters.
We are going to receive the request and also the response.
So we get a request object and a response object.
From that we can get the request from the client.
And then the response is well, already the response object that then we need to return.
I'm going to make it a bit more explicit by saying that this is an add to insert dot request, and that
one is an add to insert dot response.
Okay.
So this way it's more explicit.
We're going to make less mistakes.
And we also have nice auto completion features here for this callback okay.
You can see that the add to insert here you can clearly see it's not one message.
It's a combination of two messages.
And the first message is add to insert request.
The second message is add to insert response.
And so what do we want to do here.
Well it's pretty simple.
We want to compute the sum of.
So if I go back here of the a and the b fields that we receive from the request so I can do some is
equal to request dot a plus request dot b.
And I have the autocompletion here because I have provided the type okay.
And then I can put the some inside the response so I can actually do directly response dot some okay
response dot some.
Because that's what we have here.
Response dot some is equal to request dot a plus request dot b.
And that's it.
Actually there is one more thing you need to do is to return the response object.
Okay.
So that's a quite common mistake with services in Python is that you fill the response correctly but
then you forget to return something okay.
This method needs to return.
This callback needs to return the response if you don't do it.
Well, your program is going to be installed.
You can run your node, but then when you send a request, you will get an exception from that callback.
So just in case no.
Again, once again, I repeat that you should absolutely return the response.
And I'm also going to add a log.
So it's going to be better for us to visualize what's happening.
So self get logger I'm going to say so info I'm just going to print the equation okay.
So let's cast to string request dot a plus.
So let's add a plus sign.
And then let's just go back to a new line with request dot b.
And then we add the equal sign.
And then we add the response dot sum.
All right.
So we just print a plus B is equal to sum.
So we can see what's happening.
The callback is now finished.
We also need to set it here.
Okay.
So we have the create service.
We come back to this with the type the name and callback.
So self dot callback add to ints.
And I'm going to go back to a new line here.
Okay.
So we have three parameters here.
And let's finish with a log.
Get logger with info.
And let's say add to in server has been started.
All right.
And that's it.
So let's do a very quick recap here.
You will first initialize Rosetta communications.
And then you create your node which is going to run the code inside the constructor.
So you have the super line.
And then we create the service server.
You provide the type and name and we also provide a Callback.
Okay, so nothing's going to happen now.
It's just going to register a callback.
When the node spins, it's going to be kept alive.
And when you receive a request okay.
For the add to in server, then this callback is going to be called.
In this callback, you can get the request from the request field here from the parameter.
And then you need to well you need to process that request.
So you may want to validate the data.
You may want to do whatever you want okay.
Depends on your application.
And then you need to fill the response parameter plus return it.
Great.
So let's test that.
Let's go to setup.py and let's add yet another executable add to it server that's going to be my pi
pkg add to server.
So that's the file name here and the main function.
All right.
So you can see it's always the same thing.
We save all the files and let's go back to our roster workspace.
Let's do a click on build packages.
Select with my pi pkg.
You can add the symlink install if you want to.
I'm just going to build it like that.
And now let's just open some new terminals or use the ones that you already have.
And I'm going to run Ros to run my Pi pkg with add two ints server.
And you see the node has been started and now it's waiting.
And so here for example let's do Ros two node list.
We have the node.
Let's do Ros two node info.
We have that and in the service server.
So I'm going to come back to all of those later in this section.
But you can see we have the add two ints okay.
With example interfaces service add to it.
That's the one we have created.
So it's a service server.
Now what we can do already.
So we have the server.
We will need to write a client to test it.
But what we can do already is to test this from the terminal okay.
So I'm going to write the command and I'm going to give more details about that.
There's a dedicated lesson about the Ros two command line tool for services a bit later in this section.
So here I'm just going to write the command to test it.
And you'll get more details later.
We can do Ros two service call and use the service name.
So call add to it.
Then we need to provide the interface.
So the interface is example interfaces etc..
So just type the beginning and press tab.
So Ros two service call with the service name then the interface.
And then we can provide the request.
So the request if you remember we have an A and a B field.
So we only need to provide this.
We don't provide the response because that's what we're going to receive.
So let's use double quotes.
And in curly brackets we can say a colon and then a space important.
Let's say three and then comma B colon space let's say seven.
Let's press enter.
And you can see on the server side we have this log okay.
And on the client side here on the terminal you see that we sent a request and we get a response with
the sum ten.
So with that we can already validate that the server is working.
But just note that it's only going to work for very simple requests.
Here we just have two fields.
If you have arrays of many different fields, it's going to be very complicated to create a request
from the terminal.
So for that you will need to write some code.
And that's exactly what we're going to do in the next lesson.