-
Notifications
You must be signed in to change notification settings - Fork 0
ROS1 templates
Francesco Ganci edited this page Jul 13, 2022
·
22 revisions
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 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)
☝️ 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
#ifndef __DEBUG_MACROS__
#define __DEBUG_MACROS__
#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 )
#endif
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;
}☝️ remember to replace ??? with the names you want to use for your implementation.
#define NODE_NAME ???
#ifndef __DEBUG_MACROS__
#define __DEBUG_MACROS__
#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 )
#endif
#include "ros/ros.h"
#include <string>
#include <map>
#include <signal.h>
// 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( int sig )
{
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;
}void shut_msg( int sig )
{
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::AsyncSpinner spinner( 4 );
spinner.start( );
ros::NodeHandle nh;
TLOG( "starting ... " );
// TODO define here services and topics ...
TLOG( "ready" );
// TODO the functionality of the node ...
( ???( ) ).spin( ); // call ros::waitForShutdown( ) ?
return 0;
}import rospy
NODE_NAME = ???str_node_name???
DEV_MODE = False
LOGSQUARE = lambda mstr : f"[{mstr}] "
OUTLABEL = LOGSQUARE( NODE_NAME )
TLOG = lambda m : rospy.loginfo( OUTLABEL + str( m ) )
TWARN = lambda m : rospy.logwarn( OUTLABEL + "WARNING: " + str( m ) )
TERR = lambda m : rospy.logerr( OUTLABEL + "ERROR" + str( m ) )
TDEV = lambda m : rospy.logdebug( OUTLABEL + "ERROR" + str( m ) ) if DEV_MODE
class classname_???NODE_NAME???:
def __init__( self ):
'''Node Constrctor
TODO:
implement me!
'''
pass
def spin( self ):
'''The main functionality of the node
TODO:
implement me!
'''
'''
r = rospy.Rate( 5 )
while not rospy.is_shutdown():
pass
'''
pass
pass # ...
def shut_msg( ):
TLOG( "stopping ... " )
if __name__ == "__main__":
rospy.init_node( NODE_NAME )
rospy.on_shutdown( shut_msg )
TLOG( "starting ... " )
# TODO define here messages and services ...
TLOG( "ready" )
# TODO here the main functionality ...
( classnode_???( ) ).spin( )import rospy
NODE_NAME = ???str???
DEV_MODE = false
LOGSQUARE = lambda mstr : f"[{mstr}] "
OUTLABEL = LOGSQUARE( NODE_NAME )
TLOG = lambda m : rospy.loginfo( OUTLABEL + str( m ) )
TWARN = lambda m : rospy.logwarn( OUTLABEL + "WARNING: " + str( m ) )
TERR = lambda m : rospy.logerr( OUTLABEL + "ERROR" + str( m ) )
TDEV = lambda m : rospy.logdebug( OUTLABEL + "ERROR" + str( m ) ) if DEV_MODE- Further info about Init and Shutdown C++ nodes