Skip to content

ROS1 templates

Francesco Ganci edited this page Jun 25, 2022 · 22 revisions

⚠️ first draft ⚠️

ROS1 Templates

If you have to quickly set up a node, and you don't want to waste your time in writing "init_node" then "spin" then "main" then ... here are some ready-to-use snippets.

A bit of philosophy

  • a ROS node just implements a architectural element or an interface
  • the functionalities should be implemented in a separated library, and not in the node itself unless the node hasn't a very peculiar role in the project
  • in each package, there should be at least two levels of implemetetion: the one of the nodes (the uppermost part of the package, implementint topics, services and actions), and the one of the libraries ("low level" implementation of the functionalities beneath the interfaces)

ROSCPP node blueprint

☝️ remember to replace ??? with the names you want to use for your implementation.

This pattern also contains some macros to speed up the logging on the console. I think that logging is a very significant part of the work, extremely helpful for the software debugging for instance.

#include "ros/ros.h"
#include <signal.h>

#define NODE_NAME ???
#define N_LOOPS_PER_SEC 1

#define LOGSQUARE( str )  "[" << str << "] "
#define OUTLABEL          LOGSQUARE( NODE_NAME )
#define TLOG( msg )       ROS_INFO_STREAM( OUTLABEL << msg )
#define TWARN( msg )      ROS_WARN_STREAM( OUTLABEL << "WARNING: " << msg )
#define TERR( msg )       ROS_WARN_STREAM( OUTLABEL << "ERROR: " << msg )



void shut_msg( )
{
	TLOG( "stopping... " );
	ros::shutdown( );
}



int main( int argc, char* argv[] )
{
	ros::init( argc, argv, NODE_NAME, ros::init_options::NoSigintHandler );
	ros::NodeHandle nh;
	signal(SIGINT, shut_msg);
	
	TLOG( "starting ... " );
	
	// TODO define here services and topics ...
	
	TLOG( "ready" );
	
	// TODO the functionality of the node ... 

	/*
	ros::spin( )
	*/
	
	/*
	ros::Rate freq( N_LOOPS_PER_SEC );
	while( ros::ok( ) )
	{
		// ... do whatever you want
		
		// spin and wait
		ros::spin_once( );
		freq.sleep( );
	}
	*/
	
	return 0;
}

ROSCPP class-node blueprint

☝️ remember to replace ??? with the names you want to use for your implementation.

#include "ros/ros.h"
#include <signal.h>

#define NODE_NAME ???

#define LOGSQUARE( str )  "[" << str << "] "
#define OUTLABEL          LOGSQUARE( NODE_NAME )
#define TLOG( msg )       ROS_INFO_STREAM( OUTLABEL << msg )
#define TWARN( msg )      ROS_WARN_STREAM( OUTLABEL << "WARNING: " << msg )
#define TERR( msg )       ROS_WARN_STREAM( OUTLABEL << "ERROR: " << msg )


// TODO node name!
class ???
{
public:
	
	// node constructor
	???( /*TODO constructor args*/ )
	{
		// ...
	}
	
	// main functionality of the class
	void spin( int n_loops_per_sec = 1 )
	{
		// TODO main functionality (even a simple spin)
		
		/*
		ros::spin( )
		*/
		
		/*
		ros::Rate freq( n_loops_per_sec );
		while( ros::ok( ) )
		{
			// ... do whatever you want
			
			// spin and wait
			ros::spin_once( );
			freq.sleep( );
		}
		*/
	}
	
	// ...
	
private:
	
	// ROS node handle
    ros::NodeHandle nh;
	
	// ...
}


void shut_msg( )
{
	TLOG( "stopping... " );
	ros::shutdown( );
}


int main( int argc, char* argv[] )
{
	ros::init( argc, argv, NODE_NAME, ros::init_options::NoSigintHandler );
	signal( SIGINT, shut_msg );
	// ros::NodeHandle nh;
	
	TLOG( "starting ... " );
	
	// TODO define here services and topics ...
	
	TLOG( "ready" );
	
	// TODO the functionality of the node ... 
	( ???( ) ).spin( );
	
	return 0;
}

ROSCPP Simple publisher

ROSCPP Simple subscriber

ROSCPP Simple service

ROSCPP Simple client

ROSPY node blueprint

import rospy

NODE_NAME = "NODE_NAME"



def shut_msg( ):
	rospy.loginfo( f" [{NODE_NAME}] stopping ... " )



def main( ):
    ''' main functionality of the node
    
    TODO:
        the main functionality of the node goes here
    '''
    pass



if __name__ == "__main__":
	rospy.init_node( NODE_NAME )
	rospy.on_shutdown( shut_msg )
    
    rospy.loginfo( f" [{NODE_NAME}] starting ... " )
    
    # TODO define here messages and services ...
	
	rospy.loginfo( f" [{NODE_NAME}] ready" )
    
    # TODO here the main functionality ...
    
    main( )

ROSPY class-node blueprint

ROSPY Simple publisher

ROSPY Simple subscriber

ROSPY Simple service

ROSPY Simple client

📋 Useful Links

Clone this wiki locally