1
00:00:01,070 --> 00:00:02,840
Welcome to the third project.

2
00:00:03,050 --> 00:00:08,690
In this project, you will create your own Ross service interface and implement it into your code using

3
00:00:08,690 --> 00:00:10,970
what you learned from the previous lecture.

4
00:00:11,390 --> 00:00:17,330
For this project, you will make two nodes one node which acts like a client, which sends a request

5
00:00:17,330 --> 00:00:23,360
of an angle to a robot to turn a camera and another node which takes in the request and sends back a

6
00:00:23,360 --> 00:00:29,510
response, which will be an image the robot takes after moving the camera to the angle specified.

7
00:00:29,960 --> 00:00:34,880
Now, since we do not have a real robot and haven't learned about making robots in simulation yet,

8
00:00:34,880 --> 00:00:41,060
we're just going to have some pre taken images which are named by an angle and return one of these images

9
00:00:41,060 --> 00:00:42,380
based on the request.

10
00:00:42,830 --> 00:00:46,730
These images are available in the resources folder or you can create your own.

11
00:00:47,490 --> 00:00:52,410
It may be helpful to spend some time to think about what message types would be most ideal for our request

12
00:00:52,410 --> 00:00:53,550
and response.

13
00:00:53,760 --> 00:00:56,850
So let's break down what this project will look like.

14
00:00:58,220 --> 00:01:03,860
For this project, we will create two nodes a service client node and a service server node.

15
00:01:04,160 --> 00:01:09,680
The service client node will send a service request of how many degrees to turn the camera to the service

16
00:01:09,680 --> 00:01:10,700
server node.

17
00:01:11,780 --> 00:01:16,160
The server will then return the pre taken image data back to the client.

18
00:01:17,270 --> 00:01:21,080
Then as an added feature, see if you can make your service client.

19
00:01:21,080 --> 00:01:23,480
Display the image for the user to see.

20
00:01:25,400 --> 00:01:30,590
In order to complete this task, I will use the OpenCV Library, which is a commonly used computer vision

21
00:01:30,590 --> 00:01:31,280
library.

22
00:01:31,310 --> 00:01:36,800
I know we haven't explicitly gone over OpenCV in this course, so I'll quickly go over some useful functionality

23
00:01:36,800 --> 00:01:38,330
relevant to this project.

24
00:01:38,600 --> 00:01:40,940
In order to use OpenCV, you must install it.

25
00:01:40,970 --> 00:01:47,390
We will also utilize the complementary CV bridge package to help us convert between ROS and OpenCV data

26
00:01:47,390 --> 00:01:49,340
types when working with images.

27
00:01:49,640 --> 00:01:54,620
We need to also make sure we include dependencies for OpenCV in our package XML file as well as our

28
00:01:54,650 --> 00:01:56,240
C list text file.

29
00:01:57,650 --> 00:02:02,150
To import OpenCV in your python code simply call import CV to.

30
00:02:02,300 --> 00:02:07,790
Then we can also import the CV bridge object from the CV bridge ROS package.

31
00:02:08,210 --> 00:02:12,380
The common utility when using OpenCV is to open an image file on your computer.

32
00:02:12,410 --> 00:02:18,890
We can do this with the image read function shorthanded as I am read, followed by a string with the

33
00:02:18,890 --> 00:02:20,000
file location.

34
00:02:20,410 --> 00:02:26,030
You want to display an image, you can use the image show function which will open a window with the

35
00:02:26,030 --> 00:02:28,130
corresponding image you want to display.

36
00:02:28,430 --> 00:02:33,500
Then we can use the weight key function with a value of zero to signal that the window should stay open

37
00:02:33,500 --> 00:02:36,860
until we close it with the enter key on our keyboard.

38
00:02:37,220 --> 00:02:41,810
Then lastly, you can also have your code ensure all OpenCV display windows are closed when finish running

39
00:02:41,810 --> 00:02:44,630
your script by calling destroy all windows.

40
00:02:45,020 --> 00:02:47,580
So that's just about covers all you need to know about OpenCV.

41
00:02:47,600 --> 00:02:49,940
So now let's jump into CV Bridge.

42
00:02:50,030 --> 00:02:54,890
Once you've written the image, you may want to convert it to a ROS image message from the sensor messages

43
00:02:54,890 --> 00:02:56,030
ROS package.

44
00:02:56,090 --> 00:03:03,530
You can do this by calling the CV to to image a message method of the CV bridge object, then to convert

