Beginer's Tips for TRAX host on Raspberry Pi

初心者のための TRAX host on Raspberry Pi

by いずみ


琉球大おさな先生のTRAX hostをラズパイで動かす。 本家はこちら→ lut.eee.u-ryukyu.ac.jp/traxjp/tools-quick.html ですが、もっと易しい説明が欲しい学生さん向けに書いてみました。

なお、FPTで使用するNZ大D.Bailey先生の対戦ホスト(runtrax)は こちら→ www.traxgame.comになります。


Links

関連サイトへのリンク


Items Needed

用意するもの

ラズパイ Raspberry Pi 2 Type B がおすすめ。 ⇒例えば 例えば
2016.7.14時点でRaspberry Pi 3 Type B では動かない。 そのうち動くようになるかも。
ラズパイケース 併せてケースも買うとよい。 ⇒例えば 例えば
μSDカード テキトーなμSDカード。3G以上
電源 テキトーなAC-USB電源。2A以上とれるもの。 スマホ急速充電対応の製品でよい。 ⇒例えば
電源ケーブル テキトーなUSB-microケーブル。 2A以上流せるもの。 スマホ急速充電対応の製品でよい。 ⇒例えば
モニタ テキトーなモニタ。HDMI入力端子があること。 ⇒例えば
モニタケーブル テキトーなHDMIケーブル。 ⇒例えば
キーボード テキトーなUSBキーボード。できれば英語配列の方が幸せかも。 ⇒例えば
( USB HUB ) USBで通信と給電を行うボードを接続する場合は、 ラズパイの電源負荷を減らすため
self-powered なUSB-HUB があるとよい。
( 電流計 ) 必須ではないが、念のためUSB電流計があるとよい。 ⇒例えば
ネットワーク環境 DHCP等でラズパイが接続できること。
外部ネットワークに接続できること。
タイルの画像ファイルなど 琉球大に見に行くらしい。
表示用PC WindowsでもMacでもLinuxでもFreeBSDでもなんでもよい。
上記ネットワークに接続。ウェブブラウザが必要。
ChromeでもFireFoxでもSafariでもInternetExploreでもなんでもよい。

※ラズパイのIPアドレスがわかるのなら、外部から(例えば表示用のPCから)sshすればよいので、 モニタ、モニタケーブル、キーボードは不要。


Make your boot uSD card

起動メディアの準備

を琉球大の長名先生あてに送ると、作って返送してくれるらしい。 ビールを一緒に送ると反応がはやくなるとの噂です。

自分でつくるなら…under construction…


Boot&Login

起動&ログイン

ラズパイをセットアップ(Keyboard, Monitor, LAN, Power)。 電源スイッチは無いので、電源は最後に接続。 ネットワークにDHCPサーバがいれば、自動でネットワークが設定される。

ログインのメッセージに対して次のように入力し、ログインする。 ラズパイのIPアドレスがわかっていれば、 外部から(例えば表示用のPCのTeraTermから)sshしてもよい。

FreeBSD/arm (rpi2_trax) (ttyv0)

login:   trax
Password:   ※空でリターンまたは trax
                                                                                                

Test1: Demo match

テストその1…テスト対戦

Check the help of the matching program.

まずは、対戦プログラムのヘルプの確認。

trax@rpi2_trax:~ % match.sh -h
Usage: match.sh [-lr] Player1 Player2

   -t (x): Set communication timeout to (x) seconds
   -l    : Enable game log
   -r    : Player 1 as black, Player 2 as white
   -w    : Enable 'wait' mode on communication. Quick moves will appear slowly
   -h    : Show this message

   Player = 'path to executable file'  : executable trax client
            'path to character device' : serial port device
            'TCP port # (100xx)'       : TCP port
            auto:                      : autoscan serial ports
            bot:                       : 'trax-player' bot
                                                                                                

Execute demo match for a test.

ためしにテストプログラム対テストプログラムをしてみる。

trax@rpi2_trax:~ % match.sh bot bot
Player 1: Trax bot
Player 2: Trax bot
socat TCP:localhost:10101,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
socat TCP:localhost:10102,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
White player : TCP port 10101
Black player : TCP port 10102
Players: 0X / 0X
Turn 1 (player 0: white): @0+[X:0, Y:0, Tile:+]
   |@ A |
  0|    |
  1|  + |
Going to next turn.

     (中略)

Going to next turn.
Turn 16 (player 1: red): B1\[X:2, Y:1, Tile:\] R
Forced play: [X:2, Y:2, Tile:\] RUD
Forced play: [X:1, Y:2, Tile:/] RD
Forced play: [X:1, Y:1, Tile:/] RD
   |@ A B C D E F |
  0|              |
  1|  / \ \ \     |
  2|  / \ + / +   |
  3|  + + + \ + \ |
  4|  \ / \       |
  5|  \ / +       |
  6|  \ / /       |
  7|  \ / /       |
  8|  /           |
