ROS2 Tutorial - ROS2 Humble 2H50 [Crash Course]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome to this tutorial series slash crash course on Rush 2. if you have never used Robot Operating System before even Ross one or if you want a practical and quick refresher of the basics this series is for you and very quickly so you don't get confused Ross means Robot Operating System cross one is the first version of Ross and ros2 is the second version of Ross Ross 2 is now stable enough to be used so this is the recommended way to start with Ross in this series I will sometimes use the term Ross or ros2 and when I do I will be talking about the same thing so the goal of this crash course is simply to get you started with rostu in a very short amount of time you will learn how to install and set up everything how to use the main roster concepts with the command line interface and tools and you will also write your own ras2 programs with python in fact throughout the series we will do together a small but complete roster application using a 2d simulation of a robot I have designed the series so that you can really get a better understanding of the global picture and also get some practical knowledge that will be useful for your next steps with ros2 in this tutorial series I will Target the Ros 2 humble distribution but the concepts and most of the code will also work for other ros2 distributions now there are some prerequisites you need in order to use Ros basically you have to be familiar with Ubuntu and the Linux command line and to write a rose code you will also need to know a bit of python and C plus plus but here we will stick to python so just python will be fine now this crash course is great to get you studied and if you want to go further and dive into more details Concepts projects and C plus plus code I have also a much bigger and complete course on Rush 2. so if you are interested I've put a link in the video description below and I will talk a bit more about this later on now let's get started with the series in this first episode we are going to install and set up Ros to handle on Ubuntu 22.04 so that in the next episode you can start using Ros functionalities here I am going to start from Ubud 220 2.04 that I have already installed on a virtual machine in virtualbox you can use either Ubuntu installed with a dual boot on your computer or in a virtual machine it's up to you so to install ros2 let's first open a terminal and I'm going to put this on the side and let's also open a web browser the open Firefox here okay and let's also put these on this side and let's search for Rush to handle okay you will get two so let's Zoom a bit here you will get to this page on docs.ross.org okay make sure you have a humble in the URL if you don't have maybe you are reading the documentation for another version so let's click on handle here and then here you can see the table of contents and you're gonna choose installation and click on install handle all right now you're going to choose the binary packages installation not building from source and you're gonna go here with Ubuntu and Debian packages and now we have the instructions to install ros2 on a Ubuntu so I'm gonna follow here just the instructions that we need and just a quick note is that maybe when you browse this documentation the instructions will have changed a tiny bit but that's okay it's just because well the documentation is quite frequently updated so if you see something that is just a little bit different no worries just follow the instructions and everything will be okay so the first thing is we need to make sure that we have utf-8 so we're gonna type Locale in the terminal here and make sure that we have utf-8 so here it's good if you don't have it then you're gonna well just run those comments but your passwords okay so that's gonna install some stuff it's already installed for me you run those lines here actually let's put this like that all right so you run the four lines and then let's check local again and of course it's okay you have utf-8 now you will need to set up the sources because you can't just install ros2 like that you will need to set up the sources so that your computer here can find where to download rust and while those instructions here may be removed in the future or maybe modified so if you don't see that don't worry just go to the next step but what you can do is just do this apt cache policy grip universe and if you see stuff like that with 500 and then well you see uh Jammy and universe stuff then that's okay you don't necessarily have to have the exact same thing with for example us here you can see I have f r but the important thing is that you see 500 and universe so if you don't have those you can run those two commands here I'm not gonna run those but you can run there if you don't have the correct lines and now it's really the step to actually set up the sources so you're gonna run this line first to install curl and different functionalities so here actually I already installed it before so nothing to do for me then you run this line okay and add the repository to the sources so you just copy and paste the line and then you are good what you can do is now do an update so pseudo apt update this is going to update and you can see that you should have something like that packages.ross.org with ros2 so you will have something similar and one important thing is that before you install ros2 let's do serial apt upgrade to upgrade all the packages we have okay so you may have a lot or not it depends when was the last time you actually upgraded your system so I'm just gonna put yes and wait for the upgrade okay and now you can go down into the instructions so you have a warning here but nothing to worry about if you have correctly updated and upgraded the packages so now everything is up to date on the system now you can install runs too so here you have two choices you can install roster with this Ros Dash handle Dash desktop or Ros Dash humble Dash Ros Dash base so browse base is actually so you can see the variables just the communication the command line tools you don't have any graphical tools and utilities this is what you would want to have in a limited system for example on a Raspberry Pi or if you have a computer with very lower resources or if you don't have a graphical interface for example but here what we want is to have the base splits also all the utilities some demos some tutorials and some graphical tools so we're gonna install this so you just to serial apt install handle desktop you press enter and here well I've already installed it before for this tutorial but you will see a lot of packages so maybe you will have a few hundreds of packages for a few hundreds of megabytes to download and a few Giga to be added to your hard drive okay so that's gonna be a lot so you press yes and then you can wait for a few minutes it's gonna depend of course on your internet connection speed and the performance of your computer and right once you have successfully installed this then ros2 is installed and just a quick note here is that if you want to install any eros2 package in the future well this is very simple because all the roster package for the handle distribution for example will be Ros Dash humble Dash something so you will just need to run this command pseudo apt install Ros humble Dash the name of the package so this is quite easy now well Ross is installed but we can't just use it like this we need to set up the environment okay because so let's clear this if I just do Rust 2 you will see that ros2 command not found so to be able to run Rows 2 first you need to install it which is done and then you need to Source a setup script here in every session or every terminal where you want to use rust and so if we go to slash opt you will see that this is where Ros is installed you can go to slash to opt Ros and then you will see handle this is the distribution we just installed so Ross handle is actually Ross 200 okay and here you see we have a setup dot bash script and this is the script that we need to Source here okay we need to show that so let's go back to home directory and let's just Source this script and now that this is sourced look at that if I do Rush 2 now so we have the help actually of the comment we don't have Ross to comment not found we have the help of the command okay which means that this has been found and rosto is correctly installed and set up now the thing is let's say I open new terminal and I do Ros 2. once again I have the same problem so I need to set up the environment and now it works okay so I will need to set up the environment for each terminal I use or if you connect with SSH for example you will need to set up the environment for each SSH session and so that's not really convenient all right so what we're gonna do instead is we are going to add this line to the bash RC file in our profile here for the user so that this line is going to be executed every time we open a new terminal all session okay so to do that we are going to use jedit and then you can do bash SC so till the to go to your home directory slash dot bash SC so this is a hidden file press enter and you can see we have already a lot of lines and all this stuff is going to be executed when you open a new session or a new terminal so you go to the very end of the file and let's add a new line here and what do we put we put just this one let's save the file let's quit and now let's just quit all the terminals that we have let's open a new terminal and when you open the terminal this line will be executed because it's in the bash as you know I can do ros2 and you can see now it is working so when you have rush to weave use a draws 2 and the help of the comment it means that Ros 2 is correctly installed and configured and congratulations you are now ready to start using roster in the previous tutorial you have installed and set up ros2 now we are going to directly start a rows to node and understand what it is and very basically put a Ros to node is simply a rouse to program that's going to interact with ros2 Communications and tools okay so I have four terminals here and let's start a node so where can we find the rows to node well actually when you install the ros2 there are some packages that are actually example packages that you can use directly to start a node without having to create one so we're gonna run ros2 okay so the Ros 2 Common line and then space run and after this you will need to provide the name of a package so the rows two nodes are going to be organized in packages okay for example you have a package for a camera driver a package for a navigation of a robot Etc in each package you can have different programs or nodes so here the package we want is called demo underscore nodes and you can press tab here and you can see we have Auto completion so if I press tab twice I get this Auto completion and I have several choices I'm gonna choose demo nodes CPP and then I press space again and now I need to provide the name of the node we are going to go with a node that's name is talker so Rush 2 run demo.cpp docker then you are going to press enter and you can see we have something so the node is running so that's a program that's running and you can see it is printing stuff now you can press Ctrl C to kill the node and just one quick note is that if you don't have this but if you have ros2 command not found is because you have not correctly set up the environment after installing ros2 so in this case make sure so let's go to so let's do Jade it bash SC so let's go to The Bash RC file let's go to the button and at the bottom you should have this line okay Source rpt Ross handle setup.bash and now let's come back to the note so what you see here on the screen are logs from the node and this node is named talker here you can see the timestamp and this is what's coming from the node so that's simply a program that's gonna print publishing hello world with a counter so let's run this node again now we have run running node now in this terminal let's do clear and let's do Ros 2 run demo nodes CBP so I'm going to use the same package and in this package we have other nodes for example we have listener so listen now okay like that I can press enter and look what's here I heard hello world 22 and that's exactly what is written here okay so I have one node here one node here let's do rqt graph in another terminal so what is rqt graph rqt graph is a tool this is a Ros tool that you can use to actually see the graph so what is the graph let's run it and okay let's put it full screen and let's do refresh here so what is the graph the graph is simply the representation of all the nodes that are running so you can see that here we have one node called talker which is the first node we have studied and one node called listener which is the second node we have started and this is actually a topic so we are going to come back to topic later in this crash course but what you can see here is that this node is talking to that node so the node here Tokyo is sending some information to the node listener and that's what we can see here you can see that what's being sent here is received by this program okay let's say I kill the token node okay you can see the listener node I press enter here is still working still waiting for stuff to receive when I start again you can see publishing hello one two let's kill it and you can see here I heard hello world one two and three so with this example here you can see that a node well is simply a program that you're gonna run so it can be any problem it can be a C plus plus program with Python program and the specificity of that program is that it's connected to the roster environment so in this case the node here named talker is gonna send some messages using roster Communications and this node named listener is gonna receive messages also using ros2 Communications you can note also that the logs here are handled by Ros so nodes are also using tools like logging and also when we launched the rqt graph which is a visual tool you can also debug the nodes so a node well basically it's a program that's going to use rust 2 functionalities now let's stop everything so let's do clear and let's stop the rqt graph too okay let's clear this and let's also stop with Ctrl C and clear so now we have nothing running so actually if I do rqt graph you can see so I can refresh here well we have nothing because there is no node currently running I'm gonna use a second example we are going to run so Rush 2 run so that's the same command now we are gonna go in the turtle Sim package so total Sim is a great package to start experimenting with robots in two dimensions and so from Turtle theme we're gonna go with Turtle Sim underscore node okay so name of the package Turtle theme name of the node Turtle Sim node I press enter and what do we have oh you can see we have a window so graphical window and that's blue and inside we have a turtle if I go back to rqt graph let's refresh you can see we have a node called Turtle Sim that's the node we have studied here and this node well the previous nodes we have studied were just nodes that we're interacting with the terminal sending logs and messages here you can see this node is also creating a graphical interface now let's start so I'm gonna actually make uh it here so change the layout a bit and keep the turtle here in this terminal let's do Ros 2 run turtle Sim so still in total Sim package we're gonna do turtle underscore teleop key so I press tab here and let's press enter this note here is going to listen to what you type on the keyboard you can see here reading from keyboard so this is going to listen to what you type and then let's see what it's gonna do so for example I'm gonna use the rows of the keyboard so the app Arrow and you can see that the total here has moved if I use the left okay it's turning up down right you can see I can make the turtle navigate okay and so what's happening here well we have one note here that's responsible for creating a graphical interface with a tattoo and then we have one node here so that's another problem that's responsible for reading from the keyboard and then as we can guess sending some command to that other node okay so this one will be sending comments this one will be receiving and executing the comments now if we go back to the rqt graph let's refresh and let's keep the nodes only here you can see now so we have two nodes we have the turtle Sim node and the teleop turtle node so we have two programs running on the Ros graph and when we have different Communications here but you can see there is one going from the Tilt Turtle to the turtle Sim this is the turtle one command velocity that's the topic and again we're gonna see topics later in the course but you can see basically what's happening this program is gonna send comments to that program all right and that's exactly what's happening and make sure okay that when you want to make the turtle move you have to actually select this terminal with the turtle key okay so that when you use the keyboard you can see the turtle is moving if you select another uh terminal well you're not going to be able to move the turtle you have to select that one all right and that's pretty much it for now so what is a node well a node is basically any program that also has access to Ros functionalities and roscommunications we have seen that with nodes that just communicate between each other and that print logs on the terminal you can also have nodes that create graphical interface nodes that interact with the hardware notes that also for example host a web server or call a web server well anything and now congratulations because you've already seen a lot of things with roster nodes also with the command line so you have an iteration to command line and some raw tools like rqt graph from the next tutorial we are going to see how to create create your own rows to nodes so you can create your own custom rust 2 Programs so let's start to write some code but actually before we even write code we need to do a bit of organization because we need to create a rust to workspace you are not going to create your code wherever okay we need a bit of organization so you are going to create a rust to workspace in this roster workspace you will organize your code through different packages and you will also be able to build and install your custom code in your workspace so that you can actually use it also if you work with a team for example and if you need to share code well that's what you are going to share you are going to share a specific rust to workspace with many nodes inside so you can easily collaborate alright so the first thing we are going to do is we're going to install the build tool for ros2 because as I told you this rust workspace you're gonna write code but you're also going to build your code and build your rust to nodes and what is the build tool for ros2 the build tool is in name colcon so let's just install that sudo apt so we can do sudo apt update Maybe but the password okay and then we can do sudo apt install that's gonna be Python 3 Dash cold cone Dash common extensions so just like that and you can use the auto completion as well so let's press enter okay and let's just install that so yes and let's wait a bit okay great and now it's as simple as this cold cone is installed and we can use it there is just one more thing I'm gonna show you now is because if you just use cold cone like this so that's going to be a command line tool you will not be able to use the auto completion for the different options of the command line so we need to do something more to enable that so let's do clear here and let's go to so CD slash user so USR share and then call Con so Qualcomm underscore AG complete so you should have this now and then slash hook and in here you can see we have a bash script and that's going to be very similar to what we did with the environment setup for ros2 we're gonna need to Source this bash script so that we can use the auto completion for cold con arguments and instead of sourcing this script every time we open a new terminal I am simply going to do jedit um here bash and see so let's open this and let's put that on the side all right we're going to do so so after the line to Source the rust to installation I'm going to add another line source weave this so the path here right there slash user slash share slash colcon are complete slash hook slash this script right there okay so we can make sure that this is gonna be sourced every time we open a terminal or a station let's save the batch AC and quit okay now let's go back to our home directory and here either you open new terminals or you can just do source Vash s so you can make sure that the changes have been made and let's also Source every terminal we have for now source so dot bash SC here and source dot bash s okay so colcon is installed and we can also use autocompletion in all terminals that we have plus any new terminal that we open will be already correctly configured great now we have colcon and the autocompletion let's go back to creating our workspace and so what is a ros2 workspace well nothing more than a folder actually so I am in my home directory I'm just gonna do mkdir I'm gonna name it ros2 underscore WS so that name is actually quite common that's something you're gonna see quite often as a roster workspace you can use any name you want actually but I'm gonna keep this one for this tutorial so I press enter and then let's go to this Ros to workspace so now we will need to configure this and to actually say that this is a workspace so for now it's empty we are going to create so nkdir SRC we're going to create a source folder that should be named exactly as RC okay so now you have Ros to workspace and inside SRC folder so in this SRC that's where you actually are going to write your runs to node and how is it going to work well you already have Eros to Global installation so you are going to be able to use the functionalities and the nodes from the Ross to Global installations and also your own custom roster nodes on top of this Global installation so we can also call this workspace and otherly okay that's going to be an overlay on top of your Rush 2 Global installation alright and now well what we can do here by going to this roster workspace not in the source but in this rust to workspace directory we can do call code space build you press enter and you can see well zero package is finished because we have nothing in the source directory but the build has been successful if I do LS you can see now we have three new folders We have build install and log so colcon is going to fetch the code that is inside the source folder and then it's gonna do stuff it's gonna build and it's gonna install nodes inside the install folder and if we go to install here you can see that we have actually another setup.script and what do we need to do well we will actually need to Source this setup dot bash script if we want to be able to use our custom roster nodes okay so once again I'm going to go back to let's say here delete and we are going to need to do so let's say I'm here in the home directory I can do source workspace install setup dot Bash after I do this I can use the nodes that I have created and so this line I am actually going to copy it and add it after the last line of the bashasi right here so now in the batch I see I have three lines one line to set up the global roster installation in the environment one line for the cold con Auto completion and one line for the custom roster workspace that we have created so now I save and either you can Source The Bash SC in um so actually not cheated but you can Source The Bash SC in your terminal so that is going to be able to find your custom roster workspace or you can just open new terminals and using this roster workspace you are now ready to start creating aos2 application so you now have a roster workspace which is correctly configured and where you will be able to write your code but there is just one more thing we need to do before we can start actually to write a node we need to create a package so let's go to our ros2 workspace in the Susu choose directory we have nothing for now and we will actually write nodes inside packages okay so packages will allow us to organize the code in a better way also better organize the dependencies between packages so let's see how to create a package to create a package well first you go to the source directory of your workspace and you do rush to PKG and then create okay ros2pkg create and then the name of the package let's go with my underscore robot controller make sure you don't use spaces okay if you want to have different words use underscores and so why do I name the package like that well we're going to control so if you remember the turtle Sim robot in 2D that we have tried before we are going to create a package and inside we are going to write some notes to control this starter so that's going to be a robot controller package and why do I name it like this well we are going to experiment with some nodes inside this package and actually the final project of this crash course is to control a robot so I'm just naming it controller and I just put my robot this is something that is quite common is that if you create a package for a robot you're gonna put the robot name first and then what you want to do so for example can be a controller can be a camera driver a navigation package Etc and if your robot is named let's say C3PO then you're gonna have for example C3PO controller that's good practice to have and then each package is going to be one sub part of your application okay and the package can't contain many nodes each node will be specific to this subpart okay so here if I have a robot controller each node will be specific to the control of the robot if I have a camera package each node will be specific to the camera functionality and then of course between packages you can have dependency you can say that package a depends on package B depends on Package C Etc so what do we have for now cross2 PKG create name of the package now we will need to specify if this is a python package or a C plus plus package okay so either we are going to write python nodes or C plus plus nodes and for this one I'm gonna go with python so you do Dash Dash build type like this and then you're gonna need to provide payment underscore and here I'm going to press tab okay not enter I'm going to press tab twice and you can see we have two choices we have Ament C make and Ament python we're gonna go with payment python so what is element Ament is the build system okay call Con is the build tool that we have installed and that's gonna use the build system named payment so aim and python for a python package payment cmake for a C plus plus package great so now we have a name we have the build type and I'm gonna add dependencies so Dash Dash dependencies and the dependency are basically other packages and functionalities that we are going to need to use in this package and so here I'm just going to write RCL Pi okay what is RCL Pi we're gonna see that when we write the node actually this is the python library for ros2 so because we're gonna write python code we need of course to use the python library and so that's why I added here as a dependency and more on that later in the crash course so now I can press enter and you can see we have some logs with a lot of stuff but let's actually just see so let's do clear and let's see what we have you can see we have a new folder named my robot controller and to navigate inside this let's actually use Visual Studio code or you can use any text editor you want but I'm going to use Visual Studio code so to install it let's do sudo snap install code dash dash classic okay so now I have a visual studio code that was just the line to show you how to install it on Ubuntu and also in the following tutorials I'm gonna show you how to configure Visual Studio code to run with ros2 so you can write nodes with auto completion and everything but for now let's just come back to this package and let's do code dot inside the source directory of the workspace okay so do I trust yes I trust the authors because that's me okay and this is what we have here in vs code so you have the source folder and inside we have my robot controller so if I click I expand and this is what I have in the package my robot controller so everything here has been generated automatically so let's do a quick tour of that so first let's go to package.xml this file will be in every ros2 package so that's an XML file as you can see and it contains the name of the package you can also precise a version number a description also your email if you're a maintainer and you are publishing the code and the license okay so all of that will be useful if you decide to publish your package so for example if you want to publish on GitHub or in the official roster repository you will need to fill those informations then we have here you can see the dependencies and we have depend with RCL Pi this is what we have provided as a dependency in the command line so anytime your package so anytime the my robot controller package depends on another package you're gonna add another depend line here just after that one then we have some more stuff and you can see we have also element python for the build type so that's a python package then we have setup.c FG this file you're not going to touch it it's just to help us to know where are going to be installed the nodes and then setup.py and here you have things that are similar to The package.xml for example the name the version the maintenance the email the description the license okay and we are going to come back to this because actually in the entry points that's where we're gonna precise where actually to install the Ros to nodes but more on that later okay so you have different configuration files here then you have a test folder We're not gonna go into that for now the resource folder okay just leave it like this and we have this folder my robot controller so actually this folder will be the same name as your package name okay that's always going to be the same name and that's very important and inside you have an init.py okay and that's actually inside this folder that we are going to create our cross to nodes okay now let's come back to the terminal and let's go back one folder back to the Ros to workspace folder okay very important to go to this folder exactly and we are going to build this package so let's do call Con build press enter okay and you might see this okay so maybe the build will be successful in this case you can just skip a few seconds of the tutorial but maybe you will also have an error like that and this is because of the setup tool python package that's not working correctly here so I'm just gonna show you now how to fix that so let's go into that terminal and let's use pip3 let's do list and well if you don't have pap3 you can just sudo apt install python 3-bap okay let's install it okay now let's do pip3 list for all the packages and actually let's do a pipe grip setup tools and you can see that here I have setup tools package with version that's the version number here 59.6.0 so if things are working correctly here you don't need to change anything for this package but if things are not working correctly we will need to actually downgrade the version to the 58.2.0 so how to do that pip 3 install setup tools equal equal sign with 58.2.0 let's press enter okay downloading installing and then let's go back to this command pap3 list grep set of tools we have 58.2.0 so we have changed the version for the package and now let's go back here let's do call Con build and it should work okay it's working correctly you can see here qualcon build successful and one package finished which is the my robot controller alright so once you see this success message everything that's inside the package has been built so for now we have no nodes but if you see in the install folder you can see we have a my robot controller folder already and so what's going to happen when you do call Con build well it's going to fetch all the nodes and stuff that you want to install from this package and it's going to install it inside the install folder of the roster workspace and then from there you will be able to use ros2 command line tools for example with ros2 run that we have seen before to start your arm nodes alright so now we have fully ready to write some notes we have a roster workspace that is correctly configured we have also a package that is configured and we can start to write a Rows 2 node with python in the next tutorial now let's write our first node this will be kind of a Hello World node so that you can get familiar with how to write your own nodes how to start it and how to use the command line tools to introspect the node and after this node we are going to start our total controller project so where to create a node let's go back to our Ros 2 workspace here in the source folder we have my robot controller package so we go inside the package and now while this package is actually a python package so we have specified that when we created the package so we are going to go in the folder which name is the same as the package name so let's go to my robot controller okay so we are in my robot controller in my robot controller in the source of rust to workspace this one will contain only init.pi we just leave this here and we are going to create a new python file with touch let's call this my first node.py we just create a file like this okay and let's make it executable with ch mode plus X my first node so now it should be green here in Ubuntu terminal all right so that's the first step is to create a python file and make it executable then let's go back to our source folder of the workspace and let's open Visual Studio code here so I'm going to do code Dot okay and we are in my robot controller package so we are in the source here the source folder and we have my robot controller we have just one package for now if I open this and if I open this one I will see my first node.py and I can start to edit the file so let's add The Interpreter line so like this user bin and python 3. okay so that's interpreter line to tell The Interpreter to use Python 3. and then I am going to import scl Pi okay scl Pi is the python library for ros2 so we will need to import it every time we want to create a rust to node with python now the thing is that well you can see scl Pi is not recognized we don't have Auto completion so if we want to have Auto completion with Visual Studio code and have some nice functionalities on top of that we can go so let's just save the file here and we can go to this here extensions and I'm going to search for the Ros extension so it says do you want to install python let's just ignore that for now and let's search for Ros and find the one with the Microsoft okay so the Ross extension will actually work for cross one and for Ros 2. okay and that's the one we're gonna install so let's click on install okay now it should be good so let's go back uh actually to the extensions and let's see what we have installed so as you can see now we have different extensions that are installed so we have Ros we also have python okay which was installed with the Ross one okay we also have C plus plus so if you want to write code with Visual Studio code and do Python and C plus plus you just install the Ros extension that's going to install python C plus plus and everything you need so now we don't need to worry about it anymore so you can see now scl Pi is recognized and we will have Auto completion for all the features in scl5 great and maybe you need to restart vs code depends hey I don't need to so I'm just gonna continue like this now what I will do is I will create a main functions diff Main and I'm gonna put X is equal to no so I'm gonna allow this main function to receive some arguments and by default I put them to none okay let's just put pass for now we're gonna fill this function later and then let's do if name is equal to name and let's call the main function okay so this is gonna be useful when we want to directly execute the file from the terminal for example by just running the python script and having a main function just like that will be useful when we want to install the node with ros2 functionalities so what do we want to do in the main function well the first thing to do is to initialize rust to Communications so to do that we do scl by Dot in it and like that we can pass args is equal to X so the arcs parameter of the init function equal the args that we get from the main and so this is going to be the first line in your main we initialize scl Pi or basically we initialize ros2 Communications the last line is going to be scl by Dot shutdown all right and everything you will write will be actually here so first line scl by dot init last line scl Pi dot shutdown so that your stats roster Communications and you shut down roster Communications and in between we will be able to create a node so the node is actually not the file itself is actually not the program itself the node will be created inside the program and so for now of course we're going to create just one node per program but as you get more advanced with ros2 you will see that you can actually run multiple nodes from within the same program all right so let's just start with the first note now and actually in Rust to the way to create nodes is to use object oriented programming so we are going to create the node actually outside of the name here we are going to create a class and this class will actually inherit from the node class of scl Pi so we need to do from scl PI Dot node import node and then we can create let's say my node so that's going to be the name of the class open close parenthesis and we put node and then column so by doing this we define a class my node which inherits from the node that is from scl Pilot node why we do this so that our class can already have access to all the functionalities of ros2 now in this class the first thing to do is to create a Constructor so Dev init like this with self and the first line in the Constructor is going to be super okay we're gonna call the Constructor of the upper class so the Constructor of the node class here so super open close parenthesis Dot init open close parenthesis and here we are going to provide the node name that we want to have so this one is the node class okay it's just for programmatical purpose that's the node class we're going to use in the program but this is the nodes name that's going to be used when we actually run the node in the graph okay so let's call it let's say first node okay I'm using on purpose I'm using a different name for the node's name and the file's name okay just to show you as an example and I'm gonna come back to this just a bit later so by doing this we have initialized the node and that's the minimum you need to do to create a node create a Class A Constructor you call Super and you give the node's name now let's go back to our main here so what do we want to do well just after we initialize ros2 Communications let's actually create the node so let's just do node is equal to my node and what in the Constructor we don't have any parameters so nothing in the parenthesis here you can add as many parameters you can just do whatever you want okay that's a class so you can customize it as you want for now we have nothing just self okay so we do node is equal to my node and then we have created the node inside domain so what's going to happen here we initialize roster Communications and first two features we create a node that's actually inherited from the node class of scl Pi and then well we're gonna run some stuff and then at the end SEL Pi dot shutdown which is gonna also destroy the node and everything inside the node and shut down all Ros 2 Communications foreign line so that the node can actually do something because if we run like this nothing is going to happen so let's do self dot get logger okay so self will actually get the functionalities of the node class okay so inside this we have get logger dot let's say info and then let's say hello from cross2 all right so that's the way to write a log with rust from within a class you do self.getlogger.info and some text let's save this and now let's go back to the terminal and maybe on that on that one let's go to cross to workspace Source my robot controller my robot controller we have the file let's run it my first node okay you can see hello from rust we have a log with info level the timestamp first node is the name of the node as defined here okay and then we have hello from ros2 all right so that's working and we have run our first node okay so actually what we have run is a python script that we have set as an executable so we have run a python execute table and in that execute table we initialize ros2 we create a node we do stuff with the node and then we shut down cross2 now as you can see when I run the node we have something printed and then we directly exit from the node but if you remember when we have studied a few nodes previously well the node was continuously running and we had to press Ctrl C to kill the node here once again you can see the node directly exits so what I'm gonna do I'm gonna add after creating the node and of course before the shutdown I am going to do scl5 dot spin and pass the node as a parameter okay what is that so what is the spin functionality in ros2 well when you make a node spin basically what it means is that this node is going to be kept alive so it's going to continue to run indefinitely until you actually kill it with Ctrl C for example and while it is alive all the callbacks of the node so we're gonna see later how to create callbacks for the node so all the callbacks will be able to be run so basically we keep the node alive so that it can continue to run and to communicate with ros2 functionalities until we want to kill the node and when we kill the node with Ctrl C this is gonna return and then we can do scl by shutdown which is gonna destroy the node here the class and everything and shut down roster communication so let's save this and let's go back to the terminal let's run it again you can see hello from ros2 but now we are still you can see the node is still running okay I can press enter we are still in node now I press Ctrl C and you can see the node is killed so we have this exception which is not really a problem okay don't worry about this about the keyboard interrupts it's not a problem but you can see here that now the node is alive and we have to kill it with Ctrl C so that it stops all right let's come back to the node now well we have run the node from the terminal as a python script but that's not what you want to do later what you want to do is to be able to run it with the ros2 functionalities for example with ros2 run like we have seen before so how to do that we will need to well actually to install the node how to install the node well that's very easy you go to setup.pi of your package okay so my first node is in this package I'm gonna go to the setup.pi in setup.pai here I have entry points with console scripts I'm gonna go inside the array of console script press enter add some quotes and now what I will do is I will create an execute table name okay so for example test node and then is equal to I will need to put my robot controller so package name dot file name my first node my first node without the python extension and then colon main which is actually the function we want to run so if I go here I have a main function that's the one I'm going to provide here okay so test node this is going to become the ros2 execute table is equal to package dot file name colon function we want to run I am saving with Ctrl s and now let's go back to the terminal and we are in our rust workspace in the source folder I'm going to come back to the ros2 workspace here where we have the build install login source and I'm going to do call Con build let's press enter okay and you can see now the package has been built and now this is very important after you have built the package if you want to use new functionalities that you have developed in the package you need to Source your environment again okay you need to Source your workspace how to solve the workspace you can do source Bash I because all the source lines have been put in the brush essay so Source brush SC okay and now we can do Rush 2 run my so let's use autocompletion my robot controller if I press tab here we have test node so as you can see my robot controller this is the package test node this is the node that we have created I press enter and you can see we have the node here hello from ros2 still alive and now I can press Ctrl C to kill the node so now I'm going to come back to the names here that are very important so my robot controller this is the package name but then you can see we have so we have test node here we have used test node which is the pros2 executable then we have the file name which I have named my first node okay and we have the nodes name which is first node okay so make sure you make the difference between the three we have the nodes name inside Ros functionalities we have the file name where you're gonna write your code and we have the executable name which is the one that's going to be installed with Qualcomm build and the one that you are gonna run okay you can see here test node with the command line tool okay so execute table name and then file name and then node name three different things if you want you can use the same name for all of them for the executable the file name and the node name okay that's what I'm going to use in the future actually but here I am making it different so that you can see that there are three different things and now a quick tip I'm going to show you that's going to help you to develop faster with python so the thing is every time you're gonna change your python code you will need to actually build again okay with call Con build and then you will be able to run the updated version of the node but with python you know that actually python is an interoperative language so that would be nice if we could actually skip the building Parts when we want to run a new version of the Python script and how to do that so let's first just I'm gonna just change the log here okay just print rust tool just to show you let's go back to the terminal and now if I run the node again well you can see we have hello from rosto so this is still the old version okay you can see now the code says pros2 but we are still having hello from ros2 so how to fix that let's do click here I am still in the roster workspace I can do call Con build with Sim link install so dash dash Sim link install and you can see I can have the auto completion so if you don't have the auto completion make sure that you have correctly followed the installation steps when we created the rust to workspace when I do this okay let's Source The Bash and see now let's do us to run my robot controller with this node okay we have roster which is well quite expected because anyway we have built the package again but now I'm gonna just remove the two for example I save and now let's run again and you can see we have Ross so we have ros2 now we have Ros we haven't built the package again but because of the simlink install option what's going to happen is that you will be able to directly execute the new version of your script without having to install it or to build it every time all right so that's quite convenient and note that if you have some errors here maybe you will also need to source so when you want to modify the script after you modify the script you also Source The Bash SC and then run the node okay just in case if you have any problem all right now let's come back to the node and actually let's make this a bit more interesting so this node for now does well pretty much nothing it just prints something and that's it and then wait with the spin I'm going to create a very common structure that we are going to use in the following of this crash course and that you are going to use also all the time so what we want to do here let's say we want to print a message every second for that we are going to use a rust to timer and Eros to call back so the pretty simple is simple we create a timer inside a node that's going to say every once again I'm gonna call this function and this function is going to do something so let's create actually this timer callback with self okay so we create a timer callback inside the node okay very important inside the node with the correct indentation and here we do self get logger and let's say hello so nothing very special we just create a function that prints hello so actually not get logo hello but getlogger dot info with hello and here let's remove this line and let's do self dots create timer okay so you have another function inside the node that is create timer now you need to give a timer period in seconds and that's a float number so let's do 1.0 and then a callback self dot timer callback without the parenthesis okay here choose the name of the function and that's pretty much it let's just run this so save and run let's see what it does hello you can say hello hello hello Etc every one second you have hello so what happened here is that well we first initialize Rows 2 and then we create a node in the Constructor so we set up the node with the name we create a timer that's gonna call the timer callback every one second so until no nothing happens but then we call LCL Pi dot spin with the node so the node is going to be kept alive and spin actually will enable all the callbacks for the node so that's where it is super important is that this timer is a rust to functionality that's going to call a callback this callback will be enabled because of the spin so the spin will make sure that this node will execute all its callbacks and so every second this is going to be called and we can print hello we can also so let's say for example we add here self dot counter I'm going to use underscore at the end for attributes of the class is equal to let's put zero and then let's put hello plus Str dot self counter like that so we're going to print the Contour and then do self dot counter plus one okay so the ID is to print hello zero hello one Etc I save let's run again okay hello zero hello one hello two hello three Etc well now let's run it again and let's run here let's do clear let's run iqt graph okay let's refresh you can see now we have so we have first note okay that's the node that we have actually defined here this is the first node that's running okay so we can see it with rqt graph for now well there is just one node there is nothing else and this node is not communicating with any other node so that's just one note here and I'm gonna show you another comment because you have seen so you have seen the rust to run command to start a node but then you can also use suits to CD here you can also use rush to node so the rust to node command will allow you to introspect your nodes you can do Ros to node list you can see I have first node you can do Ros 2 node info with the name of the node okay that's gonna give you some information that we're gonna see actually later all right you have not created your first node and used a few of the most important rust to functionalities such as logging timers callbacks spin Etc you can also start your node and introspect your cross graph hey hope you're learning a lot and I also hope you like this crash course if you find it useful then you might want to check out my complete roster course which contains more than 10 hours of structured video lessons I will leave a link in the description if you are interested alright and let's continue with the video but now we are going to start focusing on Rust 2 Communications with topics you have seen what are nodes and how to create nodes now let's see how nodes communicate between each other with topics and to do that let's simply start some nodes and I'm going to explain to you along the way so let's do Ros to run demo nodes CPP let's start the Tokyo node so this node will as you can see write some logs on the terminal and say publishing hello world with a number in this terminal let's do rush to run demo nodes CPP listener oh listen and as you can see here it's quite obvious that what's being sent actually what's being published here hello world 25 is received by The Listener note okay in this terminal I'm going to do rqt graph yeah okay and you can refresh you can put nodes only or maybe notes topics all so you can have the view like this and what do we have here well as you can see we have the node talker we have the node listener so nothing new and we have this box slash chatter what is Chatter well chatter is actually a topic and so what's a topic well it's simply a way to communicate between nodes okay you will have nodes that are gonna publish so the Tokyo node is going to publish on the chatter topic and The Listener node is gonna subscribe to the chatter topic okay so in order to make one note communicate with another one by just sending data from one to the other one you're gonna use a topic so the Tokyo is actually not talking directly to the listener the Tokyo is publishing to chatter and The Listener is subscribing to chatter so in the end this data is being sent from the tokenode is going to be received by the listener but going through this topic okay let's come back to the terminal and actually let's use some more command line tool so ros2 you have seen in ros2 run you have seen Rows 2 node actually you can do Ros 2 topic with list and you can see we have the topic Charter I can do Ros to topic info slash chatter and you can see we have the type we have one publisher we have one subscriber okay so the publisher is going to be actually this one the talker the subscriber is the listener now I can do Ros 2 so this type is actually what is being sent okay because there is the topic name which is Chatter but then there is also kind of a data type that you need to respect when you publish or when you subscribe so you can do rush to interface that's going to be called an interface show with this and you can see that in this so we have some comments and you have string data so what's being sent between the talker and this listener is actually a message called so STD messages slash message slash string which contains the data of type string now let's kill this and let's kill this so you can see with command line tools you can actually introspect and see what's going on in your graph you can use the ros2 topic to see in the terminal you can use also rqt graph to have a visual representation now you can also listen to what's being sent to a topic directly from the terminal so let's say you run the talker just the talker The Listener is not running let's do here ros2 topic equal slash chatter so now we know the name of the topic because that's the one we have found here okay let's press enter here and you can see we receive data hello world 17 here etc etc and the data is here because that's actually the data type here it's so the data types so the interface is actually of type string and the name of the message is data so we receive data with hello world something what's happening in the subscriber of The Listener is that the message is going to be processed okay so we don't have data we just have the string here so I can also run the listener and you can see here we will receive the message in this terminal and in that terminal Okay so we've um I can show you that with rosstopic info we have one publisher and we have two subscribers if I do accuracy graph again let's refresh and let's also uncheck the debug so don't worry about this and and that what you can see now is that we have the topic Charter we have one publisher and we have two subscribers we have the listener node and we have a node that's actually being created when we create a subscribers so when we actually use the rest topic uh equal comment that's going to create a subscriber just in that terminal okay so you can see that we can have many subscribers for one topic and we could also have many Publishers for one topic and so all the Publishers are gonna publish to this and all the data is going to be sent to all the subscribers so this subscriber is gonna receive the same thing as this subscriber for example now if I let's say kill this one I go back to rqt graph I refresh you can see now we don't have this node anymore we just have the listener I'm gonna remove debug okay now okay that was the first example let's use another example so let's clear this let's come back to the Turtle theme so rush to run Turtle Sim with Turtle Sim node okay so we have the turtle seamless put that actually on the side and in this one let's do rush to run total Sim and what we have we can also run the total Tilly up key okay and with this if I select this terminal and I press the rows of the keyboard I can make the turtle move okay now here let's do rqt graph let's actually refresh and okay you have group two let's go to zero okay so that the view is going to be maybe a bit more simplified so what we have here we have two nodes we have the turtle Sim node and we have the teleop turtle node and so what's happening what's happening is that you can see that what we have in this node so with the total detail of key node is going to be sent to the turtle Sim node okay because when we actually price the keys on the keyboard in this terminal the total is moving but the total is handled by this program okay so two different nodes so you can see here clearly with the rqt graph that this is going to be actually here total one slash CMD valve for command velocity so we have a topic turtle one command velocity and so the teleop turtle no is gonna send some message so he's gonna publish some message to this topic and the turtle Sim node is gonna subscribe so it's gonna receive messages from this topic and this way this node can actually talk to that node and you can see we have other topics so I'm not gonna give more details about this but you can also see that this node total Sim is also sending messages to the teleop turtle okay so you can have different topics and you can have even like a closed loop control if you want between two nodes okay one node can send some data to the other node and this node can also send data to that one okay so we can have like a closed loop control but for now let's focus on that topic here so this node is sending data to that node if I do Ros 2 topic list I can see here Title 1 command velocity so I can do Rows 2 topic info slash turtle one slash common velocity and I can see I have one publisher one subscriber the publisher is that one the subscriber is that one the type of the data is this one so I can do Ros 2 interface show with the type and I can see that this interface is actually a vector 3 so that's another interface linear which contains X Y and Z and angular which contains X Y and Z so that's a common velocity to give a linear velocity okay following three axis and an angular velocity Following also three axis and so this is what is being sent actually from this node to that node all right so basically put the topic is a way to communicate between different nodes in your Ros application nodes actually don't directly talk to each other they just publish or subscribe to a topic you can have multiple nodes publishing on the same topic and multiple nodes subscribing to the same topic so a topic has a name which is kind of actually the address of the topic so the nodes know where to publish or where to subscribe and they have a data type so they also know what to send and what to receive the topic mechanism is anonymous which means is that for example if a node is subscribing to a topic it is just going to receive the messages from that topic it doesn't know which node is publishing them so now that you have a basic understanding of Ros topics let's write a topic publisher in a python node so to create a python node the first thing is actually to create a python file so let's go back to our roster workspace Source directory my robot controller my robot controller in this we have for now with my first node.py let's actually make that a bit bigger and what we can do is to create another one let's say touch draw cycle dot py so what we will want to do here is to control the turtle so with the turtle Sim node we are going to control the turtle to make it draw a cycle okay so we will not have to actually run the teleop key and press some keys on the keyboard everything is going to come from the code that we write and I do CH mode plus X so now this is an execute table all right let's go back to the source folder and let's do code Dot and we can edit the file so my first node we don't need it anymore this one found out now draw cycle and so let's just init the node so first The Interpreter user bin and python3 and we are going to import scl Pi okay also from scl PI dot node import node because we're going to use the node class and then let's do def main with args is known okay so now I'm gonna go just a bit faster because we have already actually created a node here so make sure that you have correctly followed the previous lesson on how to create a node with object oriented programming in the main function led to scl by dot init with X is equal to X and then scl Pi dot shutdown okay so that's the first thing to do then if you want to also run the script from the terminal directly you can add if name is equal to Main call the main function but I'm not going to do it here so let's just keep it like this now I'm going to create a node so class let's name it simply draw cycle node which inherits from node let's create a Constructor in it self with super Dot init and let's call this node draw cycle as you can see here I use the same name for the node and for the file just make sure that you know of course that this name is different from that name okay those are two different things you can use the same name if you want but this is the file name and this is the node name and then maybe let's do self get blogger dot info node so maybe draw cycle node has been study okay I like to have a log usually in the Constructor of the node so that you can see when you actually start the node that the node has been studied and that it's running okay so now we have initialized the node we still don't have any publisher so let's create a publisher the publisher will allow us to send some messages to a topic so how to create a publisher in ros2 with python well let's create it here we can do for example self so let's create an attribute let's call it command will Pub like that so CMD will so common velocity Pub is equal to self so you can use self create underscore publisher as simple as that the self is the node so the scl pi node and you create a publisher let's open and close parenthesis and then what do you need to give you need to give first the message type how to know the message type well we have seen that in the previous tutorial let's come back to the terminal and let's run so let's well let's run Turtle Sim here rush to run Turtle Sim total Sim node okay so we have the turtle now let's reuse here the rush to topic list you can see that this is the topic we want turtle one command velocity so if we do Rust two topic info with that name now you can see we have the type okay the type is geometry messages message twist so that's what we need to send a Twist message from the geometry messages package all right so to do that I'm going to come back here and I'm gonna do this here from geometry messages dot MSG import twist and you can see we also have the auto completion because the geometry message is packaged okay where is this package well this one was actually installed when you installed rostu with your Global installation and I can put here twist now one very important thing is that because I'm using geometry messages package in my robot controller package so let's go to package.xml and let's add a depend tag after ACL pi depends on Geometry msgs okay so any package that you're gonna use in my robot controller you're gonna also add a dependency here in package.xml and by the way I can also add Turtle Sim because funnel we don't explicitly use Turtle Sim here in the code we're going to do that later but we actually need total Sim to run because we are going to send some comment to the turtle with the turtle Sim package so I also add dependency to Total C to make sure that actually when we run something in this package we have so the python Library RCL Pi the geometry messages and the total Sim packages let's save this and that's pretty much it for the dependencies okay so now I have the message type now I need to give the name of the topic okay so a topic has a message type and a name so what is the name the name is that one turtle one common velocity so let's just use the same with quotes okay and make sure you use the exact same name okay any typo here and it's not gonna work okay and finally I will add 10 here so what is this well this is a q size okay so you need to precise a queue size so basically but let's say that you are sending some messages on a topic in a network that is not that reliable or you are sending big pieces of data the queue size will kind of create a buffer okay so that you can make sure that all the messages are gonna be sent and so the buffer here will contain 10 messages so it's not really important for now you just have to provide it let's just use 10 every time and then when you get more advanced with ros2 you can actually know more about this and use the settings that's gonna work better for your application all right so create publisher with the data type and then the topic name and 10 for the queue size so we have a publisher now while this publisher will not do anything by itself so we need to publish some data and what we are going to do is so let's say we want to send some data so we want to control the shuttle we want to send some data every 0.5 second to give an instruction to move so how to send some data every 0.5 seconds well let's just use what we did before let's just use a timer with a callback so let's do Dev let's create a callback let's name it for example send velocity connect so actually we just create a normal function and how to actually send something to the topic so we have the publisher but how to send something well we will first need to create a message so the message is equal to twist so we use twist with open close parenthesis to create a message object from the class twist and now we will need to fill this so how to know what we need to send well let's go back to the terminal and let's do Ros 2 interface show to see the inside of the interface and now you can see we have vector3 linear so that's another type so we have linear and then X Y and Z so we will have linear.x linear dot Y linear.z and the same for angular angular.x y and z now if we look at the total theme so this message is actually a 3D message but here we are in 2D so we will only be interested in a few of those for example the linear X so the x-axis here will depend on the total okay so from the total going forward this is going to be X okay going perpendicular here this is going to be y okay so if you send a linear X command you're going to tell actually the turtle to move forward so if it's positive and to go backward if it's negative okay so that's a comment we want and then if you send an angular velocity well because this is 2D the only angular velocity we can send is the Z axis okay the Z axis is basically to turn on itself here so by just sending a x linear velocity and a z angular velocity we will be able to make the turtle just turn around okay I'm not gonna go into more details about this this is just mathematics and here the most important is actually to understand how to use rust okay so let's go to the code and let's do MSG Dot and you can see here you have linear or angular so we already have the auto completion with the twist so let's do linear Dot X is equal to and let's use well let's use 2.0 that's the value I have tested before you can also test different values if you want and then let's do MSG Dot angular dot Z is equal to 1.0 great so now we have created a message we have filled the data of the message so you don't necessarily need to fill all the fields okay just the one you want all right so we have created the message and of course what we need to do is to publish the message so how to publish the message we do self dot comment will Pub so the publisher we have created dots publish and we pass the message all right so we create a publisher and then we create a message and we use the publish method of the publisher to send the message as simple as that and now well this node is still doing nothing because it creates a publisher it prints some log but we are not publishing anything so here I'm gonna do self timer is equal to self create timer I'm gonna give 0.5 seconds and the Callback is self send velocity command all right so when the node is created we're going to create inside the node a publisher and then a timer and print something the timer is going to call this function every 0.5 seconds and inside this function we create a message and we use the publisher that we have created here in the Constructor to publish the message so that's it for the node code now let's go back to the main what do we have we initialize rust 2 we shut down rust let's create the node draw cycle node and let's do scl PI dot spin with the node that's it we create the node and we make sure to of course spin the node if we don't make the node spin well we're just gonna exit the program right now if we make the note spin it is going to be kept alive and this timer will work every 0.5 seconds so this is going to be called thanks to the spin method here so let's save this and now let's go to setup.py to actually install the node so how to install the node well we're going to do the same thing as here in console script we're going to add another line so go after this one make sure you add a comma that's very important if you forget this comma you will have some weird errors after that and let's add another node so another executable here let's name it draw cycle is equal to my robot controller Dot draw cycle colon main so what we have here this is going to be the executable name draw cycle is equal to package name dot file name okay you can see here the file name is also the same as the executable draw cycle and then column main because we want to call the main function all right so let's save this as well let's go to the terminal and um okay let's kill this let's go back to Ros to workspace and let's do colcon built and I'm going to also do Sim link install so the simlink install will allow us as you have seen before it will allow us to modify this file here and not having to build again to run the updated version of the node and the thing is we still have to actually use call conville because well the first my first node was already here but draw cycle was not here so when you create a new file and you create a here a new execute table you need to do Qualcomm build the simlink install will only work for executables that are already created okay so let's do this okay finished it was very quick now let's run the total Sim node okay so we have the Twitter signal nothing happens in that terminal let's do source bash SC okay to make sure that we have set up the rust workspace environment and let's do rush to run my robot controller I'm going to press tab twice you can see now we have two executables draw cycle and test node I'm gonna run draw cycle and let's look at what's Happening Here the turtle is drawing a cycle okay and it's cycling around so if we want to debug this and let's do clear so if you want to do some introspection let's do a cutie graph and let's refresh here and you can see we have our node named draw cycle we have the turtle Sim node and the draw cycle is publishing to the total one common velocity topic the Turtle theme is subscribing to this topic so that this node is actually sending data to that node great now let's say I kill the turtle Sim okay well this draw cycle is still gonna send some data to the total one common velocity topic but there is no subscriber so nobody is going to receive it now I can start the third Sim again and you can see the total is gonna continue to move if I so let's uh put the turtle here if I stop the draw cycle node you can see the turtle is going to stop I studied again the turtle is going to move and I stop okay it stops and so the very important thing here is that you need to pay attention to go back here you need to pay attention to the type you're sending and the name okay this is the most important thing you use the exact same name and the exact same type other way the communication is not gonna work and let's come back very quickly and let's run a turtle again and the draw cycle okay so it's working and here let's do Ros 2 topic list you can see we have common velocity still here Ross to topic info with um that one you can see now we have one publisher one subscriber if I do roster topic eco with that topic you can also see what we'll receive okay so we'll receive some messages I'm going to do Ctrl C you can see we will receive some messages with linear X is equal to 2. and then we have 0 and 0. and then angular Z is equal to one that's exactly what we are sending here okay so if you want you can experiment with different values to make different cycle and well congratulations you have written your first rush to publisher in the last tutorial you have created a python publisher so now we are going to create the other side of the communication which is a subscriber so in our python code we will be able to receive data from a topic and now before we even start we need to know what kind of data do we want to receive what topic do we want to listen to so I'm going to render Turtle Sim so Ros to run Turtle Sim node again okay we have this and if we do Ros to topic list let's see what do we want to receive so here common velocity is actually to send data to the total C the pose is actually published by the turtle Sim node so if I do accuracy graph okay let's refresh and if I uncheck those boxes here dead syncs and leaf topics you can see now so we have the turtle Sim node here which is subscribing to comment velocity but the total theme is also publishing turtle one pose so the pose is the current position so pause is position and orientation of the turtle we have also other topics but let's focus on that one so found out the tether theme is publishing to that topic but there is no subscriber so the messages are just not used I can do for example Ros 2 topic Eco with the pose let's see what we get you can see we have so we receive very fast messages with the X Y Theta position okay so that's the x-axis is going to be this one the y-axis is going to be that one and the Theta is going to be the orientation so 0 is looking forward here to the right and we also have linear velocity and angular velocity so let's say we want to create a subscriber to get the current X and Y position of the turtle in the window here so we will need to subscribe to let's come back here to the total one post topic now we need more info so let's do cross to topic info so you see for now we have one publisher and you can see that this is the type Turtle Sim message pause and we can do cross to interface show with this and you can see inside we have float32 so that's the float number X Y Theta and then linear velocity angular velocity that's actually what we have found also here so now we have all the information we need we have the name of the topic we want to subscribe to we have the type and we know what's inside the message now we can start to write some code so well let's actually kill that and let's go to our workspace again my robot controller and my robot controller where we have all our python files let's do touch actually just make that touch pose subscriber okay let's keep things simple here and CH mode plus X pose subscriber great now let's go back to Source repository and code dot to start Visual Studio code here okay and we have this new file post subscriber now we can init so let's init the file and the node so user bin and python3 we will need as always to import scl pi and because we are going to create a node from scl PI dot node import node now let's create a name function X is equal to none so I'm going to go quite fast here scl pi dot init with pass is equal to X and scl Pi Dot shut down okay and everything will be in between so we have our main let's create a class so how do we name this class well let's do Post subscriber node which inherits from node and if init that's the Constructor we call Super dot init and we name the node also keep it simple pause subscriber okay so now we have the basic code for the node what we want to do is to create a subscriber to a topic so how to create a subscriber so let's create an attribute here in the concert.self dot pause subscriber is equal to self dot so it's quite easy to create a publisher you do self.create publisher here you do create subscription self.create subscription you open close parenthesis and what do you need to give first you need to give the message type what kind of message do you expect to receive if we go back to the terminal in that one you can see the interface is Turtle theme message pause so let's just include that let's do from Turtle Sim dot MSG import pose and we can put pose here note that because we use Turtle Sim we need to go to package.xml and it's already here so we already have the dependency nothing else to do so great we have the type and then well guess what the topic name what is the topic name the topic name is that one third one so with the Slash turtle one pose and here okay let's actually go back to a new line here so that is more readable and then the third parameter here will be a callback okay why a callback because actually when you create a subscriber you're gonna receive the messages and you want to process the messages when you receive them so you're gonna create a callback so you're going to create a function that's going to act as a callback and that's going to be called every time you receive a message on that topic so let's name this one pause callback with self and we are also going to receive a message so let's put MSG and the message is going to be of type pause so you can use that with python to make it easier with colon pose to tell a python here that you're gonna get a message as a pause object so you can have Auto completion key in the function all right and what are we gonna do in the Callback so the Callback is going to be called when will receive a message so let's just print the message let's do self get logo with info and let's do Str essage so just the string representation of the message and we will see later how to process it a bit more but funnel let's just print the message we receive okay and in the create subscription we have so message topic name and then the Callback itself dot pose callback and then I'm going to add 10 also as a queue size so if you remember that's kind of a buffer so if you can't receive all the messages immediately for example if you have a lossy network or if the messages are too big this is going to create kind of a buffer so I'm just gonna put to 10 for now and forget about it that's not very important at the beginning alright so quick recap to create a subscriber so you create a attribute here in your node and you do self.create subscription first with the data type then the topic name then a callback and a queue size for the Callback so what I usually do is I call it so what I'm gonna receive underscore callback so that's it's easy to know that this function is actually a callback and then in the Callback you have one parameter which is the message you receive and with a message you can do whatever you want now in order to make this work I will need to create the node here so node is equal to pose subscriber node and do SEO by Dot spin node that's very important because if you don't make the node spin well you're just going to create a subscriber but then that's it the node is going to be killed and SL pilot shutdown with the spin the node is going to be kept alive and whenever you receive a message on that topic this callback will be called thanks to the spinning functionality okay so let's save this and let's try it let's actually install it so let's go to setup.pi I'm going to add a comma here new line and let's do pause subscriber is equal to my robotcontroller dot pause subscriber colon Main so post subscriber is gonna be the executable name then package name dot file name which is that one colon Main main for the main function and then inside the node name here is going to be also post subscriber all right so let's go back to the terminal and we will need to go back here to the rust workspace and do column build and I'm also gonna put SIM link install okay so I'm building this new execute table and with simulink installed I can modify it and not having to build it again so let's do source bash SC make sure that we saw the environment and let's do Rust to run my robot controller with compose subscriber okay so the node is running we have actually nothing why is that because well we create a subscriber and we have a callback and we spin the node that's it so if we don't receive any message well nothing's gonna happen but the node is still here now on this terminal I'm gonna do Ros 2 run Turtle Sim with turtle Sim node let's put that here okay we have the turtle here and you can see now we start to receive messages on the post subscriber okay we will receive a pause with X Y Theta linear velocity and angular velocity okay because now this node is publishing to the topic pause let's check with arctic graph let's actually refresh let's remove dead things and leave topics so let's actually check the boxes now you can see the turtle Sim is publishing to the total one pose and the post subscriber is subscribing to this so it's just like the turtle Sim node was sending messages to the post subscriber so we can communicate between the two nodes and now in this so if I kill actually the total thing you can see we stop receiving messages if I start again we start receiving messages again and now in this terminal let's do Rust to run my robot controller withdrawal cycle now you can see the total is moving and also here we will receive the pose and you can see the X Y and Theta are also moving why is that so let's actually restart rqt graph and let's refresh you can see now we have the draw cycle which is publishing something to the current velocity which is then received by the total Sim and then the Turtle theme is publishing on the post topic and the post subscriber is subscribing to post topic so when the draw cycle is sending some comment the total Sim is gonna move the turtle and is also gonna update the pose so that the post subscriber is gonna receive new updated data and let's come back to the code here actually so we just print found out the strain representation of the message but let's say we want to actually do more stuff and get the fields of the message so we can do that for example let's actually modify the way we print let's just print X and Y with a nice syntax so let's put the parenthesis and then Str with message Dot and we can get access for example to message.x okay and then plus let's put a comma plus Str Ange dot why then plus um let's finish with a parenthesis okay so you can access each attribute so each field inside the message and then well I just print this but you can do whatever you want okay you can update an attribute in the class you can decide to call different functions depending on what you receive Etc so now let's save this and let's actually go back here I'm gonna kill this node I'm gonna source The Bash SC and I'm going to do Rust two so I'm just gonna run the node again and you can see now we'll receive not just the complete message but X and Y so the total is still moving yes and so we'll receive X and Y just like that with parenthesis all right and you have created your first Rush 2 subscriber wow you are still here congratulations why I say that is because many people give up on tutorials after just a few minutes but you have made it until this point and I have a feeling that you're going to continue and finish this rust to crash course if you are enjoying this tutorial so far you can check out my full course on ros2 which actually contains more than 10 hours of video content I will leave a link in the description if you are interested alright and let's continue with the video as for now in this tutorial series we have created one publisher in one node and one subscriber in another node but we can do better than that we can create one node which is going to contain both a subscriber and a publisher and in this particular case with the turtle team what we are going to do is to create a closed loop system for the turtle so first of all let me show you what we are going to do and what topics we are going to use for this closed loop control let's run so plus 2 run total Sim with total Sim node okay we have the turtle and then let's do rqt graph okay so we have just the total let's actually uncheck dead things and leaf topics so we can see all the topics even if there is no publisher or there is no subscriber and now what do we want to do well we want to control the turtle Sim with the closed loop control so we're going to control actually the turtle in the turtle Sim node what we will need to have we need to have actually the pose of the turtle to know where the turtle is and we will need to send commands to actually this topic command velocity so we will create a node somewhere here that's gonna subscribe to the pose and publish to the command velocity and this node is going to monitor the post so receive current position and send an appropriate comment depending on what it has received from the position okay so the loop will be like this closed loop control like that and basically what we are going to do in this controller is we are going to say to the turtle just move forward and then we are going to Define some borders which are not so not this border and not that border but a bit before so that the turtle can actually turn around when it gets closer to the edge of the window turn around and continue to move for example like this and then turn around continue to move Etc so that the turtle can continuously move forward and turn around when it gets closer to any of the edges of the window alright so now that we know what we want to do let's actually to the node and kill rqt graph okay and let's now create a new file so we are going to go to our workspace Source folder my robot controller my robot controller we have already three python files let's create another one touch let's do turtle controller.py and then so let's actually put this here c h mod plus x with total controller okay now let's go back to our source folder and let's do code dot to start Visual Studio code in The Source folder of our workspace so we don't need this anymore okay and now let's edit the total controller.py so first things first let's initialize the node and the file so that we've already seen several times so interpreter with python 3. and then let's import Pi let's import so from scl PI dot node import node we are going to create a main function with X none so that's gonna be the same all the time all right cancel by dot init with x equal args then scl pi dot shutdown okay I'm not gonna create a if name is equal to main so I'm not gonna do like my first node here because we are not gonna launch directly the file we're gonna install it so I just need a main function okay let's create a node let's name it turtle controller node which inherits from node and then def in it self we will need to call Super Dot init and let's give it a name total control okay let's keep things simple and then maybe do self.getlogger with info total controller has been started okay now let's complete the main node is equal to total controller node and then scl Pi Dot spin with the node and that's it for the initialization actually we can also let's save and let's install it directly so we add a comma here and then total controller is equal to my robot controller Dot total controller with a colon and Main and let's save it okay now let's go back to the terminal let's go back to our Ros to workspace and let's do colorcon build Dash Dash Sim link install good now let's do source bash SC and press 2 run to see if we correctly initialize the node with turtle controller and yes we can find it Turtle controller has been started now the node is spinning Ctrl C to quit all right and let's now start the control of the turtle so we will need to create a publisher to the command velocity topic and we need to create a subscriber to the post topic and actually we are going to manage things is that we are not going to so let's see what we did in draw cycle in draw cycle if you remember we created a publisher so the common velocity topic and then with a timer that was running here every 0.5 seconds we were publishing some velocity but we are not going to create a timer here what we are going to do is we are going to create a subscriber to the post topic and in the subscriber callback we are going to publish actually to the command velocity okay so whenever we receive a pause we publish a new comment so let's start actually with the subscriber and we're going to create a subscriber so we actually already know what we need to do here I'm gonna go back to the terminal to find the name and the type you can see the name is turtle1 pose and the type is third simple so let's do from Turtle Sim dot MSG import pose and then let's create a so pause subscriber is equal to self create subscription and the type is going to be pause actually let's go back to a new line here and then the name is going to be let's just use the same name exactly okay total one pose and then we need the Callback so let's create div pose callback with self because we're in a class and then pose so we could put MSG but I can also put pause so same with color and then pause so that we say that this is a post data type which is going to help for the auto completion for now let's just use pass okay let's keep the function empty and let's put it there so self pose callback and then 10 for the queue size all right so self create subscription message type the topic name do call back and then cue size and just like this the subscriber should work because well we have a subscriber a callback and we are spinning the note now let's create the publisher so I'm going to create a publisher here before the subscriber itself comment will publisher is equal to self dot create publisher what message do we need so let's actually go back to draw cycle where we actually did the same thing we need a Twist message from geometry messages and the name of the topic is total one common velocity so let's do that from geometrymesages.msg import twist I'm going to put twist here twist actually let's also go back to a new line or readability the topic name is Total One command velocity written like this and then let's put 10 as a queue size good so we have created a publisher and a subscriber now what do we need to do we need to publish something new when we receive a pause so here we need to check actually what is the current pause of the turtle and depending on the pose we may send different comments but just to try just to try and to make sure that we are actually sending some comments when we receive a post let's just send a very basic and stupid comment to the turtle just to check that just to check that our code is working and that the Callback is working okay step by step when we are sure that this is working then we can think about what's the best way to control the robot okay so let's actually create a command so I'm going to use command is equal to twist okay we will receive a pause here and we're gonna create a command that is actually a twist all right and now in the twist what do we have so let's do command Dot we have angular and we have linear so for this first step let's say that we just want to make the turtle go forward even if it hits the the wall on the edge of the window that's okay we just want to make it go forward so I'm going to do command linear dot X is equal to and let's use 5.0 as a velocity and then command Dot angular dot Z is equal to 0.0 I'm going to leave the other one to zero so no Y and Z linear and no X and Y angular okay I'm just gonna focus on the X linear and the Z angular like I explained before when we did the draw cycle node so we have a Twist command now I can do self dot comment the publisher dot publish with document okay so here we don't use the pose yet but we just publish when we actually receive a post so in the subscriber callback okay so this should be okay let's save the file and let's go back to the terminal I'm gonna move it like this okay clear let's actually see the end source The Bash essay so I don't need to build anymore because I've used simlink install let's just make sure that we choose the bash acid and okay in this terminal let's do rush to run Turtle Sim Turtle Sim node okay we have the turtle right there and in that one let's run the controller so for us to run my robot controller Turtle control and now let's look very closely at what's going to happen to the turtle here and press enter and okay the turtle is moving forward and then hitting the wall okay and you can see I hit the wall Etc so the thing is that it's working it is doing exactly what we wanted to do which is that when we receive a pause so here with the post callback we send a comment to go forward so that's exactly what the turtle is doing and that's already a good progress in this application so now what we want to do is we want of course to not make the total hit the wall but to actually let's say to turn around when it gets closer to the wall and then come back and continue and and just continue to move indefinitely and so to do that we will need to know what are the coordinates so I'm going to show you very quickly uh what are the coordinates so it's just to kill everything let's start the turtle Sim again and here I'm gonna start the teleop so ros2 run Turtle Sim turtle key so that I can move the turtle and when we move the turtle we also want to know what are the coordinates of the turtle and so to get the coordinates well here let's do play and let's do a rush to topic list we have the pose that we can subscribe to and in the post you have the X and the Y but also if you remember what did we do before we did a pause subscriber and in this post subscriber node we actually filter the pose to just bring the X and the Y coordinates which is basically what we want to know right now so I'm gonna use this instead cross to run my robot controller with pause subscriber good and you can see we have so the X here and the Y and so what you can see is that the total is now in the middle at about 5.5 and 5.5 so 5.5 on the x-axis 5.5 on the y-axis now let's move the turtle so let's make it go forward and hit the wall you can see now we are at 11 so just about 11 on the x axis and we are still at 5.5 on the y-axis okay so let's go to the upper right part okay we are at 11 and 11. and let's go to the other diagonal Okay so let's go to the bottom right let's focus here okay and we should reach 0 and 0 yes okay so you can see I'm gonna stop this one you can see that in this window we start at 0 0 here and then on the x axis we go until 11 on the y-axis we go until 11. so we know what other coordinates that the total can reach and so what we could say now is that if the turtle is close to the Border let's say by 2 so if the turtle reaches for example X which is 9 or more then it should turn around then we can do the same with Y is Model 9 we could do the same with X is lower than 2 and we could also do the same with Y is lower than 2. so we can make sure that we actually kind of draw the square inside the square this is going to be the safe Square where the turtle can just move forward and when the turtle goes outside of this which is closer to the actual border of the window then we make the turtle turn around okay so again let's do step by step let's first so let's actually start the Turtle theme and let's imagine the current scenario so the total is going forward okay and let's just make it turn when it reaches this wall on the right and that's it all right so let's stop this and list of that and clear everything and let's go back to the code so we are going to improve this pose callback and here we will need to use actually the pose okay we need to use the current position of the turtle so what I could do here is to check that if pulls Dot X okay we have the x coordinate is greater than nine so greater or greater or equal it doesn't really matter here so if the x coordinate is greater than 9 what do we do we make the turtle move in a circular way maybe let's actually create the comment first and then check this so let's do command dot linear and let's also make the turtle go slower so I'm gonna use linear X is 1.0 and then command dot angular dot Z is equal to 0.9 so why those values well those are values that I've tried before actually and that I know are working so if you want you can just start with those values and then increase a bit the x of the Velocity or decrease them all right to find something that works but by doing this you can see here we move at five so the speed is 5 for the X linear here the speed is one so it's gonna go slower and it's also going to turn under the axis and so if the pause is greater than 9 with this but then we need to do also else and I'm gonna put this in the else so we only go forward if the pose so if the X pose is not greater than 9 all right so we have two different commands depending on the current pose and then we of course publish the command so let's save this and let's see what we have Source SC here let's run the Turtle Sim and let's run our controller so not post subscriber but total control okay good you can see it's turning and then is going again and of course it's gonna hit the wall because we haven't specified what to do if the x is lower than 2. so as you can see here the total was going forward because the x is lower than 9 when X reaches 9 we change the comment so instead of going to five speed on the x axis we go to one and then we also add an angular velocity so the turtle is going to turn to turn until well actually until the X pose is lower than 9 and in that case we just continue to go forward so now what we need to do is we need to handle the case for the left part for the top part and for the bottom part and that's going to be actually quite easy so we can say if the pose is greater than 9 or the pause X is lower than 2. or the pose Y is greater than 9. all the poles Y is lower than 2. and that's it okay so if we do this if we check that actually the total is close to the wall okay so either the x or the Y is lower than 2 or the X other Y is greater than nine in this case we made the turtle rotate otherwise we just continue to go straight let's save this go back here let's kill this one so Splash SC let's start the total Sim node again and the controller again and let's see what's gonna happen okay we turn here and then go straight and then we turn and then go out of this let's turn and you can see it's turning again so here it's hitting the wall a bit but that that's okay okay and we turn again Etc so for example here I'm gonna so I'm gonna stop the controller and you can see when I stop the controller well the turtle just stops moving so you can see here we hit the wall and if you want to avoid that you may want to actually increase the angular Z velocity here but if you do so for example I'm gonna do 1.5 okay and let's see what's happening so let's start the tether seam controller okay what may happen is that the turtle at some point so let's wait a bit okay you can see this behavior is that the turtle is actually gonna be stuck because if it turns too fast it may stay over the limit and the limit here is y9 so the total is over the limit and is stuck so that's why I have actually reduced the angular Z2 0.9 because that's the value I found that works you could go down even to for example 0.8 or 0.7 um and that's okay even if the total hits the wall at some point that's really not a problem okay we are experimenting with ros2 here that's just a simulation all right so let's run it again actually so let's kill this and then do Source bash SC Ram the controller so we can start to run the control actually before the tether signal it doesn't matter because it's only gonna wait for the pose and then send some comments so nothing's gonna happen until we start the turtle Sim node so let's wait uh I'm gonna wait maybe one minute and show you what it's gonna do well then as you can see dirt turtle is continuously moving and turning when it reaches the edges all right so everything is working correctly and let's just run Equity graph to finish here and now we can remove dead things and leave topics and you can see we have our closed loop control so we have the tether seam here and the turtle controller node and you can see the turtle controller is listening to the pose and then sending data to the command velocity so we have a closed loop control here so in this tutorial you are going to understand what are ros2 services and to understand what are Services let's start with the problem so let's say you have different nodes and you want an interaction that is kind of a client server so you want a node to act as a client so it's going to send a request to a node with a server and then the server is going to process stuff and reply to the client and this kind of interaction well is not really what topics are made for okay with a topic as you have seen you send some data from one point to another point but you don't get an answer okay we can do a closed loop system but you can't have this client server architecture with a request and a response and so that's why we have Ros services so let's run a few services and you will quickly understand and then everything will make more sense so in this terminal I'm gonna run so Ros 2 run demo node CPP let's come back to to this package and here we have add two inks seven let's run that so when I run it nothing happens you can say press enter the node is just waiting so this is a node where we will have a service now if I do activity graph the thing is with rqt graph you can't see Services okay you can see nodes and topics but you can't see services so rqt graph will not be useful for services but we also have ros2 service so we have the rust 2 topic command for topics and we have Rose to service for services and you have pros2 service list and you can see we have add two inch Series so a service will have a name just like a topic a topic has a name and a type well a service will also have a name and a type and here you have well you have stuff that is specific to the node add to its server okay so if I do rows to node list you can see we have ADD 2 inch server node and for each node you will have a set of services but we don't really care about those what we want is this one add to int service and so how to get more info about the service Well ros2 Service and then you can see we have actually type okay so when I press tab I can say type and this so you can see that the type for the service is example interfaces SRV for service add to inch so how can I see what's inside Ros to interface show so just like we did for messages with topics we can do rows to interface show for services and let's put this and you can see we have that so that's a bit different so we have something we have int a and int B and then we have dash dash dash and then int Sim all right so this here before the three dashes this is the request that you're gonna send and after the three dashes this is the response that you're gonna get so this node adds two inch server contains the server so contains a service server named add to ins now in order to call this service you need to send a request that is this one int a int B and after you call the server the server is going to process stuff and it's gonna return the response which contains the sum so let's actually try this we can do Ros 2 service so we can call the service actually from the terminal we can create a client from the terminal so Ros 2 service call and then the service name add to ins and then let's press tab twice we need to provide the type so ros2 service call with the name with the type and then if I press tab again well you can see we have weird stuff but what I can do is use actually curly brackets so let's use curly brackets here and let's put a like that for example is equal to 2 and then B with file okay so you can use curly brackets and then the field a you can put a with quotes colon the value you want kids in integer so I put two comma and then do that for every field I'm going to press enter so look what's gonna happen here I press enter here and actually well actually no ID to do so let's change this let's use double quotes around the curry brackets and then single quotes inside I think this is gonna work and yes this is working so yes if you want to color us to service call from the terminal make sure you use that syntax and well that's kind of tricky even I forgot how it was working but yeah double quotes curly brackets and then Fields with single quotes inside so what's happening you can see making requests with a is equal to 2 and B is equal to 5 that's what we want then the response with sum is equal to 7. let's look at the server side we have log incoming requests with 2 and 5. so the request was sent from the client key to the server the server printed this log incoming request processed the request and then returned a response with the SIM and you can see this happens almost instantly let's try again let's modify let's put nine and you can see it's working too we have some 11 and here we will receive 2 and 9. all right so you can see that the service is simply well a client server communication and for the service you can have well only one server okay the servers here in this node but you can have many clients okay I could call the service from this terminal I could call it from another node so I can have as many clients as I want as an analogy let's say you have a web server so the web server for a specific URL for example we only have one if you go to example.com there is only one server on example.com there is only one URL but you can have as many clients as you want connecting to the cell okay so with a service you have one server and as many clients as you want and then we're gonna use services for mainly two kinds of requests either a computation so that's what we did we send some data in the request and we expect something in the response that's a computation related to the request and the second type of service is actually not a computation but a change of settings so in your robot you may have a lot of settings and you can use some services to be able to change the settings so you will have a service server where you want to change the settings and then other nodes can create some requests to change the setting and actually let's try that with the turtle Sim so I'm gonna just clear all of that let's kill this and clear let's run so runs to press to run Turtle Sim Turtle Sim node okay I have the node here let's actually put this on the side and let's do rush to service list as you can see we have quite a few services so we have services that are related to the node total Sim here so we don't really worry about those but then we have a bunch of services for example clear so if you call clear it's going to clear all the traces okay that the pin has left on the window kill you can actually kill a turtle so you could remove this turtle reset I think it's gonna reset the turtle to the center and then spawn you could spawn another turtle so you will have total two total three Etc and then well here the one we're gonna use is turtle one slash set pen okay so as you know the trace that the turtle leaves is gonna be white or light gray so that's what we call the pen okay let's do Ros to run Turtle Sim with Turtle Tilly up key and when I move you can see well it's kind of light gray all right but we can change the color of this we can change with setpane so that's an example of how to change a setting the service server is hosted on the turtle Sim node and then we can call this from another node or even from the terminal so let's do cross2 service type with setpend to know what we need to send okay we need to send total Sim service set pin now let's do cross two interface show with that and what do we have here well we have a request with RGB so right green blue and then the width of the pen and off if you want to turn off the pen that's the request then we have dash dash dash and you can see after dark charges we have nothing because well there is a response but the response is gonna be empty okay so it's possible that you create a service with an empty request or an empty response no problem with that so let's call this service to actually change the color okay let's do Ros 2 service call with and Total One turtle one slash set pen with the Turtle Sim service set pin service and then let's use double quotes Cherry brackets and then ah will be so here we need to give a number between 0 and 255 so let's say we want to change the color to Red I'm going to do it simple let's do 255 and then G is going to be zero and then B is going to be zero as well the width so weights let's try I don't know let's try with three and off off should be zero okay let's press enter you can see so we have nothing on the logs of the total Sim node why is that because simply well the server didn't print any log but you can see it was working because we have the response so we have an empty response because if you remember well in the interface we don't have any response so we still have one that is empty and now let's try to move the turtle and you can see now it's red so the pin has changed to a red pen and the width is three so I guess that the width was three before so that's the same one let's actually change it so let's send another request with six and then I don't know let's put red to zero green to 100 and blue to 100. okay and let's move the turtle again and you can see now we have another Trace that's a bit thicker and so here well as you can see we have called the service from the terminal and this is not that convenient if the service starts to be quite big okay if the request actually starts to be quite big this is not going to be convenient but actually of course later on we are not going to call the service from the terminal that's just for debugging and testing we are going to call it from the code directly that's what we're gonna see just later and one more thing is that so let's say kill the turtle Sim here and well I don't need that as well let's try to call the service and you can see waiting for service to become available okay because the service if I do Ros to service list while the service is listed here because we are calling it but let's do that again we don't have any service so if we try to call a service that doesn't exist well it is going to wait okay maybe you will get an error but here it's waiting if I start the total Sim then you can see the service is going to be up and then the request can be made all right so you have seen an overview of services through two different examples and so you are going to use a service when you need a client server kind of interaction and when to use a service versus a topic well topics are going to be used to send some data streams so if you need to send some data from one part to another part without expecting an answer just sending some data for example sensor data command velocity data this kind of data stream will be handled by topics but when you need to make some interaction where you're gonna for example compute something or change a setting and you expect also an answer then you are going to use services so in this tutorial we are going to create a service client with python and to see what we need to do let's actually come back to the application with the turtle controller that we have so let's run so for us to run a turtle Sim with Turtle Sim node okay we have the total here and then we have the controller roster run turtle um no actually my package my robot controller with Turtle controller so for now what we have is the total is correctly controlled to move around and not hit the wall what we want to do is we want to kind of split the screen in two and say that on the right we want the color to be let's say red and on the left we want the color to be green so the color of the pin all right so we wouldn't want to modify the color depending on if the turtle is on the right side or on the left side and how can we do this with ros2 service list we have just actually used so this one the total one set pen Series so we have just used this one in the previous tutorial to explain what are services and so that's the one we are actually going to code so we are going to call a service client inside our Turtle controller so that we can modify the color of the pen depending on where the turtle is okay so let's actually do that I don't need to create any new node or anything I can just go back to so let's go to the source folder of the routes to workspace and let's do code Dot and let's go back to the code so the turtle controller here and so that's where I am going to create the service call and where are we going to create the service call actually what we are going to call the service from the post callback okay because we need to call the service depending on where the turtle is if the turtle is on the right of the screen which means that actually the pause X is greater than 5.5 which is the middle then we're gonna choose the color red if it's on the left side we choose the color green and so we will need to call the service so to create a client with a request in the post callback okay and to do that I'm going to create a new function a new method in the class Dev call set pen service okay because we will have a few lines of code to do that so I'm going to create a method that is specific just to call the service okay let's do self and then let's put all the parameters we need so r g b with off okay how do I know that because if you do Rush 2 service type with the set pen okay where do I have nothing okay because well the service actually doesn't exist I need to run us to run total Sim Turtle Sim node then this should be better and rust to interface show we've that we have RGB with and off so those are the five parameters of the request so I create a function and I just send this as the parameters and then what do we need to do well we need to create a client in the code so clients is equal to self so self is the node create client as simple as that what do we need to provide we need to provide the service type what is the service type the service type is total Sim and SRV set pen so we are going to do if from so from Turtle Sim dots SRV okay we did NSG for messages for topic and here for service we do SRV import set pen now we need to make sure that we have the dependency to Turtle symbolt we already added it before okay in the package.xml we have total theme so everything is good so I have set pen that I can put here set pin and then we need to provide the service name all right so very similar as for topics or topics we need to provide the type and the name here we need to provide the type and the name what is the name the exact name is this with quotes it's going to be better okay and that's it for the creation of the client so now we have a client well actually we have nothing we just have an object representing the client what we will do is we will say let's say we want to wait for the service okay we don't want to call the service if the service is not up because if you go to service and the service is not up well you're going to have an error here I'm going to do while not client wait for service so you have this wait for service method in the client here that you use with create claimed and we need to provide a timeout let's say one second and here we're gonna do self dot get logger we're gonna log something and instead of info I'm gonna use one okay one is gonna print something with the yellow color and let's say waiting for service so we do wait for service for one second if the service is up so this is just gonna return immediately and we can continue but if the service is not up after one second we are gonna print waiting for service etc etc until the service is up all right now we have a client we know the service is up what we can do we can create a request so let's do request is equal to set pen Dot request so actually a request with an uppercase and open close parenthesis and then we are going to fill the request so request Dot R is equal to R okay that's going to be what we get from the parameter here and then request dot g is equal to G request dot b is equal to B request dot width with all right and the last one request dot off is equal to off so we just repeat the parameters inside the request nothing really fancy here and then well we're gonna call the service okay we have the client the services app we have the request now we can call the service so we can do clients call async so this will call the service in an asynchronous way what does it mean it means that it's gonna return immediately if you call it just with the call like this it's gonna call the service and then wait so block right here until the service has replied but if you do that you may have some problems with the different threads okay with the spinning and I'm not gonna go into much details here but if you block the thread that's calling the service you may have some errors for example that the response is never received so I'm gonna call call async and I need to send a request okay so client dot call async request this is actually going to give me a future object okay so we are going to work with future and also I'm not gonna go into much detail about future but basically a future is something that's gonna be done in the future basically so you can work on this future you can add a callback so that when you actually get the response from the service then the future is gonna call this callback and you can process the request and that's what we're gonna do so I'm gonna add here a callback div call back um let's call it callback set pin self and also future here so that's how to write the code so here well I'm showing you how to write the code it may sound a bit complicated for a service but the thing is that is always going to be the same thing so the first time you write the service client it's a bit difficult but then you're gonna write it a second time a third time and then you're gonna have written it 10 times 20 times n it's gonna be super easy at the end so here in this function let's do pass for now and that's going to be the callback for when the service replies with the response okay we call the service we send the request asynchronously so that this method is going to return and then we need to add a callback for that and to add a callback for that I'm gonna do future Dot add done callback and here I'm gonna use partial with self callback set pin so I'll provide the Callback here and partial is not found you need to import it so from thank tools import that's one thing you need to import okay with python thank tools and partial then we put future dot add down callback with partial self callback set Pane and this is gonna call this method when the service has replied and in this what we do is we do response is equal to future so that's the future we get here dot result also I'm going to add this inside a try and accept block because we might have a service exception I'm just going to accept um exception as e and if I get an exception I can do self dot get logger and here I'm going to use error okay so that's yet another level of logs okay we have info one and error and I can say service call failed and I'm gonna use this syntax with r here and then percentage e comma inside parenthesis so that's a specific syntax but that's just how you can print an exception easily here with ros2 Services all right and now the service call is complete so to recap quickly here we create a client with self create client we set the type and the name of the service then what you can do is you can also wait for service to make sure that the service is available then you create a request you do client dot call async to send the request to the server and this is gonna give you a future object then you can add a callback with future dot add don't call back and partial you can add a callback so that the Callback is gonna call when the service replies when the service replies you need to do a try accept block so that you can manage the exception if you get an exception okay so if the service could not be correctly handled by Ros 2 or if I don't know if anything bad happens then you're gonna get an exception and you can print the exception with this syntax and if everything works correctly then by doing future.result you're gonna get the response and here when I do nothing with the response why is that because uh here with Ross to interface show you can see that we have this for the request and then Dash and we have nothing in the response so if you add something in the response for example with the add to in server that we have used previously you could for example do response dot sum and that will be something you can use in this node class okay you could use it to do whatever you want you can process the response and do anything else you want all right so now we have the Syntax for the service call and this well basically this is gonna be almost the same every time you call a service inside a Ros 2 python node now well let's actually call the service because we have the main sold but we don't use that method where are we gonna use it well we're gonna use it in the pause callback so what do we do in the post callback we get so yeah we get the pause and then depending on the pose we send a different comment We're Not Gonna Change that but after we do this we're gonna also check where is the turtle so depending on the X property of the pose we're gonna change the color of the pen so for example if x is greater than 5.5 so actually pause dot X so we know that the middle point is 5.5 so everything on the right of the window will be more than 5.5 everything on the left will be less than 5.5 so if it's more than 5.5 what we can do is to do itself dot call set pen service with so we want it to be red so let's do 255 0 0 and then width let's put three and off let's put zero and then else self dot call set pen service with zero so 255 for the green 0 3 0. all right so right side of the screen right left side of the screen green as simple as that and maybe we can also add a log self dot get logger Dot um info set color to red and let's do the same here self dot get logger dot info set color to Green all right so we know when we send the request actually if you want you could also add some logs in the call set pen service and also in the Callback so in the try block to see when you get the response when you send the request Etc good so this should work but I'm gonna add something else because well now the question is how frequently this is going to happen oh no we didn't really worry about that but now we should why is that because well when you publish on a topic you can publish at very high frequencies for example 100 Hertz 1000 Hertz that could work also even a few thousands Health sometimes you have some topics that are published very very frequently but for services the service is not made to be called 100 times per second okay a service is made so that it's called when you need to call it in a punctual way so it doesn't necessarily mean that you can't call it so it's 10 times per second but the best way to handle Services is just to call them when you need to otherwise it can really slow down the application so let's find out so what do we need to find out we need to find out how frequently we get the pose and this we can use with another command so we have so total Sim is running here for us to topic list we have the pose how frequently do we receive a pose well that's a good question and we can get this with Ross to topic h z okay for Hertz that's gonna give us the frequency of the topic let's do this and it's gonna okay it's gonna listen to the topic so let's wait a bit and let's do Ctrl t it's gonna listen to the topic and then publish the average rate which give you an ID of how frequently you get some messages on that topic and you can see we have about 60 messages per second so 60 hats which means that this callback is called 60 times per second we publish a command 60 times per second and with this code we would call the service 60 times per second so for publisher 60 hertz is good for a service you don't want to call a service 60 times per second so what can we do to solve that well it's quite simple we can so let's use the total here we can keep track of the X position and we can actually just change the color when the turtle crosses the middle okay so when the turtle goes from left to right or when the turtle goes from right to left we don't need to change it when the turtle is left and that stays left okay the color is going to be the same okay we need to change it when the turtle crosses the middle so we have two cases here when the X position is lower than 5.5 and then the X position is greater than 5.5 or when the X position is greater than 5.5 and then the X position goes to lower than 5.5 so let's create well let's do that quite quickly but let's create here self previous X and let's just put zero as an initialization value okay and we're gonna do if so if the pose is greater than 5.5 and self previous X is lower or equal than 5.5 okay so it means that before the total was on the left and now the total is on the right then we change to red and then else I'm gonna add else if actually so not else if but alif with python pose is lower than 5.5 actually let's use lower or equal here and self dot previous X greater strictly than 5.5 so this means that it was previously on the right side and now it is on the left side and then we want to change the color to Green and of course we need to do self dot previous X is equal to 2 pose dot X he and also here save that previous X is equal to post dot X so that's a well that's a very quick way to solve this issue maybe there are different logical ways to do that but this is quick and easy and that's going to be enough for this tutorial so we initialize the previous X to Zero it doesn't really matter and then when we go from left to write we set the color to Red we also save the previous X and we do the same when we go to the other side so that if we stay on the same side of the screen okay so if we stay on the left we are not going to call the service if we stay on the right we are not going to call the service only when we cross the middle okay I'm going to save this and this should be it so actually let's find out and let's try that's the only way to know and let's uh so let's kill everything here clear let's do Source bash SC because I'm gonna run the script from there I'm going to run the controller from there here let's do rush to run Turtle Sim with total Sim node okay here we don't need that screen and let's run so Ros to run my robot controller with turtle let's see what happens okay and we have an error which is this is not supported between instances of pose and Float let's find out with the code Yes actually it's post.x I forgot the dot X so of course I can't compare a pause with a number because that's something that's different let's try again so let's run this and let's try this again with Source bash SC and run the controller okay you can see it's red and then it crosses the line and it's green and we have a log too it crosses the line and it's red and you can see set color to red and then set color to Green all right and then again and again I'm Gonna Leave It just a bit so you can see what's going to happen at the end okay great you can see it's working quite well the turtle continues to move tries to avoid hitting the wall and whenever it crosses the middle line it changes color so you can see everything on the right is right everything on the left is green so everything is working as expected and well congratulations you have just written a service client with python you have also mixed it with some Publishers and some subscriber in just one node so you have already a complete Ros 2 application hey it's Edward I hope you enjoyed this crash course and that you found it useful now if you want to continue to learn ros2 with a full and in-depth course covering everything about the Ross Concepts Python and C plus plus code and also more practice activities well I have the course just for you these rustucles contains more than 10 hours of structured video content and also downloadable code for each activity and project you will dive into the Ros concepts with much more details and also discover rows parameters launch files how to write service servers and many other things so if you like the way I teach check the course out the link is in the description click on the link read the course description and this side if you want to continue alright thank you for watching and I hope to see you in the course
Info
Channel: Robotics Back-End
Views: 73,010
Rating: undefined out of 5
Keywords: ros2, ros2 course, ros2 tutorial, ros2 humble, robotics back-end
Id: Gg25GfA456o
Channel Id: undefined
Length: 170min 1sec (10201 seconds)
Published: Wed Aug 31 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.