Creating Packages and Nodes

In this exercise, we will create our own ROS package and node.

Motivation

The basis of ROS communication is that multiple executables called nodes are running in an environment and communicating with each other in various ways. These nodes exist within a structure called a package. In this module we will create a node inside a newly created package.

Reference Example

Create a Package

Further Information and Resources

Building Packages

Understanding Nodes

Scan-N-Plan Application: Problem Statement

We’ve installed ROS, created a workspace, and even built a few times. Now we want to create our own package and our own node to do what we want to do.

Your goal is to create your first ROS node:

  1. First you need to create a package inside your catkin workspace.
  2. Then you can write your own node

Scan-N-Plan Application: Guidance

Create a Package

  1. cd into the catkin workspace src directory Note: Remember that all packages should be created inside a workspace src directory.

    cd ~/catkin_ws/src
    
  2. Use the ROS command to create a package called myworkcell_core with a dependency on roscpp

    catkin create pkg myworkcell_core --catkin-deps roscpp
    

    See the catkin_tools documentation for more details on this command.

    • This command creates a directory and required files for a new ROS package.
    • The first argument is the name of the new ROS package.
    • Use --catkin-deps to specify packages which the newly created package depends on.
  3. There will now be a folder named myworkcell_core. Change into that folder and edit the package.xml file. Edit the file and change the description, author, etc., as desired.

    cd myworkcell_core
    gedit package.xml
    

    If you forget to add a dependency when creating a package, you can add additional dependencies in the package.xml file.

STOP! We’ll go through a few more lecture slides before continuing this exercise.

Create a Node

  1. In the package folder, edit the CMakeLists.txt file using gedit. Browse through the example rules, and add an executable(add_executable), node named vision_node, source file named vision_node.cpp. Also within the CMakeLists.txt, make sure your new vision_node gets linked (‘target_link_libraries’) to the catkin libraries.

    add_compile_options(-std=c++11)
    add_executable(vision_node src/vision_node.cpp)
    target_link_libraries(vision_node ${catkin_LIBRARIES})
    

    These lines can be placed anywhere in CMakeLists.txt, but I typically:

    • Uncomment existing template examples for add_compile_options near the top (just below project())
    • Uncomment and edit existing template examples for add_executable and target_link_libraries near the bottom
    • This helps make sure these rules are defined in the correct order, and makes it easy to remember the proper syntax.

    Note: You’re also allowed to spread most of the CMakeLists rules across multiple lines, as shown in the target_link_libraries template code

  2. In the package folder, create the file src/vision_node.cpp (using gedit).

  3. Add the ros header (include ros.h).

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
  4. Add a main function (typical in c++ programs).

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
    
    }
    
  5. Initialize your ROS node (within the main).

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    }
    
  6. Create a ROS node handle.

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    
      // Create a ROS node handle
      ros::NodeHandle nh;
    }
    
  7. Print a “Hello World” message using ROS print tools.

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    
      // Create a ROS node handle
      ros::NodeHandle nh;
    
      ROS_INFO("Hello, World!");
    }
    
  8. Do not exit the program automatically - keep the node alive.

    /**
    **  Simple ROS Node
    **/
    #include <ros/ros.h>
    
    int main(int argc, char* argv[])
    {
      // This must be called before anything else ROS-related
      ros::init(argc, argv, "vision_node");
    
      // Create a ROS node handle
      ros::NodeHandle nh;
    
      ROS_INFO("Hello, World!");
    
      // Don't exit the program.
      ros::spin();
    }
    

    ROS_INFO is one of the many logging methods.

    • It will print the message to the terminal output, and send it to the /rosout topic for other nodes to monitor.
    • There are 5 levels of logging: DEBUG, INFO, WARNING, ERROR, & FATAL.
    • To use a different logging level, replace INFO in ROS_INFO or ROS_INFO_STREAM with the appropriate level.
    • Use ROS_INFO for printf-style logging, and ROS_INFO_STREAM for cout-style logging.
  9. Build your program (node), by running catkin build in a terminal window

    • Remember that you must run catkin build from within your catkin_ws (or any subdirectory)
    • This will build all of the programs, libraries, etc. in myworkcell_core
    • In this case, it’s just a single ROS node vision_node

Run a Node

  1. Open a terminal and start the ROS master.

    roscore
    

    The ROS Master must be running before any ROS nodes can function.

  2. Open a second terminal to run your node.

    • In a previous exercise, we added a line to our .bashrc to automatically source devel/setup.bash in new terminal windows

    • This will automatically export the results of the build into your new terminal session.

    • If you’re reusing an existing terminal, you’ll need to manually source the setup files (since we added a new node):

      source ~/catkin_ws/devel/setup.bash
      
  3. Run your node.

    rosrun myworkcell_core vision_node
    

    This runs the program we just created. Remember to use TAB to help speed-up typing and reduce errors.

  4. In a third terminal, check what nodes are running.

    rosnode list
    

    In addition to the /rosout node, you should now see a new /vision_node listed.

  5. Enter rosnode kill /vision_node. This will stop the node.

    Note: It is more common to use Ctrl+C to stop a running node in the current terminal window.

Challenge

Goal: Modify the node so that it prints your name. This will require you to run through the build process again.