Example #1
0
def buildMotion():
    # get the motions from the list
    motion_list = Motions()

    # create a Motion class for every motion in the list
    for M in motion_list:
        newMotion = FOON.Motion(M.motionId, M.objectId, M.motionOrder, M.startSurface, M.endSurface)
        newMotion.setMotionStartPose(M.startPose)
        newMotion.setMotionEndPose(M.endPose)
        # TODO: that can be done dynamically (using sort algorithm for the list)
        if M.motionId == "sort augustiner":
            if M.motionId not in functionalUnitsNames:
                functionalUnitsNames.append(M.motionId)
            
            motion_to_FU1.append(newMotion)
        if M.motionId == "sort rothaus":
            if M.motionId not in functionalUnitsNames:
                functionalUnitsNames.append(M.motionId)
            motion_to_FU2.append(newMotion)
    #endfor

    # save all motion nodes. 
    motions_FU.append(motion_to_FU1)
    motions_FU.append(motion_to_FU2)
    print("################# all motion nodes in the FOON ################################")
    print(motions_FU)
Example #2
0
def FOON_tree():

    # build the treeNode with end goal
    newTree = FOON.TreeNode("sort beer")
    functionalunitList = buildFunctionalUnit()
    newTree.setTreeFunctionalUnits(functionalunitList)
    newTree.setMergePoint("search for the next FU")
    print(newTree)

    return newTree
Example #3
0
def buildObjects():

    # get objects from the list
    objects_list = Objects()

    # NOTE: fixed objects which are the support surfaces like tables
    fixed_objects = []
    # NOTE: all objects in the sorrunding environment
    objects_info = []
    
    # create object calss for every object in the list
    for obj in objects_list:
       

        newObject = FOON.Object( obj.id, obj.name)
        newObject.setObjectLocation(obj.pose)
        newObject.setObjectSize(obj.size)
        newObject.setStatesList(obj.state)
        newObject.setOrder(obj.order)
        for neighbour in obj.neighbour:
            if len(obj.neighbour):
                newObject.addNeighbours( neighbour)
        if obj.state[0] == "fixed":
            fixed_objects.append(newObject)
        # TODO: that can be done dynamically (using sort algorithm for the list)
        if obj.order == "sort augustiner":
            nodes_FU1.append(newObject)
        if obj.order == "sort rothaus":
            nodes_FU2.append(newObject)

        objects_info.append(newObject)
        
    
    #endfor
    input_nodes_FU.append(nodes_FU1)
    input_nodes_FU.append(nodes_FU2)
    # start build motion classes after finish the object classes.
    buildMotion()

    print("+++++++++++++++++ input nodes +++++++++++++++++++++++++++++++++")
    print(input_nodes_FU)
    
    return objects_info
def identifyKitchenItems(file_name):
    _file = open(file_name, 'r')
    items = _file.read().splitlines()
    kitchen = []
    x = 0
    while x < len(items):
        line = items[x]
        # -- get the Object identifier by splitting first instance of O - indicates the object being used:
        objectParts = line.split("O")
        print objectParts
        objectParts = objectParts[1].split("\t")

        # -- read the next line containing the object's state information:
        x += 1
        line = items[x]
        stateParts = line.split("S")
        # get the Object's state identifier by splitting first instance of S
        stateParts = stateParts[1].split("\t")

        # -- create a new object which is equal to the kitchenItem and add it to the list:
        kitchenItem = FOON.Object(int(objectParts[0]), int(stateParts[0]),
                                  objectParts[1], stateParts[1])

        # -- check if this object is a container:
        if len(stateParts) > 2:
            ingredients = [stateParts[2]]
            ingredients = ingredients[0].split("{")
            ingredients = ingredients[1].split("}")
            # -- we then need to make sure that there are ingredients to be read.
            if len(ingredients) > 0:
                ingredients = ingredients[0].split(",")
                for I in ingredients:
                    kitchenItem.addIngredient(I)
                #endfor
            #endif
        #endif
        kitchen.append(kitchenItem)
        x += 1
    #endfor
    _file.close()
    return kitchen
