在Costmap_2d里面插入Prohibition_layer(禁止区域层)

在Costmap_2d里面插入Prohibition_layer(禁止区域层)
简介
costmap_2d在navigaition里面是一个很重要的板块,通常默认的是三层地图(静态/障碍/膨胀层)叠加在一起,构成整个完整的代价地图,但是我们也可以插入一些自定义的图层,然后实现自己定制化的功能,基础的教程大家可以参考costmap_2d中插入自定义层。本文的主要目的是来告诉大家如何在代价地图中插入Prohibition_layer(禁止层),然后在已经建好的地图中设立禁止通行区域,关于prohibition_layer具体的作用大家可以参照roswiki上的解释。

具体实现步骤
1 代码下载与编译
  之前我们学习插入simple_layer的时候是在自己的工作空间(catkin_ws)中建立一个pakage,然后再去自己创建.cpp文件和.h头文件,再去改cmakelist,添加.xml文件,在这个教程中我们不需要这么麻烦,我们可以直接在github上把prohibition_layer的包下载下来(源码下载地址戳这里).,解压后放在自己的工作空间中的 src 文件夹里面,然后在终端输入:

$ cd catkin_ws("catkin_ws"替换成你的工作空间名称)
$ catkin_make

编译完成以后在终端中输入:

rospack plugins --attrib=plugin costmap_2d

当你发现终端中输出:


这就表明prohibition_layer已经是一个可供使用的地图插件了. 

2 在代价地图中插入prohibition_layer
  完成步骤1后说明prohibition_layer已经可以供costmap使用了,现在我们要做的就是把prohibition_layer插入到costmap中去.
  我们在自己的代价地图参数配置文件夹中找到 global_costmap_params.yaml 和 local_costmap_params.yaml ,打开这两个文档,分别在两个文档的末尾做修改,修改后应该是下面的内容:

 plugins:
      - {name: static_map,       type: "costmap_2d::StaticLayer"}
      - {name: obstacles,        type: "costmap_2d::VoxelLayer"}
      - {name: costmap_prohibition_layer,        type: "costmap_prohibition_layer_namespace::CostmapProhibitionLayer"}     
      - {name: inflation_layer,        type: "costmap_2d::InflationLayer"}


3 修改launch文件
  完成插入地图后我们还需要修改自己的launch文件,我是在自己的move_base.launch 中插入的,这个大家根据自己的需求,你用的carlike就修改carlike的launch文件.打开自己的launch文件中插入如下内容:

<rosparam file="$(find turtlebot3_navigation)/param/prohibition_areas.yaml" command="load" ns="global_costmap/costmap_prohibition_layer" />
<rosparam file="$(find turtlebot3_navigation)/param/prohibition_areas.yaml" command="load" ns="local_costmap/costmap_prohibition_layer" />
1
2
其中的"turtlebot3_navigation"需要根据自己的情况修改,你打开自己的launch文件对照上下文就知道怎么更改了.

4 设置禁止区域坐标参数
  完成以上步骤所有的配置工作就剩下最后一步了,设置禁止区域坐标参数.
  首先需要在参数配置文件夹(就是和 global_costmap_params.yaml 以及 local_costmap_params.yaml 相同位置的文件夹)中创建新的文档,命名为 "prohibition_areas.yaml".
  然后在prohibition_areas.yaml文档中输入:

prohibition_areas:
#定义一个禁止点
 - [17.09, -6.388]
# 定义一个禁止通行的线
 - [[8.33, 2.11],
    [8.26, 5.11]]
# 定义一个禁止通行的区域
 - [[-11.15, -15.614],
    [-12.35, -13.89],
    [-10.05, -12.218]]
 
注意事项:
1 一定要严格按照上述格式来设置坐标,我之前遇到的格式错误导致不能识别禁止区域坐标情形有
  (1):坐标前的短横线没对齐
  (2):定义禁止区域或者禁止线,两坐标之间缺少了逗号
2 你可以同时定义多个禁止点/多个禁止线/多个禁止区域,或者混合定义多个点/线/区域.
3 禁止区域的坐标如何设置就需要你根据自己建的图来测量,这里就不赘述了.

5 结语
完成以上所有内容,你再次打开自己的导航就能够在rviz中看到自己的设置的禁止区域了,这里贴出我之前做的结果:

在这里插入图片描述
这是我在实验室里面建立的地图,图中的红色三角形是我设立的禁止区域,矩形框是我画的四条禁止线,小车现在在矩形框内,当我把导航目标设置在矩形框外的时候,结果显示的是无法规划路线的.

