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

Get timestamp during roslaunch

asked 2017-05-12 07:07:28 -0500

Hi ROS community!

Is there a way to get the date/time to pass on as a (string) parameter, when roslaunching a node? The idea is to pass a filename as parameter to a node, which will have a specific timestamp.

I was expecting to be able to import a bash script variable to roslaunch, such as "$(date +'%d-%m-%Y_%Ih%Mm%S')", but I guess that this isn't supported using 'find', 'env', 'optenv', 'anon', or 'arg'.

Another possible way to go would be using "$(eval <expression>)" with a python expression to get the timestamp. However, I have no idea how this can be done.

I'm using ROS Kinetic in Ubuntu 16.04.

Is this possible? If so, how can it be accomplished? Thanks in advance.

edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted
2

answered 2017-05-12 22:39:19 -0500

ahendrix gravatar image

You can use the <param> tag with the command argument to run an arbitrary command and store the output in a parameter. In you case it looks like you want:

<param name="start_time" command="date +'%d-%m-%Y_%Ih%Mm%S'"/>

Have a look at the param tag docs for more details.

edit flag offensive delete link more

Comments

ty @ahendrix. had no idea about this!

With

<param name="dst" command="$(env ROS_WORKSPACE)/`date +%d-%m-%Y_%Ih%Mm%S`.mp3"/>

I get

Invalid <node> tag: Invalid tag: Cannot load command parameter [dst]: no such command [/home/stop/catkin_ws/date +%d-%m-%Y_%Ih%Mm%S.mp3].

Any idea?

DavidPortugal gravatar image DavidPortugal  ( 2017-05-15 05:20:13 -0500 )edit
1

It sounds like you want the equivalent of:

rosparam set dst $ROS_WORKSPACE/`date +%d-%m-%Y_%Ih%Mm%S`.mp3

I tried

<param name="dst" command="echo `$ROS_WORKSPACE/\`date +%d-%m-%Y_%Ih%Mm%S\`.mp3`"/>

but:

rosparam get /dst
'`$ROS_WORKSPACE/`date +%d-%m-%Y_%Ih%Mm%S`.mp3`

 '
lucasw gravatar image lucasw  ( 2017-05-15 11:30:31 -0500 )edit
1

What works better is to make a shell script in package foo:

#!/bin/sh
echo $ROS_WORKSPACE/`date +%d-%m-%Y_%Ih%Mm%S`.mp3

but the single quotes and the carriage return are still in there

<param name="dst" command="$(find foo)/scripts/timestamp.sh" />
lucasw gravatar image lucasw  ( 2017-05-15 11:36:20 -0500 )edit

Hi @lucasw, thank you. I was able to solve the issue before with an external script, but I was curious to know if it could actually be done somehow relying only on a single launch file.

DavidPortugal gravatar image DavidPortugal  ( 2017-05-15 12:04:07 -0500 )edit

This almost works but there is an annoying trailing linebreak:

<param name="dst" command="date +$(env ROS_WORKSPACE)%d-%m-%Y_%Ih%Mm%S.mp3" />

lucasw gravatar image lucasw  ( 2019-09-05 16:26:50 -0500 )edit

I haven't managed to call the command directly without the trailing linebreak, however, if using the solution with the shell script, instead of using echo, you can use printfas:

#!bin/bash
printf "${ROS_WORKSPACE}/%(%d-%m-%Y_%Ih-%Mm-%S)T.mp3"
davidllp gravatar image davidllp  ( 2019-09-26 09:30:08 -0500 )edit

Any updates here? I am trying to get a file path from a bash script but the param ends up having both single quotes and a trailing newline, which the pcd_to_pointcloud node doesn't like

atyshka gravatar image atyshka  ( 2019-10-31 09:38:26 -0500 )edit
1

answered 2022-12-16 06:55:04 -0500

apasescu gravatar image

Bumping this with a valid reason: I have been able to find the equivalent $(eval expression) that produces a formatted timestamp and does not require any shell command hack. This also makes it work as part of arg tags, not just param tags.

<!-- Gets current time at launch execution as a formatted string -->
<arg name="time_now" default="$(eval eval ('_' + '_import_' + '_(\'datetime\')').datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))"/>

Will give credit to this blog post, as it solved the missing link which I was struggling to understand: https://alspitz.github.io/blog/roslau...

