Пример #1
0
    def test_nested_and_key_attribute_access(self):
        """
        Test the access to individual attributes that are nested within a hierarchy of types or are elements of a list,
        tuple etc.
        """

        #test access to particular nested attribute of a message
        complex_topic = '/complex_nested_type_topic'
        pub_complex = rospy.Publisher(complex_topic,
                                      PlannerStatus,
                                      queue_size=1,
                                      latch=True)
        rospy.sleep(0.1)

        test_value = 1337
        test_value2 = "second"
        test_initial_value = "initial"

        msg = PlannerStatus()

        msg.plan.append("first")
        msg.plan.append(test_value2)

        msg.goals.append(Status(activation=test_value))

        pub_complex.publish(msg)

        complex_sensor = TopicSensor(topic=complex_topic,
                                     message_attr='plan[1]',
                                     initial_value=test_initial_value)

        very_complex_sensor = TopicSensor(topic=complex_topic,
                                          message_attr='goals[0].activation')

        rospy.sleep(0.1)

        very_complex_sensor.sync()
        complex_sensor.sync()

        self.assertEquals(test_value2, complex_sensor.value,
                          "Complex test value does not match")

        self.assertEquals(test_value, very_complex_sensor.value,
                          "Complex iterated nested test value does not match")

        # empty list test
        msg = PlannerStatus()
        pub_complex.publish(msg)
        rospy.sleep(0.1)

        complex_sensor.sync()

        self.assertEquals(test_initial_value, complex_sensor.value,
                          "Complex sensor value does not match initial value")
Пример #2
0
    def test_offline_goal(self):

        method_prefix = self.__message_prefix + "TestOfflineGoal"
        planner_prefix = method_prefix + "/Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)

        topic_name = method_prefix + '/Topic'

        sensor = TopicSensor(topic=topic_name,
                             message_type=Bool,
                             initial_value=False)
        condition = Condition(sensor, BooleanActivator())

        SetTrueBehavior(effect_name=sensor.name,
                        topic_name=topic_name,
                        name=method_prefix + "SetTrue",
                        planner_prefix=planner_prefix)
        goal = OfflineGoal('CentralGoal', planner_prefix=planner_prefix)
        goal.add_condition(condition)
        m.add_goal(goal)
        for x in range(0, 3, 1):
            m.step()
            rospy.sleep(0.1)

        goal.fetchStatus(3)

        self.assertTrue(goal.satisfied, 'Goal is not satisfied')

        goal.unregister()
Пример #3
0
    def test_activator(self):
        method_prefix = self.__message_prefix + "TestOfflineGoal"
        planner_prefix = method_prefix + "Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)

        topic_name = 'IncreaseTopicTest/Topic'

        sensor = TopicSensor(topic=topic_name, name='IncreaseTopicTestSensor', message_type=Int32,
                             initial_value=0)
        activator = GreedyActivator()
        condition = Condition(sensor=sensor, activator=activator)

        IncreaserBehavior(topic_name=topic_name, effect_name=sensor.name,
                          createLogFiles=True, planner_prefix=planner_prefix)
        goal = OfflineGoal(name=self.__message_prefix + 'CentralGoal', planner_prefix=planner_prefix)
        goal.add_condition(condition)
        m.add_goal(goal)

        number_of_steps = 15
        for x in range(0, number_of_steps + 1 , 1):
            m.step()
            rospy.sleep(0.1)

        # it takes 2 steps until the activation has increased
        expected_behaviour_steps = number_of_steps - 2
        self.assertEquals(expected_behaviour_steps, sensor.latestValue)
