WEBVTT

00:00.050 --> 00:03.590
This is now step number four of this final project.

00:03.590 --> 00:05.180
And what do we have so far?

00:05.180 --> 00:12.560
Well, we have a turtle spawner node that will spawn turtles on the turtle SIM with random coordinates.

00:12.560 --> 00:16.010
And for now we spawn one new turtle every two seconds.

00:16.010 --> 00:20.180
Then we have a turtle controller node that will take the first turtle.

00:20.180 --> 00:21.830
So that's called turtle one.

00:21.830 --> 00:24.920
And it's going to make this turtle move to a target position.

00:24.920 --> 00:26.390
And what's the target position?

00:26.390 --> 00:31.580
Well, we are actually publishing a list of turtles that's going from the turtle spawner to the turtle

00:31.580 --> 00:32.390
controller.

00:32.390 --> 00:34.430
And we go to the first turtle.

00:34.430 --> 00:41.330
Now what's next to do is that first, when the master turtle reaches one turtle.

00:41.330 --> 00:44.780
So one target turtle, we should remove that turtle.

00:44.780 --> 00:48.080
So we should kill that turtle and remove it from the screen.

00:48.080 --> 00:53.060
And second, we need to give a new target to the master turtle.

00:53.060 --> 00:57.170
So it's going to go to the next turtle, etc., etc..

00:57.200 --> 00:57.650
Okay.

00:57.680 --> 00:58.310
Let's.

00:58.310 --> 01:02.540
So I have the turtle sim node running here.

01:02.540 --> 01:04.970
I have the turtle controller here.

01:05.000 --> 01:10.910
Well, we just need the turtle sim here and let's just do a Ros2 service list.

01:11.450 --> 01:16.220
So you see, we have lots of services, but we have the kill service.

01:16.220 --> 01:18.290
That's the one that we want to use.

01:18.320 --> 01:24.800
Ros2 service type with kill.

01:25.130 --> 01:25.790
Okay.

01:25.790 --> 01:28.100
So you see it's total SIM service kill.

01:28.100 --> 01:30.620
So now I can do well actually.

01:30.650 --> 01:43.280
Ros2 interface show total sim save kill to see what's inside.

01:43.310 --> 01:45.260
And you see, it's pretty simple.

01:45.860 --> 01:49.610
We just give a name and we don't receive any response.

01:49.730 --> 01:52.910
Let's call it Ros to run.

01:53.180 --> 01:54.980
Actually, no Ros to service.

01:56.390 --> 02:02.820
Call With kill and then tethered SIM service kill.

02:02.970 --> 02:07.350
I will provide the request, which is name.

02:07.710 --> 02:10.500
And while we know this first turtle here.

02:10.500 --> 02:12.120
So that's the turtle one here.

02:12.120 --> 02:13.560
That's the master turtle.

02:13.560 --> 02:19.140
And this first turtle that was spawned is named turtle two.

02:19.170 --> 02:23.040
So if I run this, you see the turtle disappears.

02:23.040 --> 02:24.720
And we want to do that in the code.

02:24.750 --> 02:25.020
All right.

02:25.050 --> 02:27.900
So we will need to call this service from the code.

02:27.900 --> 02:29.430
And where do we call it.

02:29.460 --> 02:35.640
Well you could think we could call it directly from the turtle controller because we know we have reached

02:35.640 --> 02:36.420
the goal.

02:36.420 --> 02:40.410
We know what the position of the target turtle, we could remove it from here.

02:40.410 --> 02:47.850
But as we keep the list of alive turtles in the turtle spawner, it would be best actually to do everything

02:47.850 --> 02:49.950
that's related to what?

02:49.980 --> 02:56.040
Spawning and removing turtles from that node so that we can keep the list accurate.

02:56.040 --> 03:01.780
And then we just need to publish the new list, which is going to contain just the turtles that are

03:01.810 --> 03:03.910
actually spawned and not removed.

