Esempio n. 1
0
    def __init__(self, node: Union[Node, tuple], bot_id: int):
        if isinstance(node, Node):
            self.node = node
        elif isinstance(node, tuple):
            self.node = Node(node)
        else:
            raise TypeError
        self.bot_id = bot_id
        self.moving_range = BOT_MOVING_RANGE
        self.sensor_range = BOT_SENSOR_RANGE
        self.comm_range = BOT_COMMUNICATE_RANGE
        self.loc_barrier_map = ExploreMap()
        self.loc_explore_map = ExploreMap()
        self.moving_path = []
        self.explore_node_list = []

        self.explore()
Esempio n. 2
0
    def find_way(self, nodes: List):
        """
        用于找到自身到目标点的移动轨迹
        :param nodes:
        :return:
        """
        if len(nodes) == 1:
            end_node = nodes[0]
        else:
            end_node = max(nodes, key=lambda k: self.get_moving_profit(k))
        for i, node in enumerate(robots.robots_await_nodes[self.bot_id]):
            if node.loc() == end_node.loc():
                robots.robots_await_nodes[self.bot_id].pop(i)

        a_star_map = ExploreMap()
        a_star_map.map = self.loc_barrier_map.map & self.loc_explore_map.map
        a_star = AStar(self.node, end_node, a_star_map)
        self.explore_node_list = a_star.run()
        logger.debug(
            f'bot #{self.bot_id} get path {[node.loc() for node in self.explore_node_list]}'
        )
Esempio n. 3
0
def sim():
    global robot_map
    global start
    global stop
    # global canvas_explore_map
    canvas_explore_map = ExploreMap()
    for i in range(BOT_NUMS):
        if robots.robots_list[i].is_finished():
            stop = 1
            robot_map = i
            robots.final_map = robots.robots_list[i].loc_barrier_map
            break

        # 判断是否正在执行移动
        if robots.robots_list[i].explore_node_list:
            robots.robots_list[i].run()
            continue

        # 静止状态执行拍卖过程
        while not robots.robots_list[i].explore_node_list:
            executor, target_node = robots.robots_list[
                i].release_node_and_wait_for_buyer()
            robots.robots_await_nodes[executor].append(target_node)
            if executor == i:
                robots.robots_list[i].find_way(robots.robots_await_nodes[i])
                robots.robots_list[i].run()
                break

    for bot in robots.robots_list:
        canvas_explore_map.map |= bot.loc_explore_map.map

    # 信息素挥发
    robots.phe_map.phe_volatilize()

    if stop == 1:
        pass

    for x in range(MAP_SIZE[0]):
        for y in range(MAP_SIZE[1]):
            if robots.barrier_map[x, y]:
                canvas.create_rectangle(*get_rectangle_loc(x, y), fill='black')
            elif canvas_explore_map.map[x, y]:
                canvas.create_rectangle(*get_rectangle_loc(x, y), fill='white')
            else:
                canvas.create_rectangle(*get_rectangle_loc(x, y), fill='gray')

    for robot in robots.robots_list:
        canvas.create_rectangle(*get_rectangle_loc(*robot.loc()), fill='green')

    if not stop:
        window.after(100, sim)
