Search code examples
drake

Logging abstract-valued output ports


I can't find an abstract-valued version of SignalLogger. I've been writing custom loggers for abstract-valued outputs, such as this one for ContactResults:

class ContactResultsLogger(LeafSystem):
    def __init__(self, publish_period_seconds: float):
        super().__init__()
        self.DeclarePeriodicPublish(publish_period_seconds)
        self.contact_results_input_port = self.DeclareAbstractInputPort(
            'contact_results', AbstractValue.Make(ContactResults()))
        self.sample_times = []
        self.contact_results_list = []

    def DoPublish(self, context, event):
        super().DoPublish(context, event)
        self.sample_times.append(context.get_time())
        self.contact_results_list.append(
           copy.deepcopy(self.contact_results_input_port.Eval(context)))

This works, but having one for every type of abstract-valued output can be tedious. Is there a better way to log abstract-valued outputs? Thanks!


Solution

  • In your sample code where you say AbstractValue.Make(ContactResults()), instead you could say AbstractValue.Make(model_value), where model_value is a new, required constructor argument to this class.

    Then, rename the class to something like AbstractValueLogger and rename the contact_results_list to something like values, and now you have a reusable logger, system = AbstractValueLogger(model_value=ContactResults()).