ロボコンの得点自動集計システムを作った件 (ショート版)【WRO Scoring System】

# 目次

| 章 | タイトル | 内容 |
|:-:|:-:|:-:|
| 1 | [はじめに](#1-はじめに) | この本記事について |
| 2 | [WROとは](#2-WROとは) | WROについて説明 |
| 3 | [得点集計システムとは](#3-得点集計システムとは) | 作製したシステムについて説明 |
| 4 | [システム要件・システム構成](#4-システム要件-システム構成) | システムの具体的な仕様について |
| 5 | [完成したシステム](#5-完成したシステム) | スクショを交えながらシステムを紹介 |
| 6 | [まとめ](#6-まとめ) | まとめ |

# 1. はじめに

この記事は、2023年12月25日公開予定の [小中高生向けロボコンWROの得点集計システムを決勝大会まで持ち込んだお話【WRO Scoring System】]()のショート版記事です。

↑の記事ですが、書きたいことを書きすぎて分量がとんでもないことになってしましました… **(ざっと2万字程度…)**
そこで、初めての方にもサラッと読んでまずは興味を持っていただこうと思い、記事の内容をばっさりカットして本記事を再編成しております。

本記事を読んで興味を持ってもらえた方は、12/25公開の記事もお読み頂ければ幸いです。

# 2. WROとは

WRO(World Robot Olympiad)とは、LEGO社のMindstorms EV3 および SPIKE Prime 等を使用して参加するロボットコンテストです。

![EV3&SPIKE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/b3477b8d-9f4a-836a-5218-cc221adce678.png)

日本全国で公認予選会が開かれており、それらの優秀チームがJapan決勝大会で戦います。
さらに決勝大会の上位チームは、国際大会に出場することが出来ます。

![DSCN3311.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/1f009f22-3710-0efa-83d0-6c7ff5a98e91.jpeg)

![DSCN3334.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/a17bfb71-54aa-70e3-32fa-ff776364640a.jpeg)

今回私はこのWROの **RoboMission** というカテゴリに運営側として携わりました。
本年は**公認京都予選会**の**技術委員長**、および**Japan決勝大会**の**RoboMission エレメンタリー部門 チーフジャッジ**としてお仕事をさせて頂きました。
(どちらもルールを管理して、競技を統括する役職です。)

# 3. 得点集計システムとは

ROBO MISSIONでは2~3人1組のチームを組み、課されるミッションをこなすロボットを製作します。
競技では、ミッションをどれだけこなせたかを採点する必要があります。

京都予選会では2018年まで紙の採点シートで得点を集計していました。
しかし、チーム数の増加に伴い、その集計作業に非常に長い時間を要していました。
(1時間程度はざらにかかっていた…)

これを解決するべく、2019年の予選会以降私が開発した採点システムを導入し、**集計にかかる時間を大幅に短縮**しました。
今年、得点集計システムはパワーアップを遂げ、**2つの地方予選会、さらにJapan決勝大会**で用いることとなりました。

:::note warn
昨年よりも前の経緯については昨年の記事に記しておりますので、そちらをご覧ください。

[小中高生向けロボコンWROの運営に携わり得点集計システムを運用した件 / 3. 背景・経緯](https://qiita.com/koushiro/items/bb6814092ad3a1a99e1a#3-%E8%83%8C%E6%99%AF%E7%B5%8C%E7%B7%AF)
（3章がそれにあたります）
:::

# 4. システム要件・システム構成

それでは、本年作製したシステムのシステム要件を記しておきたいと思います。

- 競技の採点をWeb上で行う
- アプリケーションはブラウザ上で動作し、入力にはタブレット端末(主にiPad)を想定する
- 競技結果を自動集計
- 予選会用システムでは最高点の算出を行い、ランキングの作成・表示までをリアルタイムに行う
- 観客用ページを用意し、リアルタイムランキングを閲覧可能にする
- 同ページから各走行の詳細結果(ミッションの成功個数など)を閲覧可能にする
- リレーショナルデータベースシステムを用い、堅牢なシステムを構築する
- ログイン認証などを備えたセキュリティ面も保たれたシステムを構築する
- チーム呼び出し機能を設ける
    - スクリーンにチーム番号を表示する
    - 採点フォームから簡単に呼び出せるようにする

## システム構成

以上を踏まえて、今回作成したシステムの構成を以下に記します。

- 実行環境 : Linuxサーバー
  - 予選会 : さくらVPSサーバー (OS: CentOS9)
  - 決勝大会 : 決勝大会用のLinuxサーバー
- エンジン : Node.js v20.0.0
- Webフレームワーク : Express
- WebSocket通信 : Socket.io
- 開発言語
  - バックエンド : javascript
  - フロントエンド : HTML / CSS / javascript

初めに、システムを動かすエンジンとして**Node.js**を採用しました。
さらにWebアプリフレームワークとして**Express**を、WebSocket通信を行うフレームワークとして**Socket.io**を導入しました。

次にこれらを動かすマシンですが、全てを統括するLinuxサーバーが必要です。
今回は予選会用にはさくらのVPSサーバーをレンタルし、CentOS9を載せて運用しました。
又、決勝大会用には主催者提供のLinuxサーバーを用いました。

開発言語についてですが、バックエンドについてはエンジンがNode.jsですので、言うまでもなくjavascriptです。
フロントについても特にこだわることなく、 HTML + CSS + javascript で構築しました。

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/9ba2466b-df1b-6406-2f08-d03cf17f9ccf.png)

# 5. 完成したシステム

それでは、作成したシステムをスクリーンショットを交えながら紹介していきます。

## 審判用ページ

### ホーム

審判用ページの始めの画面です。

![2023_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/88368e3c-7ee1-5421-96fd-02b0bf8eebe2.png)

赤〇で囲んだ「ログイン」ボタンを押し、ログイン認証をします。

![2023_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/2dd701be-4453-a043-0f33-aa04ebd8a57a.png)

ログイン認証に成功するとホーム画面に戻り、自分がアクセス可能な大会が選択できるようになります。
(選択ボタンが黄色になり押せるようになる。)

システム管理者の場合👇

![2023_home2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/88f94288-06bf-a8a4-0f68-30b138bde4cb.png)

審判アカウントの場合👇

![2023_home3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/96d94bca-26f7-f090-f5f8-ed6d8f847ea6.png)

アカウントごとにアクセス出来る大会を制御出来るのが本システムのポイントです。

中央に配置されている「選手用ホーム」は、選手・観客用ページへ遷移するためのリンクです。

その他、ホーム画面には各種機能にアクセスするためのボタンが配置されています。

### カテゴリ選択

ホームにて大会を選択すると、次に以下のようなカテゴリ選択画面に移ります。

![2023_select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/361b014b-fe42-8b66-746a-1cb724171eaf.png)

カテゴリ選択画面ではWRO Japanで実施される6つのカテゴリ(+京都予選会用の小学校ベーシック)が表示されており、実施されるカテゴリのみ「選択」ボタンがアクティブになります。

各カテゴリの列には「チーム」「結果」「選択」の3つのボタンが配置されています。

#### チーム

「チーム」ボタンを押すと「エントリービュー」が開き、そのカテゴリにエントリーしているチームの詳細情報が閲覧出来ます。

![2023_entry_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/270dfdb3-4a45-0dd1-5e81-c8cb40635fea.png)

#### 結果

「結果」ボタンを押すと「レコードビュー」が開き、そのカテゴリで送信された競技結果データが閲覧出来ます。
ランキングになる前のデータで、いつ、誰が、どのような内容のデータを送ったが全て確認できます。

![2023_record_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/8b8e0d3d-2363-31e9-367f-4997bb90cb86.png)

#### 選択

「選択」ボタンを押すと、そのカテゴリの採点フォームに遷移します。
採点フォームについては次の小見出し以降で詳しく説明します。

### 採点フォーム

本システムの胆である、競技結果を入力し送信する採点フォームです。

![2023_form_ja1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/b80519e6-9623-11a9-6c43-4dfd29438f56.png)

沢山の機能があるので、番号を振って説明します。

:::note info
昨年時点で既にある機能については👇昨年の記事で詳しく説明しております。
[昨年の記事 / 5.成果物の紹介 / Formページ](https://qiita.com/koushiro/items/bb6814092ad3a1a99e1a#form%E3%83%9A%E3%83%BC%E3%82%B8)
:::

#### ➀ 出走順表示 【アップデート】

ヘッダー部分の一番左に配置した三本線の丸ボタンを押すと、左からナビゲーションウィンドウがせり出し、各コートごとのチームの出走順が表示されます。

![2023_orderlist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/6f5f8c5d-d09c-57e5-0f07-b5c7033b5497.png)

今年度はこの画面に、 **「チーム呼び出し機能」** を追加しました。

出走順リストには各チームごとに、「競技コート」「出走順」「チーム名」 **「呼び出しボタン」** が配置されています。
この「呼び出しボタン」を押すことで、会場に設置された **「呼び出し画面」** にチーム名等が表示されます。

![2023_call.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/eb899bae-5a2c-5be4-d5cc-784991baa0d5.png)

又、チーム名の表示と共に、**合成音声によるチーム名の読み上げ**も行われます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/3UdvpLD9bzc?si=I8T4Zfu0APQI5VdI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

これらの機能は上述のとおり、**Socket.io**を用いてWebSocket通信により行っています。
これにより、リアルタイムでの呼び出しが可能となっています。

#### (i) 言語切り替え機能 【新機能】

ヘッダーに新たに **「言語切り替えトグルボタン」** を搭載しました。
このトグルボタンのON/OFFを切り替えることで、本文を日本語から英語に切り替えることが可能です。

![2023_forn_en.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/f35356a6-8c50-c211-8f4e-22687cb09a16.png)

#### ➁ ストップウォッチ機能

これまで同様、フォーム最上部にストップウォッチの機能を搭載しています。
しかしながら、ブラウザによって遅延具合に差が生じたりするため、実運用はしていません。
実際には別でストップウォッチを持ち、そちらでタイムを計測しています。

#### ➂ チーム名入力

チーム名をプルダウンから選択します。
リストについてはデータベースから引き出してきます。

#### ➃ ラウンド選択

何回目のチャレンジかを選択します。
車検違反によりエキシビジョンとなった場合は、その下にあるエキシビジョンのチェックボックスにもチェック☑を入れます。
エキシビジョンのチーム(競技結果)は、自動的にランキング生成から除外されます。

#### ➄ 各ミッションの採点

それぞれのミッションの成功の有無、もしくはその成功個数を記録していきます。

#### (ii)選択テーブル 【アップデート】

本年はUIを改良し、そのミッションごとに**横並び**に出来るようにしました。
さらに、`YES`や`NO`、`0`,`1`,`2`,`3`など判定状況の部分は色をつけて見やすくしています。

![radio_button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/c5fd9c18-a5c4-c53f-8b9a-8e7d91162bcb.png)

#### ➆ タイム入力

上述のとおり、ストップウォッチで計測したタイムをこの欄に打ち込みます。
タイムは**秒**で打ち込むこととしており、小数点以下の打ち込みも可能です。

#### ➇ 入力データ確認

審判がすべてのデータを入力した後、選手はその入力項目に間違いが無いか確認する必要があります。
その際に、ページをスクロールせずともデータを確認できるように、表に一覧表示しています。
**各項目で何を選択したか** 、 **それによる点数** 、 **合計点** 、 **タイム** 、さらに **選択エラー** (あり得ない選択をしていないか)といったことを処理しており、それらの結果がこの表に現れます。

👇 **入力エラーが発生した時の例**

![2023_form_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/2b9d2cf6-693b-ab04-d5d0-5acf7bdab2f3.png)

#### ➈ 選手による確認ボタン

審判が採点結果入力後、選手はその採点結果に同意したかを記録する必要があります。
本システムではこのチェックボックスにチェックを入れたことにより、選手は採点結果に同意したものとみなします。

## 選手・観客用ページ

ここからは、選手や観客でもアクセスできるページについて紹介していきます。

### ホーム

選手・観客用ページの始めの画面です。

![2023_audience_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/66fb02c7-4bac-33a6-0110-0aba7b71d3e9.png)

こちらのページにはログイン認証等はなく、登録されている大会が全て表示されています。

大会名横の「選択」ボタンを押すと、審判用ページと同様にカテゴリ選択画面に移ります。

### カテゴリ選択

選手・観客用ページのカテゴリ選択画面では「選択」ボタンのみが配置されており、押下することでそのカテゴリのランキング画面に遷移します。

![2023_audience_select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/2f0b39fb-fe47-76af-0413-8982df16fbc5.png)

### ランキング画面

カテゴリを選択すると、そのカテゴリのランキング、およびラウンドごとの得点が表示されます。

![2023_audience_rank.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/11a519e3-307f-8053-239f-f1a705fb50a3.png)

ランキングテーブルの下には、各ラウンドごとの得点が走行順に表示されています。

ランキングテーブルの一番右側の列、「詳細」の「チェック」リンクを押すと、そのチームの競技結果の詳細情報が閲覧できます。

### 競技結果詳細画面

![2023_audience_check.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/09ef37b4-0c29-86d4-f6b8-8723de40cf7e.png)

詳細画面では、審判用ページの確認表のようなテーブル上に、ミッション項目、点数、各ラウンドでのデータが表示されます。
本機能にて、全てのチームの競技結果を閲覧することが可能となっています。

選手は振り返り作業に役立てることが出来る他、観客も観戦しているチームがどれだけミッションをこなせたかを確認することが出来ます。

又、このページについてもヘッダーのトグルボタンを切り替えることで日本語と英語の言語切り替えが可能です。

# 6. まとめ

以上のようなシステムを開発して、 **公認京都予選会** 、 **公認福岡予選会** 、 **Japan 決勝大会** の三つの大会で運用しました。

来年はさらに多くの予選会で使用してもらえるよう拡大していくつもりです。

ここまでお読みいただきありがとうございました。
もし興味を持っていただけたら、12/25公開予定の本編記事も是非お読みいただければと思います!!