# 基準設計の物理構成 (Baseline Physical Configuration)

## 概要 (Overview)

Step 8（基準設計のキャリブレーション）で対象とする MiniTIAS 実機の物理構成を定義する．
本ドキュメントは実機写真（[REFERENCE/](../../REFERENCE/)）と Fusion 360 設計データから読み取った構成を、シミュレーション側でどう表現するかの **認識合わせ** を残すためのものである．

仕様確定前の暫定値（材料パラメータ・LED 強度等）はキャリブレーション反復で更新する．

実体は [configs/scene_baseline.yaml](../../configs/scene_baseline.yaml)．

## 座標系 (Coordinate System)

- 単位: mm（YAML 内）．シミュレータには m に変換して渡す．
- 原点: STL モデル（Fusion 360 エクスポート）の座標系を踏襲．
- 主要部品の Z 座標（中心）:
  - 評価板（照明ムラ補正ボード）: Z=+4（厚み Z=-4.5〜+12.5）
  - LED 基板カバー: Z=-65.3
  - スマホ（SH-02M）: Z=-154.4

## 評価板（照明ムラ補正ボード）

### 構造

| 面 | 法線 | Z 座標 | 構造 | 役割 |
| --- | --- | --- | --- | --- |
| 表面（外側） | +Z 法線 | Z=-2.5〜+12.5（凹凸） | 楕円窓 + AR マーカー + カラーチャート | 撮影された画像で見える側．スマホで写真を撮るときに映る面 |
| **裏面（内側）** | **-Z 法線** | **Z=-4.5（平面）** | **平坦な取付面** | **照度均一性の評価対象面．LED 光がこの面に均一に届くことが MiniTIAS の設計目的** |

### 評価対象面

**評価対象は内側（平坦面、-Z 法線面）の照度分布**．照明ムラ評価とは「この面に届く光が空間的に均一かどうか」を測ること．

## LED（光源）

### 物理仕様

| 項目 | 値 | 根拠 |
| --- | --- | --- |
| パッケージ | SMD 2835 | [REFERENCE/smd2835_datasheets.png](../../REFERENCE/smd2835_datasheets.png) |
| サイズ | 2.8 × 3.5 mm | データシート（Samsung / Bridgelux / Lumileds 共通） |
| 配光角（ビーム角） | 120°（≒ Lambertian） | データシート |

### モデル化（光の広がり方）

- Mitsuba の **AreaLight (rectangle)** として表現
- 発光面の **片面のみ** から放射する（`direction` ベクトルが示す向き側．裏面は完全に発光しない）
- 放射分布は **Lambertian**（法線方向で最大，cos(θ) で減衰）
  - データシートのビーム角 120° は半値全幅 ±60° に相当し，Lambertian の cos(60°)=0.5 と一致するため矛盾なし
- 各 LED の `direction` は **z 軸マイナス方向 `(0, 0, -1)`** で全 18 個共通．光は -Z 半球側に Lambertian で広がる
- `radiance` は暫定 `1.0 W/sr/m²`（キャリブレーション反復で実機 W 値に校正予定）
  - 全光束への換算: `Φ [W] = radiance × area × π`（Lambertian 半球積分）
  - 1 LED あたりの面積: `2.8 × 3.5 = 9.8 mm² = 9.8e-6 m²`
  - `radiance=1.0` のとき `Φ = 1.0 × 9.8e-6 × π ≈ 3.08e-5 W`（極めて小さい．実機 LED は ~0.2 W なので約 6500 倍の校正が必要）

### 配置

実機の LED 基板は **前側のでっぱりの直角部分** に取り付けられている．3 基板を Z 軸まわりに ±90° 回転で配置：

| 基板 | 基板中心 [mm] | LED 並び方向 | 個数 |
| --- | --- | --- | --- |
| 下（Y-） | (0, -70.2, -65.3) | X 軸 | 6 |
| 右（X+） | (70.2, 0, -65.3) | Y 軸 | 6 |
| 左（X-） | (-70.2, 0, -65.3) | Y 軸 | 6 |

