Make nodes executable (C++ and Python)

Requirements for this page:

TL;DR

Of course you did already read everything below, and the following TL;DR summary is just for convenience when you return to remind yourself of a small detail:

# EDIT THE C MAKE LIST TO ADD THE C++ FILE
cd ~/my-robotics-system/catkin_ws/src/my_robotics_pkg/
nano CMakeLists.txt

# COMPILE THE C++ NODE
cd ~/my-robotics-system/catkin_ws/
catkin_make

# ADD EXCUTION PERMISSION TO THE PYTHON FILE
cd ~/my-robotics-system/catkin_ws/src/my_robotics_pkg/src
chmod +x plain_py_node.py

The three not-a-comment lines in the following are all that needs to be added to the CMakeLists.txt, these lines provide instructions for how to compile the C++ node:

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/my_robotics_pkg_node.cpp)
add_executable(plain_cpp_node src/plain_cpp_node.cpp)

## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(plain_cpp_node ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )
target_link_libraries(plain_cpp_node ${catkin_LIBRARIES})

Add the C++ node to the C Make List

ROS does not automatically to try to compile new *.cpp files that you add. You need to provide explicit instructions via the CMakeLists.txt file of your ROS package. You provide the compilation instructions by adding the following three lines of code to the appropriate section of the CMakeLists.txt:

  1. Open the CMakeLists.txt file for editing:

cd ~/my-robotics-system/catkin_ws/src/my_robotics_pkg/
nano CMakeLists.txt
  1. Search the CMakeLists.txt for the following comments, which is in the section titled ## BUILD ##:

    ## Declare a C++ executable
    ## With catkin_make all packages are built within a single CMake context
    ## The recommended prefix ensures that target names across packages don't collide
    # add_executable(${PROJECT_NAME}_node src/my_robotics_node.cpp)
    

    And add the following line below this comment:

    add_executable(plain_cpp_node src/plain_cpp_node.cpp)
    

    This makes the node available to run / launch with the name plain_cpp_node. A simple convention to start with is to use the same as the file name. If, and when, you start to have naming collision across pacakges, then you can follow the recommendation of the comment to put ${PROJECT_NAME} as the prefix.

    We will return to this line when we need to add additional C++ class as executables for a node to access.

  2. Find the following a few comments further down:

    ## Add cmake target dependencies of the executable
    ## same as for the library above
    # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    

    And add the following line below this comment:

    add_dependencies(plain_cpp_node ${catkin_EXPORTED_TARGETS})
    

    We will return to this line when we need to add messages types that the node depends on.

  3. Find the following as the next comments:

    ## Specify libraries to link a library or executable target against
    # target_link_libraries(${PROJECT_NAME}_node
    #   ${catkin_LIBRARIES}
    # )
    

    And add the following line below this comment:

    target_link_libraries(plain_cpp_node ${catkin_LIBRARIES})
    

    We will return to this line when we need to add compiler flags for linking libraries to a node, for example, the gpiod library.

Compile the C++ node

Change directory to the catkin workspace and call catkin_make to perform compilation:

cd ~/my-robotics-system/catkin_ws/
catkin_make

The executable files of your C++ nodes are stored in the build and devel folders as make of the catkin_make process.

Important

In order for any changes to your C++ node to take effect, you need to:

  1. Shutdown the node if it is currently running

  2. Ensure your changes are saves

  3. Compile the changes using catkin_make

  4. Observe that catkin_make completed without any errors

  5. Run / launch the node

Note

If, and when, you encounter “strange” compilation or run time errors that have you completely stumped, one thing to try is deleting the build and devel folders and compiling again, i.e.,

cd ~/my-robotics-system/catkin_ws/
rm -rf build/
rm -rf devel/
catkin_make

Make the Python file executable

As Python is an interpreted language, ROS directly executes the Python code you write, hence the files need the neccessary permissions to execute.

At some stage when you are trying to run / launch a Python node, you are likely to get an error message similar to the following:

Couldn't find executable named plain_py_node.py below ...

This error message is likely because the Python script you are trying to run / launch does not have execution rights. If you want to check this is the case, then list the details of the file using:

ls -la ~/my-robotics-system/catkin_ws/src/my_robotics_pkg/src

Which should display the details of the Python file in question as:

-rw-rw-r-- 1 asc asc  205 Jan  1 23:45 plain_py_node.py

Use the following command to add (+) executable (x) permissions to the file:

chmod +x ~/my-robotics-system/catkin_ws/src/my_robotics_pkg/src/plain_py_node.py

The listing of the file should now display the following details:

-rwxrwxr-x 1 asc asc  205 Jan  1 23:45 plain_py_node.py

Important

In order for any changes to your Python node to take effect, you need to:

  1. Shutdown the node if it is currently running

  2. Ensure your changes are saved

  3. Run / launch the node again

References

The steps detailed on this page are mostly taken from:



Creative Commons License
Paul N. Beuchat, 2023