Files
Beyond-KLE/PHYレイヤー.md
T
ewdernaandClaude Opus 5 1e22853218 PHY: スイッチを端子配置・ソケット方式・向きの3軸で持つ(P-7解消)
ブランドは持たない。同じボードに対して利用者がスイッチを選べるため、
ボード設計の情報ではない。KLEの sm, sb, st は端子配置と対応させず、
見た目の属性と同じく不透明なまま退避して書き戻す。

未知の端子配置の扱い(P-9)とLEDノード(P-10)を未確認事項に追加。

Journal: journal/2026-09-20-switch-terminal.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 08:42:41 +09:00

257 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PHYレイヤー
## 概要
PHYレイヤーは、キースイッチやキーキャップ、その他周辺部品の物理的な配置に関する情報を提供する。
付加的な情報として、matrix情報(ELCレイヤー)や入力キー情報(MAP/IMEレイヤー)を含ませることができるが、必須ではない。
## 構造
### キースイッチ/キーキャップの配置
各キーはスイッチ・キャップの情報を統合された状態で持つ。
スイッチ位置は、キャップの (w, h) 矩形の中心からのオフセットとしてキーごとに持つ(既定値0、単位U、キーのローカル座標系)。
Stepped Caps Lockのようにスイッチがキャップ中心からずれるキーがあり、キャップ形状だけではスイッチ位置が決まらないため。
以下、単に「キー」と呼ぶ場合、キーキャップの位置・サイズを表すオブジェクトをさすこととする。
### プロファイル設定
1ファイル内に複数のプロファイルを持たせることができる。
ユニットサイズ(1Uが何mmか、x軸・y軸それぞれ)を規定。
ビジュアル表現として、内側へのオフセット位置及びオフセット距離(mm or U単位)・R(U単位)を規定。
### 座標と回転
各ノードは、親ノードから見た相対的な配置を持つ。絶対座標は保持しない。
クラスター単位の移動・回転を親ノード1つの書き換えで済ませるため、相対座標を正本とする。
配置は「親の座標系で θ 回転してから (x, y) 平行移動」と定義する。
```txt
p_parent = Translate(x, y) · Rotate(θ) · p_child
```
この定義により、(x, y) は自分のローカル原点が親座標系のどこに来るかを表し、θ は自分の向きを表す。
回転軸は常に自分自身のローカル原点であり、パラメータとしては持たない。
キーもクラスターも同じ変換を持つため、キーごとに向きが異なる配置のためにクラスターを作る必要はない。
ローカル原点はキーキャップの左上角とする。座標単位はU。1Uのサイズはプロファイルで指定する。
座標・回転角度は、ローカル座標系で0.25U単位・15度単位でスナップするが正規化しない。
KLE JSONやPCB向けの出力は、階層を畳んで絶対座標に変換した導出物として生成する。
### キーのサイズ
0.25U単位でスナップするが正規化しない。
サイズはローカルの値であり、親の変換を受けない。
ISO Enterのように長方形でないキーは、サイズに2つ目の矩形(x2, y2, w2, h2)を加えて表す。
2つ目の矩形の位置は、キーのローカル原点からの相対値とする。
### スイッチの端子配置
キーは端子配置(terminal)・ソケット方式(socket)・スイッチの向き(orientation)を持つ。
スイッチのブランドは持たない。同じボードに対して利用者が好きなスイッチを選べるため、ブランドはボード設計の情報ではない。
- 端子配置は、穴・パッドの数・サイズ・位置が同一のスイッチを1つにまとめた識別子(MX-3pin、MX-5pin、Choc V1 など)。スイッチ側の足の配置を表す
- ソケット方式は直付けかホットスワップソケットか。端子配置とは独立した軸
- スイッチの向きは0/90/180/270の4方向。キーのローカル座標系に対する値で、既定は0。90度と270度は別物として扱う
- 3つの値はファイル単位の既定値を持ち、キーごとに上書きできる。一部のキーだけ別のスイッチを使うキーボードがあるため
端子配置は階層を持たない平坦な識別子とする。低背かどうかのような分類は、端子配置の定義表に属性列として持つ。
端子配置は電気的インターフェース(2端子接点 / アナログ / 光学)も決めるため、ELCレイヤーはスイッチ種別を別に持たない。
実際のPCBフットプリントは、端子配置・ソケット方式・向きの積として出力時に決まる。
端子配置の識別子から実フットプリントへの対応表はPHYではなくPCB出力の設定に置く。
フットプリント名はライブラリ依存で、既知の端子配置でも出力時の対応づけが要るため。
未知の端子配置はユーザー定義の識別子として持ち、対応表が未登録なだけとして扱う。
### デカールとゴースト
デカールとゴーストはキーとして扱い、フラグで区別する。KLEの d, g に対応する。
### ラベル
キーはラベルを参考情報として持つ。KLE JSONの取り込みでは照合に使う。
### グルーピング
複数のキーを「クラスター」としてまとめて運用することができる。
クラスターのみにフォーカスして編集が可能。
クラスターの原点が、配下のノードの回転中心になる。
**内部処理での利用**:
- クラスターごとの一括編集・移動・回転
- 階層構造による管理(クラスターの入れ子構造)
- 編集時のフォーカス制御
- 回転中心を保存したい場合はクラスターにする(ノード自身は回転中心を持たないため)
**外部連携での扱い**:
- クラスター構造はBeyond KLEのデータにのみ存在する。外部形式へは階層を畳んだキー配置だけを出力する
## 保存形式
各ノードは親から見た変換を持つ。キーとクラスターを混在させた木構造として保持する。
`phase1-json-schema.md` のPHYスキーマは、この節の Key 型(x2〜h2, decal, ghost, labels, switchOffset, terminal, socket, orientation)にまだ追従していない。
```ts
type Transform = {
x: number, // 親座標系での位置
y: number,
rotation: number // 親座標系での回転角度(度)
}
type Size = {
w: number, // ローカル値。親の変換を受けない
h: number,
x2?: number, // 長方形でないキーの2つ目の矩形。ローカル原点からの相対値
y2?: number,
w2?: number,
h2?: number
}
type Key = {
transform: Transform,
size: Size,
profile: Profile,
decal?: boolean,
ghost?: boolean,
labels?: string[], // 参考情報
switchOffset?: { x: number, y: number }, // (w, h) 矩形の中心から。省略時は0
terminal?: string, // 端子配置の識別子。省略時はファイル単位の既定値
socket?: 'solder' | 'socket', // 省略時はファイル単位の既定値
orientation?: 0 | 90 | 180 | 270 // キーのローカル座標系。省略時は0
}
type Cluster = {
transform: Transform,
children: (Key | Cluster)[]
}
const root: (Key | Cluster)[] = []
```
## 連携用出力形式
### KLEとの関係
KLEは、PHYデータを表示できる既存のビュワーとして扱う。
KLEで編集された時点で、そのデータはBeyond KLEのデータではない。
- KLE JSONにはBeyond KLE固有の情報(キーID、クラスター構造など)を含めない。出力は素のKLE JSONで、KLE JSONを読む他ツールにそのまま渡せる
- KLE JSONの取り込みは、手元のPHYデータとの照合で行う。IDや埋め込み情報には頼らない
- 過去のKLE JSONは、PHYデータがなくても読み込めなければならない。変換を伴ってよい
### KLE JSON出力
階層を畳んで絶対座標に変換し、標準的なKLE JSON形式で出力する。
```ts
type ConfigObject = {
x?: number,
y?: number,
w?: number,
h?: number,
x2?: number,
y2?: number,
w2?: number,
h2?: number,
r?: number, // 回転角度
rx?: number, // 回転中心
ry?: number,
l?: boolean,
n?: boolean,
d?: boolean,
c?: string,
t?: string,
g?: boolean,
a?: number,
f?: number,
f2?: number,
fa?: number[],
p?: string,
sm?: string,
sb?: string,
st?: string
}
type KeyLabel = string // 表示用ラベルのみ。識別情報は含めない
const kleData = (ConfigObject | KeyLabel)[][]
```
- 回転角度は正規化せずそのまま出力する。KLEのデータは任意の角度を受け付け、15度刻みはKLEのUI上の操作単位にすぎない
- rx, ry はPHYに持たないので、出力時に選ぶ
- ユニットサイズ(mm)、ビジュアルオフセット、クラスター構造はKLE JSONに出力されない
- 端子配置・ソケット方式・スイッチの向きはKLE JSONに出力しない。sm, sb, st には取り込み時に保持した値をそのまま書き戻す
- KLEの `p` はキーキャップのプロファイル名(SA、DCSなど)であり、PHYのプロファイルとは対応させない
### KLE JSONの取り込み
既存のPHYデータを畳んだ配置に対して、KLE JSONの各キーを形状(位置・サイズ・回転)とラベルで照合する。
- 照合できたキーは元のノードとして扱う。KLE側で配置が変わっていれば、元の親から見た相対座標に戻して反映する
- 照合できないキーは root 直下に新規キーとして置く。クラスターへの割り当てはユーザーが行う
- 構造の復元は保証しない。KLE側での編集が大きいほど、クラスター構造は失われる
- 配列の順番は照合に使わない。KLEは保存時にキーを「角度 → rx → ry → y → x」の順に並べ替えるため、順番は形状から決まる以上の情報を持たない
KLEの rx, ry, r はキーの絶対配置 (x, y, rotation) に変換して取り込む。元の rx, ry は保持しない。
見た目の属性(c, t, p, a, f, f2, fa, l, n)は、KLE JSONへ書き戻せるように保持する。どの層で持つかは決まっていない。
KLEの sm, sb, st(ファイル単位では switchMount, switchBrand, switchType)も同様に、不透明なまま保持して書き戻す。
PHYの端子配置とは対応させない。st はベンダー品番であり、穴・パッドの配置が決まらないため。
## 検討済み・非採用
- ノードごとの回転中心パラメータ (journal/2026-09-18-phy-coordinate-model.md)
- KLE JSONへの識別・構造情報の埋め込み(labelのID、`_beyondkle` メタデータ、ゴーストキー) (journal/2026-09-18-kle-roundtrip.md)
- KLEのデカール・ゴースト・見た目属性を取り込み時に捨てる (journal/2026-09-19-kle-key-attributes.md)
- スイッチのブランドをPHYで持つ (journal/2026-09-20-switch-terminal.md)
- 端子配置をPCBに開ける穴の配置として定義する (journal/2026-09-20-switch-terminal.md)
## 未確認事項
### P-1 KLE JSONへ書き出した配置が行のまとまりを保てるか
- 位置づけ: 本文が前提にしているものではない。連携用出力形式の設計に関わる未解決の問い
- 現状の認識: 階層を畳んでKLEに読み込ませると行のまとまりが崩れる。他レイヤーの情報を使ってでも行ごとにまとめたいが、方法は未検討
- 手がかり: KLEは r, rx, ry が同じで y が等しいキーを1行にまとめる。同じ絶対角度を持つキーに共通の rx, ry(例えばクラスターの原点)を選べば、行にまとめられる見込み
- 格上げ条件: 回転を含むPHYデータをKLE JSONに変換してKLE本家に読み込ませ、rotation groupと行配列がどう再構成されるかを確認する
### P-2 KLE JSON取り込み時の照合基準
- 位置づけ: 本文「KLE JSONの取り込み」の具体化に必要な未解決の問い
- 現状の認識: 形状の許容誤差、ラベルの扱い、複数候補がある場合の決め方が未定
- 格上げ条件: 照合規則を決めたうえで、KLE本家でキーの移動・追加・削除をしたJSONを取り込み、意図どおりに対応づくことを確認する
### P-3 KLE JSON取り込み時のクラスター自動推定
- 位置づけ: 未解決の問い。PHYデータなしで過去のKLE JSONを取り込むとき、座標の近さや角度からクラスターを推定するか
- 現状の認識: 採用しない可能性が高い。ただし代わりに欲しい機能があり、それを思い出すきっかけとして残している
- 格上げ条件: 代わりの機能を定義し、この推定を採るか捨てるかをユーザーが決める
### P-6 キーキャップの見た目情報を持つ層
- 位置づけ: 本文「見た目の属性は保持する。どの層で持つかは決まっていない」の未解決部分
- 現状の認識: c, t, p, a, f系に加え、l, n もキーキャップの見た目属性であり、PHYとは別の層が要りそう。退避だけして書き戻す sm, sb, st も同じ置き場の問題を持つ。そもそもキーキャップは設計時に決める必要が薄く、カスタムキーボードの文脈に属するため、Beyond KLEの扱う範囲かどうかも未定。ファイル単位の backcolor, radii, background, css も同じ問いに含まれる
- 格上げ条件: キーキャップの情報をBeyond KLEの範囲に含めるかをユーザーが決め、保持する層を決める
### P-8 ラベルをMAPに適用するか
- 位置づけ: 未解決の問い。本文ではラベルを参考情報として持つことだけを決めている
- 現状の認識: どのラベルがMAPに適用できるかは、おそらく機械的には判断できない。自動で適用してユーザーが不要なものを落とす方式も考えられる
- 格上げ条件: 適用するか、する場合は自動適用とユーザーによる取捨の流れをユーザーが決める
### P-9 未知の端子配置に対する編集画面の表示
- 位置づけ: 本文「未知の端子配置はユーザー定義の識別子として持つ」の未解決部分
- 現状の認識: 識別子だけでは穴・パッドの配置が分からないため、プレート切り欠きの描画やスイッチ位置の検証ができない。最低限の形状情報を持たせるかは未定
- 格上げ条件: 編集画面でスイッチ形状を使う機能を洗い出し、未知の端子配置に何を持たせれば足りるかを決める
### P-10 LEDを独立したノードとして持つか
- 位置づけ: 未解決の問い。LED用の穴をどう表すか
- 現状の認識: 端子配置のオプションとして持つ案もあるが、LED専用ノードが要る可能性がある。詳細は未検討
- 格上げ条件: LEDの配置がスイッチに従属するか独立するかをユーザーが決め、ノードにするかを決める