Example #1
0
    def connect(self):
        """
        Connect to the MAVLINK interface, either to own SITL process or to
        a specified external connection provided via the command line.

        Returns
        -------
        None.

        """
        try:
            self.vehicle = connect(self._connection_string, wait_ready=True,
                                   vehicle_class=DroneTreeVehicle)
        except socket.error as e:
            print(e)
            return
        self._bt = BehaviourTree(self._bt_func(self.vehicle))
        self._snapshot_visitor = SnapshotVisitor()
        self._bt.visitors.append(self._snapshot_visitor)
        self._bt.visitors.append(DebugVisitor())
Example #2
0
 def setUp(self):
     env = init_taxi_s(seed=1234)
     target = list(env.decode(env.s))
     print(target)
     goalspec = 'F P_[PI]['+str(4)+',none,==]'
     keys = ['L', 'PI', 'DI']
     actions = [0, 1, 2, 3, 4, 5]
     root = goalspec2BT(goalspec, planner=None)
     self.behaviour_tree = BehaviourTree(root)
     child = self.behaviour_tree.root
     planner = GenRecPropTaxi(
         env, keys, child.name, dict(), actions=actions,
         max_trace=5, seed=123)
     child.setup(0, planner, True, 5)
     # print(child.goalspec, child.planner.goalspec, child.planner.env)
     for i in range(5):
         self.behaviour_tree.tick(
             pre_tick_handler=reset_env_s(env)
         )
         print(i, self.behaviour_tree.root.status)
Example #3
0
    def __init__(self):
        super(BTAgent, self)

        global BLACKBOARD

        py_trees.logging.level = py_trees.logging.Level.DEBUG

        BLACKBOARD = Blackboard()
        self.tree = BehaviourTree(self.create_tree())
        _thread.start_new_thread(self.tree.tick_tock,
                                 (50, CONTINUOUS_TICK_TOCK, None, None))
Example #4
0
class TestTaxiFullActionsGoal(TestCase):

    def setUp(self):
        env = init_taxi(seed=1234)
        target = list(env.decode(env.s))
        print(target)
        goalspec = '((((F(P_[L]['+give_loc(target[2])+',none,==])) U (F(P_[PI]['+str(4)+',none,==]))) U (F(P_[L]['+give_loc(target[3])+',none,==]))) U (F(P_[PI]['+str(target[3])+',none,==])))'    # noqa: E501
        keys = ['L', 'PI', 'DI']
        actions = [0, 1, 2, 3, 4, 5]
        root = goalspec2BT(goalspec, planner=None)
        # print('root', root)
        self.behaviour_tree = BehaviourTree(root)
        epoch = [80, 50, 80, 50]
        j = 0
        for child in self.behaviour_tree.root.children:
            # print('children', child, child.name, child.id)
            planner = GenRecPropTaxi(
                env, keys, child.name, dict(), actions=actions,
                max_trace=40, seed=1)
            child.setup(0, planner, True, epoch[j])
            j += 1
        # Training
        for i in range(200):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(env)
            )
        print('Training', self.behaviour_tree.root.status)

        # Inference
        for child in self.behaviour_tree.root.children:
            child.train = False
            # print(child, child.name, child.train)

        for i in range(2):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(env)
            )
        print('inference', self.behaviour_tree.root.status)

    def test_full_actions(self):
        self.assertEqual(self.behaviour_tree.root.status, Status.SUCCESS)
Example #5
0
class TestMDPSequenceGoal(TestCase):

    def setUp(self):
        goalspec = 'F P_[NC][True,none,==] U F P_[L][03,none,==]'
        startpoc = (0, 3)
        self.env = init_mdp(startpoc)
        keys = ['L', 'NC']
        actions = [0, 1, 2, 3]
        planner = GenRecPropMDPNear(
            self.env, keys, goalspec, dict(),
            actions=actions, max_trace=10, seed=123)
        root = goalspec2BT(goalspec, planner=planner)
        self.behaviour_tree = BehaviourTree(root)

        for child in self.behaviour_tree.root.children:
            # print(child, child.name)
            child.setup(0, planner, True, 20)
            # child.planner.env = env
            # print(child.goalspec, child.planner.goalspec)

        for i in range(20):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(self.env)
            )

        for child in self.behaviour_tree.root.children:
            child.setup(0, planner, True, 10)
            child.train = False
            # print(child, child.name, child.train)

        for i in range(2):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(self.env)
            )
        # print('inference', behaviour_tree.root.status)

    def test_inference(self):
        self.assertEqual(self.behaviour_tree.root.status, Status.SUCCESS)

    def test_final_loc(self):
        self.assertEqual(self.env.curr_loc, (0, 3))
Example #6
0
    def setUp(self):
        env = init_taxi(seed=1234)
        target = list(env.decode(env.s))
        print(target)
        goalspec = 'F P_[L]['+give_loc(target[2])+',none,==] U F P_[PI]['+str(4)+',none,==]'    # noqa: E501
        keys = ['L', 'PI', 'DI']
        actions = [0, 1, 2, 3, 4, 5]

        root = goalspec2BT(goalspec, planner=None)
        self.behaviour_tree = BehaviourTree(root)
        epoch = [50, 10]
        j = 0
        for child in self.behaviour_tree.root.children:
            print('children', child, child.name, child.id)
            planner = GenRecPropTaxi(
                env, keys, child.name, dict(), actions=actions,
                max_trace=40, seed=123)
            child.setup(0, planner, True, epoch[j])
            j += 1
            # print(child.goalspec, child.planner.goalspec, child.planner.env)
        # print('rootname', behaviour_tree.root.name)
        # behaviour_tree.root.remove_child_by_id(id)
        # display_bt(behaviour_tree)
        for i in range(50):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(env)
            )
        print('Training', self.behaviour_tree.root.status)

        for child in self.behaviour_tree.root.children:
            # child.setup(0, planner, True, 20)
            child.train = False
            print(child, child.name, child.train)

        for i in range(2):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(env)
            )
        print('inference', self.behaviour_tree.root.status)