According to them, by default there is no way to use python import statements inside the ROS eval substitution, unless you cheese it by manually forming the __import__('package') string. Then all you have to do is construct a valid one-liner command that produces the desired output, and you can test that by running the default python or python3 interpreter in a terminal.

Hope this helps for future reference (and to save lots of headaches)!

edit flag offensive delete link more

Comments

This works like magic. I spent nearly 3 hours on this solution, and your answer was just sitting right here.

What's even better is that this is an arg instead of a parameter, which is exactly what I wanted to pass to other launch files.

shrini96 gravatar image shrini96  ( 2023-01-08 05:11:22 -0500 )edit
1

answered 2019-09-26 10:33:29 -0500

davidllp gravatar image

To do it directly inside the command in the param tag, you can use this:

<param name="start_time" command="bash -c 'printf &quot;${ROS_WORKSPACE}/%(%d-%m-%Y_%Ih%Mm%S)T.mp3&quot;'" />

The printf won't introduce the annoying \n at the end of the parameters. However, you can not directly use printf because when called inside the roslaunch, it calls the /usr/bin/printf which does not accept the % formatting. Hence, the use of bash -c.

edit flag offensive delete link more
1

answered 2017-05-15 11:57:37 -0500

lucasw gravatar image

updated 2017-05-15 12:13:51 -0500

It's possible I'm not forming the value of command correctly, but the hacky solution I found is to create a shell script that does a rosparam set and generates some stdout to put into a dummy variable.

foo/scripts/timestamp.sh:

#!/bin/sh
rosparam set dst $ROS_WORKSPACE/`date +%d-%m-%Y_%Ih%Mm%S`.mp3
echo "blah"

And the launch file:

<param name="dummy" command="$(find foo)/scripts/timestamp.sh"/>

rosparam get dst gets a timestamped filename with the mp3 suffix, and no single quotes or carriage return as mentioned in my comments to the other answer.

There will be the dummy variable hanging around:

$ rosparam get dummy
'blah

  '

The point is to make sure the script gets run before any nodes are launched that will depend on the param being set, where just running the timestamp.sh from a roslaunch <node> may or may not create the param first ( http://answers.ros.org/question/33772... ). The documentation in http://wiki.ros.org/roslaunch/XML/param isn't explicit about that but I assume it does always run the command first.

Nested roslaunches with param command?

Could that (somewhat ugly) approach also could generalize to running entire other roslaunches that would have to run then exit before the higher level launch would launch any nodes?

<!-- launch some stuff before doing anything else here -->
<param name="dummy" command="roslaunch bar xyz.launch"/>

If that works it would be an answer to some other questions here.

It produces an error:

run_id on parameter server does not match declared run_id: 9d505b9e-3991-11e7-b59e-
d8fc93bc28de vs 9d224222-3991-11e7-b59e-d8fc93bc28de

Though at the same time I can see parameters set by xyz.launch were actually set.

edit flag offensive delete link more

Comments

Hi all, I have a very similar problem. Instead of dumping the timestamp into a parameter, I need to concatenate the timestamp as a filename for a parameter, e.g.: <rosparam command="dump" param="robot_description" file="$(env HOME)/robot_description_$(eval time.strftime('%Y-%m-%d-%H-%M-%S')).yaml" /> The code above does not work. Does anybody have the correct Python evaluation so that the expected output is a filename similar to:

/home/me/robot_description_2019-06-11-10-30-00.yaml

Thanks.

mcamurri gravatar image mcamurri  ( 2019-06-11 04:13:29 -0500 )edit
1

I figured out myself. For interested people: <arg name="time_now" value="`date +'%Y-%m-%d-%H-%M-%S'`" /> <rosparam command="dump" param="/robot_description" file="$(env HOME)/robot_description_$(arg time_now).yaml" />

This applies to the problem posted by @DavidPortugal as well

UPDATE The above does not work properly, the file is stored correctly but the string still contains the bash command instead of its output

mcamurri gravatar image mcamurri  ( 2019-06-11 04:54:15 -0500 )edit

You can pipe the output to tr. This is how I did it: echo "blah" | tr -d "\n" Then rosparam get does not show the trailing return character.

shrini96 gravatar image shrini96  ( 2023-01-08 04:48:06 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2017-05-12 07:07:28 -0500

Seen: 3,743 times

Last updated: Dec 16 '22