def constructFUGraph(file_name):
    global totalNodes
    count = totalNodes
    # -- 'totalNodes' gives an indication of the number of object AND motion nodes are in FOON.
    stateParts = []
    objectParts = []
    motionParts = []
    # -- objects used to contain the split strings
    objectIndex = -1
    # --  variables to hold position of object/motion within list of Things
    isInput = True

    newFU_lvl3 = FOON.FunctionalUnit()
    newFU_lvl2 = FOON.FunctionalUnit()
    newFU_lvl1 = FOON.FunctionalUnit()
    # object which will hold the functional unit being read.
    _file = open(file_name, 'r')
    items = _file.read().splitlines()

    x = 0
    while x < len(items):
        line = items[x]
        objectExisting = -1
        if line.startswith("//"):
            # -- we are adding a new FU, so start from scratch..
            if FUExists(newFU_lvl3, 3) == False:
                nodes_Lvl3.append(newFU_lvl3.getMotion())
                FOON_Lvl3.append(newFU_lvl3)
                count += 1
                # -- we only keep track of the total number of nodes in the LVL3 FOON.
            if FUExists(newFU_lvl2, 2) == False:
                nodes_Lvl2.append(newFU_lvl2.getMotion())
                # -- no matter what, we add new motion nodes; we will have multiple instances everywhere.
                FOON_Lvl2.append(newFU_lvl2)
            if FUExists(newFU_lvl1, 1) == False:
                nodes_Lvl1.append(newFU_lvl1.getMotion())
                FOON_Lvl1.append(newFU_lvl1)
            newFU_lvl3 = FOON.FunctionalUnit()
            newFU_lvl2 = FOON.FunctionalUnit()
            newFU_lvl1 = FOON.FunctionalUnit()
            # -- create an entirely new FU object to proceed with reading new units.
            isInput = True
            # -- this is the end of a FU so we will now be adding input nodes; set flag to TRUE.
        elif line.startswith("O"):
            # -- this is an Object node, so we probably should read the next line one time
            objectParts = line.split("O")
            # -- get the Object identifier by splitting first instance of O
            objectParts = objectParts[1].split("\t")

            # -- read the next line containing the Object state information
            x += 1
            line = items[x]
            stateParts = line.split("S")
            # get the Object's state identifier by splitting first instance of S
            stateParts = stateParts[1].split("\t")

            # Functional Unit - Level 3:
            newObject = FOON.Object(int(objectParts[0]), int(stateParts[0]),
                                    objectParts[1], stateParts[1])

            # -- check if this object is a container:
            if len(stateParts) > 2:
                ingredients = [stateParts[2]]
                ingredients = ingredients[0].split("{")
                ingredients = ingredients[1].split("}")
                # -- we then need to make sure that there are ingredients to be read.
                if len(ingredients) > 0:
                    ingredients = ingredients[0].split(",")
                    for I in ingredients:
                        newObject.addIngredient(I)

            # -- check if Object node exists in the list of objects
            for N in nodes_Lvl3:
                if isinstance(N, FOON.Object) and N.equals_Lvl3(newObject):
                    objectExisting = nodes_Lvl3.index(N)

            # -- check if object already exists within the list so as to avoid duplicates
            if objectExisting != -1:
                objectIndex = objectExisting
            else:
                # -- just add new object to the list of all nodes
                nodes_Lvl3.append(newObject)
                objectIndex = count
                count += 1

            if isInput == True:
                # -- this Object will be an input node to the FU:
                newFU_lvl3.addObjectNode(nodes_Lvl3[objectIndex], 1,
                                         int(objectParts[2]))
            else:
                # -- add the Objects as output nodes to the FU:
                newFU_lvl3.addObjectNode(nodes_Lvl3[objectIndex], 2,
                                         int(objectParts[2]))
                newFU_lvl3.getMotion().addNeighbour(newObject)
                # -- make the connection from Motion to Object

        # Functional Unit - Level 2:
            objectExisting = -1
            newObject = FOON.Object(int(objectParts[0]), int(stateParts[0]),
                                    objectParts[1], stateParts[1])

            # -- check if Object node exists in the list of objects
            for N in nodes_Lvl2:
                if isinstance(N, FOON.Object) and N.equals_Lvl2(newObject):
                    objectExisting = nodes_Lvl2.index(N)

            # -- check if object already exists within the list so as to avoid duplicates
            if objectExisting != -1:
                objectIndex = objectExisting
            else:
                # -- just add new object to the list of all nodes
                objectIndex = len(nodes_Lvl2)
                nodes_Lvl2.append(newObject)

            if isInput == True:
                newFU_lvl2.addObjectNode(nodes_Lvl2[objectIndex], 1,
                                         int(objectParts[2]))
            else:
                newFU_lvl2.addObjectNode(nodes_Lvl2[objectIndex], 2,
                                         int(objectParts[2]))
                newFU_lvl2.getMotion().addNeighbour(newObject)

        # Functional Unit - Level 1:
            objectExisting = -1
            noState = FOON.Object(int(objectParts[0]), objectParts[1])

            # -- check if Object node exists in the list of objects
            for N in nodes_Lvl1:
                if isinstance(N, FOON.Object) and N.equals_Lvl1(noState):
                    objectExisting = nodes_Lvl1.index(N)

            # -- check if object already exists within the list so as to avoid duplicates
            if objectExisting != -1:
                objectIndex = objectExisting
            else:
                objectIndex = len(nodes_Lvl1)
                nodes_Lvl1.append(noState)

            if isInput == True:
                newFU_lvl1.addObjectNode(nodes_Lvl1[objectIndex], 1,
                                         int(objectParts[2]))
            else:
                newFU_lvl1.addObjectNode(nodes_Lvl1[objectIndex], 2,
                                         int(objectParts[2]))
                newFU_lvl1.getMotion().addNeighbour(noState)

        else:
            # -- We are adding a Motion node, so very easy to deal with, as follows:
            isInput = False
            line = items[x]
            motionParts = line.split("M")
            # -- get the Motion number...
            motionParts = motionParts[1].split("\t")
            #  ... and get the Motion label

            # Functional Unit - Level 3:
            # -- create new Motion based on what was read:
            newMotion = FOON.Motion(int(motionParts[0]), motionParts[1])
            for T in newFU_lvl3.getInputList():
                T.addNeighbour(newMotion)
                # -- make the connection from Object(s) to Motion
            newFU_lvl3.setMotion(newMotion)
            newFU_lvl3.setTimes(motionParts[2], motionParts[3])

            # Functional Unit - Level 2:
            newMotion = FOON.Motion(int(motionParts[0]), motionParts[1])
            for T in newFU_lvl2.getInputList():
                T.addNeighbour(newMotion)
            newFU_lvl2.setMotion(newMotion)
            newFU_lvl2.setTimes(motionParts[2], motionParts[3])

            # Functional Unit - Level 1:
            newMotion = FOON.Motion(int(motionParts[0]), motionParts[1])
            for T in newFU_lvl1.getInputList():
                T.addNeighbour(newMotion)
            newFU_lvl1.setMotion(newMotion)
            newFU_lvl1.setTimes(motionParts[2], motionParts[3])
        #endif
        x += 1
    #endwhile
    _file.close()
    # -- Don't forget to close the file once we are done!
    return count