45
00:03:03,530 --> 00:03:09,500
a ROS image message back to an open CV data type, you can use the image of message two CV two method.

46
00:03:10,230 --> 00:03:15,000
Also a helpful reminder on how to use the image interface type in your custom service.

47
00:03:15,030 --> 00:03:20,670
Here's an example of how to use types from a different Ross package and how to include these ROS packages

48
00:03:20,670 --> 00:03:22,440
as dependencies within your CE.

49
00:03:22,470 --> 00:03:24,030
Make list text file.

50
00:03:27,260 --> 00:03:27,680
All right.

51
00:03:27,680 --> 00:03:32,710
With that OpenCV prep out of the way, it's time for you to try this project out on your own.

52
00:03:32,720 --> 00:03:38,660
So go ahead and download the sample images from the resources section of this lecture.

53
00:03:38,900 --> 00:03:45,440
Then make your custom service, which will allow you to request a degree for the camera to turn, which

54
00:03:45,440 --> 00:03:47,180
responds with an image.

55
00:03:47,420 --> 00:03:53,600
Then, with the help of OpenCV, create a service server which will take the request and return an image

56
00:03:53,600 --> 00:03:59,150
from the sample images, as well as a service client which will be used to make the request.

57
00:03:59,150 --> 00:04:04,430
And as an optional challenge, display the image returned in an open CV window.

58
00:04:04,730 --> 00:04:10,040
With that, pause the video and give yourself an hour or so to try and complete as much of this project

59
00:04:10,040 --> 00:04:11,840
as possible on your own.

60
00:04:20,180 --> 00:04:20,560
All right.

61
00:04:20,570 --> 00:04:21,350
How'd it go?

62
00:04:21,440 --> 00:04:27,110
I'm sure this was a hard project being that you had to use OpenCV, and we have not explicitly covered

63
00:04:27,110 --> 00:04:31,490
it in this course, but this is exactly how it feels to be a robotics developer.

64
00:04:31,760 --> 00:04:36,590
You may have also been able to achieve the same result with a different framework or your own custom

65
00:04:36,590 --> 00:04:37,400
solution.

66
00:04:37,400 --> 00:04:42,620
But as a developer, you always need to balance how to incorporate advanced functionality into your

67
00:04:42,620 --> 00:04:44,900
robots as quickly as possible.

68
00:04:45,200 --> 00:04:48,560
I will go ahead and walk through how I would approach this project.

69
00:04:50,750 --> 00:04:56,360
In order to do this project, make sure you have downloaded the images from the resources section here.

70
00:04:56,360 --> 00:05:01,940
I've gone ahead and downloaded it and unzipped it in my downloads folder, so I'll just go into my package

71
00:05:01,940 --> 00:05:02,840
directory.

72
00:05:09,070 --> 00:05:10,990
And copy the images into their.

73
00:05:15,350 --> 00:05:15,680
All right.

74
00:05:15,680 --> 00:05:16,950
Let's go ahead and close that.

75
00:05:16,970 --> 00:05:22,730
And the other thing to note is I will be using the OpenCV Python module to utilize some of its image

76
00:05:22,730 --> 00:05:27,040
reading, processing and display functions in order to install it.

77
00:05:27,050 --> 00:05:34,910
You can open up a terminal and update your app repository and then install lib opencv dash dev and python

78
00:05:34,910 --> 00:05:36,830
three dash OpenCV.

79
00:05:44,640 --> 00:05:47,700
And so in this case, I've already gone ahead and installed them ahead of time.

80
00:05:47,700 --> 00:05:50,490
But be sure to go through that installation process.

81
00:05:50,610 --> 00:05:57,870
We can double check that this installation worked by starting Python three in terminal and importing

82
00:05:57,900 --> 00:05:59,130
CV two.

83
00:06:01,610 --> 00:06:08,740
And then we can go ahead and run the CV to DOT and then to underscores version and to underscores again,

84
00:06:08,750 --> 00:06:11,930
note that if you have a similar or newer version, you should be fine.

85
00:06:11,930 --> 00:06:17,030
But here we can confirm I'm able to import CV two in Python and here we can just reference what version

86
00:06:17,030 --> 00:06:19,580
number we have so I can go ahead and exit this.

87
00:06:21,610 --> 00:06:22,540
And clear the screen.

88
00:06:23,140 --> 00:06:28,900
OC First thing I'm going to do is open up V's code and create a new custom SVG file.

89
00:06:28,930 --> 00:06:32,680
I'll call this RV file Turn camera, RV.