Пример #4
0
    def test_independent_behaviour(self):
        """
        Test behaviour property independentFromPlanner
        """

        method_prefix = self.__message_prefix + "test_independent_behaviour"
        planner_prefix = method_prefix + "Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)

        topic_name_1 = method_prefix + '/sensor_1'

        sensor = TopicSensor(topic=topic_name_1,
                             message_type=Bool,
                             initial_value=False)
        condition = Condition(sensor, BooleanActivator())

        #independentFromPlanner and effects
        independent_behaviour = SetTrueBehavior(effect_name=sensor.name,
                                                topic_name=topic_name_1,
                                                name=method_prefix + "SetTrue",
                                                planner_prefix=planner_prefix,
                                                independentFromPlanner=True)

        #independentFromPlanner and no effects
        independent_behaviour2 = SetTrueBehavior(effect_name=None,
                                                 topic_name=topic_name_1,
                                                 name=method_prefix +
                                                 "SetTrue2",
                                                 planner_prefix=planner_prefix,
                                                 independentFromPlanner=True)
        # not independentFromPlanner and no effects
        independent_behaviour3 = SetTrueBehavior(effect_name=None,
                                                 topic_name=topic_name_1,
                                                 name=method_prefix +
                                                 "SetTrue3",
                                                 planner_prefix=planner_prefix,
                                                 independentFromPlanner=False)

        goal = GoalBase(method_prefix + 'CentralGoal',
                        planner_prefix=planner_prefix)
        goal.add_condition(condition)

        for x in range(0, 3, 1):
            m.step()
            rospy.sleep(0.1)

        goal_proxy = m.goals[0]
        goal_proxy.fetchStatus(3)
        self.assertTrue(goal_proxy.satisfied, 'Goal is not satisfied')

        self.assertTrue(independent_behaviour._isExecuting,
                        "independent_behaviour is not executed")
        self.assertFalse(independent_behaviour2.was_executed,
                         "independent_behaviour2 was executed")
        self.assertFalse(independent_behaviour3.was_executed,
                         "independent_behaviour2 was executed")
Пример #5
0
 def setUp(self):
     rospy.init_node("TestNode")
     sensor = TopicSensor(name="test_sensor",
                          topic="sensor_topic",
                          message_type=Bool,
                          initial_value=False)
     self.conditions = [Condition(sensor, BooleanActivator())]
     self.manager_name = "Test_manager"
     self.manager = Manager(prefix=self.manager_name)
     self.goal_name = "test_goal"
     self.satisfaction_threshold = 1.0
Пример #6
0
 def setUp(self):
     rospy.init_node("TestNode")
     self.manager = Manager(prefix="test_manager")
     self.uut = TestDelegationBehaviour(name="test_behaviour",
                                        planner_prefix="test_manager")
     self.sensor = TopicSensor(name="test_sensor",
                               topic="/sensor_topic",
                               message_type=Bool,
                               initial_value=False)
     self.test_condition = Condition(self.sensor, BooleanActivator())
     self.effect = Effect(sensor_name="test_sensor", indicator=1.0)
     self.client = self.uut.delegation_client
Пример #7
0
    def test_publisher_goal(self):

        method_prefix = self.__message_prefix + "TestPublisherGoal"
        planner_prefix = method_prefix + "Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)

        topic_name = method_prefix + '/Topic'

        sensor = TopicSensor(topic=topic_name,
                             message_type=Bool,
                             initial_value=False)
        condition = Condition(sensor, BooleanActivator())

        SetTrueBehavior(effect_name=sensor.name,
                        topic_name=topic_name,
                        name=method_prefix + "SetTrue",
                        planner_prefix=planner_prefix)
        goal = PublisherGoal(method_prefix + 'PublisherGoal',
                             planner_prefix=planner_prefix)
        goal.add_condition(condition)

        goal_activated_condition = goal.create_condition()

        m.step()
        rospy.sleep(0.1)

        sensor.update(True)

        m.step()
        rospy.sleep(0.1)

        goal_proxy = m.goals[0]
        goal_proxy.fetchStatus(2)
        self.assertFalse(goal_proxy.enabled, 'Goal still enabled')
        # manually updating this conditions because it is not registered somewhere
        goal_activated_condition.sync()
        goal_activated_condition.updateComputation()
        # Satisfaction should become 0.0 if the goal is deactivated, this also tests the publishing part indirectly
        self.assertEquals(goal_activated_condition.satisfaction, 0.0,
                          'goal_condition not properly updated')