Example #7
0
def skeleton():
    main = Sequence('1')
    selec = Selector('2')
    goal1 = LTLNode('g1')
    goal2 = LTLNode('g2')
    p2 = CondNode(str(goal2.id), goal2)
    p1 = CondNode(str(goal1.id), goal1)
    selec.add_children([p2, goal1])
    seq = Sequence('3')
    seq.add_children([p1, goal2])
    main.add_children([seq, selec])
    root = BehaviourTree(main)
    return [root, p1, p2, goal1, goal2]
Example #8
0
class TestTaxiTrainingSimpleGoal(TestCase):

    def setUp(self):
        env = init_taxi(seed=1234)
        target = list(env.decode(env.s))
        goalspec = 'F(P_[L]['+give_loc(target[2])+',none,==])'
        keys = ['L', 'PI', 'DI']
        actions = [0, 1, 2, 3]
        root = goalspec2BT(goalspec, planner=None)
        self.behaviour_tree = BehaviourTree(root)
        child = self.behaviour_tree.root
        planner = GenRecPropTaxi(
            env, keys, None, dict(), actions=actions,
            max_trace=40, seed=1234)
        child.setup(0, planner, True, 50)
        print(child.goalspec, child.planner.goalspec, child.planner.env)
        for i in range(50):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(env)
            )

    def test_training(self):
        self.assertEqual(self.behaviour_tree.root.status, Status.SUCCESS)
Example #9
0
    def setup(self, timeout, agent, item):
        """Have defined the setup method.

        This method defines the other objects required for the
        behavior. Agent is the actor in the environment,
        item is the name of the item we are trying to find in the
        environment and timeout defines the execution time for the
        behavior.
        """
        self.agent = agent
        self.item = item

        dropseq = Sequence('CDP_Sequence')

        iscarrying = IsInPartialAttached('CDP_IsInPartial')
        iscarrying.setup(0, self.agent, self.item)

        drop = DropPartial('CDP_DropPartial')
        drop.setup(0, self.agent, self.item)

        dropseq.add_children([iscarrying, drop])

        self.behaviour_tree = BehaviourTree(dropseq)
Example #10
0
    def setup(self, timeout, agent, item=None):
        """Have defined the setup method.

        This method defines the other objects required for the
        behavior. Agent is the actor in the environment,
        item is the name of the item we are trying to find in the
        environment and timeout defines the execution time for the
        behavior.
        """
        self.agent = agent
        self.item = item

        # Define the root for the BT
        root = Sequence("Ex_Sequence")

        low = RandomWalk('Ex_RandomWalk')
        low.setup(0, self.agent)

        high = Move('Ex_Move')
        high.setup(0, self.agent)

        root.add_children([low, high])

        self.behaviour_tree = BehaviourTree(root)
Example #11
0
    def setup(self, timeout, agent, item=None):
        """Have defined the setup method.

        This method defines the other objects required for the
        behavior. Agent is the actor in the environment,
        item is the name of the item we are trying to find in the
        environment and timeout defines the execution time for the
        behavior.
        """
        self.agent = agent
        self.item = item

        # Define the root for the BT
        root = Sequence('CRS_Sequence')

        s1 = NeighbourObjects('CRS_NeighbourObjects')
        s1.setup(0, self.agent, 'Signal')

        s2 = ReceiveSignal('CRS_ReceiveSignal')
        s2.setup(0, self.agent, 'Signal')

        root.add_children([s1, s2])

        self.behaviour_tree = BehaviourTree(root)
Example #12
0
    def setup(self, timeout, agent, item=None):
        """Have defined the setup method.

        This method defines the other objects required for the
        behavior. Agent is the actor in the environment,
        item is the name of the item we are trying to find in the
        environment and timeout defines the execution time for the
        behavior.
        """
        self.agent = agent
        self.item = item

        # Define the root for the BT
        root = Sequence('CPC_Sequence')

        c1 = NeighbourObjects('CPS_SearchCue')
        c1.setup(0, self.agent, 'Cue')

        c2 = PickCue('CPS_PickCue')
        c2.setup(0, self.agent, 'Cue')

        root.add_children([c1, c2])

        self.behaviour_tree = BehaviourTree(root)
Example #13
0
class TestMDPTraining(TestCase):

    def setUp(self):
        goalspec = 'F P_[IC][True,none,==]'
        startpoc = (1, 3)
        env = init_mdp(startpoc)
        keys = ['L', 'IC']
        actions = [0, 1, 2, 3]
        root = goalspec2BT(goalspec, planner=None)
        self.behaviour_tree = BehaviourTree(root)
        # # Need to udpate the planner parameters
        child = self.behaviour_tree.root
        planner = GenRecPropMDP(
            env, keys, None, dict(), actions=actions, max_trace=10, seed=123)
        child.setup(0, planner, True, 10)

        for i in range(10):
            self.behaviour_tree.tick(
                pre_tick_handler=reset_env(env)
            )
            print(self.behaviour_tree.root.status)

    def test_training(self):
        self.assertEqual(self.behaviour_tree.root.status, Status.SUCCESS)
Example #14
0
def decompose():
    # goalspec = 'P_[KE][1,none,==] U P_[KA][1,none,==]'
    # goalspec = 'P_[KE][1,none,==] U P_[KA][1,none,==] U P_[KB][1,none,==]'
    # goalspec = 'P_[KA][1,none,==] U P_[KB][1,none,==] U P_[KC][1,none,==] U P_[KD][1,none,==], U P_[KE][1,none,==]'
    goalspec = '(F(P_[KE][1,none,==]) U G(P_[KA][1,none,==]))'
    # goalspec = '(P_[KA][1,none,==] & P_[KB][1,none,==]) U (P_[KC][1,none,==] & P_[KD][1,none,==])'
    # goalspec = '((P_[KA][1,none,==] U P_[KB][1,none,==]) & (P_[KC][1,none,==] U P_[KD][1,none,==])) & (P_[KE][1,none,==] & P_[KF][1,none,==])'
    root = goalspec2BT(goalspec, planner=None)
    # for i in root.iterate():
    #     print(i.id, i.name)
    behaviour_tree = BehaviourTree(root)
    # bt = UntilNode('U')
    py_trees.logging.level = py_trees.logging.Level.DEBUG
    output = py_trees.display.ascii_tree(behaviour_tree.root)
    print(output)
    recursive_until(root)
    output = py_trees.display.ascii_tree(behaviour_tree.root)
    print(output)