90
00:06:32,830 --> 00:06:37,660
For this project, I want to take in a number in degrees and return an image.

91
00:06:37,660 --> 00:06:44,140
So I will use float 32 for my request and call the attribute degree turn then separate the request and

92
00:06:44,140 --> 00:06:50,470
response section with three dashes and then for the response I will use the image message type from

93
00:06:50,470 --> 00:06:52,720
the sensor messages library.

94
00:06:52,750 --> 00:06:55,330
I will just call this response attribute image.

95
00:06:55,840 --> 00:06:56,230
All right.

96
00:06:56,230 --> 00:07:02,380
With that, I can save this file and head over to my make lists, text file, and we can go ahead and

97
00:07:02,380 --> 00:07:06,160
add it to our ROS Idle generate interfaces Command.

98
00:07:08,330 --> 00:07:14,150
Note that I am also using the image message from Sensor Messages library, so I need to be sure it'll

99
00:07:14,330 --> 00:07:20,120
make that I also need that package and that it's a dependency for these ROS idle interfaces.

100
00:07:21,920 --> 00:07:29,120
So I can do that with the dependencies keyword and followed by the name of the particular package that

101
00:07:29,120 --> 00:07:30,050
it's depending on.

102
00:07:30,200 --> 00:07:36,410
With that I can go ahead and save the file and we can head over and build the workspace.

103
00:07:39,180 --> 00:07:41,070
All right, so I can go ahead and close this.

104
00:07:41,100 --> 00:07:46,050
Open up our terminal, make sure we're sourced to our install setup file of our workspace.

105
00:07:46,050 --> 00:07:51,840
And now I can run the Ross to interface list command, and I should be able to see our new turn camera

106
00:07:51,840 --> 00:07:53,910
service interface within my package.

107
00:07:54,730 --> 00:07:55,080
Great.

108
00:07:55,090 --> 00:08:01,960
Now I can use this interface in my code, so I'll go ahead and make my service server node within my

109
00:08:01,960 --> 00:08:03,070
scripts directory.

110
00:08:03,100 --> 00:08:04,840
I'll just call it turn camera server.

111
00:08:07,600 --> 00:08:13,720
As usual, I will just copy over the service server code that we created in the last lecture as a baseline.

112
00:08:17,980 --> 00:08:22,540
And I'll go ahead and change the imported service to turn camera.

113
00:08:26,680 --> 00:08:33,520
I'll also go ahead and change the class node service topic and callback function names to match the

114
00:08:33,520 --> 00:08:35,050
context of this project.

115
00:08:42,520 --> 00:08:48,880
And I'll go ahead and delete the current content we have in our callback function for our service.

116
00:08:49,780 --> 00:08:55,300
Now, remember, for this project I will have five sample images which I'm going to choose from.

117
00:08:55,300 --> 00:09:00,160
So I'll just make a note of these values up here in a variable called available angles.

118
00:09:01,570 --> 00:09:07,150
So when I receive a request, the first thing I will do is check this list to which number is closest

119
00:09:07,150 --> 00:09:09,160
to that of the number given by the user.

120
00:09:09,310 --> 00:09:14,410
To make this a bit more organized, I will create another function called Get Image, which will help

121
00:09:14,410 --> 00:09:18,910
with this processing by taking in the degree turn attribute of the request.

122
00:09:24,300 --> 00:09:26,280
Then I can define this function below.

123
00:09:36,970 --> 00:09:42,850
So I'll go ahead and calculate the closest angle by using the min python function and making a condensed

124
00:09:42,850 --> 00:09:43,970
lambda function.

125
00:09:43,990 --> 00:09:48,910
Basically, the min function will iterate the available angles list and I use the key argument to set

126
00:09:48,910 --> 00:09:52,060
a function to find the min value of the given list.

127
00:09:52,090 --> 00:09:56,740
In this case I take the absolute value of each available angle with the angle the user gives us.

128
00:09:59,260 --> 00:09:59,950
Don't worry too much.

129
00:09:59,950 --> 00:10:03,370
If you're not experienced with Lambda functions, you could have easily gotten the same results with

130
00:10:03,370 --> 00:10:04,740
a simple for loop.

131
00:10:04,750 --> 00:10:08,700
Then, just to make sure my code is working properly, I will print out the closest angle.

132
00:10:08,710 --> 00:10:14,470
Then I can recreate the file name of the image by combining the string of fied version of the closest

133
00:10:14,470 --> 00:10:19,420
angle in the available angles list and adding the dot PNG file extension.

