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})
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")