# アプリケーション設計：概要書

資料作成者：OpenAI Codex（gpt-5.6-sol） 更新日：2026年9月3日

<p class="callout info">**このページの位置づけ**  
every\_golfのスマホアプリ、Even G2アプリ、外付け方位センサー、現在地取得機能の役割と、ラウンド中の基本動作を整理した概要書です。ここに書かれた機能が実装済みという意味ではなく、今後の設計と実装で共通の基準として使います。</p>

製品構想の正本は `/Users/trons-fuyuki/Projects/every_golf/doc/from_fuyuki/PROJECT_VISION.md` です。このシステムは完全な攻略法を決定するものではありません。コースデータ、現在地、プレイヤーの登録情報から基本的な番手と方向を提案し、最終判断はプレイヤーが行います。

#### 実現する体験

プレイヤーが現在地で次のショットを検討するとき、スマホアプリがコースデータ、現在地、頭部方位、登録済みの番手とキャリーを組み合わせ、Even G2へ必要な情報を表示します。

- どの番手を使うかの提案
- どちらの方向へ打つかの提案
- 提案方向と現在向いている方向の差
- 距離と高低差
- ショット方向付近にあるOB、池、川、海、バンカー、森・樹木
- 現在のライ、ホール番号、Par、スコア

風、プレイヤーの当日の調子、ボールの沈み方、木の実際の高さや枝の張り出しは判定しません。現地の視界と状況を見たプレイヤーの判断を優先します。

#### システム全体の構成

<div drawio-diagram="415"><img src="https://bookstack.zinichi.net/uploads/images/drawio/2026-09/application-system-architecture-drawio.png" alt=""/></div>

スマホアプリをシステムの中心とします。スマホアプリがデータとラウンド状態の正本を持ち、Even G2アプリは表示と操作を担当します。G2との接続が一時的に切れても、ラウンド情報はスマホ側に残します。

#### 役割分担

<table id="bkmrk-%E6%A7%8B%E6%88%90%E8%A6%81%E7%B4%A0%E4%B8%BB%E3%81%AA%E5%BD%B9%E5%89%B2%E6%8B%85%E5%BD%93%E3%81%97%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8-%E3%82%B9%E3%83%9E%E3%83%9B%E3%82%A2"> <thead> <tr><th>構成要素</th><th>主な役割</th><th>担当しないこと</th></tr> </thead> <tbody> <tr><td>スマホアプリ</td><td>データ保持、位置情報の選択、提案計算、ラウンド進行、ショット・スコア記録</td><td>頭部方位そのものの計測</td></tr> <tr><td>BLE接続GPS</td><td>緯度・経度、測位時刻、精度等をスマホへ提供</td><td>番手提案、コース判定、スコア管理</td></tr> <tr><td>外付け方位センサー</td><td>頭部方位、必要に応じて傾き、校正状態をスマホへ提供</td><td>現在地取得、コースデータ保持、攻略判断</td></tr> <tr><td>Even G2アプリ</td><td>HUD表示、ラウンド操作、番手変更、スコア入力・修正</td><td>永続データの正本管理、重い判定処理</td></tr> <tr><td>Web UI</td><td>プレイヤープロフィールの入力・編集</td><td>ラウンド中に必須となる処理</td></tr> </tbody></table>

Web UIは便利な編集手段ですが、通信できないゴルフ場でもラウンドできるよう、ラウンド中の基本機能はスマホ内だけで成立させます。

#### スマホアプリの役割

スマホアプリは、入力データを集約して判断し、ラウンド状態を保存する中心装置です。

- PlayerProfile、CourseData、HoleData、FloorDataを保存する
- スマホ内蔵GPSとBLE接続GPSから、実際に使用する現在地を選ぶ
- 方位センサーから頭部方位と校正状態を受け取る
- 現在地から近いコースを検索する
- Teeショットの開始条件を検査する
- 現在のライと標高をFloorDataから取得する
- 登録済み番手、キャリー、高低差、基本ルートから提案を計算する
- G2へ表示するHUD情報を作る
- ショット、パット、スコア、修正内容を記録する
- G2再接続時に継続中の状態を復元する

