def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_discrete = False # Ensure we have desired overloads. self._DeclarePeriodicPublish(0.1) self._DeclarePeriodicPublish(0.1, 0) self._DeclarePeriodicPublish(period_sec=0.1, offset_sec=0.) self._DeclarePeriodicDiscreteUpdate( period_sec=0.1, offset_sec=0.) self._DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self._DeclareInputPort(PortDataType.kVectorValued, 1) self._DeclareVectorOutputPort(BasicVector(1), noop) def _DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem._DoPublish(self, context, events) self.called_publish = True def _DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertEquals(input_port, 0) test.assertEquals(output_port, 0) # Call base method to ensure we do not get recursion. base_return = LeafSystem._DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def _DoCalcDiscreteVariableUpdates( self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem._DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_discrete) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_discrete) self.assertEquals(results["discrete_next_t"], 0.1) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0))
def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_discrete = False # Ensure we have desired overloads. self._DeclarePeriodicPublish(0.1) self._DeclarePeriodicPublish(0.1, 0) self._DeclarePeriodicPublish(period_sec=0.1, offset_sec=0.) self._DeclarePeriodicDiscreteUpdate( period_sec=0.1, offset_sec=0.) self._DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self._DeclareInputPort(PortDataType.kVectorValued, 1) self._DeclareVectorOutputPort(BasicVector(1), noop) def _DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem._DoPublish(self, context, events) self.called_publish = True def _DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertEquals(input_port, 0) test.assertEquals(output_port, 0) # Call base method to ensure we do not get recursion. base_return = LeafSystem._DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def _DoCalcDiscreteVariableUpdates( self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem._DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_discrete) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_discrete) self.assertEquals(results["discrete_next_t"], 0.1) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0))
def test_all_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_continuous = False self.called_discrete = False self.called_initialize = False self.called_per_step = False self.called_periodic = False self.called_getwitness = False self.called_witness = False self.called_guard = False self.called_reset = False # Ensure we have desired overloads. self.DeclarePeriodicPublish(1.0) self.DeclarePeriodicPublish(1.0, 0) self.DeclarePeriodicPublish(period_sec=1.0, offset_sec=0.) self.DeclarePeriodicDiscreteUpdate(period_sec=1.0, offset_sec=0.) self.DeclareInitializationEvent(event=PublishEvent( trigger_type=TriggerType.kInitialization, callback=self._on_initialize)) self.DeclarePerStepEvent( event=PublishEvent(trigger_type=TriggerType.kPerStep, callback=self._on_per_step)) self.DeclarePeriodicEvent( period_sec=1.0, offset_sec=0.0, event=PublishEvent(trigger_type=TriggerType.kPeriodic, callback=self._on_periodic)) self.DeclareContinuousState(2) self.DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self.DeclareInputPort(PortDataType.kVectorValued, 1) self.DeclareVectorInputPort(name="test_input", model_vector=BasicVector(1), random_type=None) self.DeclareVectorOutputPort("noop", BasicVector(1), noop, prerequisites_of_calc=set( [self.nothing_ticket()])) self.witness = self.MakeWitnessFunction( "witness", WitnessFunctionDirection.kCrossesZero, self._witness) self.reset_witness = self.MakeWitnessFunction( "reset", WitnessFunctionDirection.kCrossesZero, self._guard, UnrestrictedUpdateEvent(self._reset)) def DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem.DoPublish(self, context, events) # N.B. We do not test for a singular call to `DoPublish` # (checking `assertFalse(self.called_publish)` first) because # the above `_DeclareInitializationEvent` will call both its # callback and this event when invoked via # `Simulator::Initialize` from `call_leaf_system_overrides`, # even when we explicitly say not to publish at initialize. self.called_publish = True def DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertIn(input_port, [0, 1]) test.assertEqual(output_port, 0) # Call base method to ensure we do not get recursion. with catch_drake_warnings(expected_count=1): base_return = LeafSystem.DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def DoCalcTimeDerivatives(self, context, derivatives): # Note: Don't call base method here; it would abort because # derivatives.size() != 0. test.assertEqual(derivatives.get_vector().size(), 2) self.called_continuous = True def DoCalcDiscreteVariableUpdates(self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem.DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True def DoGetWitnessFunctions(self, context): self.called_getwitness = True return [self.witness, self.reset_witness] def _on_initialize(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_initialize) self.called_initialize = True def _on_per_step(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) self.called_per_step = True def _on_periodic(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_periodic) self.called_periodic = True def _witness(self, context): test.assertIsInstance(context, Context) self.called_witness = True return 1.0 def _guard(self, context): test.assertIsInstance(context, Context) self.called_guard = True return context.get_time() - 0.5 def _reset(self, context, event, state): test.assertIsInstance(context, Context) test.assertIsInstance(event, UnrestrictedUpdateEvent) test.assertIsInstance(state, State) self.called_reset = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_continuous) self.assertFalse(system.called_discrete) self.assertFalse(system.called_initialize) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_continuous) self.assertTrue(system.called_discrete) self.assertTrue(system.called_initialize) self.assertEqual(results["discrete_next_t"], 1.0) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0)) # Test explicit calls. system = TrivialSystem() context = system.CreateDefaultContext() system.Publish(context) self.assertTrue(system.called_publish) context_update = context.Clone() system.CalcTimeDerivatives( context=context, derivatives=context_update.get_mutable_continuous_state()) self.assertTrue(system.called_continuous) witnesses = system.GetWitnessFunctions(context) self.assertEqual(len(witnesses), 2) system.CalcDiscreteVariableUpdates( context=context, discrete_state=context_update.get_mutable_discrete_state()) self.assertTrue(system.called_discrete) # Test per-step, periodic, and witness call backs system = TrivialSystem() simulator = Simulator(system) simulator.get_mutable_context().SetAccuracy(0.1) # Stepping to 0.99 so that we get exactly one periodic event. simulator.AdvanceTo(0.99) self.assertTrue(system.called_per_step) self.assertTrue(system.called_periodic) self.assertTrue(system.called_getwitness) self.assertTrue(system.called_witness) self.assertTrue(system.called_guard) self.assertTrue(system.called_reset)
def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_continuous = False self.called_discrete = False self.called_initialize = False self.called_per_step = False self.called_periodic = False # Ensure we have desired overloads. self._DeclarePeriodicPublish(0.1) self._DeclarePeriodicPublish(0.1, 0) self._DeclarePeriodicPublish(period_sec=0.1, offset_sec=0.) self._DeclarePeriodicDiscreteUpdate(period_sec=0.1, offset_sec=0.) self._DeclareInitializationEvent(event=PublishEvent( trigger_type=TriggerType.kInitialization, callback=self._on_initialize)) self._DeclarePerStepEvent( event=PublishEvent(trigger_type=TriggerType.kPerStep, callback=self._on_per_step)) self._DeclarePeriodicEvent( period_sec=0.1, offset_sec=0.0, event=PublishEvent(trigger_type=TriggerType.kPeriodic, callback=self._on_periodic)) self._DeclareContinuousState(2) self._DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self._DeclareInputPort(PortDataType.kVectorValued, 1) self._DeclareVectorInputPort(name="test_input", model_vector=BasicVector(1), random_type=None) self._DeclareVectorOutputPort(BasicVector(1), noop) def _DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem._DoPublish(self, context, events) # N.B. We do not test for a singular call to `DoPublish` # (checking `assertFalse(self.called_publish)` first) because # the above `_DeclareInitializationEvent` will call both its # callback and this event when invoked via # `Simulator::Initialize` from `call_leaf_system_overrides`, # even when we explicitly say not to publish at initialize. self.called_publish = True def _DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertIn(input_port, [0, 1]) test.assertEqual(output_port, 0) # Call base method to ensure we do not get recursion. base_return = LeafSystem._DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def _DoCalcTimeDerivatives(self, context, derivatives): # Note: Don't call base method here; it would abort because # derivatives.size() != 0. test.assertEqual(derivatives.get_vector().size(), 2) self.called_continuous = True def _DoCalcDiscreteVariableUpdates(self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem._DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True def _on_initialize(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_initialize) self.called_initialize = True def _on_per_step(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) self.called_per_step = True def _on_periodic(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_periodic) self.called_periodic = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_continuous) self.assertFalse(system.called_discrete) self.assertFalse(system.called_initialize) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_continuous) self.assertTrue(system.called_discrete) self.assertTrue(system.called_initialize) self.assertEqual(results["discrete_next_t"], 0.1) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0)) # Test explicit calls. system = TrivialSystem() context = system.CreateDefaultContext() system.Publish(context) self.assertTrue(system.called_publish) context_update = context.Clone() system.CalcTimeDerivatives( context, context_update.get_mutable_continuous_state()) self.assertTrue(system.called_continuous) # Test per-step and periodic call backs system = TrivialSystem() simulator = Simulator(system) simulator.StepTo(0.1) self.assertTrue(system.called_per_step) self.assertTrue(system.called_periodic)
def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_continuous = False self.called_discrete = False self.called_initialize = False self.called_per_step = False self.called_periodic = False self.called_getwitness = False self.called_witness = False self.called_guard = False self.called_reset = False # Ensure we have desired overloads. self.DeclarePeriodicPublish(1.0) self.DeclarePeriodicPublish(1.0, 0) self.DeclarePeriodicPublish(period_sec=1.0, offset_sec=0.) self.DeclarePeriodicDiscreteUpdate( period_sec=1.0, offset_sec=0.) self.DeclareInitializationEvent( event=PublishEvent( trigger_type=TriggerType.kInitialization, callback=self._on_initialize)) self.DeclarePerStepEvent( event=PublishEvent( trigger_type=TriggerType.kPerStep, callback=self._on_per_step)) self.DeclarePeriodicEvent( period_sec=1.0, offset_sec=0.0, event=PublishEvent( trigger_type=TriggerType.kPeriodic, callback=self._on_periodic)) self.DeclareContinuousState(2) self.DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self.DeclareInputPort(PortDataType.kVectorValued, 1) self.DeclareVectorInputPort( name="test_input", model_vector=BasicVector(1), random_type=None) self.DeclareVectorOutputPort( "noop", BasicVector(1), noop, prerequisites_of_calc=set([self.nothing_ticket()])) self.witness = self.MakeWitnessFunction( "witness", WitnessFunctionDirection.kCrossesZero, self._witness) self.reset_witness = self.MakeWitnessFunction( "reset", WitnessFunctionDirection.kCrossesZero, self._guard, UnrestrictedUpdateEvent(self._reset)) def DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem.DoPublish(self, context, events) # N.B. We do not test for a singular call to `DoPublish` # (checking `assertFalse(self.called_publish)` first) because # the above `_DeclareInitializationEvent` will call both its # callback and this event when invoked via # `Simulator::Initialize` from `call_leaf_system_overrides`, # even when we explicitly say not to publish at initialize. self.called_publish = True def DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertIn(input_port, [0, 1]) test.assertEqual(output_port, 0) # Call base method to ensure we do not get recursion. with catch_drake_warnings(expected_count=1): base_return = LeafSystem.DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def DoCalcTimeDerivatives(self, context, derivatives): # Note: Don't call base method here; it would abort because # derivatives.size() != 0. test.assertEqual(derivatives.get_vector().size(), 2) self.called_continuous = True def DoCalcDiscreteVariableUpdates( self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem.DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True def DoGetWitnessFunctions(self, context): self.called_getwitness = True return [self.witness, self.reset_witness] def _on_initialize(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_initialize) self.called_initialize = True def _on_per_step(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) self.called_per_step = True def _on_periodic(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_periodic) self.called_periodic = True def _witness(self, context): test.assertIsInstance(context, Context) self.called_witness = True return 1.0 def _guard(self, context): test.assertIsInstance(context, Context) self.called_guard = True return context.get_time() - 0.5 def _reset(self, context, event, state): test.assertIsInstance(context, Context) test.assertIsInstance(event, UnrestrictedUpdateEvent) test.assertIsInstance(state, State) self.called_reset = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_continuous) self.assertFalse(system.called_discrete) self.assertFalse(system.called_initialize) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_continuous) self.assertTrue(system.called_discrete) self.assertTrue(system.called_initialize) self.assertEqual(results["discrete_next_t"], 1.0) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0)) # Test explicit calls. system = TrivialSystem() context = system.CreateDefaultContext() system.Publish(context) self.assertTrue(system.called_publish) context_update = context.Clone() system.CalcTimeDerivatives( context=context, derivatives=context_update.get_mutable_continuous_state()) self.assertTrue(system.called_continuous) witnesses = system.GetWitnessFunctions(context) self.assertEqual(len(witnesses), 2) system.CalcDiscreteVariableUpdates( context=context, discrete_state=context_update.get_mutable_discrete_state()) self.assertTrue(system.called_discrete) # Test per-step, periodic, and witness call backs system = TrivialSystem() simulator = Simulator(system) simulator.get_mutable_context().SetAccuracy(0.1) # Stepping to 0.99 so that we get exactly one periodic event. simulator.AdvanceTo(0.99) self.assertTrue(system.called_per_step) self.assertTrue(system.called_periodic) self.assertTrue(system.called_getwitness) self.assertTrue(system.called_witness) self.assertTrue(system.called_guard) self.assertTrue(system.called_reset)
def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_continuous = False self.called_discrete = False # Ensure we have desired overloads. self._DeclarePeriodicPublish(0.1) self._DeclarePeriodicPublish(0.1, 0) self._DeclarePeriodicPublish(period_sec=0.1, offset_sec=0.) self._DeclarePeriodicDiscreteUpdate( period_sec=0.1, offset_sec=0.) self._DeclareContinuousState(2) self._DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self._DeclareInputPort(PortDataType.kVectorValued, 1) self._DeclareVectorOutputPort(BasicVector(1), noop) def _DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem._DoPublish(self, context, events) self.called_publish = True def _DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertEqual(input_port, 0) test.assertEqual(output_port, 0) # Call base method to ensure we do not get recursion. base_return = LeafSystem._DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def _DoCalcTimeDerivatives(self, context, derivatives): # Note: Don't call base method here; it would abort because # derivatives.size() != 0. test.assertEqual(derivatives.get_vector().size(), 2) self.called_continuous = True def _DoCalcDiscreteVariableUpdates( self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem._DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_continuous) self.assertFalse(system.called_discrete) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_continuous) self.assertTrue(system.called_discrete) self.assertEqual(results["discrete_next_t"], 0.1) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0)) # Test explicit calls. system = TrivialSystem() context = system.CreateDefaultContext() system.Publish(context) self.assertTrue(system.called_publish) context_update = context.Clone() system.CalcTimeDerivatives( context, context_update.get_mutable_continuous_state()) self.assertTrue(system.called_continuous)
def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_continuous = False self.called_discrete = False self.called_initialize = False self.called_per_step = False self.called_periodic = False # Ensure we have desired overloads. self._DeclarePeriodicPublish(1.0) self._DeclarePeriodicPublish(1.0, 0) self._DeclarePeriodicPublish(period_sec=1.0, offset_sec=0.) self._DeclarePeriodicDiscreteUpdate( period_sec=1.0, offset_sec=0.) self._DeclareInitializationEvent( event=PublishEvent( trigger_type=TriggerType.kInitialization, callback=self._on_initialize)) self._DeclarePerStepEvent( event=PublishEvent( trigger_type=TriggerType.kPerStep, callback=self._on_per_step)) self._DeclarePeriodicEvent( period_sec=1.0, offset_sec=0.0, event=PublishEvent( trigger_type=TriggerType.kPeriodic, callback=self._on_periodic)) self._DeclareContinuousState(2) self._DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self._DeclareInputPort(PortDataType.kVectorValued, 1) self._DeclareVectorInputPort( name="test_input", model_vector=BasicVector(1), random_type=None) self._DeclareVectorOutputPort(BasicVector(1), noop) def _DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem._DoPublish(self, context, events) # N.B. We do not test for a singular call to `DoPublish` # (checking `assertFalse(self.called_publish)` first) because # the above `_DeclareInitializationEvent` will call both its # callback and this event when invoked via # `Simulator::Initialize` from `call_leaf_system_overrides`, # even when we explicitly say not to publish at initialize. self.called_publish = True def _DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertIn(input_port, [0, 1]) test.assertEqual(output_port, 0) # Call base method to ensure we do not get recursion. base_return = LeafSystem._DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def _DoCalcTimeDerivatives(self, context, derivatives): # Note: Don't call base method here; it would abort because # derivatives.size() != 0. test.assertEqual(derivatives.get_vector().size(), 2) self.called_continuous = True def _DoCalcDiscreteVariableUpdates( self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem._DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True def _on_initialize(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_initialize) self.called_initialize = True def _on_per_step(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) self.called_per_step = True def _on_periodic(self, context, event): test.assertIsInstance(context, Context) test.assertIsInstance(event, PublishEvent) test.assertFalse(self.called_periodic) self.called_periodic = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_continuous) self.assertFalse(system.called_discrete) self.assertFalse(system.called_initialize) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_continuous) self.assertTrue(system.called_discrete) self.assertTrue(system.called_initialize) self.assertEqual(results["discrete_next_t"], 1.0) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0)) # Test explicit calls. system = TrivialSystem() context = system.CreateDefaultContext() system.Publish(context) self.assertTrue(system.called_publish) context_update = context.Clone() system.CalcTimeDerivatives( context, context_update.get_mutable_continuous_state()) self.assertTrue(system.called_continuous) # Test per-step and periodic call backs system = TrivialSystem() simulator = Simulator(system) # Stepping to 0.99 so that we get exactly one periodic event. simulator.StepTo(0.99) self.assertTrue(system.called_per_step) self.assertTrue(system.called_periodic)
def test_leaf_system_overrides(self): test = self class TrivialSystem(LeafSystem): def __init__(self): LeafSystem.__init__(self) self.called_publish = False self.called_feedthrough = False self.called_continuous = False self.called_discrete = False # Ensure we have desired overloads. self._DeclarePeriodicPublish(0.1) self._DeclarePeriodicPublish(0.1, 0) self._DeclarePeriodicPublish(period_sec=0.1, offset_sec=0.) self._DeclarePeriodicDiscreteUpdate(period_sec=0.1, offset_sec=0.) self._DeclareContinuousState(2) self._DeclareDiscreteState(1) # Ensure that we have inputs / outputs to call direct # feedthrough. self._DeclareInputPort(PortDataType.kVectorValued, 1) self._DeclareVectorOutputPort(BasicVector(1), noop) def _DoPublish(self, context, events): # Call base method to ensure we do not get recursion. LeafSystem._DoPublish(self, context, events) self.called_publish = True def _DoHasDirectFeedthrough(self, input_port, output_port): # Test inputs. test.assertEqual(input_port, 0) test.assertEqual(output_port, 0) # Call base method to ensure we do not get recursion. base_return = LeafSystem._DoHasDirectFeedthrough( self, input_port, output_port) test.assertTrue(base_return is None) # Return custom methods. self.called_feedthrough = True return False def _DoCalcTimeDerivatives(self, context, derivatives): # Note: Don't call base method here; it would abort because # derivatives.size() != 0. test.assertEqual(derivatives.get_vector().size(), 2) self.called_continuous = True def _DoCalcDiscreteVariableUpdates(self, context, events, discrete_state): # Call base method to ensure we do not get recursion. LeafSystem._DoCalcDiscreteVariableUpdates( self, context, events, discrete_state) self.called_discrete = True system = TrivialSystem() self.assertFalse(system.called_publish) self.assertFalse(system.called_feedthrough) self.assertFalse(system.called_continuous) self.assertFalse(system.called_discrete) results = call_leaf_system_overrides(system) self.assertTrue(system.called_publish) self.assertTrue(system.called_feedthrough) self.assertFalse(results["has_direct_feedthrough"]) self.assertTrue(system.called_continuous) self.assertTrue(system.called_discrete) self.assertEqual(results["discrete_next_t"], 0.1) self.assertFalse(system.HasAnyDirectFeedthrough()) self.assertFalse(system.HasDirectFeedthrough(output_port=0)) self.assertFalse( system.HasDirectFeedthrough(input_port=0, output_port=0)) # Test explicit calls. system = TrivialSystem() context = system.CreateDefaultContext() system.Publish(context) self.assertTrue(system.called_publish) context_update = context.Clone() system.CalcTimeDerivatives( context, context_update.get_mutable_continuous_state()) self.assertTrue(system.called_continuous)