134
00:10:19,540 --> 00:10:24,340
In the spirit of keeping the code tidy and organized, I'll make a new function called Read an image

135
00:10:24,340 --> 00:10:29,170
by file name which will be responsible for finding the image from within our images folder.

136
00:10:30,250 --> 00:10:32,170
So now I'll create this function below.

137
00:10:39,110 --> 00:10:44,390
Now, since we are working with reading and files, I will import the OSS Python module and use some

138
00:10:44,390 --> 00:10:45,410
of its functions.

139
00:10:45,920 --> 00:10:51,200
Now I'm going to want to find our image file dynamically rather than hardcoded in the file path in terms

140
00:10:51,200 --> 00:10:52,550
of where it is on my computer.

141
00:10:52,550 --> 00:10:59,330
So I will use the OSS path dur name function which will return the full file path of a file.

142
00:10:59,450 --> 00:11:03,410
In this case I'll just use the underscore underscore, file underscore.

143
00:11:03,410 --> 00:11:05,270
Underscore python variable.

144
00:11:05,300 --> 00:11:09,210
Note that this will not lead us to the script folder if we are using the ROS to run command.

145
00:11:09,230 --> 00:11:13,880
Instead, we will end up deep within the install folder of our workspace, which is where a copy of

146
00:11:13,880 --> 00:11:16,820
our script is made when we run an build.

147
00:11:17,300 --> 00:11:21,740
So I'll take this directory path string and index it for the install folder.

148
00:11:28,420 --> 00:11:33,670
Now I can crop the string using this index so we only get the file path of our workspace.

149
00:11:38,060 --> 00:11:39,170
Then I'll just take on that.

150
00:11:39,170 --> 00:11:44,690
We want to go into Source Udemy raster package and then the images folder.

151
00:11:44,810 --> 00:11:48,770
Make sure this path matches where you put the images within your package.

152
00:11:48,980 --> 00:11:54,080
Then lastly, I will just tag on the file name, which will be the corresponding number pad.

153
00:11:55,130 --> 00:11:55,610
Great.

154
00:11:55,610 --> 00:12:00,950
Now that I have the full file location of the image, I can go ahead and read it, in which I will do

155
00:12:00,950 --> 00:12:01,980
with OpenCV.

156
00:12:02,000 --> 00:12:04,220
So I'll go ahead and import at the top of the script.

157
00:12:06,410 --> 00:12:11,020
And since I'm here, I will actually go ahead and also import our CV bridge.

158
00:12:11,030 --> 00:12:12,290
And so I'm going to need that in a bit.

159
00:12:13,400 --> 00:12:19,310
This CV bridge is a ROS package, which you should have by default when we did our ROS installation

160
00:12:19,310 --> 00:12:23,330
and we can actually check this by heading over to our terminal and I'll click the screen and do Ros

161
00:12:23,330 --> 00:12:25,070
to package list.

162
00:12:32,060 --> 00:12:35,900
And here we indeed see the CV Bridge package.

163
00:12:38,630 --> 00:12:42,530
You can feel free to check out the OpenCV documentation if you want to learn more about the tools that

164
00:12:42,530 --> 00:12:43,880
are available and how to use them.

165
00:12:43,880 --> 00:12:49,310
For now, I will just head back down to my read in image function and we'll read in the image using

166
00:12:49,310 --> 00:12:53,840
the CV to I am read function which will take in the file location.

167
00:12:53,840 --> 00:12:56,000
Then we can go ahead and return that image.

168
00:12:56,750 --> 00:12:57,110
Great.

169
00:12:57,110 --> 00:13:04,370
So it returns the image to our get image function that we have here, which returns it to our original

170
00:13:04,370 --> 00:13:06,890
callback that we have here called Return Image.

171
00:13:07,430 --> 00:13:12,820
I now have to convert this image data into an actual ROS image message to load it into the response.

172
00:13:12,830 --> 00:13:18,170
Well, the CV bridge CV to to image message function can do that for us automatically.

173
00:13:19,550 --> 00:13:24,860
Then I can go ahead and take my response variable load the image attribute of it, since that is what

174
00:13:24,860 --> 00:13:30,020
I named it in my RV file and set it equal to this image message variable.

175
00:13:30,230 --> 00:13:32,870
Then I finish this function by returning the response.

176
00:13:33,650 --> 00:13:35,840
That should be it for our service server.

177
00:13:35,840 --> 00:13:40,220
So I'll go ahead and save the file and add it to our make list text file.