Пример #8
0
    def test_conditions_in_multiple_levels(self):
        """
        Testing conditions that are used as well on the highest manager hierarchy level as well as in a sub manager of
        a NetworkBehaviour. In particular one conditions is used as precondition, the other one as goal condition.
        """

        method_prefix = self.__message_prefix + "/test_conditions_in_multiple_levels"

        pre_con_sensor = Sensor(name="Precon_sensor", initial_value=False)
        pre_con = Condition(pre_con_sensor, BooleanActivator(desiredValue=True))

        topic_name = method_prefix + '/Topic'
        sensor = TopicSensor(topic=topic_name, message_type=Int32, initial_value=0)
        condition = Condition(sensor, ThresholdActivator(thresholdValue=3))

        planner_prefix = method_prefix + "/Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)
        goal = OfflineGoal('CentralGoal', planner_prefix=planner_prefix)
        goal.add_condition(condition)
        m.add_goal(goal)

        effect = Effect(sensor_name=sensor.name, indicator=1, sensor_type=int, activator_name=condition.activator.name)

        first_level_network = NetworkBehaviour(name=method_prefix + '/FirstLevel', planner_prefix=planner_prefix,
                                               createLogFiles=True)
        first_level_network.add_effects([effect])
        first_level_network.add_precondition(pre_con)

        goal_with_same_cond = OfflineGoal('CentralGoal2', planner_prefix=planner_prefix)
        goal_with_same_cond.add_condition(condition)
        first_level_network.add_goal(goal_with_same_cond)

        increaser_behavior = IncreaserBehavior(effect_name=sensor.name, topic_name=topic_name,
                                               name=method_prefix + "TopicIncreaser",
                                               planner_prefix=first_level_network.get_manager_prefix())

        increaser_behavior.add_precondition(pre_con)

        # activate the first_level_network increaser_Behavior
        for x in range(0, 3, 1):
            self.assertFalse(first_level_network._isExecuting)
            m.step()
            pre_con_sensor.update(True)
            rospy.sleep(0.1)

        self.assertTrue(first_level_network._isExecuting)

        for x in range(0, 4, 1):
            m.step()
            rospy.sleep(0.1)

        self.assertTrue(increaser_behavior._isExecuting)
Пример #9
0
 def setUpClass(cls):
     print("Needs a running roscore")
     super(GoalWrapperTest, cls).setUpClass()
     rospy.init_node("test_node")
     cls.manager = Manager(prefix="Test_manager")
     cls.sensor = TopicSensor(name="test_sensor",
                              topic="/sensor_topic",
                              message_type=Bool,
                              initial_value=False)
     cls.test_condition = Condition(cls.sensor, BooleanActivator())
     cls.comparison_goal = OfflineGoal(name="comparison_goal",
                                       planner_prefix="Test_manager")
     cls.manager_name = "Test_manager"
Пример #10
0
    def test_register_unregister(self):

        method_prefix = self.__message_prefix + "TestRegisterUnregisterGoal"
        planner_prefix = method_prefix + "Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)

        topic_name = method_prefix + '/Topic'

        sensor = TopicSensor(topic=topic_name,
                             message_type=Bool,
                             initial_value=False)
        condition = Condition(sensor, BooleanActivator())

        goal = GoalBase(method_prefix + 'Goal', planner_prefix=planner_prefix)
        goal.add_condition(condition)

        rospy.sleep(0.1)
        m.step()

        self.assertEquals(len(m.goals), 1, 'goal not registered properly')

        goal.unregister()

        rospy.sleep(0.1)
        m.step()

        self.assertEquals(len(m.goals), 0, 'goal not unregistered properly')

        # try to register again
        goal.register()

        rospy.sleep(0.1)
        m.step()

        self.assertEquals(len(m.goals), 1, 'goal not registered properly')

        goal.unregister(terminate_services=False)

        rospy.sleep(0.1)
        m.step()

        self.assertEquals(len(m.goals), 0, 'goal not unregistered properly')

        # try to register again
        goal.register()

        rospy.sleep(0.1)
        m.step()

        self.assertEquals(len(m.goals), 1, 'goal not registered properly')
Пример #11
0
 def setUp(self):
     rospy.init_node("TestNode")
     sensor = TopicSensor(name="test_sensor",
                          topic="sensor_topic",
                          message_type=Bool,
                          initial_value=False)
     self.conditions = [Condition(sensor, BooleanActivator())]
     self.manager_name = "Test_manager"
     self.manager = Manager(prefix=self.manager_name)
     self.goal_name = "test_goal"
     self.satisfaction_threshold = 1.0
     self.mockedDM = MockedDelegationCommunicator(
         manager_name=self.manager_name, name=self.manager_name)
     self.goal_repr = " ".join(
         [x.getPreconditionPDDL(1.0).statement for x in self.conditions])