#### 現在地の取得元

現在地はスマホ内蔵GPSだけに固定しません。スマホアプリ内に共通の「現在地提供元」を用意し、スマホ内蔵GPSとBLE接続GPSを同じ形式で扱います。

<table id="bkmrk-%E9%81%B8%E6%8A%9E%E3%83%A2%E3%83%BC%E3%83%89%E5%8B%95%E4%BD%9C-%E8%87%AA%E5%8B%95%E6%8E%A5%E7%B6%9A%E4%B8%AD%E3%81%A7%E3%80%81%E6%9C%89%E5%8A%B9%E3%81%8B%E3%81%A4%E6%96%B0"> <thead> <tr><th>選択モード</th><th>動作</th></tr> </thead> <tbody> <tr><td>自動</td><td>接続中で、有効かつ新しいBLE GPS情報を優先します。使用できない場合はスマホ内蔵GPSへ切り替えます。</td></tr> <tr><td>スマホGPS</td><td>スマホ内蔵GPSだけを使用します。</td></tr> <tr><td>BLE GPS</td><td>BLE接続GPSだけを使用します。使用できない場合は現在地が必要な操作を止め、警告します。</td></tr> </tbody></table>

2つのGPS座標は根拠なく平均しません。採用した1つの測位結果を、その時点の現在地として使用します。自動切替が起きた場合は、G2へ使用中の情報源と注意状態を通知します。

#### 共通の現在地データ

各GPSから受け取った情報は、スマホアプリ内で次の共通形式へ変換します。

<table id="bkmrk-%E9%A0%85%E7%9B%AE%E5%86%85%E5%AE%B9%E5%BF%85%E9%A0%88-sourcephone_g"> <thead> <tr><th>項目</th><th>内容</th><th>必須</th></tr> </thead> <tbody> <tr><td>source</td><td>`phone_gps`または`ble_gps`</td><td>必須</td></tr> <tr><td>latitude / longitude</td><td>緯度・経度</td><td>必須</td></tr> <tr><td>altitude</td><td>GPSが報告した標高</td><td>任意</td></tr> <tr><td>horizontalAccuracyM</td><td>水平精度の目安</td><td>必須</td></tr> <tr><td>verticalAccuracyM</td><td>垂直精度の目安</td><td>任意</td></tr> <tr><td>timestamp</td><td>測位した時刻</td><td>必須</td></tr> <tr><td>fixStatus</td><td>測位の有効性やfix状態</td><td>必須</td></tr> <tr><td>satelliteInfo</td><td>衛星数等、機器が提供できる品質情報</td><td>任意</td></tr> </tbody></table>

FloorDataの標高とGPSが報告する標高は用途を分けます。コース上の高低差計算はFloorDataを基準とし、GPS標高は測位品質の確認や将来の検証材料として扱います。

#### BLE接続GPSの扱い

BLE接続GPSは「現在地提供元」です。方位センサーとは別の機能として設計します。将来、GPSと方位センサーを同じ筐体や同じBLE機器へ統合する場合も、スマホアプリ内では位置情報と頭部方位を別々の入力として扱います。

- 接続、切断、再接続をスマホアプリが監視する
- 測位時刻から古い情報を検出する
- 測位無効や精度不足を検出する
- 自動モードでは、BLE GPSが使用不能になったらスマホGPSへ切り替える
- ショット記録へ、使用した位置情報源、精度、測位時刻を残す
- GPS機器の接続状態と測位状態を別々に管理する

<p class="callout warning">**未確定**  
BLE GPSの具体的な機種、BLE serviceとcharacteristic、データ形式、通知周期、許容精度、情報を期限切れとする秒数は、機器選定と実測後に決定します。現時点では特定機器専用の形式へ固定しません。</p>

#### 現在地を使う処理