各基板上の LED 6 個は基板の長手方向に約 8.7 mm 間隔で等間隔配置．総数 **18 個**．

※ 左右基板の中心座標は STL の下基板（`LED基板カバー.stl`、bbox 中心 (0, -70.2, -65.3)）を基準に Z 軸まわり ±90° 回転で算出した推定値．Fusion 360 設計の実位置と微小なズレがある可能性あり．

## カメラ（センサ）

評価板の **内側（平坦面）の照度マップを 2D 画像として直接取得** するため、orthographic（平行投影）センサを使う．

| 項目 | 値 | 意図 |
| --- | --- | --- |
| `type` | `orthographic` | パースペクティブ歪みを排除し、評価板の各位置の輝度を pixel と 1 対 1 対応させる |
| `position` | (0, 0, -50) mm | 評価板の裏面（Z=-4.5）より少し離れ、かつ LED 基板（Z=-65.3）より評価板側．ray の経路に LED が入らない位置 |
| `target` | (0, 0, 0) mm | 評価板の方向（+Z）を見る |
| `ortho_scale` | (50, 52) mm | 評価板の bbox（X=99, Y=102 mm）に余裕を持たせた半幅 |

カメラ位置が評価板に近すぎる（Z=-10 等）と Mitsuba の orthographic の near_clip 内に入って何も映らないので注意．

## レンダリング設定（多重反射の扱い）

Mitsuba 3 の **path tracer**（モンテカルロ光線追跡）を使用し、多重反射（インターリフレクション）まで含めて計算する．

| 項目 | 値 | 意味 |
| --- | --- | --- |
| `integrator` | `path` | **多重反射を考慮した** path tracing．LED → 内壁 → 評価板 のような間接照明経路もすべて積分する |
| `max_depth` | 8 | ray の最大反射回数．**キャリブで判明: 8 はキャリブ精度には不足**（depth=12 比で勾配を約 +2.6pt 過大評価．下記「キャリブレーション経過」参照）．確定 YAML は現状 8 のまま（既知の差分 #6）．キャリブ用途は depth≥12 推奨 |
| `spp` | 1024 | pixel あたりサンプル数．大きいほどノイズ減・計算重．**spp 校正済み**（下記「キャリブレーション経過」参照）．llvm_ad_rgb・512×512 で 1 レンダ約 9.6 分 |
| `variant` | `llvm_ad_rgb` | LLVM JIT による RGB レンダリング．LLVM-C.dll が PATH（または DRJIT_LIBLLVM_PATH）で参照可能なこと |

### 多重反射の意味

LED 光が評価板に届く経路は以下のすべてが計算される：

1. **直接光**: LED → 評価板（評価板の表面に直接当たる光）
2. **1 回反射**: LED → 内壁 → 評価板
3. **2 回反射**: LED → 内壁 → 内壁 → 評価板
4. ...
5. **max_depth (8) 回反射まで**

MiniTIAS は **白い筐体内壁の多重反射で照明を均一化** する設計のため、多重反射の正確な計算が CoV 値の再現に必須．

### 制限

- 現状 Phase A のベイク（[visualize/baker.py](../../src/sm_tias_lightsim/visualize/baker.py)）は直接照度のみで多重反射を考慮しない．多重反射込みの照度マップを得るには本ドキュメント記載の path tracer（`sm-render`）を使う．
- `max_depth` を超える反射は無視される．エネルギー的には `0.85^8 ≈ 27%` 減衰で小さいが、**キャリブ実測では無視できない**：同一条件で depth=8→12 にすると勾配が linear 空間で 24.65→22.08（−2.6pt）、sRGB 空間で 12.57→11.16（−1.4pt）下がった．8 回打ち切りはまさに均一化に効く後段反射を取りこぼし、勾配を系統的に過大評価する．キャリブ用途では depth≥12 を使うこと．

## 筐体（材料）