03:03.940 --> 03:08.920
And so what I'm going to do here, I'm going to create a service between the turtle controller and the

03:08.920 --> 03:10.060
turtle spawner.

03:10.090 --> 03:14.500
Here we're going to have a service server that's going to be called Catch Turtle.

03:14.500 --> 03:18.760
And whenever the turtle controller has reached you see target reached.

03:18.910 --> 03:24.520
We are going to use a service client to call the catch turtle service.

03:24.520 --> 03:31.450
And here when we receive a request then we can call the kill service of the turtle SIM node.

03:31.480 --> 03:31.900
All right.

03:31.900 --> 03:33.430
So that's what we want to do.

03:33.460 --> 03:36.280
And for that I'm going to create a new interface.

03:36.850 --> 03:37.870
I'm going to go to.

03:37.900 --> 03:45.310
So let's stop everything and let's go to my robot interfaces SRV.

03:45.670 --> 03:52.900
Because we're going to create an interface for a service and then touch I'm going to name it Catch turtle

03:52.930 --> 03:53.860
Dot SRV.

03:54.190 --> 03:56.950
So you could use an existing interface if you want.

03:56.980 --> 04:03.040
Here, I name it Catch Total and I'm going to design it specifically for this application that we want

04:03.040 --> 04:03.520
to do.

04:03.550 --> 04:03.820
Okay.

04:03.850 --> 04:05.260
Let's go to the code.

04:05.260 --> 04:08.890
In my robot interfaces in SV we have catch total.

04:08.890 --> 04:11.260
And the only thing we really need is the name.

04:11.260 --> 04:12.850
So I'm going to put string name.

04:12.880 --> 04:13.180
Okay.

04:13.210 --> 04:17.410
So the total controller is going to send the name of the turtle to the turtle spawner.

04:17.440 --> 04:19.240
Then we have three dashes.

04:19.240 --> 04:21.400
And do we need a response.

04:21.430 --> 04:26.290
Well not really I'm still going to put a bool success okay.

04:26.320 --> 04:28.450
Just in case we can return true or false.

04:28.450 --> 04:30.070
So I save this.

04:30.070 --> 04:31.330
Make sure you have the three dashes.

04:31.360 --> 04:32.680
That's very important.

04:32.770 --> 04:46.810
And then in List.txt I am just going to add my new service SV catch turtle.sv I save all of that and

04:46.810 --> 04:49.000
then let's build the interface.

04:50.110 --> 04:57.670
So Ros2 workspace click on build packages.

04:57.790 --> 05:03.100
Select with my robot interfaces.

05:05.500 --> 05:06.160
All right.

05:06.160 --> 05:08.140
And let's just verify.

05:08.170 --> 05:11.230
So let's source setup bash.

05:11.230 --> 05:20.110
And let's verify with Ros2 interface show my robot interfaces CV.

05:20.710 --> 05:23.320
And then let's use the Autocompletion.

05:23.380 --> 05:25.120
Do we find this.

05:26.440 --> 05:29.230
So yes we have catch total.

05:29.440 --> 05:29.860
Great.

05:29.860 --> 05:39.790
And now well once again I'm going to actually stop everything and also close VSCode and start everything

05:39.820 --> 05:40.720
again.

05:42.160 --> 05:46.900
And let's go to the workspace and open VSCode.

05:47.980 --> 05:54.460
So now we know VS code has been sourced with all the new interfaces we have built.

05:55.960 --> 05:56.320
All right.

05:56.320 --> 05:58.090
So I don't need that anymore.

05:58.120 --> 06:03.790
And as we create here a service, usually the best thing is to start from the server side.

06:03.790 --> 06:18.190
So let's import the interface from my robot interfaces dot save this time import catch turtle I'm going

06:18.220 --> 06:21.580
to create a service here.

06:22.510 --> 06:32.140
Self dot catch turtle service is equal to self dot.