Esempio n. 4
0
class Robot:
    def __init__(self, node: Union[Node, tuple], bot_id: int):
        if isinstance(node, Node):
            self.node = node
        elif isinstance(node, tuple):
            self.node = Node(node)
        else:
            raise TypeError
        self.bot_id = bot_id
        self.moving_range = BOT_MOVING_RANGE
        self.sensor_range = BOT_SENSOR_RANGE
        self.comm_range = BOT_COMMUNICATE_RANGE
        self.loc_barrier_map = ExploreMap()
        self.loc_explore_map = ExploreMap()
        self.moving_path = []
        self.explore_node_list = []

        self.explore()

    def loc(self) -> tuple:
        return self.node.loc()

    def get_moving_profit(self, node: Node) -> float:
        """
        针对任务点的出价函数
        :param node: 任务点
        :return: 出价值,None表示不可达
        """
        if self.get_accessibility(node):
            moving_cost = self.get_manha_distance(node)
            phe = self.get_phe_level(node, robots.phe_map)
            explore_profit = self.get_explore_profit(node)
            r = np.exp(PROFIT_RATIO * explore_profit + (1 - PROFIT_RATIO) *
                       (moving_cost + PHE_RATIO * phe))
            return r
        else:
            return -1

    def get_manha_distance(self, node: Node) -> int:
        """
        返回自身和目标点之间的曼哈顿距离
        :param node: 另一个点
        :return: 曼哈顿距离
        """
        return np.abs(self.node.x - node.x) + np.abs(self.node.y - node.y)

    def get_phe_level(self, node: Node, phe_map: PheMap) -> float:
        """
        得到信息素水平
        :param node:
        :param phe_map: 全局信息素水平
        :return:
        """
        return phe_map.get_phe(self.node, node)

    def get_explore_profit(self, node: Node) -> int:
        """
        简化处理,考虑到达任务点确认点增加情况
        :param node:
        :return:
        """
        new_explore_node = 0
        for i in range(node.x - self.sensor_range,
                       node.x + self.sensor_range + 1):
            for j in range(node.y - self.sensor_range,
                           node.y + self.sensor_range + 1):
                if 0 <= i < MAP_SIZE[0] and 0 <= j < MAP_SIZE[1]:
                    if self.loc_explore_map.map[i, j] == 0:
                        new_explore_node += 1

        return new_explore_node

    def get_accessibility(self, node: Node) -> bool:
        """
        对任务点的探索可达性
        :param node:
        :return: bool
        """
        # todo 任务点过远问题
        return np.sqrt((self.node.x - node.x)**2 +
                       (self.node.y - node.y)**2) < self.moving_range

    def update_loc_map(self, bot):
        self.loc_explore_map.map |= bot.loc_explore_map.map
        self.loc_barrier_map.map |= bot.loc_barrier_map.map

    def is_finished(self):
        """
        检验本地探索地图,判断地图探索是否完成
        :return: bool
        """
        return self.loc_explore_map.is_finished()

    def get_await_node(self) -> Node:
        """
        边界点中找寻下一个任务
        :return: 对自己最优任务点
        """
        x, y = self.loc()
        node_list = []
        logger.debug(
            f'bot #{self.bot_id} with sum of local explore map as {np.sum(self.loc_explore_map.map)}'
        )
        for i in range(x - self.moving_range, x + self.moving_range + 1):
            for j in range(y - self.moving_range, y + self.moving_range + 1):
                if 0 <= i < MAP_SIZE[0] and 0 <= j < MAP_SIZE[1]:
                    distance = np.sqrt(np.power(x - i, 2) + np.power(y - j, 2))
                    if self.loc_explore_map.map[
                            i, j] == 0 and distance <= self.moving_range:
                        # logger.debug(f'get node {i, j} with {self.loc_explore_map.map[i, j]}')
                        node_list.append((Node((i, j)), distance))

        if node_list:
            target_node = sorted(node_list, key=lambda k: k[1])[0:4]
            return random.choice(target_node)[0]
        else:
            """
            通信范围内无可探测点
            """
            unexplored_map = np.argwhere(self.loc_explore_map.map == 1)
            barriers = np.argwhere(robots.barrier_map.map == 1)
            await_nodes = [
                tuple(node) for node in unexplored_map if node not in barriers
            ]
            choice = random.choice(await_nodes)
            logger.debug(f'bot #{self.bot_id} has no near target node!!')
            return Node(choice)

    def release_node_and_wait_for_buyer(self) -> (int, Node):
        """
        拍卖执行过程
        :return: 执行者编号 rob_id
        """

        target = self.get_await_node()
        logger.debug(f'bot #{self.bot_id} find node {target.loc()}')
        target_profit = self.get_moving_profit(target)
        node_list = [(target, target_profit)]
        await_list = [(node, self.get_moving_profit(node))
                      for node in robots.robots_await_nodes[self.bot_id]]

        node, profit = max(node_list + await_list, key=lambda k: k[1])

        executor = self.bot_id
        for bot in robots.robots_list:
            if bot.bot_id != self.bot_id:
                self.update_loc_map(bot)
                bot.update_loc_map(robots.robots_list[self.bot_id])
                if self.get_accessibility(bot.node):
                    bot_profit = bot.get_moving_profit(node)
                    if bot_profit:
                        if bot_profit > profit:
                            executor = bot.bot_id
                            self.loc_explore_map.map[node.x, node.y] = 1

        if node in robots.robots_await_nodes[self.bot_id]:
            robots.robots_await_nodes[self.bot_id].pop(
                robots.robots_await_nodes[self.bot_id].index(node))

        return executor, node

    def explore(self):
        """
        对探索地图进行更新,传感器范围内探索,移动一个单位后执行,包括未知点探索和信息素更新
        """
        x, y = self.loc()
        # 信息素更新
        robots.phe_map.update_phe(self.node)
        # 探索
        for i in range(x - self.sensor_range, x + self.sensor_range + 1):
            for j in range(y - self.sensor_range, y + self.sensor_range + 1):
                if 0 <= i < MAP_SIZE[0] and 0 <= j < MAP_SIZE[1]:
                    distance = np.sqrt((x - i)**2 + (y - j)**2)
                    if distance <= self.sensor_range and self.loc_explore_map.map[
                            i, j] == 0:
                        self.loc_explore_map.map[i, j] = 1
                        if robots.barrier_map.map[i, j]:
                            self.loc_barrier_map.map[i, j] = 1

    def find_way(self, nodes: List):
        """
        用于找到自身到目标点的移动轨迹
        :param nodes:
        :return:
        """
        if len(nodes) == 1:
            end_node = nodes[0]
        else:
            end_node = max(nodes, key=lambda k: self.get_moving_profit(k))
        for i, node in enumerate(robots.robots_await_nodes[self.bot_id]):
            if node.loc() == end_node.loc():
                robots.robots_await_nodes[self.bot_id].pop(i)

        a_star_map = ExploreMap()
        a_star_map.map = self.loc_barrier_map.map & self.loc_explore_map.map
        a_star = AStar(self.node, end_node, a_star_map)
        self.explore_node_list = a_star.run()
        logger.debug(
            f'bot #{self.bot_id} get path {[node.loc() for node in self.explore_node_list]}'
        )

    def move(self, next_node: Node):
        """
        机器人执行移动,并对移动后的点执行探索,探索包括未知点发现和信息素更新
        :param next_node: 下一个移动点
        :return:
        """
        logger.debug(
            f'bot #{self.bot_id} move from {self.node.loc()} to {next_node.loc()}'
        )
        logger.debug(
            f'bot #{self.bot_id} current paht {[node.loc() for node in self.explore_node_list]}'
        )
        self.node = next_node
        self.explore()
        self.moving_path.append(next_node)

    def run(self) -> bool:
        """
        这里的执行过程,判断是否能够进行下一步移动,如果不能移动,重新执行寻路算法,更新移动路径,并重新执行移动
        :return:
        """
        if self.explore_node_list:
            if self.loc_barrier_map.status(self.explore_node_list[0]):
                if len(self.explore_node_list) == 1:
                    self.explore_node_list = []
                    return False
                self.find_way([self.explore_node_list[-1]])
            self.move(self.explore_node_list.pop(0))
            return True
        else:
            return False