def taskTreeRetrieval():
    environment = identifyKitchenItems('kitting_experiment_objects.txt')
    # -- kitchen items needed to find the solution
    goalType = raw_input("Please type the goal node's TYPE here: > ")
    goalState = raw_input("Please type the goal node's STATE here: > ")
    goalNode = FOON.Object(int(goalType), int(goalState))

    hierarchy_level = int(
        raw_input("At what level is the search being done? [1/2/3] > "))

    searchNodes = None
    searchFOON = None

    if hierarchy_level == 1:
        searchNodes = nodes_Lvl1
        searchFOON = FOON_Lvl1
    elif hierarchy_level == 2:
        searchNodes = nodes_Lvl2
        searchFOON = FOON_Lvl2
    elif hierarchy_level == 3:
        searchNodes = nodes_Lvl3
        searchFOON = FOON_Lvl3
    else:
        exit()

    # -- first part: check if the object actually exists in the network:
    index = -1
    for T in searchNodes:
        if isinstance(T, FOON.Object) and T.equals_functions[hierarchy_level -
                                                             1](goalNode):
            index = searchNodes.index(T)

    if index == -1:
        print "Item O" + goalNode.getObjectType(
        ) + "_S" + goalNode.getStateType() + " has not been found in network!"
        return False
    #endif

    # What structures do we need in record keeping?
    #	-- a FIFO list of all nodes we need to search (a queue)
    #	-- a list that keeps track of what we have seen
    #	-- a list of all items we have/know how to make in the present case (i.e. the kitchen list)
    itemsToSearch = collections.deque()
    itemsSeen = []
    kitchen = []

    goalNode = searchNodes[index]
    # this is the actual goal node which is in the network.

    # -- Add the object we wish to search for to the two lists created above:
    itemsToSearch.append(searchNodes[index])
    itemsSeen.append(searchNodes[index])

    FUtoSearch = []
    # -- structure to keep track of all candidate functional units in FOON
    taskTree = []
    # -- tree with all functional units needed to create the goal based on the kitchen items
    tree_allPaths = []
    # -- list of ALL possible functional units that can be used for making the item.

    for T in environment:
        itemsSeen.append(T)
        index = -1
        for N in searchNodes:
            if isinstance(N,
                          FOON.Object) and T.equals_functions[hierarchy_level -
                                                              1](N):
                index = searchNodes.index(N)
        if index > -1:
            # -- this means that the object exists in FOON; if not..
            kitchen.append(searchNodes[index])
    #endfor

    max_iterations = 0
    prior = -1
    further = -1
    depth = 100000
    # -- maximum number of times you can "see" the original goal node.

    while itemsToSearch:
        # -- Remove the item we are trying to make from the queue of items we need to learn how to make
        tempObject = itemsToSearch.popleft()
        tempObject.printObject_Lvl3()

        # -- sort-of a time-out for the search if it does not produce an answer dictated by the amount of time it takes.
        if prior == len(itemsToSearch) and further == prior:
            max_iterations += 1

        if max_iterations > depth:  # just the worst possible way of doing this, but will do for now.
            return False

        further = prior
        prior = len(itemsToSearch)

        flag = False
        for S in kitchen:
            if S.equals_functions[hierarchy_level - 1](goalNode):
                flag = True
                break

        if flag == True:
            # -- If we found the item already, why continue searching? (Base case)
            #		therefore we break here!
            break

        flag = False
        for S in kitchen:
            if S.equals_functions[hierarchy_level - 1](tempObject):
                flag = True
                break

        if flag == True:
            # just proceed to next iteration, as we already know how to make current item!
            continue

        numProcedures = 0
        for FU in searchFOON:
            # -- searching for all functional units with our goal as output
            found = -1
            for N in FU.getOutputList():
                if N.equals_functions[hierarchy_level - 1](tempObject):
                    found += 1
            # -- only add a functional unit if it produces a specific output.
            if found > -1:
                FUtoSearch.append(FU)
                tree_allPaths.append(FU)
                numProcedures += 1

        # -- this means that there is NO solution to making an object,
        #		and so we just need to add it as something we still need to learn how to make.
        # -- this should probably indicate that there is no task tree.
        if FUtoSearch == False:
            # -- if a solution has not been found yet, add the object back to queue.
            found = False
            # -- both conditions true -> we have already seen the object and we have it
            for U in kitchen:
                if U.equals_functions[hierarchy_level - 1](tempObject):
                    found = True
                    break

            for U in itemsToSearch:
                if U.equals_functions[hierarchy_level - 1](tempObject):
                    found = True
                    break

            if found == False:
                itemsToSearch.put(tempObject)

        while FUtoSearch:
            tempFU = FUtoSearch.pop()
            count = 0
            for T in tempFU.getInputList():
                flag = False
                for U in kitchen:
                    if U.equals_functions[hierarchy_level - 1](T):
                        flag = True
                        break
                if flag == False:
                    # -- if an item is not in the "objects found" list,
                    #		then we add it to the list of items we then need to explore and find out how to make.
                    for U in itemsToSearch:
                        if U.equals_functions[hierarchy_level - 1](T):
                            flag = True
                            break
                    if flag == False:
                        itemsToSearch.append(T)
                else:
                    # keeping track of whether we have all items for a functional unit or not!
                    count += 1

            numProcedures -= 1

            if count == tempFU.getNumberOfInputs():
                # We will have all items needed to make something;
                #	add that item to the "kitchen", as we consider it already made.
                found = False
                for U in kitchen:
                    if U.equals_functions[hierarchy_level - 1](tempObject):
                        found = True
                        break
                if found == False:
                    kitchen.append(tempObject)

                # -- Ensuring that we do not add duplicate objects to these lists..
                found = False
                for U in itemsSeen:
                    if U.equals_functions[hierarchy_level - 1](tempObject):
                        found = True
                        break
                if found == False:
                    itemsSeen.append(tempObject)

                for x in range(numProcedures):
                    # remove all functional units that can make an item - we take the first!
                    FUtoSearch.pop()

                found = False
                for FU in taskTree:
                    if FU.equals_functions[hierarchy_level - 1](tempFU):
                        # ensuring that we do not repeat any units
                        found = True
                        break
                if found == False:
                    taskTree.append(tempFU)
            else:
                # -- if a solution has not been found yet, add the object back to queue.
                found = False
                # -- both conditions true -> we have already seen the object and we have it
                for U in itemsToSearch:
                    if U.equals_functions[hierarchy_level - 1](tempObject):
                        found = True
                        break
                if found == False:
                    itemsToSearch.append(tempObject)

    # -- saving task tree sequence to file..
    # _file = open("FOON_task-tree-for-O" + goalType + "_S" + goalState + "_Lvl" + str(hierarchy_level) + ".txt", 'w');
    _file = open("FOON_task_tree.txt", 'w')

    for FU in taskTree:
        # -- just write all functional units that were put into the list:
        FU.printFunctionalUnit()
        _file.write(FU.getInputsForFile())
        _file.write(FU.getMotionForFile())
        _file.write(FU.getOutputsForFile())
        _file.write("//\n")
    #endfor
    return True
