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