Example #15
0
def find_cheese(seed, max_trace_len=10, epoch=10):
    # Define the environment for the experiment
    goalspec = 'F P_[IC][True,none,==]'
    # startpoc = (3, 0)
    startpoc = (9, 0)
    env = init_10x10mdp(startpoc)
    keys = ['L', 'IC']
    actions = [0, 1, 2, 3]

    root = goalspec2BT(goalspec, planner=None)
    # print(root)
    behaviour_tree = BehaviourTree(root)
    # display_bt(behaviour_tree, True)
    # print(dir(behaviour_tree))
    # # Need to udpate the planner parameters
    child = behaviour_tree.root
    # for child in behaviour_tree.root.children:
    # print(child, child.name, env.curr_loc)
    planner = GenRecPropMDP(
        env, keys, None, dict(), actions=actions,
        max_trace=max_trace_len, epoch=epoch)
    child.setup(0, planner, True, epoch=epoch)
    # Experiment data
    # print(planner.trace_len_data)
    data = np.zeros(epoch, dtype=np.uint8)
    for i in range(epoch):
        behaviour_tree.tick(
            pre_tick_handler=reset_env(env)
        )
        # print(behaviour_tree.root.status)
        data[i] = check_bt_status(behaviour_tree.root.status)
    # print(planner.trace_len_data)
    # for child in behaviour_tree.root.children:
    child.setup(0, planner, True, max_trace_len)
    child.train = False
    # print(child, child.name, child.train)

    for i in range(1):
        behaviour_tree.tick(
            pre_tick_handler=reset_env(env)
        )
    # data[-1] = check_bt_status(behaviour_tree.root.status)
    # print('inference', behaviour_tree.root.status)
    # print(planner.trace_len_data)
    # print(data)
    # print(env.curr_loc)
    return (data, planner.trace_len_data)
Example #16
0
def keydoor2():
    env_name = 'MiniGrid-DoorKey-8x8-v0'
    env = gym.make(env_name)
    env.max_steps = min(env.max_steps, 200)
    env.seed(12345)
    env.reset()
    env = env_setup(env)

    state = (env.agent_pos, env.agent_dir)
    print(state)
    # Find the key and carry it
    goalspec = '(F(P_[K][1,none,==]) U F(P_[C][1,none,==])) U (F(P_[D][1,none,==]))'  # noqa: E501
    # goalspec = '(F(P_[K][1,none,==]) U F(P_[C][1,none,==]))'    # noqa: E501
    keys = ['L', 'F', 'K', 'D', 'C', 'G', 'O']
    actions = [[0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3]]

    root = goalspec2BT(goalspec, planner=None)
    behaviour_tree = BehaviourTree(root)
    # display_bt(behaviour_tree, save=True)
    epoch = [70, 40, 70]
    j = 0
    for child in behaviour_tree.root.children:
        planner = GenRecPropKeyDoor(env,
                                    keys,
                                    child.name,
                                    dict(),
                                    actions=actions[j],
                                    max_trace=40,
                                    seed=None)
        child.setup(0, planner, True, epoch[j])
        j += 1
        print(child.goalspec, child.planner.goalspec, type(child.planner.env))
    for i in range(150):
        behaviour_tree.tick(pre_tick_handler=reset_env(env))
        print(i, 'Training', behaviour_tree.root.status)

    # Inference
    for child in behaviour_tree.root.children:
        child.train = False

    for i in range(2):
        behaviour_tree.tick(pre_tick_handler=reset_env(env))
    print(i, 'Inference', behaviour_tree.root.status)
Example #17
0
def keydoor():
    env_name = 'MiniGrid-DoorKey-8x8-v0'
    env = gym.make(env_name)
    env.max_steps = min(env.max_steps, 200)
    env.seed(12345)
    env.reset()
    env = env_setup(env)

    state = (env.agent_pos, env.agent_dir)
    print(state)
    # Find the key
    goalspec = 'F P_[K][1,none,==]'
    keys = ['L', 'F', 'K', 'D', 'C', 'G', 'O']
    actions = [0, 1, 2, 3, 4, 5]

    root = goalspec2BT(goalspec, planner=None)
    behaviour_tree = BehaviourTree(root)
    child = behaviour_tree.root

    planner = GenRecPropKeyDoor(env,
                                keys,
                                child.name,
                                dict(),
                                actions=actions,
                                max_trace=40,
                                seed=None)

    child.setup(0, planner, True, 100)
    print(child.goalspec, child.planner.goalspec, type(child.planner.env))
    # Train
    for i in range(50):
        behaviour_tree.tick(pre_tick_handler=reset_env(env))
    print(i, 'Training', behaviour_tree.root.status)

    child.train = False

    # Inference
    for i in range(1):
        behaviour_tree.tick(pre_tick_handler=reset_env(env))
    print(i, 'Inference', behaviour_tree.root.status)