def findAllPaths():
    goalType = raw_input("Please type the goal node's TYPE here: > ")
    goalState = raw_input("Please type the goal node's STATE here: > ")
    goalNode = FOON.Object(int(goalType), int(goalState))

    hierarchy_level = int(
        raw_input("At what level is the search being done? [1/2/3] > "))

    searchNodes = None
    searchFOON = None

    if hierarchy_level == 1:
        searchNodes = nodes_Lvl1
        searchFOON = FOON_Lvl1
    elif hierarchy_level == 2:
        searchNodes = nodes_Lvl2
        searchFOON = FOON_Lvl2
    elif hierarchy_level == 3:
        searchNodes = nodes_Lvl3
        searchFOON = FOON_Lvl3
    else:
        exit()

    # -- first part: check if the object actually exists in the network:
    index = -1
    for T in searchNodes:
        if isinstance(T, FOON.Object) and T.equals_functions[hierarchy_level -
                                                             1](goalNode):
            index = searchNodes.index(T)

    if index == -1:
        print "Item O" + goalNode.getObjectType(
        ) + "_S" + goalNode.getStateType() + " has not been found in network!"
        return False
    #endif

    # What structures do we need in record keeping?
    #	-- a FIFO list of all nodes we need to search (a queue)
    #	-- a list that keeps track of what we have seen
    #	-- a list of all items we have/know how to make in the present case (i.e. the kitchen list)
    itemsToSearch = collections.deque()
    itemsSeen = []
    kitchen = []

    goalNode = searchNodes[index]
    # this is the actual goal node which is in the network.

    # -- Add the object we wish to search for to the two lists created above:
    itemsToSearch.append(searchNodes[index])

    FUtoSearch = []
    # -- structure to keep track of all candidate functional units in FOON
    tree_allPaths = []
    # -- list of ALL possible functional units that can be used for making the item.

    max_iterations = 0
    prior = -1
    further = -1
    depth = 100000
    # -- maximum number of times you can "see" the original goal node.

    while itemsToSearch:
        # -- Remove the item we are trying to make from the queue of items we need to learn how to make
        tempObject = itemsToSearch.popleft()

        # -- sort-of a time-out for the search if it does not produce an answer dictated by the amount of time it takes.
        if prior == len(itemsToSearch) and further == prior:
            max_iterations += 1

        if max_iterations > depth:  # just the worst possible way of doing this, but will do for now.
            break

        further = prior
        prior = len(itemsToSearch)

        found = False
        for S in itemsSeen:
            if S.equals_functions[hierarchy_level - 1](tempObject):
                found = True
                break

        if found == True:
            # just proceed to next iteration, as we already know how to make current item!
            continue

        for FU in searchFOON:
            # -- searching for all functional units with our goal as output
            found = -1
            for N in FU.getOutputList():
                if N.equals_functions[hierarchy_level - 1](tempObject):
                    found += 1
            # -- only add a functional unit if it produces a specific output.
            if found > -1:
                tree_allPaths.append(FU)
                for N in FU.getInputList():
                    itemsToSearch.append(N)
        #endfor
        found = False
        for N in itemsSeen:
            if N.equals_functions[hierarchy_level - 1](tempObject):
                found = True
        if found == False:
            itemsSeen.append(tempObject)

    # -- saving task tree sequence to file..
    _file = open(
        "FOON_all-paths-to-O" + goalType + "_S" + goalState + "_Lvl" +
        str(hierarchy_level) + ".txt", 'w')

    for FU in tree_allPaths:
        # -- just write all functional units that were put into the list:
        FU.printFunctionalUnit()
        _file.write(FU.getInputsForFile())
        _file.write(FU.getMotionForFile())
        _file.write(FU.getOutputsForFile())
        _file.write("//\n")
    #endfor
    return True
