YTread Logo
YTread Logo

Autoware Course Lecture 2: ROS2 101

Autoware Course Lecture 2: ROS2 101
hi welcome to the second apex AI oughta wear lesson I'm Catherine Scott I'm the developer advocate for open robotics if you're not familiar with open robotics we are the sort of steward organization that helps build Ross and ignition gazebo the hope today is that we'll go through basically a brief tutorial on all of the C++ API functions inside of Ross - this isn't meant to be exhaustive but it's basically to give you an introduction to all the building blocks that are used in most Ross systems and from those building blocks you can build up much more complex systems so we'll sort of be working systematically through most of the Ross API to build up to more and more complex sort of application development today we'll be using a de which is the apex a I sort of dr. ice container version of Ross and what will we doing be doing is installing most of the Ross - dashing tutorials and working through some of them and I'll be giving you a few hints and tips and tricks as we go along if you have any questions please feel free to let me know we'll be doing a little bit of work with also the rust to sort of CLI interface the next lesson is actually going to cover that more in detail so don't if you miss a few things right now don't feel like you have to get it all in one go we'll go through that sort of systematically in the next lesson right now the hope really is to get get you familiar with how to fill Ross applications what the...
autoware course lecture 2 ros2 101
sort of primitives are that are used to build systems and what the API looks like and then sort of next time we'll go through how to run things how to deploy things how to debug them and give you a good sense of just how to paw around in Ross system and see if what's going on and look at the goo inside let's see so I've also taken a lot of time and built this lesson out as a restructure text document that auto generates slides so there's both HTML slides and PDF slides so you can either follow along on those or you can actually look at the restructured text document itself and follow along either as we go or sort of watch the

lecture

and then go through and try it all out yourself I would recommend getting 8880 installed before we begin so that should help you get started to answer the question I get on all of my zoom calls yes that's a vt100 behind me it actually came from carnegie Carnegie Mellon University as property dis poem it was from the psych department so it's been repaid and it was used for psychological tests way back when okay so give me a second to switch over and we'll start going through some of this code and I'll give you an idea what's going on all right so I've got everything cued up here and what you can see basically is on the left I have my HTML slides on the right I have a bunch of terminal and a little bit of video and we can basically get started and start talking about the Ross to API and some of the built...
autoware course lecture 2 ros2 101
tools alright so why don't we get started um I think we got a preface all of this by saying this lesson is intended to be a basically a crash

course

in Ross to dashing and it's API and maybe a little bit of build tools and the hope is that after this lesson you should be able to code and build basically a rudimentary Ross 2 application may not get all of it but you'll understand the basics and how things are sort of put together should be known as that since this is a crash

course

for giving you a pre-configured doctor environment called a de we're gonna cover sort of all of the logistics of setting that up this is basically an exercise you're gonna have to cover I've tried to structure this all to work off the Ross to dashing desktop installation so if you're all new bun 2 or you can get in a bun 2 VM you should just be able to app get install it and get going it's all it also should be noted that right now this crash

course

was written for rush Jude dashing Russ to foxy is going to be released in a couple weeks and rust fox he's gonna be a big major stable LTS Ross release so you're gonna learn all this and dashing things have changed a little bit and foxy as soon as you feel like you're capable of it I would highly recommend switching over because you'll just get better support it's sort of the Ross 2 version that we hope to be supporting for a long time the other thing that I'd like to say up front is that the next...
autoware course lecture 2 ros2 101
lesson will cover basically the the Ross to CLI interface so if I if I run a few commands here and you don't get them the first time or if I don't cover them fully that's okay so just go ahead and sort of pair it what's going on and we'll cover in detail next time okay so the other thing I want to say about Ross is that it's it's difficult like learning these things it's going to be hard I you know this is the only image I have it's sort of one of these you know we choose to go to the moon not because it's easy because it's hard we choose to learn how to do robotics not because it's like easy webdev we choose to do it because it's hard and it's interesting and I want to say that you know in this process you'll almost certainly get stuck you'll certainly not understand something fully you're going to need help everyone needs help in learning Ross that's just sort of the nature of the animal we're doing hard difficult things that are changing all the time and so I wanted to make sure before we even began to sort of look at some of the resources that are out there that when you do get stuck don't get frustrated there's help out there so when we start so we have a ton of resources and you have to understand that Ross has been around for well over a decade so some of our resources actually even predate what you would try to consider normal at this point when we do a quick rundown of what's out...
there so the first resource that I would suggest is if you have a general question Ross we have our own Q&A site kind of like stack overflow it's called answers so it's answers Ross torque it actually predates or is was built at the same time a stack overflow so you really have like a decade's worth of question answer content there and all of the core developers are there a good chunk of communities there so if you have questions that's probably your first place to go we also have a dis

course

server so it's just dis

course

don't Rasta org this is more sort of community announcements and discussion and news and and those sorts of things the one thing that I ask is I sort of moderate dis

course

is do not ask questions on dis

course