Example #18
0
class MultiGoalGridUExp():
    def __init__(
            self, expname='key', goalspecs='F P_[KE][1,none,==]',
            keys=['LO', 'FW', 'KE'], actions=list(range(5)),
            seed=None, maxtracelen=40, trainc=False, epoch=80):
        env_name = 'MiniGrid-Goals-v0'
        env = gym.make(env_name)
        if seed is None:
            pass
        else:
            env = ReseedWrapper(env, seeds=[seed])
        env = FullyObsWrapper(env)
        self.env = env
        self.env.max_steps = min(env.max_steps, maxtracelen-3)
        # self.env.agent_view_size = 1
        self.env.reset()
        #   self.env.render()
        # import time
        # time.sleep(10)
        self.expname = expname
        self.goalspecs = goalspecs
        self.epoch = epoch
        self.maxtracelen = maxtracelen
        self.trainc = trainc
        self.allkeys = [
            'LO', 'FW', 'KE', 'DR',
            'BOB', 'BOR', 'BAB', 'BAR',
            'LV', 'GO', 'CK',
            'CBB', 'CBR', 'CAB', 'CAR',
            'DO', 'RM']
        self.keys = keys
        self.actions = actions
        root = goalspec2BT(goalspecs, planner=None, node=CompetentNode)
        self.behaviour_tree = BehaviourTree(root)
        self.blackboard = Blackboard()

    def run(self):
        def fn_c(child):
            pass

        def fn_eset(child):
            planner = GenRecPropMultiGoalU(
                self.env, self.keys, child.name, dict(), actions=self.actions,
                max_trace=self.maxtracelen, epoch=self.epoch,
                seed=None, allkeys=self.allkeys, id=child.nodename)

            child.setup(0, planner, True, self.epoch)

        def fn_einf(child):
            child.train = False
            child.planner.epoch = 5
            child.planner.tcount = 0
            # child.planner.verbose = True

        def fn_ecomp(child):
            child.planner.compute_competency(self.trainc)

        def parallel_hack(node):
            if (isinstance(node, Parallel)):
                return node
            elif node.children:
                for c in node.children:
                    if (isinstance(c, Parallel)):
                        # Control nodes
                        return c
                    parallel_hack(c)

        # Save the environment to visualize
        # self.save_data(env=True)

        # Setup planners
        recursive_setup(self.behaviour_tree.root, fn_eset, fn_c)
        # py_trees.logging.level = py_trees.logging.Level.DEBUG
        # py_trees.display.print_ascii_tree(self.behaviour_tree.root)

        # Parallel node hack
        def for_parallel_node(root):
            node = parallel_hack(root)
            if node:
                combgoal = [node.name for node in node.children]
                othernodes = []
                for i in range(len(node.children)):
                    if i == 0:
                        node.children[i].planner.list_goalspec = combgoal
                        node.children[i].planner.parallel_node = True
                    else:
                        othernodes.append(node.children[i])
                        node.remove_child(node.children[i])
                return node, othernodes
            else:
                return None, None
        pnode, othernodes = for_parallel_node(self.behaviour_tree.root)

        # combgoal = ['F(P_[KE][1,none,==])', 'G(P_[LV][0,none,==])']
        # self.behaviour_tree.root.planner.list_goalspec = combgoal
        # self.behaviour_tree.root.planner.parallel_node = True

        self.blackboard.shared_content['current'] = dict()
        for i in range(self.epoch):
            self.env.reset()
            self.blackboard.shared_content['current']['epoch'] = i
            for j in range(self.maxtracelen):
                self.behaviour_tree.tick(
                    # pre_tick_handler=self.reset_env()
                )
                # print(j, self.behaviour_tree.root.planner.gtable.keys())
                if self.behaviour_tree.root.status == Status.SUCCESS:
                    break
                if self.blackboard.shared_content['current']['done']:
                    break
            # print(i, 'Training', self.behaviour_tree.root.status)

        # Inference
        recursive_setup(self.behaviour_tree.root, fn_einf, fn_c)
        for i in range(self.epoch):
            self.env.reset()
            self.blackboard.shared_content['current']['epoch'] = i
            for j in range(self.maxtracelen):
                self.behaviour_tree.tick(
                    # pre_tick_handler=self.reset_env(self.env)
                )
                if self.behaviour_tree.root.status == Status.SUCCESS:
                    break
                if self.blackboard.shared_content['current']['done']:
                    break
            # print(i, 'Inference', self.behaviour_tree.root.status)
        # Recursive compute competency for execution nodes
        # print(self.behaviour_tree.root.children[0].planner.idata[0])
        # print(self.behaviour_tree.root.children[0].planner.tdata[0])
        recursive_setup(self.behaviour_tree.root, fn_ecomp, fn_c)
        self.trainc = not self.trainc
        # Recursive compute competency for execution nodes
        recursive_setup(self.behaviour_tree.root, fn_ecomp, fn_c)

        print(self.blackboard.shared_content['curve'])
        # Recursive compute competency for control nodes
        recursive_com(self.behaviour_tree.root, self.blackboard)

    def reset_env(self):
        self.env.reset()

    def check_env_done(self):

        self.reset_env()

    def save_data(self, env=False):
        # Create folder if not exists
        import pathlib
        import os
        dname = os.path.join('/tmp', 'pygoal', 'data', 'experiments')
        pathlib.Path(dname).mkdir(parents=True, exist_ok=True)
        if env:
            fname = os.path.join(dname, self.expname + '_env.png')
            img = self.env.render(mode='exp')
            plt.imsave(fname, img)
        else:
            fname = os.path.join(dname, self.expname + '.pkl')
            import pickle
            pickle.dump(self.blackboard, open(fname, "wb"))

    def draw_plot(self, nodenames, root=False, train=True):
        curves = []
        datas = []
        for nname in nodenames:
            if train:
                datas.append(np.mean(
                    self.blackboard.shared_content[
                        'ctdata'][nname], axis=0))
            else:
                datas.append(np.mean(
                    self.blackboard.shared_content[
                        'cidata'][nname], axis=0))
            curves.append(
                self.blackboard.shared_content['curve'][nname][str(train)])
        compare_curve(curves, datas, name=self.expname+str(train), root=root)
Example #19
0
def test_pf():
    r = ConditionNode('root', None)
    r = BehaviourTree(r)
    r.tick()
    print(r.root.status)
Example #20
0
def find_bt(goalspec):
    root = goalspec2BT(goalspec, planner=None)
    behaviour_tree = BehaviourTree(root)
    # display_bt(behaviour_tree, True)
    return behaviour_tree
