Search code examples
c++rosallegro5catkin

ROS/catkin compiled C++ file won't find image sources


I created a C++ game that uses images from a folder in the same parent directory.

/game_folder
----/Images
--------icon1.png
--------icon2.png
----game.cpp

Program uses Allegro 5 library to include images:

ALLEGRO_BITMAP* icon1 = al_load_bitmap("Images/icon1.png");
ALLEGRO_BITMAP* icon2 = al_load_bitmap("Images/icon2.png");

And this works great.

However now I need to place this program into ROS/catkin package 'beginner_tutorials'. If I place both Images folder and game.cpp into ../catkin_ws/src/beginner_tutorials it compiles fine using catkin make, but I get Segmentation Fault during runtime.

/catkin_ws/src/beginner_tutorials
----/Images
--------icon1.png
--------icon2.png
----game.cpp

I used gdb and guess the error is caused by the program not finding the Images folder.

I also tried to place the Images folder to ../catkin_ws/devel/include/beginner_tutorials (the same place where header files are included)

/catkin_ws
----/devel/include/beginner_tutorials
--------/Images
------------icon1.png
------------icon2.png
----/src/beginner_tutorials
--------game.cpp

and changed code accordingly:

ALLEGRO_BITMAP* icon1 = al_load_bitmap("beginner_tutorials/Images/icon1.png");
ALLEGRO_BITMAP* icon2 = al_load_bitmap("beginner_tutorials/Images/icon2.png");

But this didn't work. Where am I supposed to place the Image folder for it to be successfully included in the code? Do I also need to make adjustments in the CMakeLists.txt?

-EDIT
Tried something with CMakeLists.txt with no success:

set(game_SOURCES
  src/game.cpp
  src/Images/
)

add_executable(game ${game_SOURCES})
target_link_libraries(game ${allegro_LIBS})

Solution

  • The reason why this does not work is that your code gets compiled and is then placed inside the catkin_ws/devel/lib/<package_name> folder (lib not include!). Then when you launch the code it will look only in paths relative to the executable. This means you would actually have to place it inside the catkin_ws/devel/lib/<package_name> folder. The problem with that is though that as soon as you clean the workspace all of these directories will be deleted and you would have to re-copy all the files to it after each catkin clean.

    For this purpose the ROS C++ API has though functions that allow you to browse the folder of a given package inside the catkin_ws/src folder or display all available packages when including the header file ros/package.h:

    #include <ros/package.h>
    
    // ...
    
    std::string const package_path = ros::package::getPath("beginner_tutorials");
    ALLEGRO_BITMAP* icon1 = al_load_bitmap(package_path + "/Images/icon1.png");
    ALLEGRO_BITMAP* icon2 = al_load_bitmap(package_path + "/Images/icon2.png");
    

    should do the trick. This will make the code look in catkin_ws/src/beginner_tutorials path.

    Similarly in Python the syntax would be:

    import os
    import rospkg
    
    # ...
    
    rospack = rospkg.RosPack()
    package_path = rospack.get_path('beginner_tutorials')
    icon1_path = os.path.join(package_path, "Images", "icon1.png")
    icon2_path = os.path.join(package_path, "Images", "icon2.png")