Пример #12
0
    def test_attribute_access(self):
        """
        Test the access to individual attributes
        """

        #test default config accessing data attribute
        primitive_topic = '/primitive_topic'
        pub_primitive = rospy.Publisher(primitive_topic,
                                        Int32,
                                        queue_size=1,
                                        latch=True)

        #test access to particular attribute of a message
        complex_topic = '/complex_topic'
        pub_complex = rospy.Publisher(complex_topic,
                                      ColorRGBA,
                                      queue_size=1,
                                      latch=True)
        rospy.sleep(0.1)

        test_value = 1337

        pub_primitive.publish(test_value)
        pub_complex.publish(ColorRGBA(g=test_value))

        primitive_sensor = TopicSensor(topic=primitive_topic)

        complex_sensor = TopicSensor(topic=complex_topic, message_attr='g')

        rospy.sleep(0.1)

        primitive_sensor.sync()
        complex_sensor.sync()

        self.assertEquals(test_value, primitive_sensor.value,
                          "Primitive test value does not match")
        self.assertEquals(test_value, complex_sensor.value,
                          "Complex test value does not match")
Пример #13
0
    def test_interruptable_behaviour(self):
        """
        Test behaviour interruptable property
        """

        method_prefix = self.__message_prefix + "test_interruptable_behaviour"
        planner_prefix = method_prefix + "Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)

        topic_name_1 = method_prefix + '/sensor_1'
        non_interruptable_sensor = TopicSensor(topic=topic_name_1,
                                               message_type=Int32,
                                               initial_value=False)
        non_interruptable_condition = Condition(non_interruptable_sensor,
                                                GreedyActivator())
        non_interruptable_behaviour = IncreaserBehavior(
            effect_name=non_interruptable_sensor.name,
            topic_name=topic_name_1,
            name=method_prefix + "TopicIncreaser",
            planner_prefix=planner_prefix,
            interruptable=False)

        topic_name_2 = method_prefix + '/sensor_2'
        interruptable_sensor = TopicSensor(topic=topic_name_2,
                                           message_type=Int32,
                                           initial_value=False)
        interruptable_condition = Condition(interruptable_sensor,
                                            GreedyActivator())
        interruptable_behaviour = IncreaserBehavior(
            effect_name=interruptable_sensor.name,
            topic_name=topic_name_2,
            name=method_prefix + "TopicIncreaser2",
            planner_prefix=planner_prefix,
            interruptable=True)

        enable_sensor = Sensor(name='enable_sensor', initial_value=True)
        enable_cond = Condition(enable_sensor, BooleanActivator())
        non_interruptable_behaviour.add_precondition(enable_cond)

        goal = GoalBase(method_prefix + 'CentralGoal',
                        planner_prefix=planner_prefix,
                        permanent=True)
        goal.add_condition(non_interruptable_condition)
        goal.add_condition(interruptable_condition)

        # first normal operation: every behaviour runs as expected
        for x in range(0, 4, 1):
            m.step()
            rospy.sleep(0.1)

        self.assertTrue(non_interruptable_behaviour._isExecuting,
                        "Non-Interruptable Behaviour is not executed")
        self.assertTrue(interruptable_behaviour._isExecuting,
                        "Interruptable Behaviour is not executed")

        #disable non_interruptable_behaviour precondition and check if it is affected
        enable_sensor.update(False)
        for x in range(0, 1, 1):
            m.step()
            rospy.sleep(0.1)

        self.assertTrue(non_interruptable_behaviour._isExecuting,
                        "Non-Interruptable Behaviour is not executed")
        self.assertTrue(interruptable_behaviour._isExecuting,
                        "Interruptable Behaviour is not executed")

        #disable precondition of interruptable behaviour and check if it is disabled as well

        interruptable_behaviour.add_precondition(enable_cond)

        for x in range(0, 1, 1):
            m.step()
            rospy.sleep(0.1)

        self.assertTrue(non_interruptable_behaviour._isExecuting,
                        "Non-Interruptable Behaviour is not executed")
        self.assertFalse(interruptable_behaviour._isExecuting,
                         "Interruptable Behaviour is executed")