Example #21
0
class ControlAutomaton:
    """
    Top-level app class providing functionality for running and testing
    behaviour trees for drone control via MAVLINK.  Includes:
        - optional SITL simulation
        - optional visualisation of behaviour tree
        - connection to MAVLINK
    """
    def __init__(self, bt_func, sitl_lat=51.454531, sitl_lon=-2.629158):
        """
        Construct an app embodying a given behaviour tree.

        Parameters
        ----------
        bt_func : function
            Should take a dronekit.Vehicle as an argument and return the root
            node of a behaviour tree, as a py_trees.behaviour.Behaviour object.
            Typically built using nodes from leaf_nodes and stitched together
            using py_trees.composites and py_trees.decorators or using the
            flight_idioms.

        sitl_lat : float, optional
            Latitude for home location if app launched in SITL mode.
            The default is 51.454531.
        sitl_lon : float, optional
            Longitude for home location if app launched in SITL mode.
            The default is -2.629158.

        Returns
        -------
        The ControlAutomaton

        """
        super(ControlAutomaton, self).__init__()
        self._bt_func = bt_func
        self._bt = None
        self._snapshot_visitor = None
        self._app_name = "App name"
        self._sitl = None
        self._sitl_lat = sitl_lat
        self._sitl_lon = sitl_lon
        self._connection_string = None
        self.vehicle = None
        self._loop_should_exit = False
        self._max_ticks = 1000

    def __del__(self):
        self.cleanup()

    def startup(self, override_args=None):
        """
        Interpret command line arguments, render the tree (if --render)
        and connect to the vehicle if necessary (i.e. not in render mode)

        Parameters:

            override_args : list of str
                override command line arguments from function call
                e.g. for use in testing (see test_bridge.py)

        """
        self._app_name = sys.argv[0]
        if override_args:
            my_args = [self._app_name]
            my_args = my_args + override_args
        else:
            my_args = sys.argv[:]

        if len(my_args) != 2:
            print("""Usage:

  {0} sitl
    run with built-in SITL simulator
  {0} render
    just render the behaviour tree
  {0} <connection string>
    connect as prescribed and fly the mission""".format((self._app_name)))
        elif my_args[1] == 'sitl':
            self._sitl = dronekit_sitl.start_default(lat=self._sitl_lat,
                                                     lon=self._sitl_lon)
            self._connection_string = self._sitl.connection_string()
            print("Using SITL via {}".format(self._connection_string))
            self.connect()
        elif my_args[1] == 'render':
            print("Rendering only")
            self.render()
        else:
            self._connection_string = my_args[1]
            print(f"Attempting to connect via {self._connection_string}")
            self.connect()

    def render(self, file_name=None):
        """
        Print the behaviour tree graphically for visualization.  Produces
        a .dot file (Graphviz), a .png and a .svg (images)

        Parameters
        ----------
        file_name : str, optional
            File name stub for graphics files produced.
            The default is the name of the executed script.

        Returns
        -------
        None.

        """
        if file_name is None:
            file_name = self._app_name
        render_dot_tree(self._bt_func(self.vehicle), name=file_name)

    def connect(self):
        """
        Connect to the MAVLINK interface, either to own SITL process or to
        a specified external connection provided via the command line.

        Returns
        -------
        None.

        """
        try:
            self.vehicle = connect(self._connection_string, wait_ready=True,
                                   vehicle_class=DroneTreeVehicle)
        except socket.error as e:
            print(e)
            return
        self._bt = BehaviourTree(self._bt_func(self.vehicle))
        self._snapshot_visitor = SnapshotVisitor()
        self._bt.visitors.append(self._snapshot_visitor)
        self._bt.visitors.append(DebugVisitor())

    def finished(self):
        """
        Check if behaviour tree has completed.

        Returns
        -------
        bool
            True if root node has status 'SUCCESS' or 'FAILURE'

        """
        if self._bt.root.status == Status.SUCCESS:
            return True
        if self._bt.root.status == Status.FAILURE:
            return True
        return False

    def tick(self):
        """
        Execute one tick of the behaviour tree, printing the tree in ASCII
        form, plus some simple status information.

        Returns
        -------
        None.

        """
        print("******** {} *********".format(self._bt.count))
        self._bt.tick()
        # print BT
        if self._snapshot_visitor:
            print(unicode_tree(self._bt.root,
                               visited=self._snapshot_visitor.visited,
                               previously_visited=self._snapshot_visitor.visited))
            print("+++++++++++++++++++++")
        print(self.vehicle.battery)
        if self.vehicle.armed:
            arm_status = 'ARMED'
        else:
            arm_status = 'DISARMED'
        print(f'Mode: {self.vehicle.mode.name} {arm_status}')
        print(f'Altitude: {self.vehicle.location.global_relative_frame.alt}')
        print(f'Connected to {self._connection_string}')
        print(f'Next waypoint is {self.vehicle.commands.next}')
        # exit after timeout or completion
        if self.finished():
            print("**** Flight completed in {} steps".format(self._bt.count))
            self._loop_should_exit = True
        if self._bt.count > self._max_ticks:
            print("**** Exiting after {} steps".format(self._bt.count))
            self._loop_should_exit = True
        else:
            print("******** {} *********".format(self._bt.count-1))

    def cleanup(self):
        """
        Close connection to the MAVLINK stream and, if a SITL simulator was
        launched, kill its process.  Use at end of each test, pass or fail.

        Returns
        -------
        None.

        """
        if self.vehicle:
            print(f"Disconnecting from vehicle on {self._connection_string}")
            self.vehicle.close()
        if self._sitl:
            print("Shutting down SITL instance")
            self._sitl.stop()

    def main(self):
        """
        Execute the controller application.  Process arguments, connect,
        run tree until completion or timeout, and tidy up.

        NOTE: exit due to keyboard interrupt is trapped and cleanup() called.
        Other exceptions may leave hanging threads, connections or SITL
        processes.  Cleanup is called in destructor to minimize damage.

        Returns
        -------
        None.

        """
        self.startup()
        if self.vehicle:
            try:
                while not self._loop_should_exit:
                    self.tick()
                    time.sleep(1)
            except KeyboardInterrupt:
                self.cleanup()
            self.cleanup()