実機の筐体構造物（前側 / 後側 / LED 基板カバー / 評価板）は **すべて同じ 3D プリンタ白素材**（PLA / PETG / ABS の白フィラメント）で造形されている．スマホホルダのみ別素材．多重反射で照明を均一化する設計．

| 部品 | 材料定義名 | 材料モデル | reflectance | 備考 |
| --- | --- | --- | --- | --- |
| 前側 / 後側（筐体） | `printer_white` | `diffuse` | 0.85 | 3D プリンタ白フィラメント（暫定値．実物の素材データシートで再校正） |
| LED 基板カバー | `printer_white` | `diffuse` | 0.85 | **同じ 3D プリンタ白素材．不透明な白プラの枠**で LED の周囲を囲む構造であり、LED 光が透過するディフューザーではない |
| 評価板 | `printer_white` | `diffuse` | 0.85 | 3D プリンタ白．照度マップ上の輝度から照度への換算は `E ≈ pixel × π / 0.85` |
| スマホホルダ | `holder_dark` | `diffuse` | 0.50 | 別素材（推定．要確認） |
| スマホ本体（SH-02M） | `phone_body_dark` | `diffuse` | 0.05 | 樹脂・金属の黒系 |

### LED 基板カバーの取り扱いについて

当初 `thindielectric`（半透明 PMMA）でディフューザーとしてモデル化していたが、実機は 3D プリンタ白素材（不透明）であることが判明したため `diffuse 0.85` に変更した．これにより：

- LED 光は基板カバーを **透過しない**．Lambertian の発光面（AreaLight）から直接シーン空間に放出される
- 基板カバーの表面は **白プラとして拡散反射** に寄与し、多重反射の経路の一部になる
- 「半透明ディフューザーで散乱しない」問題は解消（そもそも実機にディフューザーは存在しなかった）

## キャリブレーション目標（実測値）

[PLAN_02](../03_PLAN/PLAN_02_開発ステップ.md) より：

| 指標 | 実測値 | 仮置き許容範囲 |
| --- | --- | --- |
| CoV | 0.0426 | ±0.005 |
| 中心/周辺比 | 1.064 | ±0.02 |
| 勾配 (%) | 6.23 | ±1.5 |

## キャリブレーション経過（spp 校正と診断）

### spp 128 → 1024 の数値比較（2026-05-18）

代表実測 1 枚（`MiniTIAS_20260408_144434`、ROI 物理対応済み）に対するシミュ結果：

| 指標 | 実測 (target) | spp=128 | spp=1024 | 実測との差 |
| --- | --- | --- | --- | --- |
| **CoV** | 0.0426 | 0.236 | **0.183** | 4.3× |
| std | 6.26 | 35.83 | 27.85 | |
| max/min 比 | 1.392 | 11.59 | 4.27 | 3.1× |
| mean | 146.71 | 151.79 | 152.02 | ≈ 一致 |
| 中心/周辺比 | 1.0650 | 1.330 | 1.328 | 1.25× |
| 勾配 % | 6.10 | 24.83 | 24.72 | 4.1× |

### 診断結論：ノイズ要因 vs 物理モデル要因の切り分け

spp を 8 倍にして判明した切り分け：

- **モンテカルロノイズ由来だった成分**：max/min 比 11.6→4.3、std 35.8→27.9、CoV 0.236→0.183．極端な外れ値ピクセルが消えた．
- **物理モデル由来（spp 非依存）の成分**：**中心/周辺比 (1.330→1.328) と勾配 % (24.83→24.72) はほぼ不変**．計算ノイズではなく構造的な空間勾配．

ノイズ分解（`std² = 信号² + ノイズ²`、ノイズ ∝ `1/√spp`）で逆算：

- spp=1024 の残留ノイズ std ≈ 8.5、真の物理信号 std ≈ 26.5
- **spp→∞（ノイズゼロ）でも CoV は ≈ 0.174 までしか下がらない**（実測 0.0426 の約 4 倍）
- ⇒ spp をさらに上げても CoV は 0.183→0.174 程度で頭打ち．**spp 増加は費用対効果なし**．spp=1024 を基準設定として確定．

