This is a simple ROS package that allows starting and stopping rosbag recordings via service calls, which is useful for performing repeated data collection. It also allows replaying those recordings for analyzing performance. You can add annotations from within the code that will appear in Rviz during execution and replay.
roslaunch data_recording data_recording.launch
uses the default mode:=minimal.
The config files for the recording are in the config directory. You can choose between different settings and add new config files. Configure the output directory for the rosbag files and topics to be recorded (regex syntax is ok). Rosbag files are saved with the current date and time as a filename.
The package creates four services:
/data\_recording/start\_recording
which can be called with adata_recording.srv.RecordRequest
message/data\_recording/stop\_recording
which can be called with astd_srvs.srv.TriggerRequest
message/data\_recording/toggle\_recording
which can be called with astd_srvs.srv.TriggerRequest
message/data\_recording/recording\_state
which can be called with adata_recording.srv.RecordStateRequest
message
Add the following imports to your ROS node:
from std_srvs.srv import Trigger, TriggerRequest
from data_recording.srv import Record, RecordRequest
In the init of your ROS node, launch the services as
start_record_srv = rospy.ServiceProxy('/data_recording/start_recording', Record)
stop_record_srv = rospy.ServiceProxy('/data_recording/stop_recording', Trigger)
Then in a regular service call:
start_record_srv(RecordRequest('name of your file', 0) # this allows you to modify name based on e.g. the run, set timeout to 0 -> infinite
do_some_stuff()
stop_record_srv(TriggerRequest())
If you leave the bagname
field of the RecordRequest
empty, the file will be named using
the datetime of the recording.
Make sure that stop_record_srv called before your node terminates, otherwise the service will continue recording.
To stop recording automatically when your node shuts down, you can register a hook rospy.on_shutdown(stop_record_srv)
.
This does not cover cases where the user cancels execution by hitting Ctrl-C
(SIGINT).
You can set up a handler for this in a similar way. To conclude, you should have at least the following
in the init of your node:
import signal
# in your init:
rospy.on_shutdown(stop_record_srv) # when something else kills this node
def handler(signum, frame):
stop_record_srv(TriggerRequest())
exit(0)
signal.signal(signal.SIGINT, handler) # when the user shuts down the node
From within the code you can add annotations to the stored rosbags by publishing
strings to a special topic /data_recording/annotations
. These messages are then displayed on Rviz
so you can analyze important events that happened in the code. This feature is optional.
Simply create a publisher in your initialization:
annotation_pub = rospy.Publisher('/data_recording/annotations', Marker, queue_size=10)
and add from visualization_msgs.msg import Marker
to your imports.
Then create a text marker. See example.py
for a function that does this.
Publish an annotation any time anywhere using annotation_pub.publish(text_marker)
If you want to test this functionality, launch the data_recording services as outlined above and
run rosrun data_recording example.py
.
You can visualize the annotations during execution and during replay in Rviz. In Rviz, simply press add
, choose Marker
and select the topic data_recording/annotations
. During replay (section below), this has been stored for you in the Rviz config file already.
Kill all ROS nodes currently running. This file will launch all necessary nodes and rviz for you.
- Launch a
roscore
and setrosparam set use_sim_time true
if you want looping to visualize correctly. roslaunch data_recording replay.launch filename:=YOUR_RECORDING
.
The rosbag won't start playing until you hit the spacebar. This is because Rviz takes a while to launch and could be replaced with a delay.
This launch file assumes a specific path for the recordings which you can
specify using filepath:=YOUR_FILEPATH
. The default filepath is the same as that for saving rosbags;
data_recording/rosbags
.
This launch file launches a specific rviz config file. You can make a new config file, store it in the config folder and load it using the mode
argument.
Add a node for every topic you would like to check for health. For example:
<node name="imu_health_check" pkg="health_checks" type="topic_health_check.py" output="screen">
<param name="title" value="IMU" />
<param name="topic" value="/imu/data" />
<param name="timeout" value="0.5" />
<param name="update_time" value="2"/>
<param name="hz_min" value="100"/>
</node>
topic
: the topictitle
: title published with every status updatetimeout
: timeout for detecting a faulty topic in secondsupdate_time
: interval for publishing OK updates. Timeouts and new data is handled immediatelyhz_min
: minimum hz, status type isTopicHealt.TYPE_WARNING
when publish frequency is lower
health_checks.msg.TopicHealth
on topic {topic}/status