==== 0X(white) GOT A LOOP in 0X(red)'s turn !
                                                                                                

Demo match is executed and reported as text above. If you feel too fast to follow, you can set wait time, for example, match.sh -t 1 -w bot bot.

…という感じで対戦が実行され、テキストで画面に表示される。 速すぎるようなら match.sh -t 1 -w bot botなどとすると 待ち時間が入る。


Test2: Show via web browser

テストその2…web表示

First, check and record IP address of the host Raspberry Pi. The command of ifconfig can be used to check it.

まず、ラズパイのIPアドレスを確認する。 ifconfigコマンドを実行して表示されるIPアドレスを記録しておく。

trax@rpi2_trax:~ % ifconfig
lo0: flags=8049 metric 0 mtu 16384
        options=600003
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
        inet 127.0.0.1 netmask 0xff000000
        groups: lo
        nd6 options=21
ue0: flags=8843 metric 0 mtu 1500
        options=80009
        ether b8:27:eb:f7:ef:1f
        inet 192.168.100.37 netmask 0xffffff00 broadcast 192.168.100.255
        media: Ethernet autoselect (100baseTX )
        status: active
        nd6 options=29
                                                                                                

In the example above, IP address is 192.168.100.37.

たとえば、上記の例では 192.168.100.37 になる。

Launch a web browser on your PC and connect to the host Raspberry Pi with the address and port number 11000. First the browser may not connect the host, but can connect by reloading the page after executing trax-httpd.

次に、表示用のPCでウェブブラウザを起動し、 アドレス入力部分に上記確認のアドレスとポート番号11000番を入力する。 最初は接続できないかもしれないが、 ラズパイ側でtrax-httpdを起動した直後に再読み込みすると接続できる。

connect to
接続先
http://ADDRESS:11000/
http://アドレス:11000/

Launch matching program and web server on the host Raspberry Pi, redirecting the output of the maching program to the web server via pipe ( | ).

表示側の準備ができたら、ラズパイで対戦とウェブサーバを起動する。 対戦プログラムにパイプ(「|」の縦棒)で並べて trax-httpd を実行する。

trax@rpi2_trax:~ % match.sh -t 1 -w bot bot | trax-httpd
Waiting on TCP port 11000...
* GET /?_=1467690342267 HTTP/1.1

* GET /?_=1467690342268 HTTP/1.1

Player 1: Trax bot
Player 2: Trax bot
socat TCP:localhost:10101,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
socat TCP:localhost:10102,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
White player : TCP port 10101
Black player : TCP port 10102
Players: 0X / 0X
Turn 1 (player 0: white): @0+[X:0, Y:0, Tile:+]
   |@ A |
  0|    |
  1|  + |
Going to next turn.
------------------------------
* GET /?_=1467690342269 HTTP/1.1

    (中略)

Turn 21 (player 0: white): D1\[X:4, Y:1, Tile:\] RD
Forced play: [X:3, Y:1, Tile:/] LRD
   |@ A B C D E F |
  0|              |
  1|    \ / \ +   |
  2|    / \ / \   |
  3|    / + + +   |
  4|    \ \ / + \ |
  5|    \ + \ \ \ |
  6|    + + / / / |
  7|  + + \ / / / |
  8|    \ \ / / / |
  9|    \ \ / / / |
==== 0X(white) GOT A LOOP in 0X(white)'s turn !
                                                                                                

Then, the match will be shown in the web browser turn-by-turn.

これで、PCのウェブブラウザには対戦の様子が順次表示されているはず。


※LAN接続する方は次の USB-Serial の項目は飛ばして「LAN接続」のところを確認。

USB-Serial(1) connecting your player board

USB-Serial(1) ボードの接続

ラズパイに対戦するFPGAボードやマイコンボードをUSB経由シリアル(UART)接続する。 Nexys4やZYBOなら、直接USB接続すればよい。 ただし、USBの電源容量に注意。 電流を喰うようなら、電源を別でとるなり、 ラズパイとの間にパスパワーのUSBハブを入れるなりすること。

つないだら、テストプログラム(bot)と対戦させてみる。 プレイヤをautoと指定すると、 COM port(USB-Serialの接続)を自動でスキャンして対戦を始める。

trax@rpi2_trax:~ % match.sh -t 1 -w bot auto
Player 1: Trax bot
Player 2: Serial autoscan
socat TCP:localhost:10101,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
White player : TCP port 10101
Trying /dev/cuaU0
Black player : serial port /dev/cuaU0
timeout!
Failed to receive player code from Black
Trying /dev/cuaU1
Black player : serial port /dev/cuaU1
OK! code=EF
Players: 0X / EF
Turn 1 (player 0: white): @0/[X:0, Y:0, Tile:/]
   |@ A |
  0|    |
  1|  / |