### 筐体内壁反射率スイープ（2026-05-18、spp=256・depth=12・raw float linear）

`printer_white`（5 メッシュ共有）の reflectance を 5 点振った結果（linear 空間）：

| R | CoV | 勾配% | C/P | 備考 |
| --- | --- | --- | --- | --- |
| 0.75 | 0.2173 | 25.91 | 1.3498 | |
| 0.80 | 0.2034 | 24.00 | 1.3157 | |
| 0.85 | 0.1893 | 22.08 | 1.2833 | 現基準反射率 |
| 0.90 | 0.1753 | 20.15 | 1.2523 | |
| 0.92 | 0.1697 | 19.42 | 1.2410 | マット白プラ実用上限 |

全指標が反射率と単調・線形に改善するが感度は低い（∂勾配/∂R ≈ −38 %/単位, linear）．実測到達には R≈1.2〜1.4 が必要で物理範囲外．**反射率は弱い二次レバーで、これ単独では差を閉じられない**．

### 手法訂正：linear vs sRGB の直接比較は不成立（OETF 順方向適用が必須）

**それまでの「シミュ linear 放射輝度 vs 実測 PNG」の数値突合は交絡していた．** CoV・勾配・中心/周辺比が「無次元だからスケール任意」で不変なのは **光量→画素値が線形のときだけ**．実測 PNG は実機 ISP の **sRGB ガンマ（OETF, IEC 61966-2-1）** が掛かった非線形符号化値（Camera2 `YUV_420_888` → BT.601 は定義上ガンマ済み R'G'B' 上の量）であり、シミュの linear とは別ドメイン．非線形変換下でこれら指標は不変でない．

実測データ提供側 README も明示していた：

> シミュ側を線形放射輝度のまま比較する場合、**勾配/CoV の絶対値は変わる**（実測は ISP 補正込み）．…ガンマ補正解除しない．実測は ISP 適用後の sRGB 表示輝度で評価している．
>
> レンズシェーディング補正が ON だと周辺光量低下の一部は ISP が補正している．「シミュの勾配が実測より大きい」ことが期待される（このため 6% は補正後の残存ムラ）．

**訂正手順（overfitting なし）**：標準 sRGB OETF を順方向適用し、露出は AE が制御する量＝実測 ROI mean (146.71) にアンカー（線形ゲインなので形状指標には自由度を持ち込まない；OETF が非線形なため「曲線上の動作点」を合わせる原理的アンカーとして必須）．データに合わせて回す係数はゼロ．無彩色シーン（LED・材料が RGB 等価）のため luminance への直接 OETF 適用はチャネル別適用後 luma と厳密一致．

OETF 適用後の比較（係数調整なし、uint8 量子化、clip 0%）：

| ソース | 空間 | CoV | 勾配% | C/P |
| --- | --- | --- | --- | --- |
| R0.85 (d8,spp1024 = 確定基準) | linear | 0.183 | 24.65 | 1.327 |
| 〃 | **sRGB** | **0.089** | **12.57** | **1.144** |
| R0.85 (d12,spp256) | sRGB | 0.091 | 11.16 | 1.126 |
| R0.92 (d12,spp256) | sRGB | 0.081 | 9.72 | 1.108 |
| **実測 TARGET** | **sRGB** | **0.0427** | **6.10** | **1.0650** |

確定基準で勾配 24.65→12.57（実測との差 18.6→6.5、**約 65% が符号化ドメイン不一致だった**）、CoV 0.183→0.089（差の **約 67%**）．標準変換だけで見かけの「物理差」の約 2/3 が消えた．

### luma vs luminance と演算順序（実測式との整合）

実測 (MiniTias-Evaluation) の「輝度値」は厳密には **Rec.709 luma Y'** ＝ ガンマ済み成分への加重和 `Y' = 0.2126R' + 0.7152G' + 0.0722B'`（README どおりガンマを戻さない＝luminance ではなく luma）．一方シミュ側は linear luminance に直接 OETF を当てている．OETF は非線形なので一般に演算順序が効く（`Σwᵢ·f(xᵢ) ≠ f(Σwᵢ·xᵢ)`）が、**矛盾しない**：