Example #22
0
def test_comptency():
    # import py_trees
    # behaviour_tree = BehaviourTree(root)
    # # Remember to comment set_state in GenRecProp before
    # # running this test case
    one = BehaviourTree(Sequence(name=str(1)))
    two = Sequence(name=str(2))
    three = Sequence(name=str(3))
    four = Selector(name=str(4))
    five = Sequence(name=str(5))
    six = Sequence(name=str(6))
    # seven = Parallel(name=str(7))
    seven = Selector(name=str(7))
    exenodes = [
        CompetentNode(name=chr(ord('A') + i), planner=None)
        for i in range(0, 11)
    ]
    three.add_children(exenodes[:3])
    four.add_children(exenodes[3:6])
    six.add_children(exenodes[6:9])
    seven.add_children(exenodes[9:])
    two.add_children([three, four])
    five.add_children([six, seven])
    one.root.add_children([two, five])
    # py_trees.logging.level = py_trees.logging.Level.DEBUG
    # py_trees.display.print_ascii_tree(one.root)
    blackboard = Blackboard()
    env_name = 'MiniGrid-Goals-v0'
    env = gym.make(env_name)
    env = ReseedWrapper(env, seeds=[3])
    env = FullyObsWrapper(env)
    env.max_steps = min(env.max_steps, 200)
    env.agent_view_size = 1
    env.reset()
    # env.render(mode='human')
    state, reward, done, _ = env.step(2)
    # print(state['image'].shape, reward, done, _)
    # Find the key
    goalspec = 'F P_[KE][1,none,==]'
    # keys = ['L', 'F', 'K', 'D', 'C', 'G', 'O']
    allkeys = [
        'LO', 'FW', 'KE', 'DR', 'BOB', 'BOR', 'BAB', 'BAR', 'LV', 'GO', 'CK',
        'CBB', 'CBR', 'CAB', 'CAR', 'DO', 'RM'
    ]

    keys = ['LO', 'FW', 'KE']

    actions = [0, 1, 2, 3, 4, 5]

    def fn_c(child):
        pass

    def fn_eset(child):
        planner = GenRecPropMultiGoal(env,
                                      keys,
                                      goalspec,
                                      dict(),
                                      actions=actions,
                                      max_trace=40,
                                      seed=None,
                                      allkeys=allkeys,
                                      id=child.name)

        child.setup(0, planner, True, 50)

    def fn_einf(child):
        child.train = False
        child.planner.epoch = 5
        child.planner.tcount = 0

    def fn_ecomp(child):
        child.planner.compute_competency()
        print(child.name,
              child.planner.blackboard.shared_content['curve'][child.name])

    recursive_setup(one.root, fn_eset, fn_c)
    # Train
    for i in range(100):
        one.tick(pre_tick_handler=reset_env(env))
    print(i, 'Training', one.root.status)

    # Inference
    recursive_setup(one.root, fn_einf, fn_c)
    for i in range(5):
        one.tick(pre_tick_handler=reset_env(env))
    print(i, 'Inference', one.root.status)
    recursive_setup(one.root, fn_ecomp, fn_c)

    # Manually setting the competency
    ckeys = [chr(ord('A') + i) for i in range(0, 11)]
    manval = [
        np.array([0.84805786, 4.76735384, 0.20430223]),
        np.array([0.54378425, 4.26958399, 3.50727315]),
        np.array([0.50952059, 5.54225945, 5.28025611])
    ]
    j = 0
    for c in ckeys:
        blackboard.shared_content['curve'][c] = manval[j % 3]
        j += 1
    # Recursively compute competency for control nodes
    recursive_com(one.root, blackboard)
    # print(exenodes[0].planner.blackboard.shared_content['curve'])

    # Manually compare the recursively computed competency values
    # for the control
    # First sub-tree
    a = exenodes[0].planner.blackboard.shared_content['curve']['A']
    b = exenodes[0].planner.blackboard.shared_content['curve']['B']
    c = exenodes[0].planner.blackboard.shared_content['curve']['C']
    threec = sequence([a, b, c])
    # print('three', threec)
    # print(
    # 'three', exenodes[0].planner.blackboard.shared_content['curve']['3'])
    assert threec == exenodes[0].planner.blackboard.shared_content['curve'][
        '3']
    # Second sub-tree
    d = exenodes[0].planner.blackboard.shared_content['curve']['D']
    e = exenodes[0].planner.blackboard.shared_content['curve']['E']
    f = exenodes[0].planner.blackboard.shared_content['curve']['F']
    fourc = selector([d, e, f])
    # print(
    # 'four', exenodes[0].planner.blackboard.shared_content['curve']['4'])
    assert fourc == exenodes[0].planner.blackboard.shared_content['curve']['4']
    # Third sub-tree
    g = exenodes[0].planner.blackboard.shared_content['curve']['G']
    h = exenodes[0].planner.blackboard.shared_content['curve']['H']
    i = exenodes[0].planner.blackboard.shared_content['curve']['I']
    sixc = sequence([g, h, i])
    # print(
    # 'six', exenodes[0].planner.blackboard.shared_content['curve']['6'])
    assert sixc == exenodes[0].planner.blackboard.shared_content['curve']['6']
    # Fourth sub-tree
    j = exenodes[0].planner.blackboard.shared_content['curve']['J']
    k = exenodes[0].planner.blackboard.shared_content['curve']['K']
    sevenc = selector([j, k])
    # print(
    # 'seven', exenodes[0].planner.blackboard.shared_content['curve']['7'])
    assert sevenc == exenodes[0].planner.blackboard.shared_content['curve'][
        '7']

    twoc = sequence([threec, fourc])
    assert twoc == exenodes[0].planner.blackboard.shared_content['curve']['2']

    fivec = sequence([sixc, sevenc])
    assert fivec == exenodes[0].planner.blackboard.shared_content['curve']['5']

    onec = sequence([twoc, fivec])
    assert onec == exenodes[0].planner.blackboard.shared_content['curve']['1']

    print(onec)