Example #8
0
def buildFunctionalUnit():

    # counter to know the number of the functional unit in the FOON.
    functionalUnitNumber = 0

    # build a functional unit class for every required functional unit.
    for functionalUnitName in functionalUnitsNames:
        # NOTE: prepare the input nodes, motion nodes and output nodes.
        # NOTE: the output node(s) information is found here such as the state changing and node name.
        new_FU_inputs = []
        new_FU_motion = []
        new_FU_output_Id = []
        new_FU_output_label = []
        new_FU_output_state = []
        

        # get the input nodes
        for input_nodes in input_nodes_FU:
            if input_nodes[0].getOrder() == functionalUnitName:
                new_FU_inputs = input_nodes
            #endif
        #endfor
        
        # get the motion node
        for motion_FU in motions_FU:
            if motion_FU[0].getMotionId() == functionalUnitName:
                new_FU_motion = motion_FU
            #endif
        #endfor

        # NOTE: build the output object after the motion
        for new_FU_input in new_FU_inputs:
            

            if len(new_FU_output_Id)  < (len(new_FU_inputs) - 1):
                obj_id = new_FU_input.getId() + " and "
            else:
                obj_id = new_FU_input.getId() 

            if len(new_FU_output_label) < (len(new_FU_inputs) - 1):
                obj_label = new_FU_input.getLabel() + " and "
            else:
                obj_label = new_FU_input.getLabel()
            

            if len(new_FU_output_state) < (len(new_FU_inputs) - 1):
                obj_output_state = new_FU_input.getStatesList()[1] + ", "
            else:
                obj_output_state = new_FU_input.getStatesList()[1] + ". "
        


            new_FU_output_Id.append(obj_id)
            new_FU_output_label.append(obj_label)
            new_FU_output_state.append(obj_output_state)
        #endfor

        Id = "".join (str(x) for x in new_FU_output_Id) 
        label = "".join(str(x) for x in new_FU_output_label )
        state = "".join(str(x) for x in new_FU_output_state)
        new_FU_output = FOON.Object(Id , label)
        new_FU_output.setStatesList([state])



        # NOTE: set the calculated information in the functional unit class
        # build a new FOON for every name
        newFU = FOON.FunctionalUnit(functionalUnitName)
        functionalUnitNumber += 1

        # build input nodes
        for N in new_FU_inputs:
            newFU.addObjectNode(N, 1)
        
        # build motion node
        newFU.setMotion(new_FU_motion)

        # build output node
        newFU.addObjectNode(new_FU_output, 2)

        # set the functional unit order in the tree
        newFU.setFunctionalUnitOrder(functionalUnitNumber)

        # save the fucntional unit
        functionalUnits.append(newFU)

    print("--------------------------new functional unit---------------------------------------")
    print(functionalUnits[0].getFunctionalUnitOrder())
    return functionalUnits