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)
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()
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()