178
00:13:46,580 --> 00:13:53,840
Now go ahead and save the file and rebuild our workspace to include this new turn camera server Hi file.

179
00:13:57,340 --> 00:13:58,390
Now, let's go ahead and test this.

180
00:13:58,390 --> 00:14:01,270
I'm going to make sure that I'm source do my setup file.

181
00:14:07,070 --> 00:14:09,110
OC our server is running.

182
00:14:09,110 --> 00:14:11,780
So now I'll open a new terminal tab.

183
00:14:13,040 --> 00:14:15,020
And I'll source my workspace again.

184
00:14:17,640 --> 00:14:22,080
And I can use the Ross to service Terminal Command to interact with my server.

185
00:14:22,320 --> 00:14:27,330
In this case, I'll use Ross to service call to send a degree turn request of ten degrees.

186
00:14:27,330 --> 00:14:32,070
And again, I'm hitting the tab key here for auto completion to help me fill in these commands.

187
00:14:33,890 --> 00:14:37,000
OC We see a bunch of numbers flying across the terminal.

188
00:14:37,010 --> 00:14:41,500
This is actually the raw image data from the image our server sent back.

189
00:14:41,510 --> 00:14:48,670
And if we look above in our server terminal, we can see it calculated the closest image to be the 15th

190
00:14:48,680 --> 00:14:49,760
degree image.

191
00:14:49,760 --> 00:14:52,730
So it seems like our code is working just fine.

192
00:14:52,730 --> 00:14:58,220
So now I'll go ahead and make a client that can actually take the image data returned by the server

193
00:14:58,220 --> 00:15:00,640
and open a display window for us to see it.

194
00:15:00,650 --> 00:15:06,520
So I'll head back over to V's code and create a new script which I'll call Turn camera client Dot Pi.

195
00:15:08,610 --> 00:15:14,070
As usual, I'll go ahead and copy over the code that we created in the last lecture for our service

196
00:15:14,070 --> 00:15:16,290
client as a baseline.

197
00:15:18,260 --> 00:15:21,350
And I'll change the contents to match this project.

198
00:15:41,620 --> 00:15:41,920
All right.

199
00:15:41,920 --> 00:15:45,370
So we've gone ahead and created our turn camera client.

200
00:15:45,370 --> 00:15:53,500
And I still have this self request call, which takes our turn camera service and creates a request

201
00:15:53,500 --> 00:15:57,850
object, which we're going to be utilizing in this send request function.

202
00:15:57,970 --> 00:16:04,720
Now, instead of an integer, I can go ahead and convert this over to a float and we will have to change

203
00:16:04,720 --> 00:16:08,280
our request type to match what we have in our SRI file.

204
00:16:08,290 --> 00:16:14,440
So my request has the attribute degree turn, so I'll go ahead and match that naming convention.

205
00:16:17,290 --> 00:16:21,090
Then we'll go ahead and wait for the service server to be available.

206
00:16:21,100 --> 00:16:26,500
We have our future object, which we will make our asynchronous call with our degree turn that we have

207
00:16:26,500 --> 00:16:31,270
set up and spin until the future complete, until we return our result.

208
00:16:32,230 --> 00:16:35,080
So the only thing I've got to change now is if I head down over here.

209
00:16:35,920 --> 00:16:37,630
Change what our input is.

210
00:16:37,630 --> 00:16:44,320
So in this case we will say enter a number in degrees to turn the camera.

211
00:16:47,010 --> 00:16:52,230
Now, rather than just printing the result, we want to actually open a display window.

212
00:16:52,620 --> 00:16:57,180
So within my class, I'm going to create a new function called display image.

213
00:16:58,830 --> 00:17:03,750
And this is going to take in the image message that gets returned to us by our service server.

214
00:17:03,930 --> 00:17:08,790
Now, in order to complete this, I'm going to need my OpenCV and CV Bridge imports.

215
00:17:08,820 --> 00:17:11,970
So I'll go ahead and copy those from the previous file.

216
00:17:18,260 --> 00:17:23,870
And so now we're going to use this bridge again to convert the image message to the CV to format.

217
00:17:26,940 --> 00:17:32,070
Now I can use the open CV's show function to create an image display window.

218
00:17:32,100 --> 00:17:37,660
I'll name the window, turn camera image and pass it in the image variable I just made.

219
00:17:37,680 --> 00:17:43,260
Then I will use the CV to weight key function and set it to zero, which means that the window will

220
00:17:43,260 --> 00:17:45,690
stay open until I press the enter key.

