Exemplo n.º 1
0
    def test_blockchain(self):
        bc = BlockChain()
        blocks_to_mine = 5
        for i in range(blocks_to_mine):
            bc.mine("data")

        self.assertSerializable(BlockChain, bc, globals())

        self.assertTrue(bc.validate_blocks(0, 1))
        self.assertTrue(bc.validate_blocks(1, 3))
        self.assertTrue(bc.is_valid_chain())
        self.assertFalse(bc.replace(bc))
        self.assertEqual(bc.blocks, bc.blocks)
        self.assertIs(bc[0], bc.blocks[0])
        self.assertEqual(len(bc), blocks_to_mine + 1)
        self.assertEqual(bc[0:-1:2], bc.blocks[0:-1:2])
        self.assertEqual(bc[::-1], bc.blocks[::-1])

        last_block = bc[-1]
        bc1 = BlockChain()
        bc1.mine("any")
        self.assertFalse(bc1.add_block(last_block))
        self.assertNotEqual(bc, bc1)
        self.assertFalse(bc.replace(bc1))
        self.assertEqual(bc[-1], last_block)
        self.assertTrue(bc1.replace(bc))
        self.assertEqual(bc1, bc)
        print()
        for i in range(blocks_to_mine):
            bc1.mine("another data")

        self.assertIs(bc1.blocks, bc.blocks)
        self.assertEqual(bc, bc1)
