ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Best practice to handle data files

asked 2018-05-14 09:45:34 -0500

vbs gravatar image

updated 2018-05-14 10:10:13 -0500

Hello,

I have a node that needs to load a binary firmware file in order to execute. I'm wondering what's the best way to handle this in ROS.

I've seen options pointing to adding a file/configure_file line in CMakeLists and then using a relative path from my .cpp; others seem to use install(); others yet say it's best to let the executable point directly to the file path in the package's source folder, using ros::package::getPath perhaps.

So, what's the best way?

Thanks in advance.

EDIT: I'm sceptical of the last option because I'm following recommendations to implement base functionalities independent from ROS and then have the ROS nodes act as wrappers. Therefore, my firmware loading happens in a base class in which I don't want to include "ros/package.h"

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2018-05-14 10:27:08 -0500

gvdhoorn gravatar image

updated 2018-05-15 11:47:19 -0500

Therefore, my firmware loading happens in a base class in which I don't want to include "ros/package.h"

you don't need to.

My recommendation: provided your base class / functionality has some sort of load_firmware_file(std::string& filename) method, just use ROS parameters to store an absolute path on the parameter server (set those in your launch file fi: $(find pkg_name)/path/to/firmware/file.bin).

Then use NodeHandle::getParam(..) (or one of the alternatives) to retrieve the parameter, if necessary massage it a bit, and call load_firmware_file(filename_from_ros_parameter_server).

The binary file itself can be included with your package. You could place it in the root of the pkg, or somewhere else. Doesn't matter, as long as your launch file sets the correct path in the ROS parameter.

As to installation: use install (FILES your/firmware/file.bin ${CATKIN_PACKAGE_SHARE_DESTINATION}) (docs). That way the file ends up in /opt/ros/$distro/share/pkg_name and will be easily find()able by launch files.


Edit:

Regarding the install() option, how could I find the installed file during runtime directly from the base class, without using find() or another ros tool?

Personally I wouldn't have an option with still using ROS parameters for this (is flexible and makes the name of the firmware file configurable, which can be a big plus), but if you really don't want to: place the firmware file in the same location as in my previous answer, but instead of ROS parameters in your launch file, use ros::package::getPath(..) as you already mentioned. That should give you the path to the share/$pkg dir in the same way as the $(find ..) substitution arg does.

From there the approaches are identical.

edit flag offensive delete link more

Comments

Thank you very much for your answer gvdhoorn. However, in my case, there's really just the one firmware file option. So I think it may be strange to have to populate the parameter server with a parameter that always has to be the same.

vbs gravatar image vbs  ( 2018-05-14 13:45:29 -0500 )edit

Regarding the install() option, how could I find the installed file during runtime directly from the base class, without using find() or another ros tool?

vbs gravatar image vbs  ( 2018-05-14 13:51:51 -0500 )edit

Thanks for the update. I was hoping to have the firmware file installed and then use a fixed path relative to the executable. But with ROS changing the working directory depending on whether you run the node from a launch file or not, this gets too complicated, not worth the overhead.

vbs gravatar image vbs  ( 2018-05-16 10:31:48 -0500 )edit

Can you comment on why you prefer a hard-coded path over something else?

gvdhoorn gravatar image gvdhoorn  ( 2018-05-16 10:32:40 -0500 )edit

Like I said, since there's just the one possible firmware file, I would rather not use the ROS parameter for it. And then, since the device initialization is a basic operation that is ROS independent, I would prefer to have it done on my pure c++ base class, without using any ROS tool like getPath()

vbs gravatar image vbs  ( 2018-05-16 11:30:09 -0500 )edit

Some options I see that involve no ROS infrastructure whatsoever are a hard-coded abs path (with the assumption that your node is installed in /opt/ros/$distro), an environment variable, installing your firmware in /lib/modules (or some other system location) or a settings file.

gvdhoorn gravatar image gvdhoorn  ( 2018-05-16 11:45:59 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2018-05-14 09:45:34 -0500

Seen: 621 times

Last updated: May 15 '18