Example #1
0
 def guess_edges(self, nodes, neighbor_len=20) -> List:
     '''
     Given a bunch of nodes in 3d space, guess some edges for each node.
     The optimal way would be to generate a complete graph (where every node
     is connected to every other node), but the minimum spanning aborescence
     causes tons of page faults and thrashes my disk. 
     '''
     edges = []
     for node in nodes:
         closest_nodes = sorted(
             nodes,
             key=lambda x: euclidean_distance(node, x))[:neighbor_len]
         edges += [(node, neighbor) for neighbor in closest_nodes]
     return edges
Example #2
0
 def build_edges(self, nodes, risk_weight=1):
     '''
     Given a list of nodes, builds as complete euclidean graph.
     Returns the aborescence (directed analog of euclidean minimum 
     spanning tree) of the graph.
     '''
     print('Building edges...')
     print(len(nodes))
     with phase_timer.Timer():
         g = nx.DiGraph()
         g.add_nodes_from(nodes)
         edges = self.guess_edges(nodes)
         # three-ple of node, node, weight
         ebunch = [(edge[0], edge[1], compute_cost(*edge))
                   for edge in edges]
         g.add_weighted_edges_from(ebunch)
         # Prepopulate edge distance
         for a, b in g.edges:
             g[a][b]['dist'] = euclidean_distance(a, b)
         self.g = g
Example #3
0
def generate_graph(path: str):
    '''
    Generate a graph data structure from a mesh polygon file
    '''
    p = plyfile.PlyData.read(path)
    # format is x, y, z, nx, ny, nz
    nodes = [Node(index, vertex) for index, vertex in enumerate(p['vertex'])]
    # convert faces to edges
    faces = [face[0] for face in p['face']]

    edges = []
    for face in faces:
        edges += face_to_edge(face)

    G = nx.Graph()
    G.add_nodes_from(nodes)
    edges = associate_edges(edges)
    G.add_edges_from(edges)
    # prepopulate edge distance
    for a, b in G.edges:
        G[a][b]['dist'] = euclidean_distance(a, b)
    #nx.set_edge_attributes(G, 'dist', edge_dists)

    return G
Example #4
0
def multi_bot(bots=4, cache=True):
    '''
    Have multiple tethered robots attempt to get to
    the goal node. Boths can't occupy the same space
    at the same time, or stray more than
    tether_distance from the other bots.help
    '''
    print('Loading graph...')
    g = nx.read_gpickle(DATA_DIR + 'graph.gpickle')
    print('Loading handholds...')
    with open(DATA_DIR + 'handhold.pickle', 'rb') as f:
        h = pickle.load(f)

    ## Generate XYZ file for pics
    with open(DATA_DIR + 'handholds.xyz', 'w') as f:
        for n in h.g.nodes:
            f.write('{} {} {}\n'.format(n.x, n.y, n.z))

    # These look like good node positions
    START_NODE_POS = [
        # planar
        (362.98, -747.74, -33.73),
        (365.12, -747.02, -34.31),
        (355.47, -732.96, -31.34),
        (370.75, -724.73, -32.03)
        # Old
#        (-249.14, 27.9, -34.4),
#        (543.18, -696.065, -28.9262),
#        (518.1, -687.459, -23.527),
#        (524.652, -667.315, -20.868),
#        (550.481, -675.239, -23.726)
    ]
    END_NODE_POS = (-139.15, 877.49, 212.1)
    # old
    #END_NODE_POS = (-63.16, -427.12, 69.33)

    if ITOKAWA:
        START_NODE_POS = [
            # MAXIMA
            #(-87.43, 50.58, 111.15),
            #(-90.38, 41, 108.55),
            #(-81.549, 39.78, 110.72),
            #(-70.25, 62.9, 106.7),
            # PLANAR
            (-159.38, -119.26, 15.17),
            (-162.14, -118.72, 14.44),
            (-162.10, -118.41, 15.70),
            (-159.33, -118.92, 16.42)

        ]

        # MAXIMA
        #END_NODE_POS = (140.88, -22.55, 113.61)
        # PLANAR
        #END_NODE_POS = (94.06, 89.07, 74.53)
        #END_NODE_POS = (-69.78, -7.15, -105.94)
        # Works
        #END_NODE_POS = (-161.405, -115.7, 25.83)
        # Works
        #END_NODE_POS = (-135.54, -56.34, 77.56)
        END_NODE_POS = (-61.57, 21.41, 116.34)


    #sorted_nodes = sorted(h.g.nodes(), key=lambda n: n.x ** 2 + n.y ** 2 + n.z ** 2)
    print(h.g.number_of_nodes())
    print(h.g.number_of_edges())
    start_nodes = [get_node(h.g, pos) for pos in START_NODE_POS]
    #start_nodes = sorted_nodes[:4]
    end_node = get_node(h.g, END_NODE_POS)
    #end_node = sorted_nodes[250]
    # Make sure that we actually find the nodes...
    assert(any(start_nodes))

    # Run a simulation with bots tethered to each other
    # they can't occupy the same space, and cannot go further
    # than Bot.tether_length from the other bots
    bots = [Bot(i, node) for i, node in enumerate(start_nodes)] 
    # init occupied nodes
    for b in bots:
        b.node.occupied = b
    print('bots', [b.node for b in bots])
    turn = 0
    try:
        while True:
            if not any([b.moved for b in bots]):
                raise Exception('No bots moved last turn')
            for bot in bots:
                turn += 1
                bot.path.append((turn, bot.node.x, bot.node.y, bot.node.z))
                try:
                    path_nodes = bounded_leg_astar(
                        h.g, 
                        bot.node, 
                        end_node, 
                        heuristic=compute_cost,
                        bots=[b for b in bots if b.id != bot.id]
                    )
                    bot.moved = True
                except:
                    print(bot.id, 'did not move') 
                    bot.moved = False
                    bot.node.occupied = bot
                    continue
                print('{}: {}: {} -> {}'.format(len(bot.path), bot.id, bot.node, path_nodes[1]))
                bot.node.occupied = False
                bot.total_dist += euclidean_distance(bot.node, path_nodes[1])
                bot.node = path_nodes[1]
                path_nodes[1].occupied = bot
                if end_node.occupied: 
                    raise Found
    except Found:
        print('Bot {} reached end node'.format(end_node.occupied.id))
        print('final pos: ', [bot.node for bot in bots])
        for n in h.g.nodes:
            if n.occupied:
                print(n, 'is occupied')
        for bot in bots:
            import compute_path
            x, y, z = compute_path.compute_hub_pos(bots)
            print('bot {} is {} units away from hub'.format(
                bot.id, euclidean_distance_c(bot.node, (x, y, z))))
        print('Saving paths...')
        for bot in bots:
            # Print stats
            print('{} moved {} total distance units'.format(bot.id, bot.total_dist))
            # Save paths for analysis
            with open(DATA_DIR + 'bot{}-path'.format(bot.id), 'w+') as f:
                for move in bot.path:
                    f.write('{} {} {} {}\n'.format(bot.id, move[1], move[2], move[3]))
            with open(DATA_DIR + 'bot{}-path.xyz'.format(bot.id), 'w+') as f:
                for move in bot.path: 
                    f.write('{} {} {}\n'.format(move[1], move[2], move[3]))
Example #5
0
def score_local_maximum(graph, node):
    '''
    Given a local maxima, return a score denoting how 'big' of a local maxima it is
    '''
    dists = [euclidean_distance(node, n) for n in graph.neighbors(node)]
    return 0.1 * sum(dists)