 All right. So we are now at time. We're going to go ahead and get started. I appreciate the intro that Tim gave me. I hope that it stands up to that. My name is Mike Anderson. I'm from the PTR Group. I've been speaking here at Embedded Linux Conference now since 2007. I was looking at all my old presentations and everything. It's been a while since I've been speaking here. I'm always happy to present additional information. I do have four presentations this week. This one right now. I have another one this afternoon on reverse engineering. If you're interested in finding out what reverse engineering is all about, definitely come to that one. That'll be fun. Then I'm speaking. I'm doing the GDB debugging session at the AIL, the Embedded Linux Apprentice Linux Engineer program tomorrow. And then on Wednesday I'm doing a thing on sensors and everything you wanted to know about sensors, what they're good for, what you use them for, why you would use a particular sensor for a particular type of task, how you interface them, that kind of stuff. And that'll be on Wednesday. All right, so let's go ahead and get started. We're here to talk about the robot operating system. And in particular, what is it and what does it do and a little bit of how it works. Now, understand that ROS has been around for a while. We'll talk about some of that and what led to it. We'll talk about what ROS is and how you go about installing it. And then testing your installation. This is a relatively complex system. So being able to test the actual installation is a key piece of success with ROS. We'll get into some of the components and the concepts associated with the operating system. We'll deal with the computation graph and some of the naming conventions. And then we'll take a look at the work to build your first robot. And we'll examine a published subscribe example and then we'll finish up with a quick little summary here. So what exactly is ROS and why am I playing around with it? Well, the reason I'm playing around with it is this little robot right here. This is a robot that's targeted at being able to help the elderly. It's just a prototype at this point. But one of the things that we find in many cases, we have older parents that want to live by themselves. They don't want to move into some care facility. They believe they can take care of themselves and that's great. Unfortunately, sometimes you just need something to remind them, have you taken your medicine today? Or have you eaten lately? Or any of those sorts of questions that would typically be the responsibility of a healthcare giver. But because they've decided they want to continue living on their own, that healthcare giver isn't typically available. So the idea is to have an Alexa-enabled robot that has a little lidar on the top of it that it uses for mapping the area, mapping the room. And it's got a raspberry pie in here where we're doing most of the processing. The motor controllers, why is it a tank drive? I just happened to have had my fill of wheel-based robots for a while, so I thought I'd try a tank drive. The whole thing, it's about like that, not terribly big. The idea is to try and make these things so that the individuals can interact with it, ask it questions, order pizza, that kind of stuff. But more importantly, it is cheap enough that you could actually have them like Roombas, where they run around on different floors, and they can then kind of keep an eye on the house without having to spend a lot of money for caregivers. But there are a lot of things that, when we get into the robot operating system, we have to understand why they created it. The idea here is to create a general-purpose mechanism for creating robotic applications. Now, why is that needed? Well, for any of you who've ever actually built a robot, how many of you have ever built a robot? Most of you. Hell, that's great. Man, that's fantastic. Then you know how complicated it is to actually get a robot to move. Motor controllers, power supplies, radio controls, all the things that go into just making a robot simply move around the floor is a significant amount of work. So the raws operating system is actually not really an operating system per se. It really is middleware to try and help speed up the development process. Now, unfortunately, when we deal with humans, humans take a lot of things for granted. We walk up to a doorknob and we turn the doorknob and we open up the door. That seems fairly natural to us. Going up and down stairs also seems fairly natural to us. Unfortunately, both of those are incredibly hard problems for robots. Just being able to grab ahold of the doorknob, if it's not one of those ADA-style doorknobs, if it's an actual doorknob, just trying to grab ahold of the doorknob is a tricky problem. And certainly going up and down steps is a very, very difficult problem for robotics. So one of the things that I've focused on with this little robot here is, again, to make them cheap enough that you could have them like Roombas, several of them in the house and they could then run around and figure out what's going on in the house at any one point in time. Of course, when we're dealing with so many different robotic applications, we have flying robots. We have swimming robots. Of course, RAWS is used in a very famous application for an underwater rover. This is all stuff that basically an individual or a lab or even a university probably could not come up with on their own. It has to be a collaborative effort and we have to be able to kind of share things back and forth in a framework that allows us to actually reuse somebody else's software. So from the history perspective, this project actually started back in 2007 as an outgrowth of some work at Stanford University. They actually sponsored some of the work. It was more of a hobbyist-style approach. An organization called Willow Garage, they're a robotics incubator. They produced a robot known as the PR2, which is what you see right there. And actually, there was a PR2 in one of the charts, one of the slides at the keynote this morning. And the PR2 is a relatively complicated robot. It has vision. It has, obviously, manipulators. It's got grippers. It's mobile. It can turn. It can recognize things and people. So what they wanted to do is they wanted to create an environment that would allow folks to be able to share, develop and share individual pieces of code. Now, they licensed it under the permissive BSD license. Now, having been licensed under permissive BSD, it gives you the ability to release binaries without necessarily releasing the sources, but most of the community, of course, does release their source. However, not all of the modules for RAWS are actually covered under the BSD license. Some of them are under Apache Software License Version 2. Some are GPL. Some are MIT license. So when you're playing around with RAWS as just kind of something, a learning process, then you don't really have to pay all that much attention to the licenses because they're all open source. But if you're planning on doing something commercially, then you absolutely have to pay attention to the licensing to make sure that you don't run a foul of that. Now, RAWS is supported by the Open Source Robotics Foundation. They're at osrfoundation.org. Great organization. Good to get some, you know, work with those folks and try to figure out exactly what they're up to. They're trying to put RAWS forward as an operating system that could be used for multiple different applications. Now, installing RAWS, the latest and greatest version of RAWS came out in May of 2017. It's called the Lunar Loggerhead. You will find that all of the RAWS releases are named after turtles of some sort or another in alphabetical order. So the Kinetic Comma and the Lunar Loggerhead, and I'm not sure what M is going to be, but the thing about the way RAWS has been put together, if you are running a Debian distribution, you are in good shape. Debian distributions are the primary mechanism that they use on their website for doing their installations. They have Debian repos. So whether you're using Ubuntu, Linux Mint, Debian, or one of the derivative distributions, you're in good shape. There is some experimental support right now on Lunar Loggerhead for Gen2 and macOS, and of course on Yachto. The nice thing about the way they've done RAWS is they have associated with the... Let's see if I can pull it up here. Where did it go? Maybe there. Yes, there we go. So these are the installations that they support right now. They've got, of course, Debian Stretch. The nice thing that they have, which is kind of special, is that they have support for ARM. In the case of the Ubuntu distribution, of course that would be the Mate 0.2 distribution right now on the Raspberry Pi. They support both ARM-HF, the hardware float, and the 64-bit ARM architectures, in addition to the standard AMD64 type architectures. This is the 1604 release. They have not moved this forward on either the Yakini or Zesty releases. So I'm assuming that probably what will happen when they come out with their next release, they're probably gonna jump, and they'll jump to Bionic Beaver, which is the next long-term support release. So that'll be 1804. That'll come out next month, as a matter of fact, I hope, if everything's on time correctly. But you'll notice there's no explicit support here for any of the Fedora or RPM-based distributions. There are individuals who've taken the code and repackaged it for those, but it's not supported officially here at the RAWS website. Now, when you get ready to do the installation, it's a fairly straightforward installation. If you've ever done any Debian distributions, any installations of Debian PPAs, you add your GPG key, you add the sources, you do an app get update, app get install sequence, typical sort of thing we'd expect to see with any Debian distribution. If you follow this link that you see here, that link will actually lead you through the process of doing this in Ubuntu in the 16.04 release. So all that's pretty straightforward. Once we get it installed, we need to make sure that everything is installed correctly. Now, normally what we're going to do when we do an install, if it's going to be on a desktop-based machine, then we'll do a RAWS desktop full installation. That will bring down all of the extra goodies, the 3D visualization tools, Gazebo, which is a 3D simulation environment. We'll show you some examples of that a little bit later here. And if you do the desktop full, it brings all those things down. If you do the normal desktop, it brings our Viz down, but doesn't bring Gazebo. And then there are, of course, individual pieces that you can piece this thing out. Understand that the RAWS distribution is several dozen individual packages. So being able to select which packages you're really interested in is a challenge in and of itself. But if you go with the desktop distribution, just the desktop install, it'll bring down most of the meta packages that you need. The desktop distribution is a meta package that brings down most of the ones that you need for doing typical work. So now, assuming that we have it installed, we'll use the RAWSDEP command. RAWSDEP and NIT, it has to be done as root. So this is one of the few places actually in RAWS where we have to be super user. The RAWSDEP and NIT will then initialize the repos and make sure that it understands what packages are available to it. And then we'll do a RAWSDEP update, and that will then pull down whatever changes that may have been made in the meantime. We want to make sure that we have our environment set up. There is a setup.bash that they include. If you understand how RAWS works, basically there's a lot of Python in the background in RAWS. So although it works quite nicely with both Python and C and C++, most of the infrastructure here is Python. So we need to make sure that we have the correct sourcing of the paths to make sure we pick up the RAWS distribution, and we get this thing called the cat can build system. We'll talk about that here in a moment. If you want to be able to just run RAWS robots, that's all you have to do. If that's all you're interested in and you just want to deploy a robot, then hey, that's great. That's all you do. And as a matter of fact, you'll notice they have an option here that says select your robot. And so there are a number of robots that are available. It turns out that the PR2 robot that you saw there is several thousand dollars. So it's kind of out of the range of most hobbyists. But nonetheless, you can select a robot and then it'll pull down all the packages associated with that particular robot. But if you're going to be really working with RAWS, the whole reason you got this is to do new code. So we need to make sure that we have some additional packages installed. Again, these are typical packages that we would find in an Ubuntu distribution, 16.04 Xenial distribution. We see the Python RAWS install, RAWS install generator, WS tool, and of course the infamous build essential. If you've ever built a kernel, then you already have build essential in there. But in any case, that's just ready to... That's the additional stuff you have to have in order to be able to build code. Now, at this point, we're ready to test the actual installation. So the first piece of this is just to check to make sure that we have RAWS installed. Now we're going to actually try and build something. We'll build something really quick. Actually, it's an empty build just to make sure that the cat can build system is actually working correctly. Now, where does the name cat can come from? It turns out it is a tail-shaped flower cluster found on willow trees, which of course Willow Garage was the place where this all started. So it's kind of an homage to Willow Garage. So it's called the cat can build system. As if we needed another build system. Yes, this is yet another build system. Now, at this point, we want to try and simple build. So what we're going to do is we're going to create a directory called cat-can-ws-slash-source. This will typically be in our home directory. And then we'll CD into that directory and we'll initialize a workspace. Now, cat-can-init workspace is going to create some infrastructure for us, basically a few directory entries. And at that point, we can then CD back down to the cat-can-ws-base directory and issue cat-can-make. If all goes well, it should spit out about 25 or 30 lines worth of output that indicate a successful build. If something fails, obviously you need to go back and try and figure out what that is. But generally, if you just follow the instructions up to this point, you're going to be able to get past this initial build, no problem. And it should take you all of about, well, the longest amount of time that it takes is the actual installation of ROS itself because there are several dozen packages involved. The cat-can-make itself is over in about 10 seconds or so. Not a whole lot of stuff involved in that. Now, at its core, ROS is a published-subscribed message passing middleware. So what happens here, we will describe messages. We'll describe a format for a message and then that message will be published from one set of nodes, and the node is what they call their programs. We'll publish from one set of nodes and then we will subscribe to these things from other nodes. The communications in this particular model is asynchronous. So that actually works well for a lot of sensors, a lot of things that could potentially provide data at any time. However, it does not work all that well when you actually need lockstep behavior. So in order to handle lockstep behavior, they have another type of interface called a service interface, and we'll talk about that in a moment, but a service interface is remote procedure call-based. So if you need that lockstep, don't go beyond this point until after this has completed. There's a mechanism for doing that. Although the normal behavior here is to simply use asynchronous published-subscribed. Now, the modules, they publish the topics. And of course, in a typical pub-sub environment, you've got topics, people subscribe to topics. When you publish a topic, then it'll let folks know that the topic has been published and they'll be able to go read it. Communication is total message passing here. Because it is message passing, there is no global memory that people can somehow write things into and pass lots of data. Although there is a parameter server, we'll talk about that in a moment, but the idea here is by forcing everyone to use a message passing interface, we get nice clean interfaces. If it's not in the message passing format, if it's not part of the interface definition language, then basically it doesn't happen. So in some ways, they're actually trying to force you to do a better job at engineering your robots. Certainly I've built enough robots over the years that in some cases they're kind of slammed together and not necessarily as robust as they probably should have been. Now, the communications is basically running on top of TCP. So we have TCP connections. There is an option to get into UDP if you need that for whatever reason, but that is the primary mechanism that we use. It does support the recording and playback of messages. Now, this is interesting. The actual recording of messages goes into something called a bag, and what will happen is we can then kind of post-process the bag and then use that to regenerate those messages over and over and over again for regression testing. Of course, that's also something that you end up doing a lot of with robotics. There's a lot of regression testing because you always thought that you had it right the first time and it never quite seems to be what you thought it was. So that's always something that we need to be able to take into account. There is, as I mentioned, support for remote procedure calls and there is a distributed parameter system which allows me to have a master node. The master node is basically the clearing house for all the PubSub, all the topics and everything go through the master node, and then we have this parameter system that's usually associated with the master node. That parameter system will then be able to feed configuration data into individual nodes as needed. There are a lot of diagnostic capabilities built into ROS. There are replacements for the C-OUT functions, basically, that will then write into a bag so that you can then capture all that information. The interesting approach here, because it is using typical network protocols, the robot nodes, the individual controller pieces do not have to be on the same processor core. So they can be split out amongst various microcontrollers and processors and you can have them not only be distributed in the robot itself, but also geographically distributed if you needed to have a wide area kind of knowledge going on inside of the robot for whatever reason. Now, ROS has got three levels of concepts associated with it. They've got a file system level, a computation level, and then there's the community level. At the file system level, these are all the things that you will write and work with on the file system itself. These are things you find in directories. So we have packages and meta packages. Meta packages, of course, collect packages together to make some logical connection between the packages. We also have repositories. Repositories in this sense are not the same type of repository that we see in the Debian world. This is more like a stack. So we'll have a lidar repository that will have all the functions inside of it for using laser imaging or laser guided radars. We have, of course, then message types and service types. Message types will define the actual pub sub piece. Service types will define the remote procedure call interfaces. So now, when we get a little bit further into this, we get into the computation graph. Now, the computation graph is a peer-to-peer network. So all of these ROS processes, known as nodes, are all connected together and they are communicating with each other over the network. So the computation graph level has the node, the individual components. We have the master, which is responsible for setting up and running the namespace. We have the parameter server, which is going to be providing those configuration options down to the individual nodes. And then, of course, the messages associated with messages are topics because we are doing pub sub and the services for the remote procedure call mechanisms and I've already talked about bags. Now, at the community level, I understand there is a lot of folks working on ROS. And this is worldwide. They have their own distributions. The lunar loggerhead is one distribution. The kinetic commy is another one. We have the ROS wiki, excellent source of information. If you have questions about what's going on, definitely take a look at the ROS wiki. There is a blog, which kind of shows what people are up to and the latest and greatest things they've been able to do. And there's also a very nice fact site. So the community in ROS is very well set up, very well distributed, and very supportive of things that you're doing. So there's no... Well, that's a really stupid thing to do, kind of questions. It's a, well, I might do it a little bit differently and here's how we've done it in the past. Now, on the file system specifics, the package is the primary unit of software in ROS. It's the finest granularity. It basically is the source of libraries, nodes, datasets, configuration files. Anything that needs to be viewable at compile time will typically be associated with a package. Metadata then collects those packages together. There is a package manifest, and if for whatever reason you've been avoiding XML over the last several years of your career, you cannot avoid XML when it comes to ROS. ROS is extremely XML centric. So even when we get ready to describe robots, we describe them in XML, which can get a little bit tedious. We'll see some examples of this coming up here, but understand that the whole idea is to have some universal format that can be easily parsed, and that's why they went with XML. The message types, of course, these are actually data structures. Now, the data structures are comprised of primitive types. So we've got integers, we've got booleans, we've got floats, those are the basic types, and then we combine them together into structures just like we have in C or C++. Additionally, those structures can be nested, so we can, in fact, have structures within structures. That works fine in ROS. The service level entities, that is hardcore kind of remote procedure call, request, response type data structures, and of course we have to define those as well. Now, at the computation graph level, the nodes are processes that perform the computation. So they will have things like motor control, the LiDAR interface, the graphical view, all of those will be represented as nodes. We then have the nodes talking to each other. This might be a remote procedure call using service invocation, but normally nodes are going to publish topics. Other nodes have subscribed to topics, and as soon as the topic gets published, the node, when it goes into one of its loops to look for subscriptions, it'll basically update and pull down the latest information. The master is that clearing house for name registration and lookup for the rest of the graph. So if the master dies for whatever reason, the entire thing dies. So you need to make sure that the master is stable and is running on a machine that is stable with good power and all that sort of stuff associated with it in order to make sure that everything continues to function correctly. We talked about the primitive types there, so we got that. Now, the topics are the messages that are routed via the PubSub semantics. The node subscribes to topics. It does support one to many. It also supports many to many transport. So we do have the ability to kind of send a broadcast, if you will, to all of the nodes inside of the robot, something like, I'm getting ready to shut down now because the battery is almost out. All of these kinds of things actually are supported quite well. Additionally, what will happen inside of the ROS nodes, there is a secret, or silent, it's not really secret, but it's a silent signal handler that gets installed for Control-C. So the Control-C signal handler will intercept that and then it lets everybody know that the system is going down and it sends that information out automatically for you. All right, so we've got the bags. We've already talked about those. Now, the naming structure. As you might guess, since this looks like a file system, it is also very file system-like. Slash is the top level. Now, slash can then have associated with it resources. So resources are defined in their individual namespaces. They may define or share other resources. Effectively, what happens, the code as it's running will stay in its own namespace There is a way to get out of a namespace. We'll show you what that looks like here in a moment. But the name basically gets resolved locally as though each one of the domains was a top level domain. So if I have a slash and then I have a lidar and I have a motor controller and I have a camera, each one of those top level domains are going to be effectively a stovepipe. They can communicate with each other. We can actually have an integrator that sets up at a higher level that then takes messages from one, say the camera, and then feeds them over to the motor controller or what have you. That can actually be done. It's not that complicated. But it turns out that when we're dealing with the namespace, names will typically begin either with a tilde, which means you're at the home, a slash or an alpha character, either upper or lower. Then all the subsequent characters are either alphanumeric underscores or slashes. It is fairly pedestrian in some of the naming conventions that it uses, but it does keep you out of trouble when you're talking about relatively complex systems where more than one group may be responsible for individual subsystems. So the name resolution, we always have to have a base name. Without a base name, we can't start a robot. We then will have relative access, so it's going to be from wherever I am right now slash something underneath me. We have global names, which begin with a slash, and then we have private names, which begin with a tilde. The tilde private name allows me to have pieces of data that aren't visible outside of the namespace in case we need to be able to do that equivalent of the private call in C++. So the package resources names will then have this format, a package name slash message type. An example here, standard messages. There is a package called standard messages, which has the base types in it. One of those base types is the string base type. That's basically just a string-oriented message from that package. That's how that would be referenced. And when we look in the code, we'll actually see them reference these kinds of things. So now here we get to the ugly part of what happens in RAWS. And that is describing things in the unified robot description format, URDF. URDF is XML, and it is an interesting approach to representing things, given that you have to describe every possible connection that the robot may have. Joints, wheels, connection points on the wheels, you have to describe the physics associated with the wheels, the structure, you have to describe all of that. And this, at one level, this is focusing more on the simulation piece of it. Oftentimes what we will do is we will create a simulation of the robot so we can drive it around and it does what we think it should do in the world that we've defined in case of something like gazebo. And then we will take that and build the actual item. We like to be able to simulate it first just because that way we can work out a lot of the details of how things are going to be interfaced with each other. Obviously the real world always gets in the way and we never quite get the kind of wheel friction we hope for or the motor torque that we hope for, depending on how things are put together. But at least we have a simulation of how it's supposed to work so that we can then go, oh well that's not what it's supposed to do. It's supposed to turn to the right, not to the left. So those kinds of things can actually be done here in URDF. We have also, there's a developed language called ZACRO. ZACRO is an XML macro language and that's because when you start describing things like wheels and axles and motors and things of that sort, the number of descriptions can get very, very large. So for instance, some of my larger robots or six-wheel drive robots just defining the gearboxes and the wheels and the interfaces to RAZ for all of that is fairly long and tedious. So using ZACRO we can actually abbreviate that, create a macro that says give me a six-wheel drive, give me a six-wheel drive base and then boom, a six-wheel drive base shows up. So that helps us quite a bit in terms of being able to kind of rapidly develop things in this approach. So we're going to build a basic chassis here. We'll have two URDF components. They'll define a simple robot chassis. It's basically just a box. Then the link components will describe a rigid body based on its physical properties. So we'll talk about the width, the height, the length, the color, those kinds of things. Then the links are going to be connected by a joint. The joint components then describe how our wheels are going to be attached. We have to describe the type of joint, the degrees of freedom, the axis of rotation, the amount of friction. There's a lot of physics in this and that's of course because if you're actually trying to build real robots in the real world, physics matters. I try to describe this to my students, my robotic students and say, look, the real world is not very forgiving. Things have more friction than you anticipate. Wheels slip a lot more than you think they're going to. In our particular case for this last competition last weekend, chains break and you didn't anticipate that. So the real world is not a very forgiving place when it comes to robots. It's nice to be able to build a robot in a relatively nice little sandbox and work from there. So speaking of a box, here is the box in URDF. So we've described an ELC robot. We have declared it as the base link and in the visual world it has an origin at 0, 0, 0 which is right in the middle of the field. So as we'll see with RVIS, which is a 3D graphics visualization tool, we will describe the box sitting basically in the middle of the field. The RPY there, this is the roll pitch and yaw of the device, so it's starting out flat. No angles, no orientation other than just flat sitting on a floor. The box size itself, these are in meters. So this is a half meter long, half meter wide and a quarter meter high. That describes the geometry and we've ended the visual here and of course, you know, typical XML stuff here. We got to add all the additional verbosity associated with it. So now, assuming that we have described this adequately, we want to create the package that this URDF is going to go into. So we'll do a cat can create package and we'll call it ELC robot. This will be in our cat can workstation. So in the cat can WS directory we'll do this cat can create package ELC robot. This will automatically create some structure for me. It's going to create a package manifest, the package XML, and it's also going to create a CMake list that will allow me to then launch the build. So at this point, it's created the files in cat can source ELC robot, adjust the values and package that XML if you have to. I mean, if you're going to be bringing in additional depends, dependencies and things of that sort, you need to express them here in the make so that we can then make sure that we bring those in correctly. We then CD to cat can workspace and then do a cat can make. This will produce all kinds of build output. All this is doing now, and remember is building an empty project. There's nothing here yet other than just the infrastructure. So this is just a test to make sure that the infrastructure built correctly and now we can start populating it with actual files. So we're going to create the robot for URDF. We'll do the, we'll CD to source CD to source ELC robot and then we'll make a directory called URDF. We'll copy the URDF model we just created into that directory and in order to run the model we're going to have to have what's called a launch specification. So raw's launch is a mechanism for taking a launch spec and then turning that into running code. So what raw's launch will do is it'll be responsible for starting up the master, starting up the parameter server, making sure that all the connections are there. It will then look at your code to see if you've produced any, if you've produced any topics it will then make sure those topics are in the global namespace. All that stuff will be taken care of by raw's launch but we have to have the launch specification. So the launch specification is itself not necessarily trivial. We'll do a make-dure on launch and then we'll go in and edit the launch using your favorite editor. In my case that's VI. Oh, not VI. No, just simple, easy. Something simple. Here is the launch file. All right, so let's take a look at the launch file. First of all we are setting up a model here. We've defined the GUI. Right now it's not going to be coming on just yet. We'll actually do that a little bit later. We'll have our robot description. We are going to find ELC robot in the workspace. Look for URDF. And then we will specify the argument which model we're going to be using. So we'll show how this is done when you actually from the command line list a particular model of the robot. This is nice because it means that I can have subsequent releases in the same directory and simply launch them as different models. So I can have a ELC robot, ELC robot 2, robot 3, robot 4, etc. Getting up to the point where I've actually incrementally built all the tools or all the pieces that go along with the robot. I have a joint. In this particular case the joint state publisher will get into the actual joints associated with the wheels. Here's the robot state publisher and here is the mechanism that actually allows me to do the visualization. RViz and what RViz will do is it will run that, find ELC robot and look for URDF RViz. If it finds it then that says that this has already been created as a 3D model. If it doesn't find it and it won't in the first case there is no 3D model and I have to tell it to create one. We'll show you how that's done in a moment. If RViz dies then the entire ROZ launch will be killed off and that's the basic simple launcher. These launchers can get a lot more complicated. Obviously we can have more nodes, we can have more dependencies. There is its own kind of art to writing launchers, but this is a very simple one that we'll be using for this case. Now what we're going to do is we're going to launch it. We'll do a ROZ launch, ELC robot, ELC robot, RViz launch was the thing we just created. The model here will be ELCrobot.URDF which was that URDF that we looked at a couple charts ago. Now what we get out of that is this lovely red box sitting in the middle of the field. It seems like a lot of work to go through just to get a red box. But again, this is kind of incrementally developing a robot in a 3D space as we go through the process. So what we're going to do is we're going to put some wheels on it, we're going to color it something other than red and then in order for us to be able to do that we have to describe the wheels, we have to describe their radius, the joint connection to the base link, their inertia, the collision characteristics, the mass of the wheels. Fortunately again, there are predefined setups for certain classes of tires, wheels and general motors. So we can just simply use those instead of having to ride all this stuff by hand. But once we finish with all that we end up with Loala, a blue box with wheels. We have wheel on this side, wheel on that side. We have the indicators for the center of mass. And in this particular case what you don't see is I actually put a little caster underneath the robot. Otherwise the robot kind of does this. The caster is not a non-functional item. We just simply stick it underneath there to keep the robot level as the robot rolls around. Now once that's done we can actually load it into the 3D model and drive it around inside of Gazebo. So Gazebo is a 3D world simulator and it's used not only for Roz but it's used for many, many different examples. There's something called Stage as well. These all give us the ability to describe a 3D world. And in this particular 3D world I have two objects, two cones. There is a sun which is generating the shadows that you see there. And my robot sitting in the middle of the field. At this point I have now the ability to do things like manipulate gravity. So I can go into the Gazebo environment and change things around. What we're not seeing here is the rest of the interface for Gazebo which allows me to describe characteristics like gravity is really heavy at this end or this is actually slanted in some way or it's a hyperbolic space. It turns out that Gazebo has about 100 or so predefined models associated with it and you can define your own models for your own space if you want to, you know, one of the examples we've used this for is in first robotics competition a couple of years ago they had the entire field which is a 56 by 28 field with a lot of objects on it completely described inside of Gazebo. So the teams could actually create robots and drive them around on the field using the actual joysticks and actuators that we were going to be using on the real robot. So it was a really handy way of being able to kind of test some ideas out does the arm do what it's supposed to do am I able to lift this thing up correctly can we drive all that sort of practice before the physical robot was actually created in the first robotics competition we have six weeks from the time they announced the game to the time we have to finish the robot and put it in a bag and then we can't touch it until we get to the competition and hopefully it works when we get it out of the bag it almost never does but in any case using something like this gives us the opportunity of being able to actually get the drive team familiar with the controls before we actually get out on the real field. So Gazebo is a very nice tool again you had to have installed the full desktop version of ROS in order to pull Gazebo down if you did not install Gazebo when you installed ROS that's okay you can go out to the Gazebo website and it has a one click link which then does the app get to add the GPG key adds the repository pulls Gazebo down installs all the auxiliary functions additional packages that have to be installed to support Gazebo. Gazebo is also 3D aware so if you happen to have NVIDIA graphics controllers or something else that's providing you 3D it knows OpenGL so if you have OpenGL it will actually do OpenGL acceleration which really helps for fields that have a lot of objects on them especially when you've got robots running in a swarm you're trying to see how the swarm behavior works or you're trying to figure out how you're going to interact with certain obstacles on the field. Now a PubSub of course the ROS Wiki's got an example of a simple PubSub but we're going to take a look at a PubSub just so that you can see what that looks like there is in this particular case it's just a pub on one side there's just one topic that's going to publish and then the listener will subscribe to the other side so let me see if I can go over there and actually make this come together I think it's this one yeah there we go alright so let's do this oops I think that's actually here there we go alright so what we have and hopefully you can read that from the back there I have two C programs one's called listener the other's called talker talker will be the publisher it will publish the object and the listener will be then waiting for updates so let's take a look at talker of course this is a demo so it's got lots of header stuff on it we're interested in let's just scroll up a little bit here there's our main include for raws so that's going to be the brain header and in this case we're going to be putting out a string so it's going to have a topic that will have just a string in it we're also we've got some other includes here for the streaming information our main looks just like any other main you would expect to see we will then do a raws and knit the raws and knit will then read the arguments from the command line and it's going to initialize a node called talker and that's what we see here then we're going to create a handle to be able to deal with that node so this will be the mechanism that the master uses for being able to actually get the the publishing the subscribe options so we're going to have an advertise here so this is how we actually put a topic out there into the global namespace we're going to use the advertise command and in this case we're just going to advertise a string into that world it's going to be called chatter and of course maximum length here is a thousand characters we will then set up a loop rate now this loop rate is in Hertz so this is running at 10 Hertz a hundred milliseconds per pass this is just simply setting our polling loop so in those cases where we're actually doing polled IO instead of interrupt driven IO we have a way of being able to control that poll rate now we've got an integer this is just standard stuff here but while we are connected to Roz while Roz is okay then what we're going to do is we're going to put a string out there and declare that is the message data and then we're going to turn around and publish that so this is the publish call here where we've now published that message at this point we now have an option in this case there's a thing called spin once that allows it to poll to see if there's been any updates since this is the publisher not the subscriber chances are we actually don't need this particular call but they do have it here and there is a sleep mechanism as well if we need to go to sleep for whatever reason it's going to keep track of how many times it's written that information out into the publish on the subscribe side the listener the listener is actually a little bit easier than the publisher so the listener again we have Roz that we had to declare and our standard messages string we do declare a callback so in this case when something gets published it's going to hit my callback and let me know that there's been an update to this particular topic so in the main I will do a Roz and it and I'm going to declare myself as the listener I again have a handle that I'll be using to be able to have the master talk to me and be able to keep track of what things have been subscribed and then I have the subscriber I'll just subscribe to chatter and when it happens it's going to call the chatter callback and call that piece of code that we just looked at and it'll let me know that there's been a message there and I'll be able to read it and in this case we do have the spin the spin actually does something here the spin in this case is just simply waiting for that update to happen when the update happens then I'll be able to call that chatter back that chatter callback and pull the information out and that's basically it for a listener to a particular message for services and things of that sort get a little bit more complicated unfortunately we don't have the time to get into that the tags they're all comments basically they are mechanisms that you don't actually don't have to have them the tags are just simply there that there are some error checking code that's available some actual testing code that's available that will allow you to make sure you've enumerated everything correctly so you don't actually have to have those tags but if you have them then you get a little bit more diagnostic information out of the build so that is basically it for being able to do a pub sub not a whole lot to that actually and what we have here of course is we are just about out of time but it's been kind of a whirlwind introduction to Roz Roz because of all the XML looks to be a little bit intimidating fortunately because of the definition of a lot of these macros we have the ability to just simply pull in a macro without having to go through the detail definition of everything and we're obviously we're standing on the shoulders of giants here we're actually working with other universities other labs and other hobbyists that are going through this process of actually trying to build up individual Lego block type components that we can then stick together there are a number of books that are out there some of them are really nice this one that you see up here the systematic approach to learning robot programming with Roz Roz robots by example is a nice one that gets you kind of up to speed quickly and then they have one that is the gentle introduction to Roz down here this one is a relatively new one I haven't had a chance to really play with it all that much and kind of read through and review it yet but I just like the idea of a gentle introduction to Roz because Roz is by no means gentle if you just simply start looking at all the XML and everything especially the definition of the languages and everything when you get ready to do a for instance I'll show you this when you get ready to do a robot that has let's see where am I I think they're there nope nope nope nope alright well that's okay catkin workspace go to source and go to the ELC robot and then go to URDF this robot here number six has got all the definitions in it for all the wheels and how the inertia works and everything else so for instance we see here there's the base that we've got defined we see what its mass is and this is in kilograms inertia this is an inertial framework if you look up inertia in Wikipedia it'll actually take you down this path and they use the exact same definition that Wikipedia has so if you're interested in that here is I told you I had a caster there's the definition of the caster and again this caster doesn't actually do anything it's just simply stuck on the bottom of the box and it's just simply there to keep the box from tipping over but we see this roll pitch and yaw again is zero we see the size and we see the relative attachment point we see that it's our sphere or radius 0.05 and again we have some characteristic of the inertia associated with the caster then the right wheel there's the right wheel we specify that we want a dark grey color we specify its radius in this particular case there is a roll associated with it because it is not flat it's kind of vertical here and it's going to be attached to the box we then have the that's the right wheel then we have the right wheel joint that we have to describe the left wheel and then the left wheel joint and once we get past the left wheel joint then we basically describe the whole robot to launch this what we'll do is we'll do a raw's launch and we need the launch file which is let me go look at that oh I'm in the wrong directory so there's the visualization so we'll do a raw's launch if I can spell yes there we go and this and then model colon equals elc robot 6 dot urdf and I messed up somewhere oh yeah yeah yeah so I messed up but I'm missing what but I should find it actually maybe I'm in the wrong directory here because I should have launched oh you're right there it is now you'll notice there's nothing here right now because what I have to do since this is the first time I've run it on this particular model I need to specify that I'm interested into the base link is what I'm interested in and I want to add a robot model there's my robot model and then I want to add the the transform so I can actually then roll it around so if you scroll in far enough you'll actually notice that there's a blue and a red marker here which indicates up and forward so we can now start messing around with this and start rolling it around just to see what it does but that's the general idea behind our vis and then you take that same thing and you put that into gazebo and now you have a 3D model that you can run around in space alright questions anybody still awake yes as a hobbyist not this actually there are a lot of ones from seed studio S-E-E-E there's three E's for whatever reason I'm not sure why they have the Cherokee which is a little like $49 robot chassis runs off of an Arduino has a very simple motor controller little 2 amp motor controllers so it's a good place to get started because it's easy to get it up and running obviously there's nothing really spectacular about it because it doesn't have RF control no Wi-Fi or anything like that but it's an easy platform that you can start with and then start adding Wi-Fi start adding or Bluetooth or 802.15.4 add cameras things of that sort it's a unit's about that big and you can actually buy it off of Amazon so that would be where I would start it's pretty easy to get up and running and doesn't cost a whole lot of money if you want to have higher end stuff you basically start at a hundred bucks and go up some of my robots are three or four thousand dollars so it's a hobby that my wife is not fond of okay thank you very much