CMRoboBits Wiki

Writing a Python ROS Node

In order to write a python node, you must make a folder in the cobot_python directory. This is because of manifest files that are shared by c++ code but not by python code. You can copy the manifest.xml file from cobot_dialog and change the description to your own name.

For the python file, you have some set up to do first. The code snippet is below

# setup ROS stuff                                                                                                                            
NODE_NAME = 'cobot_dialog'
import roslib; roslib.load_manifest(NODE_NAME)
from std_msgs.msg import *
import rospy
import sys
import time

from cobot_msgs.srv import *
from cobot_msgs.msg import *
from sensor_msgs.msg import *

class Cobot2Dialog():

        def __init__(self):
                rospy.init_node(NODE_NAME, disable_signals = True)
                rospy.Subscriber('Cobot/Status', CobotStatusMsg, \
                        self.__update_status, queue_size=1)
                rospy.Subscriber('Cobot/TalkerStatus', CobotTalkerMsg, \
                        self.__update_talker_status, queue_size=1)
                self.__publish = rospy.Publisher('Cobot/TaskPlannerStatus',CobotTaskPlannerMsg)
  • Define a NODE_NAME for your program and add the lines below it.
  • Make a class of functions for your code, including an __init__

function that subscribes and publishes to different messages and creates services (functions that other Nodes can call). Our example does each - see the Topics and Services page to understand how to use them.

  • To look up the messages that you should subscribe or publish to, go to the cobot_msgs/msg/ folder and search through the defined messages. To make services, use cobot_msgs/srv
  • Finally, to run your python node, make sure you have a main method. If you are receiving messages, make sure it runs forever.
    if __name__ == "__main__":
        while True:

Writing a C++ ROS Node

Source Code

New C++ modules should be created in a new folder under cobot_linux/src folder: mkdir myNewModule You first need a main function where the new node is defined. In this main function you can specify the topics that your new node publishes and those that it subscribes.
You can find a template with all the necessary includes and initializations at cobot_linux/src/cobot/cobot_node_template.cpp. You just need to copy it into your folder (probably changing the name) cp cobot_linux/src/cobot/cobot_node_template.cpp cobot_linux/src/myNewModule/myModuleMain.cpp and edit it according to your needs. For example, to add a subscription:

  void myTopicCallBackFunction([msg type] myMessage){
      //does whatever you want to do when you receive the topic
  int main(int argc, char **argv) {
     ros::NodeHandle n;
     ros::Subscriber sub = n.subscribe("myTopic", 1, myTopicCallBackFunction);


To compile your code you need 2 things: first to update the cobot_linux/manifest.xml to include your dependencies. Then to add your new node as a target at the CMakeLists.txt.
So, if your node depends on another package from cobot or from ros (e.g. the opencv package), you just need to the line in the cobot_linux/manifest.xml

  <depend package=opencv/>

Then you edit the CMakeLists.txt in 2 places (assuming that there is no dependency in external libraries). First add the path for the header files in your node. You will find a list of such entries more or less around line 85


You add one of such lines for each directory you would add in front of a -I in a normal gcc command

Second add your node as a target. You will find similar declarations more or less at line 332

set (target yourModule)
rosbuild_add_executable(${target} src/myNewModule/myModuleMain.cpp src/myNewModule/OtherCppFile1.cpp src/myNewModule/OtherCppFile2.cpp)
add_dependencies(${target} shared_libraries)
target_link_libraries(${target} shared_libraries)

where the add_dependencies line adds all the packages and libraries that should be compiled before your node and in the target_link_libraries you should add everything that you would put in front of a -L in a normal gcc command.

If you have extra libraries you should add their header files using the include_directories and linking them using target_link_libraries.

Topics and Services in Python

  • The rospy.Subscriber

function takes a message name and type (from the msg folder), a function to call when the message is received, and the number of these messages to keep in a queue if your code is slower than the message rate. (see the msg folder)

  • The rospy.Publisher

function takes a message name and type. Later, you can publish messages by instantiating a new message of the correct type and including all the arguments self.__publish.publish(CobotTaskPlannerMsg(self.__currentTask,self.__stack[0],"",self.__currentFrom, self.__current

To, self.__currentObj, False, False, False))
  • The rospy.Service

function takes a name, service type (from the srv folder), and a function to call when the service is called. To use someone else's service, you must create a ServiceProxy, which returns a function pointer and then call that function with the necessary arguments (defined in the srv file) speaker_call = rospy.ServiceProxy('/Cobot/Talker',

        result = speaker_call(str(words))

Topics and Services in C++

Refer to the ROS C++ Tutorials:

Running Nodes

You will need to start the nodes that your program depends on and then your own program.

  • If those nodes are found in the cobot_linux directory:

In the cobot_linux directory, run ./bin/nameOfTheNode for each of the nodes that you need.

For example, ./bin/cobot_manager to get the status of the robot and ./bin/cobot_talker to get the last thing cobot said.

  • If those nodes are found in the cobot_python directory:

In your directory, run python