<table id="bkmrk-%E5%87%A6%E7%90%86%E7%8F%BE%E5%9C%A8%E5%9C%B0%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9-%E3%82%B3%E3%83%BC%E3%82%B9%E6%A4%9C%E7%B4%A2%E5%90%84%E3%83%9B%E3%83%BC%E3%83%AB%E3%81%AE"> <thead> <tr><th>処理</th><th>現在地の使い方</th></tr> </thead> <tbody> <tr><td>コース検索</td><td>各ホールのFloorData境界と現在地の最短距離を調べ、どれか1ホールでも2km以内にあるコースを表示します。</td></tr> <tr><td>Teeショット開始</td><td>現在地から登録済みTee座標までの距離を調べ、半径5m以内であれば成立します。</td></tr> <tr><td>現在のライ</td><td>現在地に対応するFloorDataセルの地表属性を取得します。</td></tr> <tr><td>ショット記録</td><td>直前のアドレス位置から現在地までの距離、到着地点の属性、使用した位置情報源を記録します。</td></tr> <tr><td>番手・方向提案</td><td>現在地、基本ルート、FloorDataの標高、プレイヤーのキャリーを組み合わせます。</td></tr> </tbody></table>

CourseDataには、コース検索用として各ホールのFloorDataの四隅または同等の境界情報を保存します。ホール番号だけでOUT・INを決めず、それぞれに所属するhole IDを明示します。

#### プレイヤープロフィール

プロフィールはスマホアプリまたはWeb UIで入力します。スマホアプリはラウンド中に使える状態でプロフィールを保持します。

- 右打ち／左打ち
- 所有している番手
- 番手ごとのキャリー
- パター

キャリーが未入力の番手は選択候補へ出しません。パターはデフォルトで所有しているものとして扱います。

#### コース検索とラウンド開始

1. G2で「コースを探す」を押します。
2. スマホアプリが現在地とCourseData内の各FloorData境界を比較します。
3. どれか1ホールでも2km以内にあるコース名をG2へ表示します。
4. プレイヤーがコースを選びます。
5. OUT、IN、FULLからラウンド形式を選びます。
6. CourseDataに明示されたhole IDの順序でラウンドを開始します。

#### ラウンド中の状態

ラウンド中は、次の状態をスマホアプリが管理します。

```
コース選択
  ↓
ラウンド設定（OUT / IN / FULL）
  ↓
Teeショットモード
  ↓ 「アドレス状態」ボタン
アドレス状態
  ↓ ショット
通常ショットモード
  ↓ 「アドレス状態」ボタン
アドレス状態
  ↓ 必要回数繰り返す
ホールアウト
  ↓
スコア確認・修正
  ↓
次ホールのTeeショットモード
```

#### Teeショットモード

1. プレイヤーが「Teeショット」ボタンを押します。
2. スマホアプリが半径5m以内に登録済みTee座標があるか検査します。
3. 成立したらTeeショットモードを開始します。
4. 提案された方向と番手を確認し、必要であれば登録済み番手へ変更します。
5. 「アドレス状態」ボタンを押すと、正式なアドレス状態へ進みます。

#### 通常ショットモード

1. プレイヤーが次のボール位置へ移動し、「アドレス」ボタンを押します。
2. 直前のアドレス位置から現在地までを前回ショットの飛距離として記録します。
3. 前回使った番手と、現在地の床属性を記録します。
4. 現在地から次の打数のショットモードを開始します。
5. 提案された方向と番手を確認・変更し、「アドレス状態」ボタンを押します。

「アドレス」ボタンは前回ショットの確定と次ショットの検討開始に使います。「アドレス状態」ボタンは、方向と番手を決めた後にスイング姿勢へ進むための別操作です。

#### 正式なアドレス状態

ショット方向を検討している状態と、実際にスイングする姿勢を区別します。正式なアドレス状態では、右打ちの場合、ショット方向に対して上から見て時計回りに90度回転した向きを基準にします。左打ちは反対方向の90度を基準にします。