221
00:17:45,720 --> 00:17:50,280
Then I can just make sure it closes all the open windows once we are done.

222
00:17:52,630 --> 00:17:55,540
And it seems my tabs are not configured properly.

223
00:17:55,540 --> 00:17:57,790
So just go ahead and fix this really quickly.

224
00:17:58,660 --> 00:18:00,040
And that takes care of that error.

225
00:18:01,250 --> 00:18:05,860
Then last thing I need to do is actually implement this function down in our main call.

226
00:18:05,870 --> 00:18:12,770
So instead of just doing our server returned, we will take our result and pass it to our display image

227
00:18:12,770 --> 00:18:13,430
function.

228
00:18:14,410 --> 00:18:14,790
Great.

229
00:18:14,800 --> 00:18:15,730
That's it for this node.

230
00:18:15,730 --> 00:18:22,090
Let's go ahead and save it and go over to our Quick List text file and make sure we install this program.

231
00:18:23,380 --> 00:18:24,820
So I'll save this.

232
00:18:24,880 --> 00:18:26,920
I'll go ahead and rebuild the workspace.

233
00:18:28,820 --> 00:18:29,090
All right.

234
00:18:29,160 --> 00:18:30,620
We can head back to our terminal.

235
00:18:31,630 --> 00:18:34,090
So our turn camera service server is still running.

236
00:18:34,090 --> 00:18:35,320
So go ahead and clear the screen.

237
00:18:36,250 --> 00:18:41,470
Make sure this workspace is source and run our turn camera client.

238
00:18:44,600 --> 00:18:44,930
Here.

239
00:18:44,930 --> 00:18:47,720
I get prompted how much I want to turn the camera angle.

240
00:18:47,750 --> 00:18:50,930
I'll just set it to ten like we did earlier.

241
00:18:50,930 --> 00:18:53,630
When we use the Ross to service, call command and terminal.

242
00:18:54,780 --> 00:18:58,980
Oh, and we get an error here saying attribute error turn and camera response object has no attribute

243
00:18:58,980 --> 00:19:03,300
encoding, so it seems like it's expecting an image, but it's getting our response object.

244
00:19:03,300 --> 00:19:07,650
So that means I forgot to edit our callback function in turn camera client.

245
00:19:08,160 --> 00:19:12,060
So here when we send the request, we get returned the entire result.

246
00:19:12,060 --> 00:19:15,630
So this encompasses the entire result object.

247
00:19:15,630 --> 00:19:22,680
So what I'm going to return instead is the image attribute of it, which is the attribute we named here.

248
00:19:22,920 --> 00:19:28,350
So now it's actually returning that image message instead of the response object.

249
00:19:28,350 --> 00:19:33,660
So if I go ahead and save that and we can go ahead and clear the screen and try rerunning this file.

250
00:19:35,880 --> 00:19:37,770
I'll try my ten again.

251
00:19:38,310 --> 00:19:44,640
And this time we get a display window which has the corresponding image for 15 degrees.

252
00:19:44,640 --> 00:19:47,520
Since that was the closest value we had to ten.

253
00:19:49,890 --> 00:19:54,750
Close this window, we can just go ahead and hit enter and we can go ahead and try this out with different

254
00:19:54,750 --> 00:19:55,260
pictures.

255
00:19:55,260 --> 00:19:58,500
So, for example, I could try -17.

256
00:19:59,790 --> 00:20:04,530
And they should give us the -15 image from our images folder.

257
00:20:05,840 --> 00:20:10,250
And you can keep trying this out for all the images we have in the folders corresponding to a certain

258
00:20:10,250 --> 00:20:10,850
degree.

259
00:20:12,510 --> 00:20:18,030
And with that, you have successfully completed this services project in which you implemented a Ross

260
00:20:18,030 --> 00:20:19,680
service to send a number.

261
00:20:19,680 --> 00:20:22,630
We wanted our fake robot to turn its camera to.

262
00:20:22,650 --> 00:20:27,990
And since we don't have a real camera, we instead just returned a pre taken image based on the request

263
00:20:27,990 --> 00:20:28,680
sent.

264
00:20:28,980 --> 00:20:35,850
You also learned how to incorporate the popular OpenCV framework into your raw code to process and view

265
00:20:35,850 --> 00:20:36,750
image data.

266
00:20:36,780 --> 00:20:41,850
So I hope this gives you a little taste as to how you can implement computer vision in your robotics

267
00:20:41,850 --> 00:20:42,810
applications.
