Getting feet wet with ROS (A Beginner’s Tutorial)


Hi there,

This tutorial is about using ROS. ROS stands for Robotics Operating System, which is pretty much self-explanatory. ROS is widely used to provide a platform for robots to function. And the ROS official website itself provide a gold-mine of tutorials and information. So I would not give a shot at attempting re-inventing the wheel. But, I reckon it is imperative to give away the tip of the ice-berg before delving into advance stuff.

Basics and Setting up…

Basic knowledge of ROS is essential before any sort of further advancement. If one wants to use ROS, they should know the following components of ROS.

  • Nodes: A node is an executable that uses ROS to communicate (via publish and subscribe) with other nodes.
  • Messages: ROS data content subscribed to or publishing to, by a topic.
  • Topics: Nodes can publish messages to a topic as well as subscribe to a topic to receive messages.

Now let’s setup our workspace. Here we go…

  1. First needs to creat a catkin workspace.(Tutorial: Create a catkin workspace)
  2. After successfully creating, you should have 3 important folders in your workspace; /src,/build and /devel. /src is the folder you would place your ROS packages in. Usually you don’t “under the hood” inside /build and /devel. /build contains temporary build files created. /devel space will contain libraries, executables and compiled codes generated after catkin_make.
  3. Now the next step is to create a ROS package in catkin ws/src, this will contain the launch files, codes, etc. So the stuff you actually write goes in here. (Tutorial: create a ROS package)

Toil the Soil… (Implementing something cool)

Now let’s try doing something for real. Let’s create a ROS package withe a Publisher that writes “Hello from Publisher” to a ROS topic \ros_hello every 2 seconds and a subscriber, that captures the message modify it to “Hello from Publisher. Goodbye from Subscriber” and print it to a console. I assume you already have the catkin workspace ready at this point. So let’s get cracking!

  1. cd into the directory catkin_ws/src. Remember this is where all the ROS magic happens.
  2. Create a new ROS package by running catkin_create_pkg ros_hello std_msgs rospy. ros_hello is the name of the package and std_msgs and rospy are dependencies. std_msgs have import standard ROS messages such as Strings where rospy allows us to use ROS in python scripts.
  3. Now let’s cd into the catkin_ws/src/ros_hello. If the package creation was successful, you should see this the following in the package.xml found inside the folder (I removed all the commented stuff). This says that our ros package now depends on rospy and std_msgs just as we wanted. Side note, so if you miss any dependencies during catkin_create_pkg, you can add those packages to package.xml manually.

    <?xml version="1.0"?>
    <package>
      <name>ros_hello</name>
      <version>0.0.0</version>
      <description>The ros_hello package</description>
      <maintainer email="user@todo.todo">user</maintainer>
    
      <buildtool_depend>catkin</buildtool_depend>
      <build_depend>rospy</build_depend>
      <build_depend>std_msgs</build_depend>
      <run_depend>rospy</run_depend>
      <run_depend>std_msgs</run_depend>
    
      </export>
    </package>
    
  4. Let’s build our package. To do that, run catkin_make inside the catkin_ws/ directory. Note: If you have multiple packages in the catkin workspace and you want to build only one of that, run the following catkin_make -DCATKIN_WHITELIST_PACKAGES="ros_hello"
  5. Cool, now we got the package skeleton done. Time to write actual code. Now create a ros_hello_publisher.py in the catkin_ws/src/ros_hello/src directory.
  6. Now, whip out your favorite Python IDE and write this in there. I won’t explain this line by line. But if you want an explanation, this Tutorial does that for you.
    #!/usr/bin/env python
    __author__ = 'user'
    
    import rospy
    from std_msgs.msg import String
    
    if __name__=='__main__':
    
        rospy.init_node("ros_hello_node")
        hello_publisher = rospy.Publisher("/ros_hello",String, queue_size=10)
    
        while not rospy.is_shutdown():
            hello_publisher.publish("Hello from Publisher. ")
            rospy.sleep(2)
    
  7. Then another file called the ros_hello_subscriber.py in the same location and put this code in there. Basically listens to a topic called /ros_hello.
    #!/usr/bin/env python
    __author__ = 'user'
    import rospy
    from std_msgs.msg import String
    
    def callback_ros_hello(msg):
    
        msg_str = str(msg.data) + " Goodbye from Subscriber."
        print msg_str
    
    if __name__=='__main__':
    
        rospy.init_node("ros_hello_sub_node")
        hello_subscriber = rospy.Subscriber("/ros_hello",String, callback_ros_hello)
    
        rospy.spin()
    
  8. Now you’ve got too options to run things.
    • Shoot up two terminals and run ros_hello_publisher.py and ros_hello_subscriber.py in each.
    • Or write a launch file to launch both nodes simultaneously from a single script.