方位センサーから受信した頭部方位と基準方向を比較し、G2へ左右の回転量や一致状態を表示します。方位センサーが未接続、未校正、精度不足の場合はアドレス案内を止め、理由を表示します。

#### 番手とショット方向の提案

1. 現在地から基本ルートを先へたどります。
2. プロフィールに登録された番手とキャリーを候補にします。
3. 番手ごとの一般的な弾道の高さと、現在地から着弾候補までの高低差を使ってキャリーを補正します。
4. 補正後のキャリーと基本ルートが交わる付近を提案方向とします。
5. プレイヤーが別の登録済み番手へ変更した場合は、キャリー、方向、周辺情報を再計算します。

風は計算へ入れません。木や建物の実際の高さもFloorDataにないため、弾道が越えるかどうかは判定しません。

登録されたキャリーでは池や森などへ到達する場合、同じ番手を使うときの力加減を20％単位で案内できます。人が再現しにくい5％単位の表示は行いません。

#### 障害物・地形情報の表示

表示対象は次の6種類です。これらの存在を理由に基本ルートや提案方向そのものは変更せず、プレイヤーが判断するための情報として表示します。

- OB
- 池
- 川
- 海
- バンカー
- 森・樹木

暫定の最大表示件数は5件です。提案したショット方向とキャリーに近い対象を優先し、左右へ外れた場所よりも、ショット方向の手前や先にある対象を優先します。

<p class="callout warning">**未確定**  
ショット中心線から左右何mまでを検査するか、着弾候補の手前と先を何mまで検査するか、対象が重なった場合の詳細な順位は、FloorDataを使った試験で決定します。</p>

#### G2へ表示する情報

情報名、方向記号、距離を小さな表示へまとめます。距離を1行目、方向記号と情報名を2行目にする表現を基本とします。

```
145yd
▼ Green
```

HUDには次を表示します。

- ホール番号とPar
- 前ホールまでのトータルスコア
- 現在のライ
- 提案中または選択中の番手
- 補正後キャリーと力加減
- ショット方向
- 最大5件の障害物・地形情報
- GPS情報源、位置精度、方位センサーの警告

#### G2アプリの役割

G2アプリはスマホアプリから表示用データを受け取り、プレイヤーの操作をスマホへ返します。

- コース検索、コース選択、OUT・IN・FULL選択
- Teeショット開始
- 提案内容の表示と登録済み番手への変更
- アドレス状態の開始
- 次のショット位置の確定
- ホールアウト
- パット数入力、スコア表示、スコア修正

G2側ではCourseData一式やスコアの正本を持ちません。操作イベントをスマホへ送り、スマホが検査・保存した結果を再表示します。

#### 外付け方位センサーの役割

外付け方位センサーは、プレイヤーの頭が向いている方角を測定し、BLEでスマホへ送ります。

- 方位角
- 必要に応じたPitch・Roll
- 校正状態または精度
- 測定時刻
- バッテリー残量

方位センサーは番手、ルート、障害物、スコアを判断しません。購入済みのAE-NRF52840単体には方位センサーがないため、追加センサーの選定とファームウェア実装は現在保留中です。

#### ホールアウトとスコア

1. 「ホールアウト」ボタンを押すと、直前のアドレス位置から現在地までを最終ショットとして記録します。
2. そのホールの総打数とParを比較し、バーディ等の対Par表現を表示します。
3. パット数を入力します。パット数は総打数に含まれる内数で、チップイン等では0回も認めます。
4. チップイン、押し間違い、ペナルティ等へ対応するため、総打数、パット数、ペナルティを修正できます。
5. 自動記録したショット履歴と、最終確定したスコアを分けて保持します。

スコア表示の呼称と見せ方は、「みんなのGOLF」シリーズで馴染みのある対Par表現を参考にします。

#### 主なデータ