Пример #14
0
    def test_handle_interfering_correlations(self):
        """
        Test manager interference resolving capabilities
        """

        method_prefix = self.__message_prefix + "test_handle_interfering_correlations"
        planner_prefix = method_prefix + "Manager"
        m = Manager(activationThreshold=7.0, prefix=planner_prefix)

        topic_name_1 = method_prefix + '/sensor_1'
        sensor1 = TopicSensor(topic=topic_name_1,
                              message_type=Int32,
                              initial_value=False)
        condition1 = Condition(sensor1, GreedyActivator())
        behaviour1 = IncreaserBehavior(effect_name=sensor1.name,
                                       topic_name=topic_name_1,
                                       name=method_prefix + "TopicIncreaser",
                                       planner_prefix=planner_prefix,
                                       interruptable=True)

        topic_name_2 = method_prefix + '/sensor_2'
        sensor2 = TopicSensor(topic=topic_name_2,
                              message_type=Int32,
                              initial_value=False)
        condition2 = Condition(sensor2, GreedyActivator())
        behaviour2 = IncreaserBehavior(effect_name=sensor2.name,
                                       topic_name=topic_name_2,
                                       name=method_prefix + "TopicIncreaser2",
                                       planner_prefix=planner_prefix,
                                       interruptable=True)

        # add a conflict here "-1"
        behaviour1.add_effect(
            Effect(sensor_name=sensor2.name, indicator=-1, sensor_type=int))

        goal = GoalBase(method_prefix + 'CentralGoal',
                        planner_prefix=planner_prefix,
                        permanent=True)
        goal.add_condition(condition1)
        goal.add_condition(condition2)

        # first one of the behaviours can not be executed due to a conflict
        for x in range(0, 4, 1):
            m.step()
            rospy.sleep(0.1)
        # behaviour 2 should be executed because it does not conflict
        self.assertFalse(behaviour1._isExecuting,
                         "Behaviour 1 is executed in spite of a conflict")
        self.assertTrue(behaviour2._isExecuting, "Behaviour 2 is not executed")

        behaviour1.priority = 1  # increase priority

        for x in range(0, 1, 1):
            m.step()
            rospy.sleep(0.1)

        # now behaviour 1 should be executed
        self.assertTrue(
            behaviour1._isExecuting,
            "Behaviour 1 is not executed in spite of higher priority")
        self.assertFalse(behaviour2._isExecuting,
                         "Behaviour 2 is executed in spite of lower priority")

        behaviour1.priority = 0  # reset priority

        # Manipulate activation of behaviour 2 with an extra goal, wish is positively influencing
        goal2 = GoalBase(method_prefix + 'ExtraGoal',
                         planner_prefix=planner_prefix,
                         permanent=True)
        goal2.add_condition(
            condition2)  # this condition is targeted by behaviour 2

        rospy.sleep(0.1)

        for x in range(
                0, 5, 1
        ):  # it takes some time with configured decay factor to integrate the changed activation
            m.step()
            rospy.sleep(0.1)

        self.assertFalse(behaviour1._isExecuting, "Behaviour 1 is executed")
        self.assertTrue(behaviour2._isExecuting, "Behaviour 2 is not executed")