- Rec.709 重みは合計 1（0.2126+0.7152+0.0722 = 1.0000）．**R=G=B=x の無彩色画素**では「チャネル別 OETF→加重和」`Σwᵢ·f(x)=f(x)` も「加重和→OETF」`f(x·Σwᵢ)=f(x)` も**厳密に一致**．
- シミュのシーンは白色 LED（RGB 等価 radiance）＋無彩色拡散材で**厳密に R=G=B**．よって「luminance に直接 OETF」＝「実測の演算順（チャネル別 OETF→Rec.709 加重和）」と同値．
- 本質: **OETF は不整合を作る操作でなく消す操作**．OETF 前のシミュ＝linear 空間 luma、実測＝gamma 空間 luma で別ドメイン（＝真の不整合）．OETF 後は両者とも gamma 空間 luma で同種量になり、突合が初めて正当化される．

残る近似（いずれも二次、調整しないモデル誤差に含む）：
1. 無彩色等価が厳密なのはシミュ側のみ．実測白板画像は LED 分光・ISP ホワイトバランス・センサ応答で微小に非グレー（R'≈G'≈B' が完全でない分の luma vs luminance 差）．
2. カメラ実 OETF ≠ 厳密 sRGB（独自トーンマップ）．

**実装時（productionization）の方針**: sm-evaluate への正規実装では「linear RGB をチャネル別 OETF → その後 Rec.709 luma」の順（実測の演算順そのもの）にする．無彩色シミュでは数値同一だが、将来カラー LED・色付き材料を入れても破綻しない忠実実装になる．今回の `apply_oetf.py` は無彩色前提の同値ショートカット．

### 寄与順の訂正と残差

以前の「主因は ISP レンズシェーディング（83%）」は OETF を抜かした交絡判断で**誤り**．正しい寄与順：

> **OETF（最大・約 2/3）＞ ISP レンズシェーディング補正（中・残差の主因候補）＞ 筐体内壁反射率（小・弱いレバー）**

OETF 適用後も最良点（R0.92,d12,sRGB）で勾配 9.72／CoV 0.081 と実測 6.10／0.043 の **1.6〜1.9 倍**が残る．この残差は **ISP レンズシェーディング補正＋スマホ独自トーンマップ＋モデル誤差**．LSC は周辺を持ち上げる動径ゲインで勾配・C/P を下げる方向＝残差の符号と整合．**残差はガンマ曲線いじりで消さず正直に残す**（OETF は標準で固定、調整対象は LSC 側）．

### 次アクション

1. ~~OETF 順方向適用を sm-evaluate へ正規実装~~（**完了**）．`evaluation/oetf.py`（標準 sRGB OETF + 露出ソルバ）＋ `EvaluationConfig.oetf` スキーマ＋ `sm-evaluate` 統合として実装済み．`configs/eval_baseline.yaml` で有効化、`configs/eval_real.yaml` は非適用（二重適用禁止）．後方互換（oetf 省略時は linear 評価）．参照実装 `apply_oetf.py` と数値一致をテストで担保．以降の全シミュ vs 実測比較は OETF 後ドメインで行う．設定仕様は [SPEC_02 evaluation.oetf](SPEC_02_シーン定義仕様.md) 参照．
2. **【次の本筋】残差に対し LSC 順方向モデルを当てる**．overfitting 回避のため自由多項式ではなく物理動機づけ低自由度形（cos⁴ ベース等）に限定し取得パラメータ数を明記する．
3. 反射率は均一性からは一意に定まらない（物理範囲内で縮退）ため暫定 0.85 据え置き．実フィラメント分光反射率データ入手時に再校正．

## 想定どおりの挙動（追加対応不要）

以下は実機と一致する挙動として **意図的にそのままにしている** 項目：

