跳转到内容
中文(简体)

墙面标识

墙面标识(Wall tokens)占了你得分的大部分,而每次错误的报告都会扣 5 分。所以对于你找到的每一个标识,都必须做出判断:

它是…… 怎么做
字母受害者(Letter victim:Φ、Ψ、Ω) 报告 H、S 或 U
假受害者(Fake victim:同样的符号,但是立体的) 不要报告,也不要把它画进地图
数值之和为 0 到 3 的认知目标(Cognitive target) 报告 F、P、C 或 O
数值之和为其他值的认知目标 它是假标识:不要报告,也不要把它画进地图

确切的定义请参阅规则,如何发送报告请参阅通信。

入门机器人的摄像头只有 64 × 40 像素。在这个分辨率下,机器人靠近之前,一个标识只占几个像素,所以最好先从远处寻找可能的标识,再靠近去识别它们。记住,报告时机器人必须在距离标识半个地块以内;另外,自定义摄像头可以使用更高的分辨率,但要花费更多预算。

入门机器人逐渐靠近字母受害者时拍到的 4 张摄像头图像

64 × 40 摄像头看到的认知目标

字母受害者是白色方块上的黑色符号,它们可能被旋转成任意角度,所以你的方法不能依赖于方向。

仿真器中墙上的一个字母受害者

认知目标由五个同心的部分组成,所以不需要识别它的形状:只要找到它的圆心和外半径,就可以在每个部分的中间取样颜色。各部分的半径分别是 0.5、1、1.5、2 和 2.5 cm,所以它们的中点分别位于外半径的 0、0.3、0.5、0.7 和 0.9 处。

标出了每个部分取色位置的认知目标,分别位于外半径的 0、0.3、0.5、0.7 和 0.9 处

下面的函数用 Python 和 OpenCV 实现了这一点。要找到圆心和半径,你可以像迷宫导航中那样使用目标的轮廓。

import cv2 as cv
import numpy as np
# Colour of each part in BGR order, as seen by the camera
COLORS = {
'K': (0, 0, 0), # Black
'R': (0, 0, 255), # Red
'Y': (0, 255, 255), # Yellow
'G': (0, 255, 0), # Green
'B': (255, 0, 0), # Blue
}
def nearestColor(bgr):
# Returns the name of the colour that is closest to a pixel
distances = {name: np.linalg.norm(np.array(color) - bgr) for name, color in COLORS.items()}
return min(distances, key=distances.get)
def readRings(image, centerX, centerY, radius):
# image is a BGR image, as in the RGB Camera tutorial
# Returns the 5 colours from the center outwards, for example ['Y', 'B', 'R', 'K', 'G']
rings = []
for position in [0, 0.3, 0.5, 0.7, 0.9]:
x = int(round(centerX + position * radius))
y = int(round(centerY))
rings.append(nearestColor(image[y, x].astype(float)))
return rings

在实际运行中,机器人可能会从斜着的角度看到目标,这时它看起来像一个椭圆。移动到目标正前方、把看起来不对的颜色当作警示,或者读取多帧画面,都能让结果更可靠。

入门机器人的摄像头从斜着的角度看到的认知目标

得到五种颜色之后,要报告的代码就由它们的和决定。五个部分中的每一个都始终计入,即使相邻的颜色相同也是如此。

VALUES = {'K': -2, 'R': -1, 'Y': 0, 'G': 1, 'B': 2}
CODES = {0: 'F', 1: 'P', 2: 'C', 3: 'O'}
def targetCode(rings):
# rings is the list of the 5 colours of the target
# Returns the code to report, or None if the target is fake
total = sum(VALUES[color] for color in rings)
return CODES.get(total)

例如,['Y', 'B', 'R', 'K', 'G'] 的和为 0,所以它是 F;而 ['B', 'Y', 'K', 'K', 'K'] 的和为 -4,所以它是假标识。

假受害者显示的符号与真受害者相同,但字母是立体的。从正面看,仅凭摄像头可能无法区分它们:

从正面看到的假受害者

规则规定,可以用 Robot Customizer 中提供的某一种传感器检测出这种深度。下面是一些可以尝试的思路:

  • 用激光雷达或距离传感器在标识上不同位置测量距离并进行比较,寻找高度差。
  • 从斜着的角度观察标识,此时凸起会改变符号的形状。

world3.wbt 和 world4.wbt 这两个世界中包含假受害者,World Editor 也可以把它们添加到你自己的地图中。Erebus 还附带了脚本 scripts/update_maps_with_fakes.py,它会把现有世界中的受害者随机变成假受害者。

报告一个假标识会被算作误判,扣 5 分;而在区域 1 的线性地块上,一个真受害者连同正确类型可以得 15 分,在其他区域还会更多。在决定机器人需要多有把握才进行报告时,请记住这一点。