<table id="bkmrk-%E3%83%87%E3%83%BC%E3%82%BF%E5%86%85%E5%AE%B9%E6%AD%A3%E6%9C%AC%E3%82%92%E6%8C%81%E3%81%A4%E5%A0%B4%E6%89%80-playerp"> <thead> <tr><th>データ</th><th>内容</th><th>正本を持つ場所</th></tr> </thead> <tbody> <tr><td>PlayerProfile</td><td>左右の打ち方、所有番手、番手ごとのキャリー</td><td>スマホアプリ</td></tr> <tr><td>CourseData</td><td>コース情報、OUT・INのhole ID、検索用FloorData境界</td><td>スマホアプリ</td></tr> <tr><td>HoleData / FloorData</td><td>地形、属性、Tee、Green/Cup、基本ルート</td><td>スマホアプリ</td></tr> <tr><td>LocationSample</td><td>GPS情報源、座標、精度、時刻、測位状態</td><td>スマホアプリが選択</td></tr> <tr><td>HeadPoseSample</td><td>頭部方位、傾き、校正状態、時刻</td><td>方位センサーから受信</td></tr> <tr><td>RoundState</td><td>コース、ホール、打数、現在のモード</td><td>スマホアプリ</td></tr> <tr><td>ShotRecord</td><td>始点・終点、番手、距離、ライ、位置情報源</td><td>スマホアプリ</td></tr> <tr><td>HUD表示データ</td><td>G2へ表示する提案、方向、距離、警告</td><td>スマホアプリが生成</td></tr> </tbody></table>

#### 異常時と復旧

<table id="bkmrk-%E7%8A%B6%E6%85%8B%E5%8B%95%E4%BD%9C-ble-gps%E5%88%87%E6%96%AD%E8%87%AA%E5%8B%95%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A7"> <thead> <tr><th>状態</th><th>動作</th></tr> </thead> <tbody> <tr><td>BLE GPS切断</td><td>自動モードではスマホGPSへ切り替えます。BLE GPS固定モードでは位置依存操作を止めます。</td></tr> <tr><td>GPS情報が古い・無効・精度不足</td><td>Tee判定やショット位置確定を止め、G2へ理由を表示します。</td></tr> <tr><td>方位センサー切断・未校正</td><td>アドレス方向案内を止め、再接続または校正を案内します。</td></tr> <tr><td>G2切断</td><td>スマホ側でラウンド状態を保持し、再接続後にHUDを復元します。</td></tr> <tr><td>CourseData不正</td><td>ラウンド開始前に拒否し、不足項目を表示します。</td></tr> <tr><td>キャリー未登録の番手</td><td>番手選択候補へ表示しません。</td></tr> </tbody></table>

#### 確定している方針

- スマホアプリを判断、保存、復旧の中心にする
- 現在地はスマホGPSとBLE接続GPSの両方を扱える構造にする
- 方位センサーとGPSを別の入力として扱う
- OUT・INはhole IDの一覧で明示する
- Teeショットは登録済みTee座標から半径5m以内で成立する
- 番手提案後にプレイヤーが登録済み番手へ変更できる
- 障害物情報は方向を自動回避させるためではなく、判断材料として表示する
- 力加減は20％単位とする
- パット数は総打数の内数とし、スコアを後から修正できる

#### 実装前に決定・検証する項目

- BLE GPSの機種、通信service、データ形式、通知周期
- 位置精度の許容値と、測位情報を期限切れにする時間
- BLE GPSとスマホGPSを切り替える際の画面表示と記録方法
- 番手種別ごとの標準弾道モデルと高低差補正式
- 障害物検索範囲と優先順位の数値
- Even G2 SDKで利用できる画面、入力、通信、保存機能
- HUDに同時表示できる情報量と実機上の読みやすさ
- Web UIとスマホアプリ間のプロフィール同期方式

<p class="callout warning">**現在の実装状況**  
このページはアプリケーション設計の概要です。スマホアプリ、Even G2アプリ、BLE GPS連携、方位センサーファームウェアが完成したことを示す資料ではありません。実装後は自動テストだけでなく、スマホ、G2、GPS、方位センサーを組み合わせた実地確認が必要です。</p>