that should be on answers to Ross org this is sort of the thing that happens all the time if you have a very specific question answers don't roster to work is where you're gonna get immediate help on that we also have a very very large Ross wiki it's mostly for Ross one it's just we keyed out Ross that org most of that content is generally still helpful it may not be relevant to your particular version but conceptually most of the content there is is correct when it comes to Ross to documentation it's in a different spot we're taking a different tact with how we're building it and you can find that in ducks Ross dot org slash dog slash Ross - and so if you're looking for documentation...
that's probably place to go most of this tutorial basically pulls directly from that and so you should be able to find more detailed explanations sort of follow-on lessons and additional materials there while we have a second there's also sort of unofficial resources so other places you can look there is a Ross and robotic subreddit those are great places to also have discussions before you go to sort of the community sponsored stuff but those are there you should know about them there's also an unofficial Ross discord server that you can try if you get really really stuck and want to talk to somebody we have a yearly Developers Conference called Ross con it's gonna be the US this year so if this is something you're really really interested in perhaps you should look into going to Ross con it's going to be in New Orleans so that should be fun we're not huge social media people but we do have a couple of Twitter accounts I'm secretly behind those so if you have questions or problems I'll probably be answering them or you've just taken all these lessons to heart and built something super cool and like to show us just let me know and then you can also just check out the open robotics website it's basically some of the events that happen some of the news that comes up we post stuff there on that periodically before we get I just want to cover a little bit of history of Ross because sometimes people see these things and and they see them...
in the context of modern development and they don't understand that the reason sometimes the way things are structured are or is because Ross has developed over time right it's developed over quite literally decades at this point and where it all came from and I think giving a sense of that history would sort of help you understand why things are a certain way and I think that's that's helpful so if you go back to the early 2000s open source is not in the sort of primacy role that it is today and so it's growing but sort of windows dominates and robotics is still stuck in this before the turn of the millennium phase and the robots are big expensive capital equipment that I mean we used for manufacturing in R&D and they're mostly running sort of real-time control systems and they're moving arms to do manufacturing and there's not a lot of open source so about 2006 some former Google VP's decide that they want to go work on robots you know why don't we take all this Google knowledge and we try to apply it to robots and they sort of created a company called Willow Garage and the spirit of something like Bell Labs or Xerox PARC and let's just get a bunch of smart people in room and go build stuff and from this org we got things like open CV PCL Ross the pr2 robot and a bunch of spin-out startups so Willow was around for a long time there's actually been some document documentaries on what happened there and then approximately...
2012 willow folded and then sort of out of the group of people that were working there open robotics emerged and so open robotics worked on Ross too for quite a while and Ross for quite a while and then about a 20-17 we decided to sort of take all the feedback that we had gotten in in prior years and you know all of these things that make people say things like well Ross is a great utility but it's really only helpful for academics or research applications well let's go and fix all those things let's understand what the problems are and address them so we can really build a system for these next-generation robotic applications and you know we started looking at things like addressing security concerns and robustness concerns and and quality of service needs and let's put those all into a new version of Ross that gets things ready to really go out in their field and to build these autonomous vehicles to build these sort of next-generation manufacturing applications you know drones all of these things let's actually build them for the long term so before before we begin actually talking about software and in this holes there's a lot on this slide and if I had all the time in the world I'd say this slide really should be a whole hour to of discussions because to to understand what Ross is you have to sort of understand where it came from and all of this sort of design software design patterns that motivated how Ross is built so I wanted to touch on...
them briefly this is all sort of cross-referenced with the appropriate Wikipedia articles and everything else and I think it's really really helpful that before you begin or you know after this lesson is done it might be helpful to go and look at these things because I think if you understand the the fundamental design pattern of why we built something some way or what has been used for the past you'll have a much better understanding of what Ross is so let's take a couple look at a couple of design patterns the other thing is that I've structured this a little bit as analogy so if you're coming from say a web dev world I try to point to the things that I think are fairly analogous so let's let's start with Ross nodes if you're familiar with say creating a new process or new thread a Ross node is basically a process that's running inside of Ross and it's just a self-contained execution thread just like a program and so whenever I say node you should just think Oh Ross node is basically a program another thing that comes up fairly often are Ross topics a Ross topic is basically just a a structured message on a pub sub bus so pub pub sub basically means publish/subscribe if you've ever used something like 0 mq or rabbit and Q or even in the hardware world something like Modbus they're all very analogous to what's going on in Ross in the sense that you have a bunch of different devices and a different threats of execution and...
what they do is they just publish repeated messages over and over and over again or they update them with new data and then you can listen to those and make choices based on what you've heard so if you've used RabbitMQ or 0 mq or something like that just whenever I say Ross topic oh just think oh it's a zero mutant you another big thing that you should be familiar with or try to understand is serialization so in in Ross our civilization format is effectively something called a Ross message and these Ross messages can be used and sort of stored in something we call a Ross bag what Ross does underneath the hood is you define basically a gamma file with what your messages and then the whole system can basically serialize and deserialize those messages between different nodes if you've ever worked with Google protocol buffers it's it's fairly analogous another way to think about at least ross bags is if you've ever made a python pickle file it's kind of like that where it's like let's take a bunch of data and serialize it out and give you a way to replay it and get in there another high-level concept that i think is useful for understanding is ross params so ross parameters come from what's called a blackboard pattern a blackboard is like in if you go back to say in the 1940s or something right there'd be like if you want to communicate a bunch of information to a roomful of people you'd have a blackboard and you'd say like...
what is the value of this and you've write in our number and then somebody else could read that number and then if it changes you just erase it put in a new number well that's the blackboard pattern it's just a way of keeping an ordered set of parameters if you can kind of think of it like Redis in a certain sense like it's just basically key value pairs so you can go in to find one and get its value or change its value another core concept that we'll cover today are Ross services a Ross service is just basically a synchronous remote procedure call so if you've ever sort of read about remote procedure calls this notion of hey I have my computer I have that computer over there I want to execute some code on that computer over there via remote procedure call that's essentially what our Ross services similarly we have Ross actions which are the sort of asynchronous remote procedure call they're a little bit more complex so generally the canonical example that you would use with Ross action is I don't want to create an action where I can tell my robot hey go to that point over there and let me know once you get there so an action is this asynchronous from a procedure called where you say hey hey robot go do this thing and then send me periodic updates as you get there or don't get there so those are all the sort of core cop topics I know that's a lot to cover and to digest but I wanted to make these these analogies upfront so hopefully...
you can swap them out in your head while we're going through stuff and it'll help you understand all right so let's let's jump right into the deep end let's start easy and basically install and update our dependencies so basically at this point you should at least have 80 installed it's probably a good video a time to pause the video and run the commands underneath I've already done this so we're not gonna have to wait but what we're gonna do is install ad e per the other instructions and then we're gonna add basically gonna install Ross dashing and a couple of tools so here are my terminal actually turn this up just a little bit a de start get into our VM it's already running so we'll do a de enter and let this queue up okay so now what we're gonna do is first thing on all Ross systems that you always want to do is we're gonna source our set up top batch file what's this gonna do is basically in this terminal tell the terminal hey we're running with this version of frost source this file and on this machine it is on most machines it's an opt ross dashing set up and you if you're not familiar with linux systems you can use tab right there to sort of help you autocomplete all of those things you don't have to type that whole thing out and try to remember it so on the Left what I see you do is do a sudo apt update and if you're not familiar clinics apt is basically program that's it's an...
installation program it'll basically install a program for you so apt update so we update our list of programs we're gonna install Ross dashing turtle sim mas dashing our cutie star which just all of the Qt related GUI apps and then I personally as a terminal manager like to use Bo boo if you use team ox or something else feel free to use whatever is comfortable for for you if you have a sort of IDE or IDE or perhaps a text editor of choice you can install it not to okay so we've got everything ready so let's talk about a little bit of nomenclature before we even begin so basically frost is built upon packages and a package is just a collection of code it can be c++ it can be python sometimes people do Java or go those are less common but it's just a collection of Ross code that is particularly published and perhaps somebody has released on the web and that you can also pull down and use along the those lines there's also this notion of a workspace and so a workspace is just a collection of source code and Ross packages that we want to deploy on a robot so generally what's gonna happen is you're gonna build a robot you're gonna build an autonomous vehicle and it's gonna have a workspace that defines all the packages that are on there all of your sort of client code that you want to run again by analogy a good example of this would be a Python virtual environment a couple other bits of nomenclature that might be helpful is an overlay an...
overlay is basically a second workspace with more different new related packages if there are multiple versions of a package code then one the one at the bottom is used so in a sense like if you create a user space that's going to be the overlay if over and above your system installation of Ross there's also this notion of underlay which is the works be workspace underneath the overlay I'm aware this is confusing it's not the best nomenclature but essentially the way to think about it if you're familiar on is I kind of like to think about it as like layering virtual environments on top of each other and yes that's really complex and problematic sometimes but the reason we do it that way is sort of to allow people to have multiple systems to do what they need to do and build up capabilities and the other thing I think I need to mention at this place is people often get stuck on this the stuff is hard it's confusing it's sort of complex and the short of it is that you need to realize that that Ross is this ecosystem of tens of thousands of developers working on thousands of packages across like a handful of platforms on multiple languages and all of our build system and all of these sort of complex things are there to allow us to make that happen ok so let's let's get started so as we're diving headfirst into Ross or shrubs to check out a repository of examples and basically build it the the steps do soar really simple fire terminal...
manager so and enter a de so I'm already an ad so I'm gonna go terminal manager cool and I'm just for safety's sake I'm gonna source or opt dashing percent confident that I've sourced it and what we're gonna do really quickly is we're gonna make a workspace called frost to example workspace so you just if you want to follow those examples below so you do mcdr and I've already done all of this but essentially you make der and we're gonna call it Ross to example workspace or sorry Ross to example WS 4ws means workspace we're going to create the source file we're going to CD over to that drink we're gonna clone this github repo which is full of frost to examples and we're going to go over there into that directory check out the the dashing me examples now we're gonna go to the root of the work space and we're gonna run this command so let me get over there real quick and we're gonna run the command so Ross uses a build tool or a build system I should say called coal Kong and coal con is it's not a build tool underneath it's basically taking a bunch of different build tools and allowing them to work together and that's the way you should think about it so you know if you're using Python right your build tool is going to be something like set up PI versus like C++ your build tool is going to be C Meg and Sokol con is sort of this layer that sits above all of that to help organize everything it...
allow you to build these very complex Ross projects where you might have Python interspersed with C++ and that's what's really cool about it so let's go run this real quick and I've already built it so shouldn't take too long and we're going to do a symlink install cool and so what coquelin just did is it actually built 15 different packages right so it built all of the example packages that are in this repository and it did all fairly quickly and we can see here it basically started this minimal action client and it started this minimal action server etc etcetera etcetera it built all of these and these are all sort of separate packages so let's go to the next one alright nodes and publishers okay let's talk about nodes and publishers so the core of Ross is the sort of Ross pub/sub bus and in Ross parlance we like to call a publisher is a topic right so a topic has a message type that is published on a particular has a message type that's published on a particular topic on this sort of upset bus these messages are defined in a yamo file that defines the serialization in deserialized format for Ross messages Ross has a lot of built-in message type and there are a lot of really good predefined messages for controlling a robot or distributing sensor data or understanding the geometry of robot if you find the case that you need to make your own custom message type you're probably doing something wrong because there's so many of them at...
this point and you're probably better off extending something that already exists because there's already tooling that exists for a lot of common message types a Ross publisher can produce messages as slowly as quickly as it needs to and once it's published you can have a Ross subscriber that subscribes to that particular topic and then gets those messages and does something with them the Ross topics themselves have a lot of tools for for management so you can list them you can echo or watch a topic you can rename or remap a topic and you can store all the data coming across them a particular topic and a serialization format called bag ross nodes are basically pro that or processes that run concurrently on Ross Ross node can have one or more publishers Roscoe can have one or more subscribers and many nodes can subscribe or publish to topics that are already out there and Russell has a lot of tooling to start and stop these nodes and bring them all up at the same time so preparing to run a Ross node so what am i cyst you open up a new terminal you can do this by pressing f2 and bo bo first what we need to do is to source the setup batch file for our Ross to works basis so to do this we just do source slash setup - and what this is gonna do is it's basically you tell the terminal hey this is where I'm gonna put all your programs this is where I want to put all of your stuff that we build and you know it kind of acts as a a namespace or a workspace for...
whatever you're building on it's generally recommended in Ross that you build in one terminal and execute in another terminal and this this sort of helps so in one terminal where you're building you're gonna be sourcing just to set up that batch file for the version of Ross if you're running and then the next one you're going to be sourcing the batch file inside of the workspace so you're saying the first one here I'm just using dashing and then inside of the the workspace that you're actually running your code in you're going to say I'm using Ross dashing inside of this workspace and that's generally how you work and if you encounter problems this is just the a number one beginner problem that happens make sure you've sourced the correct setup that bash file so and we've built or we've sourced the correct file let's go and run enough so what we're gonna do first is we're just going to simply run a simple c++ publisher note and all this publisher node does is it's got a topic a single topic called message and or sorry called topic and it's just gonna take a simple string message type and push out a string every at a certain frequency the way we're going to run this is we're gonna use the raziel I will cover this in depth next time and we're gonna run an executable called publisher lambda in the package called examples are CL CPP minimal publisher the general syntax for this command is...
basically Ross - so Russ to run and then the package type so text type here is examples and you can tab complete this such really helps so we're running Rossia our CL so Ross common library CPP sure and then we're going to run publisher land here oops most of us build something when in doubt copy and paste mmm copy paste inner and if we did everything okay we should be seeing this and so we're publishing on topic and it's just saying hello world hello world hello world and then giving a number so it's kind of a sequence number every time it sends a new message it updates the number so what just happened we just executed a Ross note that publishes a simple string message to a topic called topic and it's publishing at 2 Hertz so twice a second and we can actually if we open up a new terminal here I'm gonna press f3 we can actually inspect this topic so I'm going to show you a little bit of this command-line magic we're covering it in depth next time but we can go topic list you can see all the topics and we can see that we have a topic called slash topic and topics are kind of names in the same way that you would name say something in a file system so you can have like my node slash topic a topic B topic C and that's how you sort of segment the different kinds of data that you're you're spitting out or digesting we can run a command line tool to actually see what's inside of this topic so we can do echo topic it should output...
a message yeah I see 156 157 so it's still going up ctrl C will exit out of these programs if you get stuck and we can also see what rate it's running out so we can go Ross to topic and then Hertz so and we want to look at we do this actually tell us how fast this topic is running and give us a general idea if it's performance and we can say it's just running right now at approximately two parts kill this so why don't we dig into the code um if you since this is a de you can either use your favorite IDE on your sort of host system if you want I'm just gonna use less and like Emacs inside of a te right now for simplicity but you can kind of pick how you want to do this and if we want to go look this file is located inside source and then our example repositories and we're looking at the c-plus example so it's in our CL Roscommon library CP and it is in the minimal publisher and it's in this directory let's just make sure and the function we're gonna want to look at is member function and CPP and when it says member function we're gonna look at a publisher that is a publisher as a member function in a big class so let's open this up and it's also on the left to with syntax highlighting so we can take a look at both so what's going on in here I kind of abbreviated it here on the left but we can see if we look at our includes the first include here is this rclc PP / r CL c PP dot H P P P so this is just a header file but...
saying hey we're using Roth's we're using CPP library for us to the next include its standard messages messages string HTTP what this is this is a basically an automatically generated header file that gives us a realization format for your message and this is all auto-generated by Ross so you don't have to think about anything you just need to include it in your source code and if we look through here we also have namespace and then we define really really quickly a class called minimal publisher and this class inherits the public interface to our CL CPP note so basically what we're saying is hey we're creating this minimal publisher class that is a raw C++ know so let's go next step so let's take a look at the notes constructor so if we scroll down here just a little bit alright so we have this minimal publisher and what it's gonna do is it's gonna inherit from the base class and we're gonna give it a name and a counter right so there's just a member variable called counter that's the 1 2 3 4 5 whatever number that gets published and we're gonna give it a name which is minimal publisher and it's the same name that we're gonna call let's see we're create a publisher that pushes standard messages that message to the topic topic so we create this publisher or we take this variable that's publisher and we say create publisher or the type is standard message messages string and we're going to call it...
topic then we're going to create a little timer that calls back every 500 milliseconds and we're gonna find that to the function called minimal publisher timer called so if you're not familiar find all this is saying is that it's a callback so it's a function that's gonna get called at some regular frequency let's go to next slide here so let's go take a look at how this callback which is the thing that's gonna get called twice a second that was gonna publish a message what does it look like so it's a private member function and it's got a tight and you c++ auto here so auto message and we create this standard messages messages string type or string message type and it's got sort of a member variable called data and we just say hey it's gonna say hello world plus a standard string of the number which is the member variables our class count and every time we call this we're gonna increment it and then we're gonna call our logging function here and we're just gonna say here's an info message send it to the logger we're publishing blah and then look over here we're gonna call our publisher member we're gonna say hey call publish on this message pretty simple and then below this we just have our private member variables that's all there is to this and if you look down at the bottom there is you scroll over here to there's just a main function and the main function is just calling the Rossi...
closest interface and it's passing through the arc C and our V to our program and we're saying hey spin this process spend this node on this thing called and then this class that we've created called minimal publisher and just keep calling it with the callbacks that are in there all the time until we say shut down Ross and then Ross shuts down and returns zero and basically when you call this shutdown it'll help clean up everything and that's it so let's go alright so when we do a little quick exercise here and I'm not gonna we're not gonna write a ton of code but I think it's good just really quickly to do it once so lesson so I'm actually going to open this real quick function I may use max you can use whatever you want okay so when we try to do a few things say we're gonna make this run a lot faster so we're gonna make it run ten times a second and we're gonna change the topic name from topic - greetings because that's really like topics a bad topic name you should give it something a little bit more clear so we'll call it greetings and people change the message - and we'll also change its name from minimal publisher to revenge of minimal publisher so when we go through and do all of these things so the first thing we want to do is let me change the rate I said instead of running every 500 milliseconds we're gonna make it run every hundred milliseconds and we're gonna change the topic name we see here...
it's called topic so we don't want to be named topic we want it to be named readings what else did we want to do we don't want our name our note name minimal publisher anymore we want it to be named revenge of minimal publisher so we'll change its names minimal publisher and we want to say one more thing so since we're doing a self-driving car