1. **評価板の楕円窓からの光漏れ**: 楕円窓は撮影用開口で、均一性測定時にも何も塞がない．シミュ上で楕円窓から外部に光が逃げる挙動は実機と整合．
2. **筐体開口部（スマホ取付穴等）からの光漏れ**: 同上．実機でも漏れる構造で、シミュも同じ．
3. **被写体（白板）は別途配置しない**: 「補正ボード」= 評価板（照明ムラ補正ボード）そのものを指す．楕円窓の奥に追加の白板は置かない．

## 既知の差分（実機との不一致）

Step 8 進行中に把握した、実機との未解消の差分：

1. **3D プリンタ白素材の反射率の正確な値**: 暫定 `0.85` だが、実物のフィラメント（PLA / PETG / ABS のどれか）と分光反射率データで再校正が必要．
2. **左右 LED 基板の正確な位置・向き**: STL から推定した座標で、Fusion 360 設計とのズレがある可能性．
3. **LED 1 個あたりの実 W 値**: 現状 `radiance=2807.25`（実測 mean=146.7 にスケール校正済み）．mean は一致するが、実機 SMD 2835 の規格値（~0.2 W）からの物理的整合性は未検証．
4. **スマホホルダの実素材**: 推定 `holder_dark` (0.50)．実物確認が必要．
5. ~~**linear vs sRGB のドメイン不一致（OETF 欠落）**~~（**最大要因・解消済み**）: シミュ linear と実測 gamma 空間 luma を直接突合していた交絡で見かけ差の **約 2/3**．標準 sRGB OETF 順方向適用＋実測 mean アンカーを `sm-evaluate` に正規実装して解消（`evaluation/oetf.py` + `EvaluationConfig.oetf`、`configs/eval_baseline.yaml` で有効化）．以降の比較は OETF 後ドメインで行う．※ 旧版でここを「主因は ISP レンズシェーディング」としていたのは OETF を抜かした誤り．
6. **【残差の主因候補・未対処】ISP レンズシェーディング補正**: 実測 PNG は実機 ISP の周辺減光電子補正込み、シミュは未補正．OETF 適用後も残る 1.6〜1.9 倍差の主因候補．LSC 順方向モデル（物理動機づけ低自由度形、overfitting 回避）で対処予定．
7. **【残差・不確実・未対処】スマホ独自トーンマップ**: ISP は sRGB OETF に加え独自トーンマッピング/コントラストを掛けうる．真のトーンカーブ未知．残差の一部．調整で消さず正直に残す方針．
8. **【未対処】max_depth=8 が勾配を過大評価**: depth=8→12 で勾配 linear 24.65→22.08（−2.6pt）/ sRGB 12.57→11.16（−1.4pt）．確定 YAML は現状 8 のまま（レンダコスト優先で変更保留）．キャリブ用途は depth≥12 を使うこと．
9. ~~**評価 ROI の不一致**~~（**解消済み**）: ROI を実機と物理対応させ（`configs/eval_baseline.yaml` = pixel (24,37,464,450)）、`sm-evaluate` は実測 PNG に対し MiniTias-Evaluation と小数点 14 桁レベルで一致を確認済み．評価ロジック起因の差はない．

## 参照（References）

- 実機写真: [REFERENCE/housing_interior_real.jpg](../../REFERENCE/housing_interior_real.jpg)
- LED 基板拡大: [REFERENCE/led_board_closeup.jpg](../../REFERENCE/led_board_closeup.jpg)
- Fusion 360 内部視点: [REFERENCE/fusion360_housing_interior.png](../../REFERENCE/fusion360_housing_interior.png)
- LED データシート: [REFERENCE/smd2835_datasheets.png](../../REFERENCE/smd2835_datasheets.png)
- YAML 仕様（一般形）: [SPEC_02_シーン定義仕様](SPEC_02_シーン定義仕様.md)
- 基準設定の YAML 実体: [configs/scene_baseline.yaml](../../configs/scene_baseline.yaml)
