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
45
Embed
What is ROS? R obot O perating S ystem ROS essentially provides two things: – A set of tools that are generally useful for controlling robots E.g. Interfaces.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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 publisher
cam_data subscriber
cam_data subscriber
ROS$ roscore
... 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
rosout
$ rosrun package1 first-nodeNote: run this in a
new terminal window
ROS
first-node
Master
Advertise topic1
rosout
$ rosrun package2 second-nodeNote: run this in a
new terminal window
ROS
first-node
Master
rosout second-node
Subscribe to topic1
ROS$ rosrun package2 second-node
Note: run this in a new terminal
window
first-node
Master
rosout second-node
Master connects topic1 publisher to topic1 subscriber
ROS$ rosnode list
/rosout/first-node/second-node
first-node
Master
rosout second-node
topic1
ROS
first-node
Master
rosout second-node
$ rostopic list
/rosout/rosout_agg/topic1
topic1
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
#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 */
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;}
Line-by-Line Breakdown
• Include the ROS library
/* Body of event loop goes here */
#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;}
Line-by-Line Breakdown
• 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 */
#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;}
Line-by-Line Breakdown
• 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 */
#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;}
Line-by-Line Breakdown• 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 */
#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;}
Line-by-Line Breakdown
/* Body of event loop goes here */
• 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
#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;}
Line-by-Line Breakdown
• 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 */
#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;}
Line-by-Line Breakdown• 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
#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;}
ROS Subscriber• 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”
• 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_msgsMessage Type Include Callback signature Usagestd_msgs::String #include
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!
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
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 localplanner in general, roscd [package-name]
src
localplanner
include bin
CMakeLists manifest
ROS will find the specified package and will change your working directory to be the top-level package directory
roscd
$ rosmake localplanner in general, rosmake [package-name]or, when in a package directory, just rosmake