course

we're gonna say I said hello world hello open road you save all of this too high and generally like I said before we don't want to build over here so we're gonna go back to our building and we're gonna say cold Khan build so we're gonna use our build system to say build all this stuff and reinstall it and you know air is cool go back over kill this which was still running and what we can do is I'm just gonna copy this do we do everything yes we can see this is publishing a lot faster it's changed from hello world to hello open road and that's about the sum of it and the notes changed right because we can see the command has changed so instead of running a packet or or the note name is Jana chair so it's now revenge of minimal publisher cool I might kill this okay so the next next thing we're gonna try is we've created a publisher now why don't we go look at building a subscriber so we want something that is taking this message that we're publishing and basically absorbing it looking at what's in there and then doing something with it so the sort of...
example to think about this is a lot of times when you're doing data processing right there's a stream of data coming from say a sensor and you want to go and process that sense their data and clean it up or make a decision based on it and published a new message so I don't know say you had a wheel encoder and the wheels going you know the encoder just gives you clicks and you want to go from clicks to velocity so you'd make a note that basically there's a note publishing the encoder clicks you create a new node that takes on that click topic and picks and then processes it publishes you know rpms or something like that right so we're going to create something subscribe to our topic and do something with that so why don't we take a look at this then this is basically in the minimal subscriber example so in your favorite editor or using less or whatever you want we can go back up in the file I also have it on the left but I feel like it's good just to have it in both places so let's take a look at this file what is it made out of what it's a subscriber doing well we can see here that it's still including the same header file just like before hey we're using the Ross header files we're gonna be using this standard message mission screen we have a placeholder and then we're gonna create this class and we're going to create a class called minimal subscriber that's also inheriting from the Roscommon library note...
interface and it's gonna be named minimal subscriber and in the constructor we're gonna create a subscription because and this is sort of coming from the Ross node API and we're going to subscribe to a message of type standard messages messages string and we're gonna say off the phone off the bet that we're subscribing to something called topic and we're going to bind to that topic and whenever we get and then here's the last little bit that's actually really useful and that is that whenever that topic that we've subscribed to or that message that we've subscribed to gets published we want this function minimal subscriber topic call back to get called that's that's all that's going on so let's go back and I'm gonna scroll over here a little bit so let's take a look at the topic call back so this is gonna get called every time that we the topic that we subscribe to that a new message is published on that and this call basically gets a standard message message string and it's just a shared pointer to that message and inside of here all we're doing is we are writing to Ross lager and we said I heard this message and we go in the message and we get its actual data as a C string and we publish that and if we scroll down here just a little bit we can see that we're basically using the same pattern all over again in our main entry point that is to say we initialize Ross we say hey we're making a shared...
memory pointer to this thing called minimal subscriber this class that we created called minimal subscriber and we're calling the spin function which is just gonna keep calling it when basically whenever something happens and we're gonna do this until Ross gets told to shut down and we'll worker on 0 let's do this over here so then the publisher we changed the name why don't we go in and start looking at how we can modify this publisher so and she's over to my editor okay so why don't we change as just sort of a moaning what's going on here why don't we change what it's subscribed to so we changed the last thing from publishing to topic - greetings so why don't we subscribe - greetings instead and we can see that it's here it's where it says topic we can just say no you're not subscribing to topic anymore you're subscribing cute greetings and I think the thing that's worth noting here is that you can change this in code but there's once we get into some more advanced topics in Ross you can actually change this program or you don't have to change the compiled code for this you can actually remap it so remapping is this concept where instead of manually changing this we just rename it at runtime which makes things a lot easier so once we have this all go and saved we go back over here and we can rebuild and let's see let's fire up my guy here that was publishing on greetings and we'll open up a...
new terminal press f3 and what we can do is we can now run our subscriber that's gonna listen to this and every time it here is a message from the other node it's going to basically spit out a response now you can see here you see how it started really quick up there like at 195 so our subscriber now is saying hey I heard this other message I'm a completely separate node I've heard this other message and I'm just basically spitting it out so this is pretty cool it's very very this is a very very primitive example but basically we've now connected these two nodes that are running concurrently one of them spitting out messages and other ones basically digesting those messages and doing something with it it's not that complex Rex is just in parsing right now but you can see how we can build much more complex systems with this as we go along all right and so we can see all this one side the other and let's go ahead and kill all of these and I'll kill this one and so I think the thing that's interesting here and that we have to remember is that you know we've just built a very very very primitive raw system right we have two nodes once publishing one subscribing they're spitting out data and taking in data and doing something with it and while this is really really simple it's the basis of basically how most ross robots work all right so we've we've covered the basics of Ross right we used to talked about notes...
we've talked about publishers we've talked about topics we've talked about subscribers we've talked about all of these pieces that are sort of the building blocks of Ross um but we're still missing a bit and the bit we're missing is that we're right now we know how to process data right we know how to get in how to do something to it to spit it out and that's good we can understand the world around us but now we need to like make things happen based on that data and in Ross there's basically two ways that you do that there are these things little services that I'm going to talk about right now and then I'll talk a little bit about actions which are the second bit so a service is the simplest way to think about it is it's like a fancy function call in Ross and services are for anything where you think a robot can perform a task synchronously so a good example of a service a toy example of a service call in Ross would be let's say we take her a ton of this vehicle use case it'd be something like turn on the lights um check the sensor really quick man just give me a value unlock the doors beep the horn these these things that happen you know real time or faster synchronous all of them are hard to define but things that happen like while you wait so you're just like go do this thing I'll wait for you to do it and it comes back and all of these things can be done in a Ross node so note is basically the container is...
the the executable container and a service is something that I can take it the note does or that it offers to the other nodes to be done so let's let's take a look so as a toy example of a raw service we're going to make a note that offers and add to int services it's it's the stupidest possible service that's out there basically is a very very complex way of saying here's a here's B please add a and B together for me and return the results um there is a full tutorial on how all this is done I'm not going to cover it in SuperDuper depth because there's some steps I'm gonna gloss over there's a link in there you should go take a look at the full tutorial and it'll it'll lay things out for you so before we talk about how the service is constructed out of code the first thing we should do is talk about sort of how we define a service so in Ross there are these things called serve files SRV files and what they do is they basically define the inputs to find the outputs of a service as a yamo file and from that yamo file we generate a bunch of message types and headers that can then be used in the executable code for your note and what's actually secretly don't tell anyone it's going out of the hood is that it's kind of I believe built on top of some of these topics so why don't we take a look at a predefined service file it's in kind of a funky location because it kind of comes with the desktop...
examples but what we'll do here is I'll open up this file called add to end serve right here and what we'll see is that there's basically n64 over to the type right a n64 type B and then three dashes and then n64 which is a type and some and this is defining a service the things the tops are the inputs the things on the bottoms or the results and you start your service by like just defining this file let's file go over here all right so in Ross once you've created that service file what Cole cone will do is it'll take it you know Auto generate all of these things that you you'll need all the header files for all the different or languages are supported and it'll make them for you and make all this sort of types that are associated with it and then you can just use them in your codes you don't have to think about it it's just sort of magic so why don't we open up our favorite editor right here I'm hoping this file called it's in our workspace source examples are CL CPP minimal service main dot CPP that works okay so let's take a look at this and we'll gloss over it it'll be pretty interesting um so we look at right at the top like I was saying hey here's this here's path to an included header file that basically defines the add to services include file for Ross common libraries and then what we do first thing here is we use its using directive to basically say hey this thing called add to ants well...
it's actually example interfaces scope resolution serve scope resolution add two ants but you can just call it at two minutes and then we also create a shared pointer to basically raus raus note and we'll see right here at the top in this service main handle service which is just a function call right so what do we have in this function call do this so in this function call it's called handle service and has a shared pointer e to a request header request header it's just basically a baked in free to find things that you can look at to say when was something said who sent it why they send it think of it as like the address on a piece of mail or something like that then we have a share pointer to an ad to in type requests so that's gonna be our a and B and then we have a share pointer to an ad to intz response which is just our sums and then if you look in here basically all we do is they say we got these things we add them together and down here if we say a response there's this thing called some take the input a take the input B shove it into song cool and that's it that's that's the that's the all of it and then all we have to do to make this work is we create a main right here we initialize Ross we create a minnow a node called minimal services and we create the service call add two ents and we bind it to basically this function call called handle service and then we tell Ross hey just keep this thing running until we shut down and...
and that's it that's all there is to it yep cool all right so now let's build and run the service so this should already be built the syntax you're running a service is pretty simple you should kind of be getting the pattern here it's Ross to run uh and we're gonna run examples Ross common library CPP minimal service and this thing is called service main is the executable we hit enter and nothing happens why is nothing happening because we haven't sent a request so what we need to do is send it a request we have an A and a B so they can send us back a sum so we'll do this just in the sake of example we'll do this via the command line and then you will do a client that I code show you how to do it in software so the way you make a service call um is well actually show you this chip what we can do is for us to service list see what services are running and we can see that our add to int service is already running and so what we can do is so the only difficult part about this before I do it is that we're going to send the service request and we have to define the message correctly in the command line which is kind of ham fisted you have to basically say the path to the type and then you have to kind of write the type so it ends up looking a little bit weird but what you end up doing is you end up saying boss to service call it tap completes add two ends and then I gotta grab this bit right here pull interfaces so we're giving it kind...
of the path to the type and then we're giving it the type and we're just gonna add 1 1 here and I hit enter and we can see waiting for service to become available so what it does is it checks if the services there makes the request and then gets the response which is - we can just approve that there's nothing up my sleeve we can make this like should be okay yep I'm assuming that's correct and we can go back over here and we can see that the service itself has said yeah somebody requested this some weirdo requested this just Saltworks alright so why don't we show when we figure out how we can use this service in another cause we're gonna make one note that has a service running we're making another note that calls a service and we can kind of get the feeling of this pattern so I'm gonna go back over here leave that guy running and why don't we open up this minimal service quiet right here and take a look at the code and then we'll run it in here all right so let's see what's in here well we see our familiar pattern already include the service header add two minced HPV include the Ross headers and then also this add to its scope resolutions totally cool and then all this is it's a main wien it Ross basically we make a note called minimal client right so we've created a node right here and then we say create a client to this but create a client and this is a the type here all right the template type is add to ants and...
it's named at two ends this will this will get you every time you just have to be very very clear you can see how some how we sort of set a pattern here where the type is add to intz and then the name in camel case and then the the runtime name is underscored right so there's two different kinds so we've done we're trying to show you a good pattern here for keeping these things straight otherwise it'll it'll bite you in the butt every time all right so then what do we do well we tell the client to wait for the service so wait a second and check that the surfaces there so it could be the case you could start this node and there's no client so it wouldn't do anything you couldn't call anything so you need to check that it's there if it's not there throw an error and then let's go down and go forward here and let's see what we do so we make our request auto types are great right so you say standard make sure add to int request type and I was kind of convoluted but now we request and we know that has an A and has a B so we set their values we're gonna add 40 101 and then we create this asynchronous request so we say okay our client a simply only send this request request and call us back in the future when everything gets done right so basically we just we just kind of wait we check it's sort of return value right so this results future thing you can basically spin it and it'll return some value and we're hoping...
it's the test but if it's not success will spit out a bunch of garbage and say oh it failed for some reason that we don't know if it completed successfully we'll just get the result and we'll log it and we'll try to go all right let's close that and now let's go run this client so I'm already in our new windows I don't need to open it up so all we have to do and let's double still check here serves still running cool so all we need to do is call this thing which should be Ross to run client client and then it's client you see so you see it's set right there and then it got the result if we toggle over is there other terminal you can see it came in cool so that's that's fairly straightforward so that's that's fairly simple so now let's talk about action so we talked about the simple case where it's like hey I want to send you this thing just do it send it back real quick not a big deal but some some things that a robot might do aren't aren't that simple and so the kind of canonical use case that you'd use is it's like an avocation use case so you have this robot like a turtle bot I got one right here kind of it's not exactly running right so it's right here this little guy hang out you say like okay turtle bop on the floor I want you to go over there and like do something something cool so the robot doesn't instantaneously teleport from over here to over there it takes time...
and things happens it's like life things happen so like the turtle bot there could be some on the floor runs into batteries could fail I could go over there and kick it so there's all you know I want to request this thing but it's it's unsure if it'll happen and so we have these things in Ross called actions and actions are there for these sort of asynchronous will take a while request things and they're basically the preferred approach for doing things that may not happen instantaneously and so there are basically multiple parts to an action and you're also gonna have both an action server where's the thing that does the things and the thing that asks for the thing to be done so there's a client and actions can also that the thing about how they're structured is that you can have an action server that does the thing and it can have multiple clients so like if you imagine in an autonomous vehicle something that may not happen instantaneously even though we'd like it to is like you know stop the vehicle you know especially here on the highway right so it's got to go through lanes you got a like signal to traffic maybe but you really want to request that the vehicle stop so you might you know run across system right let's say no that's like one node that's doing radar or something it says stop and there's another perception node that also like sees something in front of the vehicle and wants to say stop and they...
might say stop simultaneously and so the action server has to be able to say oh I got too many people somebody else already asked me to stop you know this guy asked me to stop first versus this other person or other node another thing that might happen other than this multiple clients coming at the action server at once is this notion that the client may ask you to cancel so an example of how that might happen is you're driving along cars running and the perception system like I think I've heard of this actually happens so there's like a plastic bag we've gotten rid of those in California thankfully but plastic bag is getting blown across the road and the perception system freaks out and doesn't know what to do with it it's like I don't that bag is I'm gonna assume it's a person we should stop and it will issue the the it'll ask an action that's the stop action to stop and it'll start the action will do ok cool I'm gonna do that and let's just start slowing down the vehicle and meanwhile the perception system says oh that wasn't a person it was a bag cancel that stop we can keep driving so you can you need to be able to cancel these actions in the middle of things do so it's a bunch of different stuff you're gonna have to handle it's a little bit more complex but it's also a little bit more robust and handles all of these sort of real-world use cases and so you know a lot of magic can kind of live in...
there so parts of an action um basically when an action starts up you need to find the action the action server may be down so when your action starts if you're a client you need to say like is the action server up you need to make the request and often as a server you can you can say no I don't want to do that yes I can do that so there's a sort of you know back and forth on the initial requests then the actions accepted the action you know can then go along and it'll give updates saying like in that sort of stopping example the action might say ok I'm changing lanes I'm changing lanes I changing lanes then I'm slowing down now I'm coming to a good stop that feedback needs to be sort of given to the client and maybe to other people or other nodes as well all along that timeframe somebody might come in and say uh cancel and you have to handle that and then there's the final final like everything's done I'm just gonna send it back to you like the the action has been completed we're all done here sort of salt cool everything's over the transactions complete so so as sort of our toy example here what we're gonna do is we're gonna create a feminazi action so if you know the fibonacci sequence basically you know 0 1 1 2 3 5 8 so on and so forth so we're gonna create an action that you request the nth order number in the Fibonacci sequence and the action will spit out each successive number until it calculates the one...
you want and then I'll return the whole thing and you should be able to cancel and and do all these other things I'm not gonna do all of that in the sake of time I'm not gonna do all of those different steps and show you how they're all handled but they're all in the codebase in this example code book so you can go there and kind of get a sense of how they're structured so let's let's start taking a look here so just like before just like services actions use an action file just like a service file to define the parts of the action they don't define all the parts because they don't define like cancel by all of the II like requests the final result and then the feedback steps in between those are all defined in the actual definition files so why don't we take a look at one really quick these are all written llamo I believe so if you do all right so here I have one it's pretty straightforward so the goal the it starts out it's always first the goal so the goal here it's just gonna be an integer which is the the order or the the sequence number in the Fibonacci sequence so in that like each number is one two three four five six seven eight nine um so whichever one you want up to a certain number there's the result which is the the sequences of actually calculated numbers all the way to the enth order one and then finally this the feedback which is sort of the intermittent growing list of numbers that we're going to...
send all the time okay so this and just real quick just to show you kind of what's going on underneath the hood here the the the action is used by Ross's you spike welcome to build messages like Ross messages that define all the different sort of bits and pieces of this action and they're all sort of strung along as sort of internal topics I don't know then let's let's take a look at this so I've moved over to this directory here and what I can do is LS and this is from the the Fibonacci action that I just showed you and what you can see here is that there's the action feedback message there's the action result message there's all these different messages right and they're all auto-generated from that initial action message which is kind of cool right it just saves you a bunch of work and to find all these things automatically so they're correct it's quite handy all right so why don't we take a look first at our action server go back home and love to example workspace source examples are CL action server and then we're gonna look at and we're gonna just open up member functions so a couple different ways to do this I'm gonna show you how to do it as member functions inside of class because I think that's sort of the most intuitive way so let's take a look so standard headers include directives at this point this this here should be no surprise right there's an automatically generated header file...
for all these message types and you need to include it along with the Ross headers make sure school and then it turns out our action server is just a note just like before and then we have a public interface so um and we use a couple using directives so we don't type too much so we basically say hey Fibonacci is actually the interface example interfaces actions fibonacci things and then the gold handle is actually the cool thing of this type definitely cool all right so then let's let's actually instantiate this guy our instantiate why don't we take a look at this action server and its constructor and it basically takes in a couple options and is given a name minimal action server and uses those options to the base class and then we say hey we're using this namespace I would say internally it's got a pointer for this action server is going to equal create a server of type Fibonacci and we're gonna basically pass it some information about the calling nodes sort of interfaces so all this is doing is saying like hey this action server lives inside this node this is where this node is logger is its way table interfaces this is where it's clock is you're just saying that you're giving it our name and then this is where things kind of get interesting does what you're doing is you're saying here's my thing that's a little hard to read without the definition right in front of you but basically saying hey we need somebody to...
handle your goal bind it to this function called handle cold when you need somebody to handle cancel call this function handle cancel and what do you need a function to handle it being accepted call this and that's it so let's go look at here oops let's scroll down here into the private member functions and see what's going on um and what's this this is just a sure pointer to the action server itself base class all right and so when we handle with goal we're going to take in a UID and so this is a goal request right so like I said before you might have multiple people asking so they need like a unique identifier so that's what that is and then share pointer to a goal which is that's just the input and what we do we say here's our goal we check to make sure that our goal is less than a certain number so or not here all day the thing you need to note here is just how you return the type right you can basically say screw you I don't wanna do your thing and you return a goal response reject and the client that called this action server will have to say oh well they don't want to do my thing otherwise you can return an action goal response except can execute and so we return that we're saying yeah we'll do your thing the next function here is handle cancelling so all we're doing is let me get a handle and basically if the client at any point says hey don't do that thing that I wanted you basically say accept and...
that's about it and we just say that we got it and I think it'll automatically stop execution now we have this thing called executed I'll show you how this gets I think how this gets wired up is a little bit lower in the cold code but basically you get a gold handle I'm just basically that's the goal right you're passing it in and you say I'm gonna execute it you've got this little great thing it's basically a wait for asleep like if you're doing Python like sleep we get the goal let me do this so you can see this a little bit better a little bit more now we create a feedback object we also create this thing called a sequence and the sequence so this is the sequence of numbers in the feminazi series so we push back zero and we push back one which always the first do and our result which is the thing we're finally going to return and what happens here so we basically go about doing with Avinashi sequence here with lunch as ah as long as I is less than the goal the order and this is the important one here okay which we're saying as long as Ross is running to you because Ross might fail and it might say like I want to call these things down now I'm not gonna wait for you to finish so you wanna make sure you check that in your loop so check as long as somebody's not cancelling if they do cancel we basically give them the current status say cancelled in return otherwise we do the feminazi stuff we publish the feedback so this...
call just says like here's the goal handle publish the feedback like type feedback and we wait a second and we iterate all over all this finally if the goal is done we set the results cool handle succeed results so we say we're finished and we say goal succeed we set it over cool so that's just calculating feminazi sequence pretty simple you probably should have done it before okay so now finally handle accepted so what this doing I think basically is this is a little bit tricky and what's going on here is if this function gets called we're saying handle accepted with the gold handle which is the thing that's gonna go do we which basically says calculate this order Feb anoche sequence we're gonna bind it to the execute in our in our class and let it run and then detach so all this is basically doing is just wiring up between accept and execute and and spinning off a new thread so all of the you know you can do multiple people can call this action server and every time they call they're gonna spin off a new thread and you know there can be like 20 of them running at the same time and finally let's go down here all we do is like we've seen before and it Ross create the create our class let it run until Ross says shut down and that's it no don't save it cool all right so let's let's run this action server and then I'll I'll call it from the command line what if she had to do that real quick don't don't...
don't worry if you don't get it the first time it's not ideal and also you have to do it from code so let's go up and yeah I was I would say if you were modifying this also you have to refill but we didn't really touch the coders kind of peeking at it so that's execute this guy cool so this is running there's nothing there's no logging output at the top so it's not really gonna do anything it's just gonna sit there so let's open up a new terminal and all I'll call it from the command line real quick so we can see what it does so sending these things requests through the CLI has kind of little take in terms of the message format it's possible it just doesn't look all that good so we do it is Russ to action so you can see a little bit of this you can say action list well why don't we try sending it the goal boss to action send Bowl and I'm gonna just copy this so basically all I'm going to do is tell it where the message type is and then I'm gonna set up a message oh that's what I'm missing need to know which action server is sending the goal to I think that figured that let me I'm just gonna do this right with copiers interesting okay that took a second but oh you guys wanna see me all right now if we correctly start the right server it's the action server instead of the service like this all right should be quiet and then we go over here and we can send it the goal and this is what'll...
happen so we can see it set a goal of order ten and the goal was accepted with ID so this is for the UID there and you can see it's just returned response so so what we didn't get there is we didn't get to see the steps of the feedback but we can walk over here and see that it was publishing feedback it's just that the client doesn't actually spit that out cool all right so why don't we take a look at how to go and build a client that talks to this action server so this is recently State forward it's still kind of convoluted because you have to handle all the cases where the client or the server can say hey I can't handle your action right now or whatever but roughly the process is like check for connection to Ross and the action circuit check for the action server send the goal check that the goal has been accepted after it's been saddened update with the feedback information and then receive the final results so when we go take a look at roughly what that looks like we can do is I'm going to this server so when we do this over here we open this up and take a look at the member functions let's see what we got here there so it is workspace minimal action and of