Going to next turn.

    (中略)

Turn 4 (player 1: red): A3\[X:1, Y:3, Tile:\] U
Forced play: [X:2, Y:3, Tile:/] LU
   |@ A B |
  0|      |
  1|    + |
  2|  / \ |
  3|  \ / |
==== EF(red) GOT A LOOP in EF(red)'s turn !
                                                                                                

この例では/dev/cuaU1でチームコードEFの返答を確認し、 このプレイヤ相手に対戦を開始している。


USB-Serial(2) Trouble shooting

USB-Serial(2) トラブルシューティング

うまくいかないときの基本的な確認方法を解説する。

FreeBSDではCOM port(シリアル接続)は/devの下のcu*という 名前のデバイスファイルとして認識される。 ls /devとしてみて、cu*を探す。 USB-Serialを接続する前と後で見比べると、 どれが当該ボードのものか推測がつく。 Nexys4やZYBOではふたつ見えるが後者(U0ではなくU1)がUSB-Serialになる。

trax@rpi2_trax:~ % ls /dev
bpf             fido            mmcsd0s2        ttyU1           ufssuspend
bpf0            full            mmcsd0s2a       ttyU1.init      ugen0.1
console         geom.ctl        msdosfs         ttyU1.lock      ugen0.2
consolectl      gpioc0          nfslock         ttyu0           ugen0.3
ctty            iic0            null            ttyu0.init      ugen0.4
cuaU0           iic1            openfirm        ttyu0.lock      ugen0.5
cuaU0.init      kbd0            ptmx            ttyv0           ugen0.6
cuaU0.lock      kbd1            pts             ttyv1           ugen0.7
cuaU1           kbdmux0         random          ttyv2           ukbd0
cuaU1.init      klog            reroot          ttyv3           ums0
cuaU1.lock      kmem            sndstat         ttyv4           urandom
cuau0           led             snp             ttyv5           usb
cuau0.init      log             stderr          ttyv6           usbctl
cuau0.lock      mdctl           stdin           ttyv7           vchiq
devctl          mem             stdout          ttyv8           vcio
devctl2         midistat        sysmouse        ttyv9           xpt0
devstat         mixer0          ttyU0           ttyva           zero
fb0             mmcsd0          ttyU0.init      ttyvb
fd              mmcsd0s1        ttyU0.lock      ufs
                                                                                                

ボード接続の前後でcu*が変わらないようであれば、 USBのケーブル、コネクタ、ハブの接続を見直し、さらには断線や故障を疑う。

/dev/cu*が見えているようなら、 tipコマンドで直接ボードと話をしてみる。 まず、ポートがどのように登録されているか /etc/remoteを見て確認する。

trax@rpi2_trax:~ % more /etc/remote
# $FreeBSD: head/etc/remote 184352 2008-10-27 17:19:14Z thompsa $
#
#       @(#)remote      5.2 (Berkeley) 6/30/90
#

    (中略)

ucom1:dv=/dev/cuaU0:br#9600:pa=none:
ucom2:dv=/dev/cuaU1:br#9600:pa=none:
ucom3:dv=/dev/cuaU2:br#9600:pa=none:
ucom4:dv=/dev/cuaU3:br#9600:pa=none:
ucom5:dv=/dev/cuaU4:br#9600:pa=none:
ucom6:dv=/dev/cuaU5:br#9600:pa=none:
ucom7:dv=/dev/cuaU6:br#9600:pa=none:
ucom8:dv=/dev/cuaU7:br#9600:pa=none:
                                                                                                

この例では/dev/cuaU1が対象ポートであり、 それがucom2という名前になっていることがわかる。 その名前でtipを起動する。 スピード(ボーレート,baudrate,bps)は各自の設定に合わせる。 この例では19200bpsとする。

trax@rpi2_trax:~ % tip -19200 ucom2
can't open log file /var/log/aculog.
connected
(-Tを入力)EF
(-Wを入力)@0/
(~.を入力)~
[EOT]
                                                                                                

チームコード問合せ(-T)への応答や、先手を指示(-W)した場合の初手を確認する。 このとき、こちらから入力した文字は見えない。 「 ~. 」(チルダとピリオド)あるいは「 ~^D 」(^Dはコントロールを押しながらD)で終了する。

Linux (Raspbian) の場合

USBひとつでSerialがふたつ見えるボード(Nexys-4,ZYBO,ZedBoard等)と Raspbian等Linux系の環境の組合せで使用すると プレイヤのauto指定がうまく働かないことがある。 この場合、シリアルのデバイス/dev/ttyUSB?を直接指定する。