Exemplo n.º 2
0
class Bot:
    def __init__(self, known_ports, state_map, config):

        self.bot_instance = bot(config["port"], config, 0, 0)
        self.port = config["port_socket"]
        known_ports.discard(self.port)
        self.other_ports = known_ports
        self.chain = BlockChain(state_map)

        self.vrep_port = config["port"]
        pos = self.bot_instance.Get_postiton()
        # print("this is pos in main bot: ", pos)
        self.coordinates = {"x": pos[0], "y": pos[1]}
        # print("coordinats::: ", self.coordinates)
        # self.get_coordinates_from_vrep()
        self.status = None  # * "Picked" or "Placed" or "Dropped" or "Free"
        self.block = None

    # TODO INTEGRATION:
    def get_coordinates_from_vrep(self):
        self.coordinates = self.bot_instance.coordinates
        # print("these are the bots coord", self.coordinates)
        # return coordinates

    # * computes euclideian distance between two points
    def euclidean_dist(self, c1, c2):
        # print("this is c1: ", c1)
        # print("this is  c2: ", c2)
        delta_x = c1["x"] - c2["x"]
        delta_y = c1["y"] - c2["y"]
        # delta_x = 5
        # delta_y = 10
        return (delta_x**2 + delta_y**2)**(0.5)

    def spit_weighted_number(self, length):
        if length == 0:
            return 0
        random_array = []
        for i in range(1, length + 1):
            random_array.append([i] * (length + 1 - i))
        flattened = [item for sublist in random_array for item in sublist]
        return random.choice(flattened)

    def force_update(self):
        pass

    def sort_coords(self, c1):
        # print("this is bot coords:", self.coordinates)
        # print("this is c1", c1)
        c1 = {"x": c1["current"]["x"], "y": c1["current"]["y"]}
        dist1 = self.euclidean_dist(c1, self.coordinates)
        # dist2 = euclidean_dist(c2, bot_coordinates)
        # if dist1 < dist2:
        #     return -1
        # elif dist1 > dist2:
        #     return 1
        # else:
        #     return 0
        return dist1

    # * query the blockchain and obtains the state_map (topmost block) as data
    def queryBlockChain(self):
        response = self.chain[len(self.chain.blocks) - 1]
        # print("this is response::::", response.data)
        return response

    def prepare_to_send(self):
        latest_block = self.chain.get_block()
        json_string = json.dumps(latest_block.data)
        return json_string

    async def send_block(self):
        print("sending block to all other ports: ")
        block_json = self.prepare_to_send()
        for port in self.other_ports:
            async with websockets.connect(host + str(port)) as websocket:
                await websocket.send("block " + block_json)
                print("data sent to port number: ", port)

    def start_server_loop_in_thread(self):
        new_loop = asyncio.new_event_loop()
        asyncio.set_event_loop(new_loop)
        start_server = websockets.serve(self.bot_server, "localhost",
                                        self.port)
        new_loop.run_until_complete(start_server)
        new_loop.run_forever()

    # * Gets the blockchain and updates it
    def update_blockchain(self, state):
        # print("update blockchain called")
        latest_block = self.queryBlockChain()
        latest_copy = latest_block
        # print("this is latest_copy", latest_copy)
        # print("its type??: ", type(latest_copy))
        # print("its data:: ", latest_copy.data)
        block_data = latest_copy.data["block_data"]
        block = block_data[self.block["id"]]
        print(
            "!!!!!!!!!!!!!!----------BLOCKCHAIN UPDATED-------------!!!!!!!!!!!!!!!!!!!!"
        )
        data_str = json.dumps(block_data)
        data_dict = {"data": data_str}
        G.add_node(data_dict)
        print(data_dict["data"])
        block["status"] = state
        # block["current"]["x"] = self.coordinates["x"]
        # block["current"]["y"] = self.coordinates["y"]
        block_data[self.block["id"]] = block
        latest_copy.data["block_data"] = block_data
        self.chain.add_block(latest_copy.data)
        new_loop = asyncio.new_event_loop()
        new_loop.run_until_complete(self.send_block())
        G.layout()
        G.draw('blockchain_plot.png')

    # * Returns the kth closest block to the bot
    # * Return data:
    # * {
    # * "current":
    # *   {
    # *   "x":..
    # *   "y":..
    # *   },
    # * "final":
    # *    {
    # *      "x"...,
    # *      "y"...
    # *    },
    # * "id"..
    # * }

    # * if all blocks are picked or placed, it returns None
    def get_kth_closest_block(self, k=1):
        latest_block = self.queryBlockChain()
        block_array = []
        # self.coordinates = self.get_coordinates_from_vrep()
        for block_id in latest_block.data["block_data"].keys():
            block = latest_block.data["block_data"][block_id]
            if (block["status"] != states["PLACED"]
                    and block["status"] != states["PICKED"]):
                block_array.append({
                    "current": {
                        "x": block["current"]["x"],
                        "y": block["current"]["y"],
                    },
                    "final": {
                        "x": block["final"]["x"],
                        "y": block["final"]["y"]
                    },
                    "id": block_id,
                })
        if len(block_array) == 0:
            return None
        block_array = sorted(block_array, key=self.sort_coords)
        if k <= len(block_array):
            return block_array[k - 1]
        else:
            return block_array[len(block_array) - 1]

    # * chooses a block and tries to pick it
    def choose_block(self):

        length = 0
        latest_block = self.queryBlockChain()
        # print(latest_block)
        for bl in latest_block.data["block_data"]:
            block = latest_block.data["block_data"][bl]
            # print(block)
            if (block["status"] == states["IDLE"]
                    or block["status"] == states["DROPPED"]):
                length += 1
        k = self.spit_weighted_number(length)
        print("chosen k:: ", k)
        if k == 0:
            return None
        block = self.get_kth_closest_block(k)
        return block

    # * pick_block if threshold error is less than given threshold
    def state_block_check(self, state=states["MOVING"], threshold=0.1):
        if state == states["MOVING"]:
            block_coords = self.block["current"]
        elif state == states["PICKED"]:
            block_coords = self.block.final
        if euclidean_dist(self.coordinates, block_coords) <= threshold:
            return True
        return False

    def pick_block(self):

        self.bot_instance.pick()
        if self.bot_instance.objectPicked != 0:
            self.update_blockchain(states["PICKED"])
            return True
        return False

    def goto_destination(self):
        pass

    async def bot_server(self, websocket, path):
        print("server running at port: ", self.port)
        message = await websocket.recv()
        print("MESSAGE RECEIVED")
        if message[0:6] == "block ":
            print("receiving block")
            message = message[6:]
            block = json.loads(message)
            self.chain.add_block(block)
        elif message[0:6] == "chain?":
            chain_string = json.dumps(self.chain)
            await websocket.send(chain_string)

    def is_block_pickable(self):
        latest_block = self.queryBlockChain()
        block = latest_block.data["block_data"][self.block["id"]]
        if block["status"] == states["DROPPED"] or block["status"] == states[
                "IDLE"]:
            return True
        return False

    def place_block(self):
        self.update_blockchain(states["PLACED"])
        self.bot_instance.place()
        # self.coordinates = self.get_coordinates_from_vrep()
        # self.status = states["LOOKING"]
        # block_coords = latest_block["block_data"][block_id].final

    def follow_path(self, block, final=False):
        if final:
            x = block["final"]["x"]
            y = block["final"]["y"]
        else:
            x = block["current"]["x"]
            y = block["current"]["y"]
        # print(block)
        # print(x,y)
        self.bot_instance.Follow_path([x, y, 0.05])

    def chooseTargetBlock(self, chosenLabel, labels):
        pass

    # choose closest block from chosen cluster
    def infinite_loop(self):
        # r=print("inside infinite loop")
        self.state = states["BEGIN"]
        while self.state != states["END"]:
            self.block = self.choose_block()
            if self.block == None:
                print("No block to pick")
                self.state = states["END"]
                break
            else:
                print("chosen block id: ", self.block["id"])
                self.state = states["MOVING"]
                self.follow_path(self.block)
                if self.is_block_pickable():
                    # print("before time sleep")
                    time.sleep(2)
                    # print("after time sleep")
                    status = self.pick_block()
                    print(status)
                    if status:
                        self.state = states["PICKED"]
                        self.follow_path(self.block, True)
                        self.place_block()
                        self.state = states["PLACED"]
                self.states = states["BEGIN"]
                continue

    async def force_update(self):
        chain_array = []
        for port in self.other_ports:
            async with websockets.connect(host + str(port)) as websocket:
                await websocket.send("chain?")
                response = await websocket.recv()
                chain = json.loads(response)
                chain_array.append(chain)
        for chain in chain_array:
            if len(chain) > len(self.chain):
                self.chain = chain

    def main_driver(self):

        # inter = setInterval(3, self.get_coordinates_from_vrep)

        t1 = threading.Thread(target=self.infinite_loop, args=[])
        t1.start()
        t3 = threading.Thread(target=self.start_server_loop_in_thread)
        t3.start()
        # foce_push_interval = setInterval(60, self.force_update)
        # TODO: FORCE PUSH
        t1.join()
        t3.join()