06:33.190 --> 06:38.350
Create service with the catch turtle type.

06:38.410 --> 06:40.360
The name is going to be.

06:40.390 --> 06:43.570
Well let's name it simply Catch turtle.

06:43.600 --> 06:46.450
You see once again we use a verb catch.

06:46.660 --> 06:48.280
And then I need a callback.

06:48.280 --> 06:51.340
So let's add a callback here.

06:51.370 --> 06:52.820
The order it doesn't matter.

06:53.510 --> 06:54.650
Callback.

06:55.370 --> 06:56.300
Catch.

06:56.810 --> 06:57.710
Turtle.

06:59.930 --> 07:11.210
With self request is going to be catch turtle dot request and then response is going to be catch turtle

07:11.240 --> 07:13.670
dot response.

07:15.140 --> 07:27.560
What I can do is put my callback here self dot callback catch turtle and this on a new line.

07:27.560 --> 07:28.670
So it's a bit better.

07:28.700 --> 07:29.810
All right we have the service.

07:29.840 --> 07:30.770
We have the callback.

07:30.770 --> 07:32.240
What do we do in the callback.

07:32.240 --> 07:36.740
Well we are going to call the kill service from turtle SIM.

07:36.740 --> 07:42.800
So I'm going to put a comment here for now call kill service.

07:42.800 --> 07:44.840
Then we will need to return a response.

07:44.840 --> 07:47.990
So response dot success.

07:47.990 --> 07:53.450
I'm not going to do anything here really I'm going to just put true because we're going to call the

07:53.450 --> 07:53.960
service.

07:53.960 --> 07:57.590
But you could decide to wait until you get a response from the service.

07:57.590 --> 08:02.450
But anyway, you don't get any, uh, thing in the response of the kill service.

08:02.450 --> 08:05.780
So this boolean flag is not really useful.

08:05.810 --> 08:06.200
Okay.

08:06.230 --> 08:08.360
We are just using it because I created it.

08:08.360 --> 08:12.560
So let's just put true and return a response.

08:13.040 --> 08:13.370
All right.

08:13.400 --> 08:14.810
So that's for the catch total.

08:14.840 --> 08:17.840
Now here we need to call the kill service.

08:17.840 --> 08:30.080
So the kill service if I start total SIM again rose to run total sim total sim node okay.

08:30.110 --> 08:33.440
Let's just do a rose to service list.

08:33.950 --> 08:44.900
Rose to service type with kill and a rose to interface show with that one.

08:45.950 --> 08:48.710
So we have all the information we need okay.

08:48.740 --> 08:51.780
The name the type and what's inside the interface.

08:51.780 --> 08:54.570
So let's import that interface.

08:54.930 --> 09:03.990
I can put it here for example from turtle sim dot csv import kill.

09:04.050 --> 09:08.460
Just make sure I have everything in the package dot XML.

09:08.640 --> 09:11.730
And actually I forgot to do that before.

09:12.210 --> 09:14.610
You see we are using my robot interfaces.

09:14.610 --> 09:16.110
So I'm going to add a tag.

09:16.110 --> 09:22.470
Here depend my robot interfaces.

09:23.190 --> 09:27.870
Okay, so we have our CLP turtle SIM geometry messages and my robot interfaces.

09:27.870 --> 09:31.140
As you can see, the code was still running fine okay.

09:31.140 --> 09:39.300
This is mostly when you're going to do core code build in case this package is not built before you

09:39.330 --> 09:44.550
try to build the turtle sim catch them all package, then you're going to get an error.

09:44.640 --> 09:46.830
Okay, so that's why you add a depend tag here.

09:46.830 --> 09:48.930
For example for Python code.

09:48.960 --> 09:53.910
It's just to make sure that when you do call on build, all the packages here are found first.

09:53.940 --> 09:54.150
Great.

09:54.180 --> 09:56.370
So let's save that.

09:56.370 --> 09:59.610
And now where to call the kill service.

