ROS provides a really nice
set of tools for working with packages and stacks. But I am sure the
community has come up with some additional cool tools. Here are some bash
functions that I find helpful.
#
cd toggle between _msgs and non _msgs packages
function
roscdmsg
{
PACKAGE=${PWD##*/}
LEN=${#PACKAGE}
if (( "$LEN" < 5 ))
then
roscd $PACKAGE"_msgs"
return
fi
END=${PACKAGE:$(( $LEN - 5 ))}
if [ $END = "_msgs" ]
then
roscd ${PACKAGE:0:$(( $LEN - 5 ))}
else
roscd $PACKAGE"_msgs"
fi
}
#
Helper function to test if a list contains a given string.
#
Usage: isinlist <string> <list>
function
isinlist
{
for ITEM in $2
do
if [ "$1" = "$ITEM" ]
then
return 1
fi
done
return 0
}
#
CD up to the root package dir
function
roscdpkg
{
# store original pwd
ORIG_DIR=$PWD
# get all package names
ALL_PACKAGES=`rospack list-names`
# get the name of the current dir
DIR=${PWD##*/}
# test if we are in a dir that is also a ros package
isinlist "$DIR" "$ALL_PACKAGES"
# while 'isinlist' returns 0
while [ "$?" = "0" ]
do
# go up a dir
builtin cd ..
# get the new dir name
DIR=${PWD##*/}
# if the dir name is empty (i.e. we have gone all the way to '/')
if [ -z $DIR ]
then
builtin cd $ORIG_DIR
echo "Not under a ros package"
return -1
fi
isinlist "$DIR" "$ALL_PACKAGES"
done
}
#
CD up to the root stack dir
function
roscdstack
{
# store original pwd
ORIG_DIR=$PWD
# get all package names
ALL_PACKAGES=`rosstack list-names`
# get the name of the current dir
DIR=${PWD##*/}
# test if we are in a dir that is also a ros stack
isinlist "$DIR" "$ALL_PACKAGES"
# while 'isinlist' returns 0
while [ "$?" = "0" ]
do
# go up a dir
builtin cd ..
# get the new dir name
DIR=${PWD##*/}
# if the dir name is empty (i.e. we have gone all the way to '/')
if [ -z $DIR ]
then
builtin cd $ORIG_DIR
echo "Not under a ros stack"
return -1
fi
isinlist "$DIR" "$ALL_PACKAGES"
done
}
#
This function will print on the screen a list of #include
#
lines that you can paste at the top of your C++ file.
#
The files are found using your .manifest file.
function
rosgenincludes
{
DEPS_LIST=`rospack depends1 $1`
for PACKAGE in $DEPS_LIST
do
echo "// $PACKAGE:"
PATH_TO_DEP=`rospack find $PACKAGE`
PATH_ARRAY[0]=$PATH_TO_DEP/include
# CTurtle paths
PATH_ARRAY[1]=$PATH_TO_DEP/msg_gen/cpp/include/$PACKAGE
PATH_ARRAY[2]=$PATH_TO_DEP/srv_gen/cpp/include/$PACKAGE
# BoxTurtle paths
#PATH_ARRAY[1]=$PATH_TO_DEP/msg/cpp/$PACKAGE
#PATH_ARRAY[2]=$PATH_TO_DEP/srv/cpp/$PACKAGE
NOTES_ARRAY[0]=""
NOTES_ARRAY[1]="$PACKAGE messages:"
NOTES_ARRAY[2]="$PACKAGE services:"
NUM_PATHS=3
for (( i = 0 ; i < $NUM_PATHS ; i++ ))
do
# if path does not exist
if [[ ! -d "${PATH_ARRAY[$i]}" ]]
then
#echo "path does not exist"
continue
fi
INCLUDE_FILES=`ls -1 ${PATH_ARRAY[$i]}`
# if there are any files found
if [ "${#INCLUDE_FILES}" -gt 0 ]
then
# only display note if it is non-zero
if [ "${#NOTES_ARRAY[$i]}" -gt 0 ]
then
echo "// ${NOTES_ARRAY[$i]}"
fi
# print each include
for FILE in $INCLUDE_FILES
do
echo "#include <$PACKAGE/$FILE>"
done
fi
done #end for each search path
done #end for each package in dependencies
}
And here is some example
usage:
baxelrod@mycomp:~$
roscd actionlib
baxelrod@mycomp:/opt/ros/cturtle/stacks/common/actionlib$
roscdmsg
baxelrod@mycomp:/opt/ros/cturtle/stacks/common_msgs/actionlib_msgs$
roscdmsg
baxelrod@mycomp:/opt/ros/cturtle/stacks/common/actionlib$
rosgenincludes
//
roscpp:
#include
<roscpp/ros>
//
roscpp messages:
#include
<roscpp/Logger.h>
//
roscpp services:
#include
<roscpp/Empty.h>
#include
<roscpp/GetLoggers.h>
#include
<roscpp/SetLoggerLevel.h>
//
rospy:
//
rostest:
#include
<rostest/rostest>
//
actionlib_msgs:
//
actionlib_msgs messages:
#include
<actionlib_msgs/GoalID.h>
#include
<actionlib_msgs/GoalStatusArray.h>
#include
<actionlib_msgs/GoalStatus.h>
baxelrod@mycomp:/opt/ros/cturtle/stacks/common/actionlib$
cd msg
baxelrod@mycomp:/opt/ros/cturtle/stacks/common/actionlib/msg$
roscdpkg
baxelrod@mycomp:/opt/ros/cturtle/stacks/common/actionlib$
roscdstack
baxelrod@mycomp:/opt/ros/cturtle/stacks/common$
Anybody else have something
neat?
-Ben
Ben Axelrod
Research Scientist
iRobot Corporation
8 Crosby Drive, Mail Stop 8-1
Bedford, MA 01730
(781) 430-3315 (Tel)
(781) 960-2628 (Fax)
baxelrod@irobot.com