The RecordROSBagState TemplateΒΆ
RecordROSBagState
smacha/src/smacha/templates/RecordROSBagState.tpl.py
{% block meta %}
name: ROSBagAPIThreadRecorder
description:
SMACH template that can start and stop rosbag recordings using different types
of recorder classes, namely ROSBagCLIProcessRecorder or ROSBagAPIThreadRecorder.
language: Python
framework: SMACH
type: None
tags: [core]
includes: []
extends: []
variables: []
input_keys: []
output_keys: []
{% endblock meta %}
{% from "Utils.tpl.py" import import_module, render_init_callbacks, render_execute_callbacks %}
{% extends "State.tpl.py" %}
{% if recorder is not defined %}
{% set recorder = 'ROSBagCLIProcessRecorder' %}
{% include "ROSBagCLIProcessRecorder.tpl.py" %}
{% elif recorder == 'ROSBagAPIThreadRecorder' %}
{% include "ROSBagAPIThreadRecorder.tpl.py" %}
{% else %}
{% include "ROSBagCLIProcessRecorder.tpl.py" %}
{% endif %}
{% block class_defs %}
{{ super() }}
{% if 'class_RecordROSBagState' not in defined_headers %}
class RecordROSBagState(smach.State):
def __init__(self, name, bag_recorder, action, input_keys=['file', 'topics'], output_keys=[], callbacks = None):
smach.State.__init__(self, input_keys=input_keys, output_keys=output_keys, outcomes=['succeeded', 'aborted'])
# Save the state name
self._name = name
# Save the ROSBagRecorder object reference
self._bag_recorder= bag_recorder
# Save the action
self._action = action
{{ render_init_callbacks() }}
def execute(self, userdata):
{{ render_execute_callbacks() }}
# Get filename from userdata
try:
bag_file = userdata.file
assert(isinstance(bag_file, str))
except Exception as e:
rospy.logerr('The rosbag filename must be specified as a userdata input key: {}'.format(repr(e)))
return 'aborted'
# Get topic names from userdata
try:
topics = userdata.topics
assert(not any(not isinstance(x, str) for x in topics))
except Exception as e:
rospy.logerr('Topic names must be specified as a userdata input key: {}'.format(repr(e)))
return 'aborted'
# Start or stop recording
outcome = 'aborted'
if self._action == 'start' or self._action == 'record':
outcome = self._bag_recorder.start(bag_file, topics)
elif self._action == 'stop':
outcome = self._bag_recorder.stop(bag_file)
elif self._action == 'stop_all':
outcome = self._bag_recorder.stop_all()
return outcome
{% do defined_headers.append('class_RecordROSBagState') %}{% endif %}
{% endblock class_defs %}
{% block main_def %}
{{ super() }}
{% if 'bag_recorder' not in defined_headers %}
bag_recorder = {{ recorder }}()
{% do defined_headers.append('bag_recorder') %}{% endif %}
{% endblock main_def %}
{% block header %}
{{ super() }}
{#
# By using this bit of trickery, we ensure that the mandatory userdata variables
# 'file' and 'topics' get defined as empty strings before any other userdata
# variables are defined (these are rendered via the 'header_userdata' block
# usually, which is rendered after the 'header' block). This allows for the
# specification of 'file' and 'topics' to be omitted in the SMACHA script state
# definitions when the 'action' variable is set to 'stop_all', for example.
#}
{% if mandatory_userdata is not defined %}{% set mandatory_userdata = dict() %}{% endif %}
{% if action == 'stop_all' and 'file' not in mandatory_userdata.keys() %}{% set _dummy = mandatory_userdata.update({'file':''}) %}{% endif %}
{% if (action == 'stop_all' or action == 'stop') and 'topics' not in mandatory_userdata.keys() %}{% set _dummy = mandatory_userdata.update({'topics':''}) %}{% endif %}
{% if mandatory_userdata is defined %}{{ render_userdata(parent_sm_name, mandatory_userdata) }}{% endif %}
{% endblock header %}
{% block body %}
smach.{{ parent_type }}.add('{{ name }}',
{{ '' | indent(23, true) }}{{ class_name }}('{{ name }}', bag_recorder, '{{ action }}'{% if input_keys is defined %}, {{ render_input_keys(input_keys, indent=0) }}{% endif %}{% if output_keys is defined %}, {{ render_output_keys(output_keys, indent=0) }}{% endif %}{% if callbacks is defined %}, {{ render_callbacks(name, uuid, callbacks, indent=0) }}{% endif %}){% if transitions is defined %},
{{ render_transitions(transitions) }}{% endif %}{% if remapping is defined %},
{{ render_remapping(remapping) }}{% endif %})
{% endblock body %}