是一个使用Python编写的五子棋游戏,包含禁手规则的实现: ```python import numpy as np # 定义棋盘大小 BOARD_SIZE = 15 # 定义棋子类型 EMPTY = 0 BLACK = 1 WHITE = 2 # 定义禁手类型 NO_PROHIBITION = 0 TRIPLE_THREE = 1 FOUR_FOUR = 2 OVERLINE = 3 # 定义禁手状态 NO_PROHIBITION_STATE = 0 TRIPLE_THREE_STATE = 1 FOUR_FOUR_STATE = 2 OVERLINE_STATE = 3 # 定义禁手状态对应的提示信息 PROHIBITION_MSG = { TRIPLE_THREE_STATE: "三三禁手!", FOUR_FOUR_STATE: "四四禁手!", OVERLINE_STATE: "长连禁手!" } # 定义棋盘 board = np.zeros((BOARD_SIZE, BOARD_SIZE), dtype=int) # 定义当前下棋方 current_player = BLACK # 定义禁手状态 prohibition_state = NO_PROHIBITION_STATE # 判断是否在棋盘内 def is_in_board(x, y): return x >= 0 and x < BOARD_SIZE and y >= 0 and y < BOARD_SIZE # 判断是否为空位 def is_empty(x, y): return board[x][y] == EMPTY # 判断是否为当前下棋方 def is_current_player(x, y): return board[x][y] == current_player # 判断是否胜利 def is_win(x, y): # 判断横向是否连成五子 count = 1 for i in range(1, 5): if is_in_board(x, y+i) and board[x][y+i] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x, y-i) and board[x][y-i] == current_player: count += 1 else: break if count >= 5: return True # 判断纵向是否连成五子 count = 1 for i in range(1, 5): if is_in_board(x+i, y) and board[x+i][y] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x-i, y) and board[x-i][y] == current_player: count += 1 else: break if count >= 5: return True # 判断左上到右下是否连成五子 count = 1 for i in range(1, 5): if is_in_board(x+i, y+i) and board[x+i][y+i] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x-i, y-i) and board[x-i][y-i] == current_player: count += 1 else: break if count >= 5: return True # 判断左下到右上是否连成五子 count = 1 for i in range(1, 5): if is_in_board(x+i, y-i) and board[x+i][y-i] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x-i, y+i) and board[x-i][y+i] == current_player: count += 1 else: break if count >= 5: return True return False # 判断是否存在禁手 def has_prohibition(x, y): global prohibition_state # 判断三三禁手 count = 0 for i in range(-2, 3): for j in range(-2, 3): if is_in_board(x+i, y+j) and board[x+i][y+j] == current_player: count += 1 if count >= 5: if prohibition_state == NO_PROHIBITION_STATE: prohibition_state = TRIPLE_THREE_STATE return True count = 0 # 判断四四禁手 count = 0 for i in range(-1, 2): for j in range(-1, 2): if i == 0 and j == 0: continue if is_in_board(x+i, y+j) and board[x+i][y+j] == current_player: count += 1 if count >= 2: for i in range(-1, 2): for j in range(-1, 2): if i == 0 and j == 0: continue if is_in_board(x+i, y+j) and is_empty(x+i, y+j): board[x+i][y+j] = 3 - current_player if has_prohibition(x+i, y+j): board[x+i][y+j] = EMPTY if prohibition_state == NO_PROHIBITION_STATE: prohibition_state = FOUR_FOUR_STATE return True board[x+i][y+j] = EMPTY count = 0 # 判断长连禁手 count = 1 for i in range(1, 5): if is_in_board(x, y+i) and board[x][y+i] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x, y-i) and board[x][y-i] == current_player: count += 1 else: break if count >= 6: if prohibition_state == NO_PROHIBITION_STATE: prohibition_state = OVERLINE_STATE return True count = 1 for i in range(1, 5): if is_in_board(x+i, y) and board[x+i][y] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x-i, y) and board[x-i][y] == current_player: count += 1 else: break if count >= 6: if prohibition_state == NO_PROHIBITION_STATE: prohibition_state = OVERLINE_STATE return True count = 1 for i in range(1, 5): if is_in_board(x+i, y+i) and board[x+i][y+i] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x-i, y-i) and board[x-i][y-i] == current_player: count += 1 else: break if count >= 6: if prohibition_state == NO_PROHIBITION_STATE: prohibition_state = OVERLINE_STATE return True count = 1 for i in range(1, 5): if is_in_board(x+i, y-i) and board[x+i][y-i] == current_player: count += 1 else: break for i in range(1, 5): if is_in_board(x-i, y+i) and board[x-i][y+i] == current_player: count += 1 else: break if count >= 6: if prohibition_state == NO_PROHIBITION_STATE: prohibition_state = OVERLINE_STATE return True return False # 下棋 def play(x, y): global current_player global prohibition_state if is_in_board(x, y) and is_empty(x, y): board[x][y] = current_player if has_prohibition(x, y): board[x][y] = EMPTY print(PROHIBITION_MSG[prohibition_state]) prohibition_state = NO_PROHIBITION_STATE return if is_win(x, y): print("黑方胜利!" if current_player == BLACK else "白方胜利!") return current_player = 3 - current_player # 打印棋盘 def print_board(): print(" ", end="") for i in range(BOARD_SIZE): print(chr(ord('a')+i), end=" ") print() for i in range(BOARD_SIZE): print("{:2d}".format(i+1), end="") for j in range(BOARD_SIZE): if board[i][j] == BLACK: print("●", end=" ") elif board[i][j] == WHITE: print("○", end=" ") else: print("+", end=" ") print() # 游戏循环 while True: print_board() if current_player == BLACK: print("黑方下棋:", end="") else: print("白方下棋:", end="") move = input() if move == "exit": break x, y = ord(move[0])-ord('a'), int(move[1:])-1 play(x, y) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值