09:59.610 --> 10:02.730
That's going to be very similar to that.

10:02.730 --> 10:04.200
Call spawn service.

10:04.200 --> 10:08.220
We're going to do the same structure and the same structure here basically.

10:08.220 --> 10:10.590
So let's add a function here.

10:10.620 --> 10:17.400
Def call kill service self.

10:17.400 --> 10:21.720
We're going to put the turtle name and that's it.

10:21.750 --> 10:28.680
So actually if I call the service I need a service client I'm going to create a service client here.

10:28.680 --> 10:42.990
For example just after that one self dot kill client is equal to self create client with kill and name

10:42.990 --> 10:44.970
is slash kill.

10:45.000 --> 10:47.190
You can get that from the terminal.

10:50.220 --> 11:00.990
So in my method here I will do while not self dot kill client wait for service.

11:01.350 --> 11:04.740
Okay, I'm going quite fast here because we've done that already several times.

11:04.800 --> 11:07.920
And uh, let's just take that log.

11:07.980 --> 11:09.330
Wait for.

11:11.490 --> 11:12.600
Kill service.

11:12.630 --> 11:14.130
Even though we should never have this.

11:14.160 --> 11:16.440
If we start turtle sim first, you know.

11:16.470 --> 11:26.130
But just in case, it's a bit delayed so we can create the request, which is going to be a kill dot

11:26.130 --> 11:27.240
request.

11:27.240 --> 11:29.580
And in the request, we can do request.

11:29.610 --> 11:34.020
Dot name is equal to turtle name.

11:34.050 --> 11:38.460
That's the only thing we need to provide as you see here just the name.

11:39.510 --> 11:44.970
And then we can call the service.

11:44.970 --> 11:55.810
So I'm going to get future self dot kill client dot call async with the request.

11:56.020 --> 11:57.970
So it's always the same thing.

11:59.290 --> 12:04.060
And then let's add a future add done callback.

12:04.090 --> 12:11.560
I'm also going to use partial because I'm going to give the request to the callback because we need

12:11.560 --> 12:13.150
the name of the turtle.

12:13.330 --> 12:14.020
Okay.

12:14.020 --> 12:18.070
So before I write this let's write the callback.

12:18.100 --> 12:26.950
So callback call kill service will receive a future.

12:26.950 --> 12:34.420
And the request which is a kill dot request.

12:37.480 --> 12:39.160
Okay let's finish that.

12:39.160 --> 12:44.680
So partial self dot callback Kill.

12:44.920 --> 12:46.270
So callback call.

12:46.300 --> 12:51.970
Kill service and then request is equal to request.

12:52.000 --> 12:56.530
So the request parameter here is equal to the one we've created here.

12:57.970 --> 12:58.240
Okay.

12:58.270 --> 13:00.400
So nothing really new.

13:00.430 --> 13:03.880
It's always the same thing you see for this function.

13:03.880 --> 13:06.310
And then what do we do here.

13:06.340 --> 13:15.700
Well we don't really need to get the response because there is nothing and there is nothing in the response.

13:15.700 --> 13:21.580
So you could get the response object, but then you will not do anything with it.

13:21.580 --> 13:22.630
So that's it.

13:22.660 --> 13:28.150
When we get to this callback, basically we have the information that the service was executed.

13:28.180 --> 13:28.420
Okay.

13:28.450 --> 13:31.660
So we know the server has finished and is getting back to the client.

13:31.660 --> 13:34.660
So basically we know that the turtle was killed.

13:34.690 --> 13:34.900
Okay.

13:34.930 --> 13:38.890
If we provided a name that was valid, we know the turtle was killed.

13:38.890 --> 13:41.350
If the turtle is killed what do we want to do?

13:41.380 --> 13:48.200
We want to remove it from the list of alive turtles here.

13:48.230 --> 13:52.040
Okay, so when we spawn, we add a new one.

