What is ROS? Robot Operating System

Slides:



Advertisements
Similar presentations
Chapter 7: User-Defined Functions II
Advertisements

Teaching Assistant: Roi Yehoshua
CSE 332: C++ exceptions Overview of C++ Exceptions Normal program control flow is halted –At the point where an exception is thrown The program call stack.
Teaching Assistant: Roi Yehoshua
Informática II Prof. Dr. Gustavo Patiño MJ
Teaching Assistant: Roi Yehoshua
Teaching Assistant: Roi Yehoshua
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Teaching Assistant: Roi Yehoshua
1 Procedural Concept The main program coordinates calls to procedures and hands over appropriate data as parameters.
Program Input and the Software Design Process ROBERT REAVES.
CSE 332: C++ program structure and development environment C++ Program Structure (and tools) Today we’ll talk generally about C++ development (plus a few.
C++ Functions. 2 Agenda What is a function? What is a function? Types of C++ functions: Types of C++ functions: Standard functions Standard functions.
Teaching Assistant: Roi Yehoshua
What is RobotC?!?! Team 2425 Hydra. Overview What is RobotC What is RobotC used for What you need to program a robot How a robot program works Framework.
Robot Operating System Tutorial ROS Basic
Teaching Assistant: Roi Yehoshua
Beginning C++ Through Game Programming, Second Edition by Michael Dawson.
CMSC 202 Exceptions. Aug 7, Error Handling In the ideal world, all errors would occur when your code is compiled. That won’t happen. Errors which.
© The McGraw-Hill Companies, 2006 Chapter 4 Implementing methods.
Variables, Functions & Parameter Passing CSci 588 Fall 2013 All material not from online sources copyright © Travis Desell, 2011.
Java Introduction to JNI Prepared by Humaira Siddiqui.
REVIEW On Friday we explored Client-Server Applications with Sockets. Servers must create a ServerSocket object on a specific Port #. They then can wait.
Introduction to Bash Programming Ellen Zhang. Previous three classes What have we learnt so far ?
Teaching Assistant: Roi Yehoshua
Object-Oriented Programming in C++
Classes and Objects in Java
Loops (cont.). Loop Statements  while statement  do statement  for statement while ( condition ) statement; do { statement list; } while ( condition.
C Functions Three major differences between C and Java functions: –Functions are stand-alone entities, not part of objects they can be defined in a file.
1 A simple C++ program // ======================================================= // File:helloworld.cpp // Author:Vana Doufexi // Date:1/4/2006 // Description:Displays.
BEGINNING PROGRAMMING.  Literally – giving instructions to a computer so that it does what you want  Practically – using a programming language (such.
1 CS161 Introduction to Computer Science Topic #9.
Teaching Assistant: Roi Yehoshua
C++ / G4MICE Course Session 2 Basic C++ types. Control and Looping Functions in C Function/method signatures and scope.
C++ / G4MICE Course Session 1 - Introduction Edit text files in a UNIX environment. Use the g++ compiler to compile a single C++ file. Understand the C++
More about Java Classes Writing your own Java Classes More about constructors and creating objects.
1 Chapter 9 Scope, Lifetime, and More on Functions.
Teaching Assistant: Roi Yehoshua
1 Recall that... char str [ 8 ]; str is the base address of the array. We say str is a pointer because its value is an address. It is a pointer constant.
1 Chapter 15-1 Pointers, Dynamic Data, and Reference Types Dale/Weems.
I/O Software CS 537 – Introduction to Operating Systems.
T. Meyer ROD Software Workshop July 2002 Scripting and Interpreted Languages Tom Meyer Iowa State University
3-July-2002cse142-D2-Methods © 2002 University of Washington1 Methods CSE 142, Summer 2002 Computer Programming 1
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
1 Intro to the Shell with Fork, Exec, Wait Sarah Diesburg Operating Systems CS 3430.
Lecturer: Roi Yehoshua
Functions Students should understand the concept and basic mechanics of the function call/return pattern from CS 1114/2114, but some will not. A function.
User-Written Functions
Chapter 6 CS 3370 – C++ Functions.
Lecturer: Roi Yehoshua
ROSLab: a High Level Programming Language for Robotic Applications
Command line arguments
Why exception handling in C++?
What is ROS? ROS is an open-source robot operating system
Programmazione I a.a. 2017/2018.
Multi-Robot Systems with ROS Lesson 2
Chapter 9 Scope, Lifetime, and More on Functions
- The Robot Operating System
Program Breakdown, Variables, Types, Control Flow, and Input/Output
Quick Introduction to ROS
Robotic Perception and Action
Java Programming Language
Robotic Perception and Action
Functions Reasons Concepts Passing arguments to a function
CMSC 202 Exceptions.
Pointers, Dynamic Data, and Reference Types
Robot Operating System (ROS): An Introduction
Presentation transcript:

What is ROS? Robot Operating System ROS essentially provides two things: A set of tools that are generally useful for controlling robots E.g. Interfaces to sensors, general-purpose algorithms, etc. A communication framework to allow different pieces of your robot brain to talk to one another

Intro to ROS Nodes cam_data subscriber cam_data publisher

ROS $ roscore Master rosout ... logging to ~/.ros/log/9cf88ce4-b14d-11df-8a75-00251148e8cf/roslaunch-machine_name-13039.log Checking log directory for disk usage. This may take awhile. Press Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB. … blah blah blah Master Launches the ROS Master, which keeps track of all of nodes that your run and all of the topics that each node publishes and subscribes to Also initializes some other ROS components that are generally useful rosout

Note: run this in a new terminal window ROS $ rosrun package1 first-node Note: run this in a new terminal window Master Advertise topic1 rosout first-node

Note: run this in a new terminal window ROS $ rosrun package2 second-node Note: run this in a new terminal window Master Subscribe to topic1 rosout first-node second-node

Note: run this in a new terminal window ROS $ rosrun package2 second-node Note: run this in a new terminal window Master Master connects topic1 publisher to topic1 subscriber rosout first-node second-node

ROS $ rosnode list /rosout /first-node /second-node Master rosout topic1 rosout first-node second-node

ROS $ rostopic list /rosout /rosout_agg /topic1 Master rosout first-node second-node

ROS commands roscore : Run this first; starts the Master and some other essential ROS stuff rosrun [package-name] [node-name] : Use this to start a ROS node rosnode : rosnode list : List all currently running nodes rosnode info [node-name] : Get more info about a particular node rosnode -h : Learn about more things rosnode can do rostopic : rostopic list : List all topics currently published rostopic echo : See the messages being published to a particular topic rostopic -h : Learn about more things rostopic can do

ROS commands roslaunch [package-name] [launch-file-name] : Reads a .launch file, which contains instructions for running multiple nodes, and doing fancy things like passing parameters to nodes, renaming topics, etc. <launch> <node name="listener-1" pkg="rospy_tutorials" type="listener" /> <node name="listener-2" pkg="rospy_tutorials" type="listener" args="-foo arg2" /> <node name="listener-3" pkg="rospy_tutorials" type="listener" respawn="true" /> <group ns="wg2"> <remap from="chatter" to="hello"/> <node pkg="rospy_tutorials" type="listener" name="listener" args="--test" /> <node pkg="rospy_tutorials" type="talker" name="talker"> <param name="talker_1_param" value="a value" /> <remap from="chatter" to="hello-1"/> <env name="ENV_EXAMPLE" value="some value" /> </node> </group> </launch>

/* Body of event loop goes here */ ROS Skeleton #include "ros/ros.h" int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h"   int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; Include the ROS library /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h"   int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; Program execution always starts at “main” main gets passed command line arguments (argc, argv), which you are required to pass into ros::init so it can handle them appropriately /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h" int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; ros:: is a namespace; a collection of related functions, data, etc. that are all packaged together Anything in this namespace has to be accessed by prefixing it with ros:: ros::init (initialize) must be called before any other ROS functions; it expects to be passed main’s command line arguments (argc, argv) and the name of the current node /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h" int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; ros::NodeHandle is a class which allows us to communicate with the ROS system You must create a NodeHandle object in order to properly initialize and register your ROS node; when the handle goes out of scope at the end of the program, it will automatically cleanup after itself In the body of your ROS node, a NodeHandle can also be used to advertise or subscribe to topics /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h" int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; The main body of a ROS program is a loop The loop keeps running as long as this ROS node hasn’t been asked to shutdown (i.e. as long as ros::ok() returns true) At a high level, a typical loop might look like this: Do some work Publish results Handle any incoming messages Sleep for a little while, then repeat /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h" int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; ros::spinOnce() checks to see if there are any new incoming messages from other ROS nodes, and if so, it invokes callbacks to handle them appropriately We haven’t subscribed to any topics in this example, but we’ll see shortly how this works /* Body of event loop goes here */

Line-by-Line Breakdown #include "ros/ros.h" int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; ros::Rate is essentially a timer class that helps to keep your main loop running at a reasonable frequency We first declare loop_rate(10), which is a 10Hz timer At the end of our main loop, we call loop_rate.sleep(); if our loop took less than 0.1s (1/10th of a second), loop_rate.sleep() will wait until the full 0.1s has passed This way, our main loop always runs at a (roughly) consistent frequency /* Body of event loop goes here */

Now, let’s subscribe to a topic

ROS Subscriber #include "ros/ros.h"   int main (int argc, char **argv) { ros::init(argc, argv, “name"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe(“topic1", 1000, callbackFunction); ros::Rate loop_rate(10); while (ros::ok()) ros::spinOnce(); loop_rate.sleep(); } return 0; Recall, `n` is our NodeHandle Subscribe to a topic using n.subscribe(...) “topic1” is the name of the topic to subscribe to 1000 is the number of incoming messages to hold on to before deleting some (so, if we cannot process messages fast enough, and get more than 1000 messages behind, we will start dropping old messages) callbackFunction is the name of the function to invoke when a new message is received n.subscribe(…) returns a ros::Subscriber object; as long as we hold on to this object, we will remain subscribed to “topic1”

ROS Subscriber // somewhere else in the program … void callbackFunction(const std_msgs::String::ConstPtr& msg) { printf("I heard: [%s]", msg->data.c_str()); } This function will be invoked whenever a new “topic1” message is processed by ros::spinOnce() Note the signature of the function: it returns void, and it accepts a single parameter “msg”, which is a pointer to the message received The type of “msg” will naturally vary, depending on the type of messages that you are subscribed to. In our case, messages published to “topic1” are string messages, and have type std_msgs::String Note this is not the same thing as a C++ string object; it is a ROS message which contains a C++ string

Common std_msgs Message Type Include Callback signature Usage std_msgs::String #include “std_msgs/String.h” void callback( const::std_msgs::String::ConstPtr & msg) string data = msg->data std_msgs::Bool #include “std_msgs/Bool.h” void callback( const::std_msgs::Bool::ConstPtr & msg) bool data = msg->data std_msgs::Int32 #include “std_msgs/Int32.h” const::std_msgs::Int32::ConstPtr & msg) int data = msg->data std_msgs:: Float64 #include “std_msgs/ Float64.h” const::std_msgs::Float64::ConstPtr & msg) double data = msg->data

Let’s publish to a topic

ROS Publisher Advertise a topic using n.advertise(...) #include "ros/ros.h“ int main (int argc, char **argv) { /* … blah blah blah … */ ros::Publisher pub = n.advertise<std_msgs::String> (“topic1”, 1000); ros::Rate loop_rate(10); while (ros::ok()) std_msgs::String msg; msg.data = “Foobar”; pub.publish(msg); ros::spinOnce(); loop_rate.sleep(); } return 0; Advertise a topic using n.advertise(...) Unlike with subscribers, where the type of the message can be inferred from the callback function, we need to explicitly tell ROS what type of message to expect using <> triangle brackets “topic1” is the name of the topic to advertise 1000 is the number of outgoing messages to hold on to before deleting some (so, if we cannot send messages fast enough, and get more than 1000 messages behind, we will start dropping old messages) n.advertise(…) returns a ros::Publisher object; we send a message by calling its .publish(…) method and passing in a ROS message of the appropriate type

Okay, we’ve got a complete (trivial) program – let’s build it!

ROS Package workspace

workspace ROS Package art

art ROS Package localplanner artsystem imu ucontroller

localplanner ROS Package src include bin CMakeLists.txt manifest.xml

ROS Package Source files go in here localplanner src include bin CMakeLists.txt manifest.xml

ROS Package Header files go in here localplanner src include bin CMakeLists.txt manifest.xml

ROS Package Executables will be built here localplanner src include bin CMakeLists.txt manifest.xml

ROS Package Build instructions go here localplanner src include bin CMakeLists.txt manifest.xml

ROS Package CMakeLists.txt cmake_minimum_required(VERSION 2.4.6) include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) # This is a comment rosbuild_init() rosbuild_gen_msg() rosbuild_add_executable(localplanner src/main.cpp)

ROS Package rosbuild_add_executable(localplanner src/main.cpp) CMakeLists.txt ROS Package You don’t have to worry about most of this junk … But this line is important. ROS doesn’t magically know where your source files are and which ones you want to package into an executable. So you need to say rosbuild_add_executable(executable_name source.cpp) or rosbuild_add_executable(executable_name source1.cpp source2.cpp source3.cpp) cmake_minimum_required(VERSION 2.4.6) include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) # This is a comment rosbuild_init() rosbuild_gen_msg() rosbuild_add_executable(localplanner src/main.cpp)

localplanner ROS Package src include bin CMakeLists.txt manifest.xml

ROS Package Package description goes here localplanner src include bin CMakeLists.txt manifest.xml

ROS Package manifest.xml <package> <description brief=“localplanner”> Local Planner </description> <author>Your Name Here</author> <license>BSD</license> <review status=“unreviewed” notes=“”/> <url>http://ros.org/wiki/localplanner</url> <depend package=“roscpp”/> <depend package=“artsystem”/> <depend package=“nav_msgs”/> <depend package=“ucontroller”/> </package>

manifest.xml ROS Package <package> <description brief=“localplanner”> Local Planner </description> <author>Your Name Here</author> <license>BSD</license> <review status=“unreviewed” notes=“”/> <url>http://ros.org/wiki/localplanner</url> <depend package=“roscpp”/> <depend package=“artsystem”/> <depend package=“nav_msgs”/> <depend package=“ucontroller”/> </package> You need to list your dependencies here! So if you #include something, and ROS is complaining, one of the first things that you should check is whether you need to add another dependency to the manifest.

roscd $ roscd localplanner in general, roscd [package-name] localplanner ROS will find the specified package and will change your working directory to be the top-level package directory src include bin CMakeLists manifest

rosmake ROS will build the specified package $ rosmake localplanner in general, rosmake [package-name] or, when in a package directory, just rosmake ROS will build the specified package

Output of rosmake $ rosmake localplanner [ rosmake ] rosmake starting … [ rosmake ] Packages requested are: [‘localplanner’] [ rosmake ] Logging into directory /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 [ rosmake ] Expanded args [‘localplanner’] to: [‘localplanner’] [ rosmake-0] Starting >>> roslang [ make ] [ rosmake-1] Starting >>> geometry_msgs [ make ] … blah blah blah … [ rosmake-0 ] Finished <<< ucontroller [PASS] [ 1.53 seconds ] [ rosmake-0] Finished <<< localplanner [PASS] [ 1.02 seconds ] [ rosmake ] Results: [ rosmake ] Built 8 packages with 0 failures. [ rosmake ] Summary output to directory [ rosmake ] /home/sandro/.ros/rosmake/rosmake_output-20130921-135115

Output of rosmake $ rosmake localplanner [ rosmake ] rosmake starting … [ rosmake ] Packages requested are: [‘localplanner’] [ rosmake ] Logging into directory /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 [ rosmake ] Expanded args [‘localplanner’] to: [‘localplanner’] [ rosmake-0] Starting >>> roslang [ make ] [ rosmake-1] Starting >>> geometry_msgs [ make ] … blah blah blah … [ rosmake-0 ] Finished <<< ucontroller [PASS] [ 1.53 seconds ] [ rosmake-0] Finished <<< localplanner [PASS] [ 1.02 seconds ] [ rosmake ] Results: [ rosmake ] Built 8 packages with 0 failures. [ rosmake ] Summary output to directory [ rosmake ] /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 You could potentially see a lot of stuff here, because rosmake actually goes and builds all of your package’s dependencies for you.

Output of rosmake $ rosmake localplanner [ rosmake ] rosmake starting … [ rosmake ] Packages requested are: [‘localplanner’] [ rosmake ] Logging into directory /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 [ rosmake ] Expanded args [‘localplanner’] to: [‘localplanner’] [ rosmake-0] Starting >>> roslang [ make ] [ rosmake-1] Starting >>> geometry_msgs [ make ] … blah blah blah … [ rosmake-0 ] Finished <<< ucontroller [PASS] [ 1.53 seconds ] [ rosmake-0] Finished <<< localplanner [PASS] [ 1.02 seconds ] [ rosmake ] Results: [ rosmake ] Built 8 packages with 0 failures. [ rosmake ] Summary output to directory [ rosmake ] /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 [PASS] means that rosmake successfully built a package. [FAIL] means there were errors.

Output of rosmake $ rosmake localplanner [ rosmake ] rosmake starting … [ rosmake ] Packages requested are: [‘localplanner’] [ rosmake ] Logging into directory /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 [ rosmake ] Expanded args [‘localplanner’] to: [‘localplanner’] [ rosmake-0] Starting >>> roslang [ make ] [ rosmake-1] Starting >>> geometry_msgs [ make ] … blah blah blah … [ rosmake-0 ] Finished <<< ucontroller [PASS] [ 1.53 seconds ] [ rosmake-0] Finished <<< localplanner [PASS] [ 1.02 seconds ] [ rosmake ] Results: [ rosmake ] Built 8 packages with 0 failures. [ rosmake ] Summary output to directory [ rosmake ] /home/sandro/.ros/rosmake/rosmake_output-20130921-135115 0 failures is what you’re looking for (obviously). If there were failures, you’ll also see a list of error messages.