Exemplo n.º 3
0
class Bot:
    def __init__(self, my_port, known_ports, data):

        # ! DO THIS
        self.coordinates = self.get_coordinates_from_vrep()
        self.port = my_port
        known_ports.discard(my_port)
        self.other_ports = known_ports
        self.chain = BlockChain(data)

        # ! INSTEAD OF THIS
        self.coordinates = {
            "x": -0.024999968707561493,
            "y": 0.04999999701976776
        }
        bot_coordinates = self.coordinates
        self.status = None  # * "Picked" or "Placed" or "Dropped" or "Free"
        self.block = None

    # TODO INTEGRATION:
    def get_coordinates_from_vrep(self):
        # <<<<<<< dev_blockchain

        #*port is the port which the vrep simulation is running
        # scene = scene(port)
        # map = scene.scenesinit(port)
        map = []
        #*process map here according to req and return
        return map
        # =======
        global bot_coordinates
        self.coordinates = {
            "x": -0.024999968707561493,
            "y": 0.04999999701976776
        }
        bot_coordinates = self.coordinates
        pass
# >>>>>>> master

# * query the blockchain and obtains the map as json data

    def force_update():
        pass

    def queryBlockChain(self):
        response = self.chain.get_block()
        # JSONresponse = jsonpickle.decode(response)
        # plotBots(JSONresponse)
        # plotBlocks(JSONresponse)
        return response

    # * Comparator -> Sorts coordinatse based on least distance from bots cordinates

    def prepare_to_send(self):
        latset_block = self.chain.get_block()
        json_string = json.dumps(latset_block)
        return json_string

    async def send_block(self):
        global host
        block_json = self.prepare_to_send()
        for port in self.other_ports:
            async with websockets.connect(host + str(port)) as websocket:
                await websocket.send("block " + block_json)

    # * Gets the blockchain and updates it
    def update_blockchain(self, state):
        latest_block = self.queryBlockChain()
        block_data = latest_block.data["block_data"]
        block = block_data[self.block["id"]]
        block["state"] = state
        block["current"]["x"] = self.coordinates["x"]
        block["current"]["y"] = self.coordinates["y"]
        block_data[self.block["id"]] = block
        self.chain.add_block(block_data)
        asyncio.get_event_loop().run_until_complete(self.send_block())

    # * Returns the kth closest block to the bot
    # * Return data:
    # * {
    # * "current":
    # *   {
    # *   "x":..
    # *   "y":..
    # *   },
    # * "final":
    # *    {
    # *      "x"...,
    # *      "y"...
    # *    },
    # * "id"..
    # * }

    # * if all blocks are picked or placed, it returns None
    def get_kth_closest_block(self, k=1):
        latest_block = self.queryBlockChain()
        block_array = []
        for block_id in latest_block.data["block_data"].keys():
            block = latest_block.data["block_data"][block_id]
            if (block["status"] != states["PLACED"]
                    and block["status"] != states["PICKED"]):
                block_array.append({
                    "current": {
                        "x": block["current"]["x"],
                        "y": block["current"]["y"],
                    },
                    "final": {
                        "x": block["final"]["x"],
                        "y": block["final"]["y"]
                    },
                    "id": block_id,
                })
        if len(block_array) == 0:
            return None
        block_array = sorted(block_array, key=sort_coords)
        if k <= len(block_array):
            return block_array[k - 1]
        else:
            return block_array[len(block_array) - 1]

    # * chooses a block and tries to pick it
    def choose_block(self):
        length = 0
        latest_block = self.queryBlockChain()
        print(latest_block)
        for bl in latest_block.data["block_data"]:
            block = latest_block.data["block_data"][bl]
            print(block)
            if (block["status"] == states["IDLE"]
                    or block["status"] == states["DROPPED"]):
                length += 1
        k = spit_weighted_number(length)
        block = self.get_kth_closest_block(k)
        return block

    # * pick_block if threshold error is less than given threshold
    def state_block_check(self, state=states["MOVING"], threshold=0.1):
        if state == states["MOVING"]:
            block_coords = self.block["current"]
        elif state == states["PICKED"]:
            block_coords = self.block.final
        if euclidean_dist(self.coordinates, block_coords) <= threshold:
            return True
        return False

    def pick_block(self):
        # self.status = states["PICKED"]
        self.update_blockchain(states["PICKED"])

    def goto_destination(self):
        pass

    async def bot_server(self, websocket, path):
        while True:
            message = await websocket.recv()
            if message[0:6] == "block ":
                message = message[6:]
                block = json.loads(message)
                self.chain.add_block(block)
            elif message[0:6] == "chain?":
                chain_string = json.dumps(self.chain)
                await websocket.send(chain_string)

    def is_block_pickable(self):
        latest_block = self.queryBlockChain()
        block = latest_block.data["block_data"][self.block["id"]]
        if block["status"] == states["DROPPED"] or block["status"] == states[
                "IDLE"]:
            return True
        return False

    def place_block(self):
        self.update_blockchain(states["PLACED"])
        # self.status = states["LOOKING"]
        # block_coords = latest_block["block_data"][block_id].final

    def chooseTargetBlock(self, chosenLabel, labels):
        pass

    # choose closest block from chosen cluster
    def infinite_loop(self):
        self.state = states["BEGIN"]
        while self.state != states["END"]:
            self.block = self.choose_block()
            if self.block == None:
                self.state = states["END"]
                break
            else:
                self.state = states["MOVING"]
                while not self.state_block_check(states["MOVING"], 0.5):
                    pass
                if self.is_block_pickable():
                    self.state = states["PICKED"]
                    self.pick_block()
                    while not self.state_block_check(states["PICKED"], 0.5):
                        pass
                    self.state = states["PLACED"]
                    self.place_block()
                    self.state = states["BEGIN"]
                    continue

                else:
                    self.state = states["BEGIN"]
                    continue

    async def force_update(self):
        chain_array = []
        for port in self.other_ports:
            async with websockets.connect(host + str(port)) as websocket:
                await websocket.send("chain?")
                response = await websocket.recv()
                chain = json.loads(response)
                chain_array.append(chain)
        for chain in chain_array:
            if len(chain) >= len(self.chain):
                self.chain = chain

    def main_driver(self):

        inter = setInterval(1, self.get_coordinates_from_vrep())
        start_server = websockets.serve(self.bot_server, "localhost",
                                        self.port)
        t1 = threading.Thread(target=self.infinite_loop, args=[])
        t1.start()
        foce_push_interval = setInterval(60, self.force_update)
        loop = asyncio.get_event_loop()
        loop.run_until_complete(start_server)
        loop.run_forever()