13:52.040 --> 13:56.570
But when we remove a turtle, we also remove it from that list.

13:56.570 --> 14:00.980
And what information we have here we have the information of the name.

14:00.980 --> 14:02.210
So we have the turtle name.

14:02.210 --> 14:09.230
So basically we can go through the turtle list and find turtles which correspond to that name and just

14:09.230 --> 14:10.100
remove it.

14:10.400 --> 14:22.520
I'm going to do four and I'm going to use I turtle in enumerate self alive turtles okay.

14:22.550 --> 14:25.790
So I use this because I will need the index.

14:25.820 --> 14:26.120
All right.

14:26.150 --> 14:32.420
So with this we get an element turtle and we get the index for each element in that list I can do if

14:32.450 --> 14:43.340
turtle dot name, which is each turtle we're going to go through is equal to request Dot name.

14:43.340 --> 14:47.750
So that's the turtle name we have provided here to the call kill service.

14:47.810 --> 14:54.290
And actually here to make it a bit more readable, instead of just passing the request, I could just

14:54.410 --> 14:55.430
pass.

14:55.670 --> 15:05.330
Turtle name and say that's the turtle name is equal to the well, the turtle name we get here.

15:05.360 --> 15:05.630
Okay.

15:05.660 --> 15:07.670
Just pass the same parameter name.

15:08.150 --> 15:11.480
We get it here, we pass it here, we receive it here.

15:11.480 --> 15:12.590
And I can say.

15:12.620 --> 15:13.760
Turtle name.

15:14.360 --> 15:14.660
All right.

15:14.660 --> 15:17.990
So if the turtle we go through each turtle in the array.

15:18.470 --> 15:19.640
If one of the turtle.

15:19.670 --> 15:26.120
Name corresponds to the turtle name we have sent to the kill service, then we know it's that turtle.

15:26.240 --> 15:36.050
And we can do, for example del to delete self dot live turtle with the index I okay, that's why I.

15:36.080 --> 15:37.040
Used the I here.

15:37.040 --> 15:37.880
And then what.

15:37.880 --> 15:42.830
I'm just going to add a break Because we just need to do this once.

15:42.830 --> 15:46.970
Once we find the turtle, we don't need to continue this loop.

15:47.120 --> 15:47.660
All right.

15:47.660 --> 15:50.900
And there's one more thing I'm going to do is I'm going to publish.

15:50.900 --> 15:58.910
So just before we break and we exit this callback, I'm going to do self dot publish a live turtles.

15:59.750 --> 16:00.590
Why is that.

16:00.590 --> 16:04.970
Because well now we have updated the list of turtles.

16:05.240 --> 16:09.200
So the array is not the same as it was just before the service.

16:09.200 --> 16:15.650
So I'm going to publish the new list and so that the turtle controller is going to receive the new list.

16:15.890 --> 16:16.280
All right.

16:16.280 --> 16:23.690
So by doing this you see in the turtle controller in the callback live turtles, whenever I receive

16:23.690 --> 16:27.920
the turtle list I just go to the first turtle.

16:27.920 --> 16:33.890
So if I remove one turtle and I publish the list again, then we're going to get a different list and

16:33.890 --> 16:35.930
we can get to another turtle.

16:35.960 --> 16:36.170
Okay.

16:36.200 --> 16:41.910
So by just doing this, it's going to take care of giving the turtle controller an updated list every

16:41.940 --> 16:44.070
time with the turtles to catch.

16:44.070 --> 16:49.110
So you see, we only publish when we spawn a new one and when we delete a new one.

16:49.110 --> 16:51.540
And let's just finish the code here.

16:51.540 --> 16:56.070
We need to actually call the kill service here.

16:56.070 --> 17:06.660
So self dot call kill service with the turtle name, which is going to be from the request dot name

17:06.930 --> 17:07.380
okay.

17:07.410 --> 17:10.110
From the catch turtle interface okay.

