Robot Operating System (ROS)

The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. It’s a Middleware.

ROS facilitates the communication between between applications, so you don’t need to implement your own ZeroMQ.

I fully use ROS2 now, NOT ROS1.


These 3 are really fundamental:

If you want to really get good at ROS2, understand the design philosophies: See ROS Design.

can you run ROS on Mac?

For a very long time, I was super afraid because it was super annoying, but then I found this: I use

NASA is a user of ROS. That is insanely cool.

You should be able to look at this diagram and understand exactly what is going on. This is because you’ve met Brian who worked at Open Robotics before and seeing his breadth of knowledge on ROS is very inspirational.

Master the concepts


Why do people hate ROS?

People hate the performance overhead of ROS. But is there really a better solution.


ROS2 Networking

ROS2 comes with networking communication out of the box, meaning if both instances are on the same network, ROS2 nodes came send messages wirelessly to each other. To test that networking works:

On 1st computer, run

ros2 run demo_nodes_cpp talker

On 2nd computer, run

ros2 run demo_nodes_py listener

If it doesn't work

You might need to install the demo_nodes package, run sudo apt-get install ros-<insert-distro>-demo-nodes-cpp

Passing arguments

For a launch file

Use params_file:=, ex:

ros2 launch slam_toolbox slam_params_file:=/f1tenth_ws/src/f1tenth_system/f1tenth_stack/config/f1tenth_online_async.yaml

For a ros2 node

Use the --ros-args, and then -p for every new flag, credits this Articulated Robotics for the info. For every new argument, you need the -p flag.

ros2 run nav2_mamcl amcl --ros-args -p use_sim_time:=true

Create a new ROS2 Node

You could use the command ros2 pkg create --build-type ament_python --node-name <node_name> <package_name>, but we don’t like this because there are annoying ignores that you need to remove. Also, doesn’t include like launch file options, which is super annoying.

So usually, you can just copy paste a node that you already have. Then, you need to change (both NODE and PACKAGE name):

  • CMakeLists.txt package

My points of references:

  • Create3_lidar
  • F1TENTH code

Building Packages

Use --packages-up-to instead of --packages-select to install all the dependencies that are defined in package.xml

colcon build --packages-up-to PACKAGE_NAME

Also always use --symlink-install so you don’t have to rebuild every time, so

colcon build --symlink-install --packages-up-to PACKAGE_NAME

ROS2 Package with both Python and CPP nodes

I was getting stuck on launching nodes, since the files have both Python and CPP, see these tutorials which are super helpful:

ahh i finally understand ros2 parameters now, in code

this->get_parameter_or<std::string>("odom_topic", odom_topic, "/pf/pose/odom");

The above doesn’t set the parameter, so if you do ros2 param get <node_name> odom_topic, it will tell you that the parameter has not been set. However, the odom topic has still been set.

Basic Concepts

  • Node: A program that uses ROS2
  • Message: A message containing data being sent by one node to another
    • each message has a type, which determines what kind of data it contains
  • Topic: Topics act as a bus for nodes to exchange messages. Messages are sent to topics, and nodes can listen to the topics they are interested in to receive messages sent to that topic.
    • nodes communicate over topics
      • Nodes can publish or subscribe to a topic
      • Typically, 1 publisher and n-subscribers
    • Topic is a name for a stream of messages
  • Publisher: Nodes can publish messages to a topic
  • Subscriber: Nodes receive a message from a topic by subscribing to it
  • Service: Services are another method of communication for nodes in the ROS graph. Services are based on a call-and-response model, versus topics’ publisher-subscriber model. While topics allow nodes to subscribe to data streams and get continual updates, services only provide data when they are specifically called by a client
  • Package: A package can be considered a container for your ROS 2 code. If you want to be able to install your code or share it with others, then you’ll need it organized in a package. With packages, you can release your ROS 2 work and allow others to build and use it easily. A Package contains one or more nodes

Topics vs. Messages?

Topics are channels, messages are data types. Different topics can use the same message type.

  • Note that the above diagram is slightly outdated since a ROS master only exists in ROS1

Going from ROS1 \rightarrow ROS2

  • Before, you did like rostopic list, now, you do ros2 topic list
  • Launch files use python scripts, not .xml
  • You don’t need to start roscore now

ROS2 Commands

Workspace Commands

source /opt/ros/foxy/setup.bash # VERY IMPORTANT: Add this to your .bashrc everytime you start
mkdir -p ~/ros2_ws/src # Only run 1st time, create the directory
cd ~/ros2_ws
rosdep install -i --from-path src --rosdistro foxy -y  # Resolve Dependencies
colcon build
. install/setup.bash

If you do colcon build --symlink-install, then that creates symlinks so you don’t need to rebuild everytime you update the URDF, except when you add a new file.

Basic Commands

# ros2 run package_name node_name
ros2 run turtlesim turtlesim_node
ros2 node list
ros2 node info /turtlesim # Learn more about a particular node
ros2 topic list # List of topics
ros2 topic info /turtle1/pose 
ros2 topic type /turtle1/pose 
ros2 msg show turtlesim/Pose # * I am NOT sure about this
ros2 topic echo /turtle1/pose # show the messages of a particular topic

Node Commands

ros2 run <package_name> <executable_name>
ros2 launch <package_name> <launch_name>
ros2 node list
ros2 node info <node_name>

Topic Commands

ros2 topic list
ros2 topic list -t # list the type of messsages published by topic
ros2 topic echo <topic_name>
ros2 topic info <topic_name>
ros2 interface show <msg_type>
ros2 topic pub <topic_name> <msg_type><args>
ros2 topic hz <topic_name>

Service commands

ros2 service list
ros2 service type <service_name>
ros2 service list -t
ros2 service find <type_name>
ros2 interface show <type_name>.srv
ros2 service call <service_name> <service_type> <arguments>


ros2 param list
ros2 param get <node_name> <parameter_name>
ros2 param set <node_name> <parameter_name> <value>
ros2 pkg create --build-type ament_python --node-name camera_object_detection camera_object_detection # Python Package

The package.xml file is very important. It contains all the information about the dependencies of the package:

  • For dependencies only used in testing the code (e.g. gtest), use test_depend.
  • For dependencies only used in building the code, use build_depend.
  • For dependencies needed by headers the code exports, use build_export_depend.
  • For dependencies only used when running the code, use exec_depend.
  • For mixed purposes, use depend, which covers build, export, and execution

See ROS Examples for examples of nodes.