(参考)Raspbian の場合
pi@raspberrypi:~ $ ls /dev
autofs           loop6               ram7     tty16  tty43      uhid
block            loop7               ram8     tty17  tty44      uinput
  : (中略)       :                   :        :      :          :
loop3            ram4                tty13    tty40  ttyprintk  xconsole
loop4            ram5                tty14    tty41  ttyUSB0    zero
loop5            ram6                tty15    tty42  ttyUSB1

pi@raspberrypi:~ $ match.sh bot /dev/ttyUSB1
Player 1: Trax bot
Player 2: character device /dev/ttyUSB1
socat TCP:localhost:10101,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
White player : TCP port 10101
Black player : serial port /dev/ttyUSB1
Players: 0X / EF
Turn 1 (player 0: white): @0+[X:0, Y:0, Tile:+]
   |@ A |
  0|    |
  1|  + |
Going to next turn.

    (中略)

Turn 6 (player 1: red): @1/[X:0, Y:1, Tile:/] R
Forced play: [X:1, Y:2, Tile:\] RU
   |@ A B C |
  0|        |
  1|  / \   |
  2|  \ /   |
  3|    +   |
  4|    + + |
==== EF(red) GOT A LOOP in EF(red)'s turn !
                                                                                                

USB-Serial(3) Match between two player boards

USB-Serial(3) 対戦


Test3: LAN connection

テストその3…LAN 接続

通信テスト用のTRAXプレイヤを走らせるテキトーなマシンを用意する。 FreeBSD でも Linux でも Windows上のcygwinでも可。 socat というコマンドをインストールしておく。

cygwin インストーラで socat を探してインストール
linuxsudo apt-get install socat
FreeBSD(たぶん)pkg install socat

通信テスト用のTRAXプレイヤは次のとおり。 @1に+を置き続けるのでそのうち反則負けする。

traxtest.c
/* TRAX player for communication test which may cause violation */

#include 
#include 
char buf[256];

int main(void){
  while (1) {
    scanf("%s",buf);
    fprintf(stderr,"%s\n",buf);
    if (!strcmp(buf,"-T")) {
      printf("ZZ\n");
    } else if (!strcmp(buf,"-W")){
      printf("@0+\n");
      break;
    } else if (!strcmp(buf,"-B")){
      break;
    }
  }
  while (1) {
    scanf("%s",buf);
    fprintf(stderr,"%s\n",buf);
    printf("@1+\n");
  }
}

通信テスト用マシンでこれをコンパイルして実行してみる。

通信テスト用マシンにて
izumi@cygwin$ gcc traxtest.c
(コンパイル終了)

izumi@cygwin$ ./a.exe
-T
-T
ZZ
-W
-W
@0+
A0/
A0/
@1+
A0/
A0/
@1+
(Ctrl-Cを押して強制終了)
                                                                                                

対戦ホストプログラムを起動する。 LAN接続するプレイヤはTCPポート番号を指定する。 10001,10002,10003,...を使うものとする。 次の例では、先攻は bot, 後攻はLANでTCP10001番ポートに接続する。

対戦ホストマシンにて
trax@rpi2_trax:~ % match.sh -w -t 1 bot 10001
Player 1: Trax bot
Player 2: TCP port 10001
socat TCP:localhost:10101,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
White player : TCP port 10101
Black player : TCP port 10001
(接続待ちの状態になる)
                                                                                                

通信テスト用マシンにて、socat を使って通信テスト用プレイヤを起動し、 入出力を対戦ホストマシン(この例ではIPアドレス 192.168.100.37)の TCP10001番ポートに接続する。

socatの使い方 socat TCP:IPアドレス:ポート番号 exec:実行ファイル名,pty,ctty,echo=0

通信テスト用マシンにて
izumi@cygwin$ socat TCP:192.168.100.37:10001 exec:./a.exe,pty,ctty,echo=0
-T
-B
@0/
C1\
C2+
C2/
C3/
C0/
                                                                                                

プレイヤが接続されると、対戦ホスト側でも対戦の経過が表示される。

対戦ホストマシンにて
trax@rpi2_trax:~ % match.sh -w -t 1 bot 10001
Player 1: Trax bot
Player 2: TCP port 10001
socat TCP:localhost:10101,retry=100,interval=0.1 exec:"trax-player",pty,ctty,echo=0
White player : TCP port 10101
Black player : TCP port 10001
Players: 0X / ZZ
Turn 1 (player 0: white): @0/[X:0, Y:0, Tile:/]
   |@ A |
  0|    |
  1|  / |
Going to next turn.

    (中略)

Turn 12 (player 1: red): @1+[X:0, Y:1, Tile:+]
**** ISOLATED ****
   |@ A B C D E F G H |
  0|                  |
  1|  +     / \       |
  2|    + + + + + / \ |
  3|          \ / +   |
  4|          /       |
---- VIOLATION ! ----
==== ZZ lost the game by violation.