Example #23
0
def find_key():
    env_name = 'MiniGrid-Goals-v0'
    env = gym.make(env_name)
    # env = ReseedWrapper(env, seeds=[3])   # Easy
    env = ReseedWrapper(env, seeds=[5])  # Medium
    # env = ReseedWrapper(env, seeds=[7])     # Hard
    env = FullyObsWrapper(env)
    env.max_steps = min(env.max_steps, 200)
    env.agent_view_size = 1
    env.reset()
    # env.render(mode='human')
    # time.sleep(10)
    # state, reward, done, _ = env.step(2)
    # print(state['image'].shape, reward, done, _)
    # Find the key
    goalspec = 'F P_[KE][1,none,==]'
    # keys = ['L', 'F', 'K', 'D', 'C', 'G', 'O']
    allkeys = [
        'LO', 'FW', 'KE', 'DR', 'BOB', 'BOR', 'BAB', 'BAR', 'LV', 'GO', 'CK',
        'CBB', 'CBR', 'CAB', 'CAR', 'DO', 'RM'
    ]

    keys = ['LO', 'FW', 'KE']

    actions = [0, 1, 2]

    root = goalspec2BT(goalspec, planner=None, node=CompetentNode)
    behaviour_tree = BehaviourTree(root)
    child = behaviour_tree.root

    planner = GenRecPropMultiGoal(env,
                                  keys,
                                  child.name,
                                  dict(),
                                  actions=actions,
                                  max_trace=50,
                                  seed=None,
                                  allkeys=allkeys)

    def run(pepoch=50, iepoch=10):
        # pepoch = 50
        child.setup(0, planner, True, pepoch)
        # Train
        for i in range(pepoch):
            behaviour_tree.tick(pre_tick_handler=reset_env(env))
        # Inference
        child.train = False
        child.planner.epoch = iepoch
        child.planner.tcount = 0
        for i in range(iepoch):
            behaviour_tree.tick(pre_tick_handler=reset_env(env))

    competency = []
    epochs = [(80, 10)] * 2
    datas = []
    for i in range(2):
        run(epochs[i][0], epochs[i][1])
        datas.append(
            np.mean(
                planner.blackboard.shared_content['ctdata'][planner.goalspec],
                axis=0))
        competency.append(planner.compute_competency())
    print(competency)
    compare_curve(competency, datas)
Example #24
0
def carry_key():
    env_name = 'MiniGrid-Goals-v0'
    env = gym.make(env_name)
    env = ReseedWrapper(env, seeds=[3])
    env = FullyObsWrapper(env)
    env.max_steps = min(env.max_steps, 200)
    env.agent_view_size = 1
    env.reset()
    # env.render(mode='human')
    state, reward, done, _ = env.step(2)

    # Find the key
    goalspec = 'F P_[KE][1,none,==] U F P_[CK][1,none,==]'
    allkeys = [
        'LO', 'FW', 'KE', 'DR', 'BOB', 'BOR', 'BAB', 'BAR', 'LV', 'GO', 'CK',
        'CBB', 'CBR', 'CAB', 'CAR', 'DO', 'RM'
    ]

    keys = ['LO', 'FW', 'KE', 'CK']

    actions = [0, 1, 2, 3, 4, 5]

    root = goalspec2BT(goalspec, planner=None, node=CompetentNode)
    behaviour_tree = BehaviourTree(root)
    epoch = 80

    def fn_c(child):
        pass

    def fn_eset(child):
        planner = GenRecPropMultiGoal(env,
                                      keys,
                                      child.name,
                                      dict(),
                                      actions=actions,
                                      max_trace=40,
                                      seed=None,
                                      allkeys=allkeys)

        child.setup(0, planner, True, epoch)

    def fn_einf(child):
        child.train = False
        child.planner.epoch = 5
        child.planner.tcount = 0

    def fn_ecomp(child):
        child.planner.compute_competency()

    recursive_setup(behaviour_tree.root, fn_eset, fn_c)
    # recursive_setup(behaviour_tree.root, fn_c, fn_c)
    # py_trees.logging.level = py_trees.logging.Level.DEBUG
    # py_trees.display.print_ascii_tree(behaviour_tree.root)

    # Train
    for i in range(100):
        behaviour_tree.tick(pre_tick_handler=reset_env(env))
    print(i, 'Training', behaviour_tree.root.status)

    # Inference
    recursive_setup(behaviour_tree.root, fn_einf, fn_c)
    for i in range(5):
        behaviour_tree.tick(pre_tick_handler=reset_env(env))
    print(i, 'Inference', behaviour_tree.root.status)
    recursive_setup(behaviour_tree.root, fn_ecomp, fn_c)
    # recursive_setup(behaviour_tree.root, fn_c, fn_c)
    blackboard = Blackboard()
    print(recursive_com(behaviour_tree.root, blackboard))