Esempio n. 5
0
def sim():
    global robot_map
    global start
    global stop
    # global canvas_explore_map
    canvas_explore_map = ExploreMap()
    for i in range(BOT_NUMS):
        if robots.robots_list[i].is_finished():
            stop = 1
            robot_map = i
            robots.final_map = robots.robots_list[i].loc_barrier_map
            break

        # 判断是否正在执行移动
        if robots.robots_list[i].explore_node_list:
            robots.robots_list[i].run()
            continue

        # 静止状态执行拍卖过程
        while not robots.robots_list[i].explore_node_list:
            executor, target_node = robots.robots_list[
                i].release_node_and_wait_for_buyer()
            robots.robots_await_nodes[executor].append(target_node)
            if executor == i:
                robots.robots_list[i].find_way(robots.robots_await_nodes[i])
                robots.robots_list[i].run()
                break

    for bot in robots.robots_list:
        canvas_explore_map.map |= bot.loc_explore_map.map

    # 信息素挥发
    robots.phe_map.phe_volatilize()

    if stop == 1:
        pass
    canvas.delete('all')
    for x in range(MAP_SIZE[0]):
        for y in range(MAP_SIZE[1]):
            if robots.barrier_map[x, y]:
                canvas.create_rectangle(*get_rectangle_loc(x, y), fill='black')
            elif canvas_explore_map.map[x, y]:
                canvas.create_rectangle(*get_rectangle_loc(x, y), fill='white')
            else:
                canvas.create_rectangle(*get_rectangle_loc(x, y), fill='gray')

    for robot in robots.robots_list:
        canvas.create_rectangle(*get_rectangle_loc(*robot.loc()), fill='green')

    if not stop:
        window.after(100, sim)

    if stop:
        explorer_time = time.time() - start
        logger.info('{:.2f}s elapsed'.format(explorer_time))
        logger.info(f'最终障碍物地图为在机器人 #{robot_map} 上')
        logger.info(
            f'总步数为 {sum([len(item.moving_path) for item in robots.robots_list])} '
        )
        logger.info(
            f'单个机器人移动 {sum([len(item.moving_path) for item in robots.robots_list]) // BOT_NUMS}'
        )