Пример #15
0
    def test_simple_sensor_aggregation(self):
        """
        Test an aggregation of simple topics with the AggregationSensor
        """

        primitive_topic_1 = '/primitive_topic1'
        pub_primitive_1 = rospy.Publisher(primitive_topic_1,
                                          Int32,
                                          queue_size=1,
                                          latch=True)
        primitive_topic_2 = '/primitive_topic2'
        pub_primitive_2 = rospy.Publisher(primitive_topic_2,
                                          Int32,
                                          queue_size=1,
                                          latch=True)

        rospy.sleep(0.1)

        test_value_1 = 3
        test_value_2 = 7

        pub_primitive_1.publish(test_value_1)
        pub_primitive_2.publish(test_value_2)

        primitive_sensor_1 = TopicSensor(topic=primitive_topic_1)
        primitive_sensor_2 = TopicSensor(topic=primitive_topic_2)

        # wait until the topic callbacks have been processed
        while primitive_sensor_1.latestValue is None or primitive_sensor_2.latestValue is None:
            rospy.sleep(0.1)

        def aggregation_function(sensor_values):
            return sum(sensor_values)

        aggregation_sensor = AggregationSensor(
            name="aggr",
            sensors=[primitive_sensor_1, primitive_sensor_2],
            func=aggregation_function)

        aggregation_sensor.sync()

        self.assertEquals(test_value_1 + test_value_2,
                          aggregation_sensor.value,
                          "Aggregation value does not match")

        # Testing alternative way of using the AggregationSensor with Inheritance

        aggregation_sensor = AggregationSensor(
            name="aggr",
            sensors=[primitive_sensor_1, primitive_sensor_2],
            func=None)

        self.assertRaises(NotImplementedError, aggregation_sensor.sync)

        class MyAggregationSensor(AggregationSensor):
            def __init__(self,
                         name,
                         sensors,
                         optional=False,
                         initial_value=None):
                super(MyAggregationSensor,
                      self).__init__(name=name,
                                     sensors=sensors,
                                     optional=optional,
                                     initial_value=initial_value)

            def _aggregate(self, sensor_values):
                return sum(sensor_values)

        aggregation_sensor = MyAggregationSensor(
            name="aggr", sensors=[primitive_sensor_1, primitive_sensor_2])

        aggregation_sensor.sync()

        self.assertEquals(test_value_1 + test_value_2,
                          aggregation_sensor.value,
                          "Aggregation value does not match")
Пример #16
0
    def test_multiple_embedded_network_behaviors(self):
        """
        Tests the case, that one network behavior is embedded into another network behavior.
        The goal requires to receive an int (3) in a topic.
        """

        method_prefix = self.__message_prefix + "/test_multiple_embedded_network_behaviors"

        topic_name = method_prefix + '/Topic'
        sensor = TopicSensor(topic=topic_name, message_type=Int32, initial_value=0)
        condition = Condition(sensor, ThresholdActivator(thresholdValue=3))

        planner_prefix = method_prefix + "/Manager"
        m = Manager(activationThreshold=7, prefix=planner_prefix)
        goal = OfflineGoal('CentralGoal', planner_prefix=planner_prefix)
        goal.add_condition(condition)
        m.add_goal(goal)

        effect = Effect(sensor_name=sensor.name, indicator=1, sensor_type=int, activator_name=condition.activator.name)

        first_level_network = NetworkBehaviour(name=method_prefix + '/FirstLevel', planner_prefix=planner_prefix, createLogFiles=True)
        first_level_network.add_effects_and_goals([(sensor, effect)])

        second_level_network = NetworkBehaviour(name=method_prefix + '/SecondLevel',
                                                planner_prefix=first_level_network.get_manager_prefix(), createLogFiles=True)
        # Doesnt matter, whether the effects are added via the constructor or the add method.
        # Both methods are used here, to demonstrate both ways.
        second_level_network.add_effects_and_goals([(sensor, effect)])

        increaser_behavior = IncreaserBehavior(effect_name=sensor.name, topic_name=topic_name,
                                                    name=method_prefix + "TopicIncreaser",
                                                    planner_prefix=second_level_network.get_manager_prefix())

        # activate the first_level_network, second_level_network and increaser_Behavior
        for x in range(0, 3, 1):
            self.assertFalse(first_level_network._isExecuting)
            m.step()
            rospy.sleep(0.1)
        self.assertTrue(first_level_network._isExecuting)

        for x in range(0, 3, 1):
            self.assertFalse(second_level_network._isExecuting)
            first_level_network.do_step()
            rospy.sleep(0.1)
        self.assertTrue(second_level_network._isExecuting)

        for x in range(0, 3, 1):
            self.assertFalse(increaser_behavior._isExecuting)
            second_level_network.do_step()
            rospy.sleep(0.1)
        self.assertTrue(increaser_behavior._isExecuting)

        # Satisfy goal
        for step in range(0, 3, 1):
            sensor.sync()
            self.assertEqual(step, sensor.value)
            second_level_network.do_step()
            rospy.sleep(0.1)

        goal.fetchStatus(3)
        self.assertTrue(goal.satisfied, 'Goal is not satisfied')