17:10.140 --> 17:12.090
So catch turtle we have a name.

17:12.780 --> 17:16.200
We basically forward this name to the kill service.

17:17.220 --> 17:17.490
All right.

17:17.520 --> 17:24.720
So what we did here very basically we created a catch turtle service that will basically forward to

17:24.720 --> 17:26.610
the kill service.

17:26.610 --> 17:28.680
So that's going to be a service client.

17:28.680 --> 17:29.970
We call the service.

17:29.970 --> 17:34.200
And when we get a response from the server we know the turtle has been removed.

17:34.200 --> 17:36.330
And we find the turtle from the list.

17:36.360 --> 17:38.940
We update the list and we publish a new list.

17:39.300 --> 17:44.970
And now we need to do the other side, which is the turtle controller, because who is going to call

17:44.970 --> 17:46.200
this catch turtle?

17:46.230 --> 17:46.500
Okay.

17:46.560 --> 17:48.030
Nobody is calling that for now.

17:48.030 --> 17:51.900
So we're going to create a service client in the turtle controller.

17:51.900 --> 17:55.680
And I'm going to create first here a method.

17:55.710 --> 17:58.650
Def call catch.

17:58.860 --> 18:06.120
Turtle service will just need to provide a turtle name.

18:06.720 --> 18:09.840
And I'm going to create a service client.

18:09.840 --> 18:16.680
So I'm going to create a service client here for example right here self dot catch.

18:16.740 --> 18:23.490
Turtle client is equal to self dot create client.

18:23.520 --> 18:34.140
I need the interface which is from my robot interfaces dot srv import catch turtle.

18:35.010 --> 18:37.270
All right I provide the interface here.

18:37.300 --> 18:42.700
Catch turtle and Servicename is is here.

18:42.730 --> 18:45.160
Catch turtle and make sure I use the same.

18:46.690 --> 18:49.120
Okay, now I can use this client.

18:50.380 --> 18:55.990
And actually I'm just going to take that code for example that one.

18:55.990 --> 19:04.270
I'm going to take all of that actually and put it there to show you that it's basically the same code.

19:04.450 --> 19:07.240
Just make sure to have the indentation.

19:07.630 --> 19:12.130
So it's not the kid client, it's catch turtle client okay.

19:12.160 --> 19:16.960
So why not, uh, client wait for service.

19:17.530 --> 19:22.450
We want waiting for catch turtle service.

19:22.450 --> 19:30.400
Then we create a request which is of type catch turtle dot request the request dot name.

19:30.400 --> 19:34.210
So it's also the same thing as for the kill here.

19:34.210 --> 19:35.650
It's also a name.

19:36.010 --> 19:37.570
Here we have a name attribute.

19:37.600 --> 19:44.860
A name field corresponds to the total name we do self dot catch total client call async.

19:44.890 --> 19:49.270
With the request we add a done callback with partial.

19:49.270 --> 19:55.420
So I'm going to add from func tools import partial.

19:58.240 --> 20:07.540
And it's going to be the actually callback I'm going to call it catch total.

20:09.820 --> 20:12.250
And I'm also going to pass the total name.

20:12.700 --> 20:12.970
All right.

20:12.970 --> 20:15.400
So you see the code is basically the same.

20:15.400 --> 20:16.720
We wait for the service.

20:16.750 --> 20:17.680
We create a request.

20:17.710 --> 20:18.820
We send the request.

20:18.850 --> 20:20.050
We add a callback.

20:20.050 --> 20:21.250
We add a callback.

20:21.250 --> 20:22.900
And what do we do in this callback.

20:22.900 --> 20:30.460
Well there's actually not much to do because the only thing we receive is well, a boolean.

20:30.460 --> 20:31.540
So success.

20:31.540 --> 20:34.180
You could just check maybe if Future.

20:34.180 --> 20:41.050
So we actually have the response which is a catch.

