コンテンツにスキップ
日本語

壁のトークン

得点の大部分は壁のトークン(Wall tokens)から得られ、誤った報告は 1 回ごとに 5 点の減点になります。そのため、見つけたトークンごとに、次のどれにあたるかを判断する必要があります。

トークンの種類 すべきこと
文字の被災者(Φ、Ψ、Ω) H、S、U のいずれかを報告する
偽の被災者(同じ記号で、立体的なもの) 報告せず、地図にも含めない
合計が 0 〜 3 のコグニティブターゲット F、P、C、O のいずれかを報告する
合計がそれ以外のコグニティブターゲット 偽物です。報告せず、地図にも含めない

正確な定義はルールを、報告の送り方は通信を参照してください。

スターターロボットのカメラは 64 × 40 ピクセルです。この解像度では、ロボットが近づくまでトークンは数ピクセルにしか写らないので、遠くから候補を探し、近づいてから読み取るのがよいでしょう。報告するにはロボットがトークンからタイル半分以内にいる必要があること、そしてカスタムのカメラはコストをかければ解像度を上げられることを覚えておきましょう。

文字の被災者に近づいていくスターターロボットのカメラ画像 4 枚

64 × 40 のカメラで見たコグニティブターゲット

文字の被災者は白い正方形の上の黒い記号で、どの角度にも回転していることがあるので、向きに依存しない方法にする必要があります。

シミュレーター内の壁にある文字の被災者

コグニティブターゲットを読み取る

Section titled “コグニティブターゲットを読み取る”

コグニティブターゲットは 5 つの同心円の部分でできているので、形を認識する必要はありません。中心と外側の半径がわかれば、各部分の中央の色をサンプリングできます。各部分の半径は 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

実際の走行では、ターゲットを斜めから見ることがあり、その場合は楕円に見えます。ターゲットの正面に回る、おかしく見える色を警告として扱う、複数のフレームを読み取る、といった工夫で結果の信頼性が上がります。

スターターロボットのカメラで斜めから見たコグニティブターゲット

5 つの色がわかれば、報告するコードはその合計から決まります。隣り合う色が同じでも、5 つの部分はそれぞれ必ず数えます。

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 なので偽物です。

偽の被災者(Fake victims)は本物と同じ記号ですが、文字が立体的になっています。正面からでは、カメラだけでは見分けられないことがあります。

正面から見た偽の被災者

ルールでは、奥行きは Robot Customizer で使えるセンサーのいずれかで検出できるとされています。試してみるとよいアイデアを紹介します。

  • LiDAR や距離センサーでトークンをまたいで測った距離を比べ、高さの差を探す。
  • トークンを斜めから見る。凹凸があると記号の形が変わります。

ワールド world3.wbt と world4.wbt には偽の被災者が含まれていて、World Editor で自作のマップに追加することもできます。Erebus には、既存のワールドの被災者をランダムに偽物に変えるスクリプト scripts/update_maps_with_fakes.py も含まれています。

偽物を報告すると誤識別として 5 点の減点になりますが、エリア 1 のリニアタイルにいる本物の被災者は、種類まで正しければ 15 点になり、ほかのエリアではさらに高くなります。ロボットがどのくらい確信したら報告するかを決めるときは、このことを考慮しましょう。