course

they do that again cool alright so let's see what's going around in here here so again this should all look super familiar header files etc these are exact same as before what you'll notice also I think it's worth noting that the client and the server...
or the client and the server both use basically the same header file right because they're all using a shared message you have the header file here for right here for actions which is useful and then the client is just basically a Ross note is a class it's just basic across node again and we go through and do some scope resolution just so things aren't too long we create the consider we build constructor for our action client and this is the same as before - we basically need a client pointer inside of the class and we do this we say hey create a client the template type is Fibonacci point it to all of our note our base node basically interfaces and name it and then what's kind of tricky right here is we set a timer so in the constructor we set a timer for half a second that's bound to this end goal class or function so basically once you call the constructor and wait half a second and then it will call the send goal function all right so here's a function is called done that's just doing some checking and then here is our send goal which is called fright from the constructor and cancel the timer say that we're not done check that our client is initialized and then all this code right here it's pretty simple we look at the client interface and say hey hey check out our action server is up and running and if it's not spit out some messages saying self once the server is actually spun up we create a goal in this case we're saying hey...
let's do order 10 we say send goal um so this is this is the tricky part right here so this is we say hey we're an action client of this type and we're sending goal and what we have to tell the underlying action interface is basically the set of functions that we want called back for particular events within the lifecycle of our action client but just to say we want to be called back when the action client when the goal is accepted when it gets feedback and then when there's finally results so we need callbacks for all three of those and we can see that here basically we bind the feedback or sorry the goal response the feedback call and the result call and then we send them all off this is a synchronous message or asynchronous in the goal which should kick it and then all we just sort of wait for the callbacks to happen so let's go look at those callback functions first thing here we have a couple private member variables and first one is goal response callback so this is gonna happen whenever the let me move this forward a little bit single so this is gonna happen as soon as the action sir itself says hey I got your thought request and I'm gonna handle it because it can say hey the server I can't reach I can't do this you know I'm busy something's happened I can't handle your request but more often than not it'll say yes so here's the callback we do this we get the gold handle um and we can tell like oops well it was...
rejected if it's not we just I mean you neither case we just basically print things out and that's about it and then we come down here and this is basically our feedback callback and we get the feedback information and we just print it out pretty straightforward and then finally the results we have this wrapped result thing and the wrap result is basically because there's the output right which is the sequence of numbers 0 1 2 0 1 1 - mwah but then there's also a status code and the status code will tell you whether the action itself succeeded was aborted was canceled etc etc etc so first we check that result code and we basically log whatever happened if it succeeded we just drop out of this switch statement and then we go through and print all the results and then finally we just have this exact same main pattern that we've seen before multiple times where we just instantiate our thing basically spin indefinitely or until our goal is done and so I guess it is a little bit different in the sense that we wait to look all this done and then we just shut down afterwards it doesn't run until rush shuts down alright so why don't we exit out of here save that well we'll give this a run so the way you do this is it's to run and now so I believe our server is still running so all we have to do is run or client code yeah you should get some interesting sending goal call accepted by server waiting for result you can see we're getting the the...
next number in the sequence and finally we get the full result and if we toggle over here we should be able to see yep same settings as before okay so you just seen the the set of API primitives upon which most Ross based systems or me generally speaking when you build a robot you're gonna work from simple complex so you're gonna start with the nodes the publishers the subscribers etc etc and then you're going to take those build up smaller services from those services and other things build up action so you generally you work in that process it's worth noting that we didn't cover quite everything I think I've mentioned that multiple times and then also for all of this stuff there is also a Python API I would generally recommend that if you're you're trying to learn and just get the basics down sometimes working with the Python API could be a lot easier and a little bit more forgiving so that might help especially if you're stuck on one subject it doesn't hurt to to try and python and then see if you can get it working a c++ oh I guess the other thing worth noting is a ton of other examples inside of this workspace so feel free to pause and see what you can get running and seeing what you change I think it would be super super helpful for next time right right so I am hopefully that was a pretty good introduction to the Ross to dashing API I think we got most of the bases covered no subscribers publishers services and actions and those...
primitives basically make up most of your raw system in terms of software there's still a lot of other functionality a lot of other tools out there but that handles most of the internal software architecture so next time we'll be covering the rust to command-line interface so that I'll show you all of the command-line tools for starting stopping looking at introspecting and capturing rösti data and rosty messages and that should be a lot of fun so you know hopefully see you next week