Example #25
0
class MultiGoalGridExp():
    def __init__(
            self, expname='key', goalspecs='F P_[KE][1,none,==]',
            keys=['LO', 'FW', 'KE'], actions=list(range(5)),
            seed=None, maxtracelen=40, trainc=False, epoch=80):
        env_name = 'MiniGrid-Goals-v0'
        env = gym.make(env_name)
        if seed is None:
            pass
        else:
            env = ReseedWrapper(env, seeds=[seed])
        env = FullyObsWrapper(env)
        self.env = env
        self.env.max_steps = min(env.max_steps, 200)
        # self.env.agent_view_size = 1
        self.env.reset()
        self.expname = expname
        self.goalspecs = goalspecs
        self.epoch = epoch
        self.maxtracelen = maxtracelen
        self.trainc = trainc
        self.allkeys = [
            'LO', 'FW', 'KE', 'DR',
            'BOB', 'BOR', 'BAB', 'BAR',
            'LV', 'GO', 'CK',
            'CBB', 'CBR', 'CAB', 'CAR',
            'DO', 'RM']
        self.keys = keys
        self.actions = actions
        root = goalspec2BT(goalspecs, planner=None, node=CompetentNode)
        self.behaviour_tree = BehaviourTree(root)
        self.blackboard = Blackboard()

    def run(self):
        def fn_c(child):
            pass

        def fn_eset(child):
            planner = GenRecPropMultiGoal(
                self.env, self.keys, child.name, dict(), actions=self.actions,
                max_trace=self.maxtracelen, seed=None, allkeys=self.allkeys)

            child.setup(0, planner, True, self.epoch)

        def fn_einf(child):
            child.train = False
            child.planner.epoch = 5
            child.planner.tcount = 0

        def fn_ecomp(child):
            child.planner.compute_competency(self.trainc)

        # Save the environment to visualize
        # self.save_data(env=True)

        # Setup planners
        recursive_setup(self.behaviour_tree.root, fn_eset, fn_c)
        # import py_trees
        # py_trees.logging.level = py_trees.logging.Level.DEBUG
        # py_trees.display.print_ascii_tree(self.behaviour_tree.root)
        # exit()
        # print(dir(self.behaviour_tree.root.children[0]))
        # print(self.behaviour_tree.root.children[0].parent.children)
        # Train
        for i in range(150):
            self.behaviour_tree.tick(
                pre_tick_handler=self.reset_env(self.env)
            )
        # print(i, 'Training', self.behaviour_tree.root.status)

        # Inference
        recursive_setup(self.behaviour_tree.root, fn_einf, fn_c)
        for i in range(10):
            self.behaviour_tree.tick(
                pre_tick_handler=self.reset_env(self.env)
            )
        # print(i, 'Inference', self.behaviour_tree.root.status)
        # Recursive compute competency for execution nodes
        recursive_setup(self.behaviour_tree.root, fn_ecomp, fn_c)

        # Recursive compute competency for control nodes
        recursive_com(self.behaviour_tree.root, self.blackboard)

    def reset_env(self, seed=12345):
        self.env.reset()

    def save_data(self, env=False):
        # Create folder if not exists
        import pathlib
        import os
        dname = os.path.join('/tmp', 'pygoal', 'data', 'experiments')
        pathlib.Path(dname).mkdir(parents=True, exist_ok=True)
        if env:
            fname = os.path.join(dname, self.expname + '_env.png')
            img = self.env.render(mode='exp')
            plt.imsave(fname, img)
        else:
            fname = os.path.join(dname, self.expname + '.pkl')
            import pickle
            pickle.dump(self.blackboard, open(fname, "wb"))

    def draw_plot(self, nodenames, root=False, train=True):
        curves = []
        datas = []
        for nname in nodenames:
            if train:
                datas.append(np.mean(
                    self.blackboard.shared_content[
                        'ctdata'][nname], axis=0))
            else:
                datas.append(np.mean(
                    self.blackboard.shared_content[
                        'cidata'][nname], axis=0))
            curves.append(self.blackboard.shared_content['curve'][nname])
        compare_curve(curves, datas, name=self.expname, root=root)
Example #26
0
class CompositeMultipleCarry(Behaviour):
    """CompositeMultipleCarry behavior for the agents.

    Inherits the Behaviors class from py_trees. This
    behavior combines the privitive behaviors to succesfully carry any heavy
    carryable object. It combines IsCarrable, IsMultipleCarry
    and InitiateMultipleCarry primitive behaviors.
    """
    def __init__(self, name):
        """Init method for the CompositeSingleCarry behavior."""
        super(CompositeMultipleCarry, self).__init__(name)
        self.blackboard = Blackboard()
        self.blackboard.shared_content = dict()

    def setup(self, timeout, agent, item):
        """Have defined the setup method.

        This method defines the other objects required for the
        behavior. Agent is the actor in the environment,
        item is the name of the item we are trying to find in the
        environment and timeout defines the execution time for the
        behavior.
        """
        self.agent = agent
        self.item = item

        # Root node from the multiple carry behavior tree
        root = Sequence("MC_Sequence")

        # Conditional behavior to check if the sensed object is carrable or not
        carryable = IsCarryable('MC_IsCarryable')
        carryable.setup(0, self.agent, self.item)

        # Conditional behavior to check if the object is too heavy
        # for single carry
        is_mc = IsMultipleCarry('MC_IsMultipleCarry')
        is_mc.setup(0, self.agent, self.item)

        # Check if the object is alread attached to the object
        partial_attached = IsInPartialAttached('MC_IsPartialAttached')
        partial_attached.setup(0, self.agent, self.item)

        # Initiate multiple carry process
        initiate_mc_b = InitiateMultipleCarry('MC_InitiateMultipleCarry')
        initiate_mc_b.setup(0, self.agent, self.item)

        # Selector to select between intiate
        # multiple carry and checking strength
        initial_mc_sel = Selector("MC_Selector")
        initial_mc_sel.add_children([partial_attached, initiate_mc_b])

        strength = IsEnoughStrengthToCarry('MC_EnoughStrength')
        strength.setup(0, self.agent, self.item)

        strength_seq = Sequence("MC_StrenghtSeq")

        strength_seq.add_children([strength])

        # Main sequence branch where all the multiple carry logic takes place
        sequence_branch = Sequence("MC_Sequence_branch")
        sequence_branch.add_children([is_mc, initial_mc_sel, strength_seq])

        # Main logic behind this composite multiple carry BT
        """
        First check if the object is carryable or not. If the object is
        carryable then execute the sequence branch. In the sequence branch,
        check is the object needs multiple agents to carry. If yes, execute
        the initiate multiple carry sequence branch only if it has not been
        attached before. Finally, check if there are enought agents/strenght
        to lift the object up.
        """
        root.add_children([carryable, sequence_branch])
        self.behaviour_tree = BehaviourTree(root)

    def initialise(self):
        """Everytime initialization. Not required for now."""
        pass

    def update(self):
        """Just call the tick method for the sequence.

        This will execute the primitive behaviors defined in the sequence
        """
        self.behaviour_tree.tick()
        return self.behaviour_tree.root.status