Writing a launch file to launch the two ROS nodes

So you decided you need to learn more. Good choice. Now what you need to do is create the a ros_hello_launch.launch file. Let’s do stuff from the terminal so you could learn a few ROS commands.

  1. Try roscd ros_hello on the terminal. This should bring you to the root directory of the ros_hello package.
  2. Now go ahead and do, mkdir launch.
  3. Then do a cd launch/.
  4. Now fire up your favorite text editor to create a launch file called ros_hello_launch.launch in the launch directory.
    Then add the following code in there.

    <launch>
        <node name="ros_hello_publisher" pkg="ros_hello" type="ros_hello_publisher.py" output="screen" />
        <node name="ros_hello_subscriber" pkg="ros_hello" type="ros_hello_subscriber.py" output="screen" />
    </launch>
    

For more information about ROS launch files: ROSLaunch Wiki Page

3…2…1…Launch…

Now it’s time to test run things. You must be pretty pumped up at this moment. Aaaah! I remember the first time I tried this. Sweaty palms, shaky fingers. Funny story… did not go so well! But hopefully you’ll have better luck

With Launch file
  1. Open up a terminal and run roscore
  2. Open up another terminal and run roslaunch ros_hello ros_hello_launch.launch
  3. In the same console you should be able to see what you wanted being printed
  4. Your should see the following as the output.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://pc-3w47-1:48273/

SUMMARY
========

PARAMETERS
 * /rosdistro: indigo
 * /rosversion: 1.11.13

NODES
  /
    ros_hello_publisher (ros_hello/ros_hello_publisher.py)
    ros_hello_subscriber (ros_hello/ros_hello_subscriber.py)

ROS_MASTER_URI=http://localhost:11311

core service [/rosout] found
process[ros_hello_publisher-1]: started with pid [11245]
process[ros_hello_subscriber-2]: started with pid [11248]
Hello from Publisher.  Goodbye from Subscriber.
Hello from Publisher.  Goodbye from Subscriber.
Hello from Publisher.  Goodbye from Subscriber.

Note: If you get an error such as, ERROR: cannot launch node of type [ros_hello/src/ros_hello_publisher]: can’t locate node [src/ros_hello_publisher] in package [ros_hello] try the following.
Run roscd ros_hello/src and sudo chmod +x ros_hello_publisher.py and sudo chmod +x ros_hello_subscriber.py

Without the Launch file
  1. Open up a terminal and run roscore
  2. Open up another terminal run roscd ros_hello/src and run python ros_hello_publisher.py
  3. Open up another terminal run roscd ros_hello/src and run python ros_hello_subscriber.py
  4. You should see the following being printed in the ros_hello_subscriber terminal
    user@pc:~/catkin_ws/src/ros_hello/src$ python ros_hello_subscriber.py 
    Hello from Publisher.  Goodbye from Subscriber.
    Hello from Publisher.  Goodbye from Subscriber.
    Hello from Publisher.  Goodbye from Subscriber.
    
Tags: ,