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

Unable to read a file while using relative path

asked 2016-05-27 03:49:54 -0600

ravijoshi gravatar image

Hi, I want to read a file inside python script in ros indigo in the following way -

file_name = rospy.get_param("~file", None)

Below is the snippet of launch file -

<launch>
    <arg name="file"  default="$(find kinematics)/sample/joint_states.csv" />
    <arg name="animation" default="true" />  <!-- run animation -->
    <group if="$(arg animation)">
        <node pkg="kinematics" type="trajectory.py" name="trajectory_animation" respawn="true">
            <param name="file" value="$(arg file)" />
        </node>
    </group>
</launch>

While providing the file parameter as a command line argument, it says No such file or directory. Below is the output of terminal -

ravi@ravi-pc:~/ros_ws$ roslaunch kinematics baxter.launch file:=src/../../Desktop/joint_states.csv 
  File "/home/ravi/ros_ws/src/kinematics/src/trajectory.py", line 19, in __init__
    with open(file_name, 'r') as f:
IOError: [Errno 2] No such file or directory: 'src/../../Desktop/joint_states.csv'
ravi@ravi-pc:~/ros_ws$ ll src/../../Desktop/joint_states.csv
-rw-rw-r-- 1 ravi ravi 179308 May 19 20:46 src/../../Desktop/joint_states.csv
ravi@ravi-pc:~/ros_ws$ roslaunch kinematics baxter.launch file:=src/kinematics/sample/joint_states.csv
  File "/home/ravi/ros_ws/src/kinematics/src/trajectory.py", line 19, in __init__
    with open(file_name, 'r') as f:
IOError: [Errno 2] No such file or directory: 'src/kinematics/sample/joint_states.csv'
ravi@ravi-pc:~/ros_ws$ ll src/kinematics/sample/joint_states.csv
-rw-rw-r-- 1 tom tom 179308 May 19 20:46 src/kinematics/sample/joint_states.csv
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
9

answered 2016-05-27 05:22:08 -0600

gvdhoorn gravatar image

updated 2016-05-27 05:23:18 -0600

You are probably not aware that by default, the working directory of all nodes is set to $ROS_HOME, which in most cases will be $HOME/.ros, not the base of your catkin workspace.

Some earlier questions and answers about this:

Note: you don't want to go and change the value of ROS_HOME. Instead, either specify an absolute path, or place data in a package that is on the ROS_PACKAGE_PATH and use $(find ..)/path/to/data.file (as you are doing in your launch file). Note that the equivalent of $(find ..) in your launch file is rospack find .. on the command line.


Edit: and a direct link to the wiki page documenting this: roslaunch/XML/node - Attributes. Look for the cwd attribute.

edit flag offensive delete link more

Comments

Many thanks. I still didn't get the answer. One of the link suggest to provide the absolute path, which I don't prefer. Another link suggest to keep the data file inside the package and use rospack find command. I don't prefer this too, as the file is provided by user as input. Please suggest.

ravijoshi gravatar image ravijoshi  ( 2016-05-27 10:10:33 -0600 )edit

There is nothing to suggest. Those are the two supported options.

keep the data file inside the package

Note that the suggestion is to keep it inside a package, not necessarily your package.

gvdhoorn gravatar image gvdhoorn  ( 2016-05-27 10:28:47 -0600 )edit
1

I've no idea of the side effects / consequences, but you could see whether you can work around this by using something like chdir(..) or current_path(..) from Boost.

gvdhoorn gravatar image gvdhoorn  ( 2016-05-27 10:30:25 -0600 )edit
1

Another option could be to pass the cwd to your node as a parameter, and prefix the file parameter with that.

gvdhoorn gravatar image gvdhoorn  ( 2016-05-27 10:31:53 -0600 )edit
2

answered 2022-08-17 10:58:31 -0600

v4hn gravatar image

From ROS kinetic on you can use $(eval to check whether the path is absolute and prepend $(env PWD)/ if it is not. That way you can pass a file with relative path and the node will receive a full path automatically. For your example it should look something like this:

<launch>
    <arg name="file" />
    <node pkg="kinematics" type="trajectory.py" name="trajectory_animation" respawn="true">
        <param name="file" value="$(arg file)" if="$(eval file[0] == '/')" />
        <param name="file" value="$(env PWD)/$(arg file)" unless="$(eval file[0] == '/')" />
    </node>
</launch>

Of course it would be nicer to have direct support for this mechanism in roslaunch (also in bash completion...) via something like <arg type="file", but someone would have to implement it of course.

edit flag offensive delete link more

Comments

Appreciate your kind response. Though I completely forgot about it. It's been ages!

ravijoshi gravatar image ravijoshi  ( 2022-08-17 21:14:52 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2016-05-27 03:49:54 -0600

Seen: 12,796 times

Last updated: Aug 17 '22