20:41.050 --> 20:49.120
Total response is equal to future dot result.

20:49.510 --> 21:00.520
You could say if not response dot success and then self dot get logger error.

21:01.060 --> 21:14.440
Uh, for example turtle could not be removed turtle plus turtle name and then could not be removed.

21:14.470 --> 21:15.190
Okay.

21:15.190 --> 21:22.030
So because you know that there is a success flag inside the response, you could handle that and just

21:22.030 --> 21:24.400
print the log in case something bad happens.

21:24.400 --> 21:29.830
We already know from the server side that, well, it's not going to happen.

21:29.830 --> 21:31.570
We just return true every time.

21:31.570 --> 21:34.040
But as the client, you don't necessarily know that.

21:34.040 --> 21:37.460
So you might just handle the error in case.

21:37.460 --> 21:42.590
But basically for this service client you could also have just done that okay.

21:42.620 --> 21:47.210
And just call the service and not really wait for any reply.

21:47.210 --> 21:49.580
But I'm going to do things completely here.

21:49.580 --> 21:54.530
And the only thing left to do is to call that function here.

21:54.530 --> 21:57.470
And when do we want to call that.

21:57.500 --> 22:01.820
Well when we have reached the target, you see we already have the code structure here.

22:01.820 --> 22:09.980
So after we reach the target I will do self dot call catch turtle service.

22:10.370 --> 22:12.530
And I need to provide the turtle name.

22:12.530 --> 22:13.760
What is the turtle name.

22:13.760 --> 22:25.520
Well we are actually chasing the turtle to catch so self dot turtle to catch dot name as simple as that.

22:25.520 --> 22:26.990
And then I'm going to do something else.

22:26.990 --> 22:32.270
I'm going to do self dot turtle to catch is equal to none.

22:32.270 --> 22:36.560
So I put back it to none because we don't need to send any more comments.

22:36.590 --> 22:41.150
Okay, we have reached the target turtle, so I just put it back to none.

22:41.150 --> 22:45.980
Which means that the next time we go to the control loop, you see, we're not going to do anything.

22:45.980 --> 22:47.150
We're just going to return.

22:47.150 --> 22:55.550
And then when we get a new array, we just get the first turtle that becomes the new turtle to catch.

22:55.550 --> 23:00.260
And we can continue to chase that turtle until we reach it.

23:00.290 --> 23:01.910
We call this service.

23:01.940 --> 23:04.550
It's going to kill the turtle on the turtle spawner.

23:04.580 --> 23:12.980
Send back the new array, and we can go back to this subscriber callback and chase a new turtle, etc.

23:13.010 --> 23:18.560
etc. as long as you have turtles on the screen, it's going to continue to chase turtles.

23:18.590 --> 23:21.890
All right, so the loop is kind of finished.

23:21.920 --> 23:24.620
Now we can test the code.

23:26.120 --> 23:30.990
So I am going to well I have the turtle sim node here.

23:31.980 --> 23:33.660
I'm just going to put that on the side.

23:36.120 --> 23:37.980
Keep the total SIM node here.

23:38.970 --> 23:47.520
And then I can start here across to run total sim.

23:48.660 --> 23:51.750
Catch them all with controller.

23:51.990 --> 23:55.560
So it should not print any error.

23:55.560 --> 23:56.130
It's working.

23:56.130 --> 24:01.710
The control loop is working but we don't have any turtle to chase, so nothing is happening.

24:01.710 --> 24:03.660
And then I'm going to start the spawner.

24:03.660 --> 24:12.240
So Ros to run turtle sim catch them all with the spawner and let's see what's going to happen.

24:13.650 --> 24:16.440
So we wait for one turtle to spawn.

24:16.440 --> 24:21.090
And you see, as soon as one turtle has spawned, we chase the turtle.

24:21.090 --> 24:24.360
Then the turtle disappears and then we chase another one.

24:25.470 --> 24:28.950
So you see, it is currently working.
