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

15 KiB
Raw Blame History

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) 平行移動」と定義する。

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)にまだ追従していない。

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形式で出力する。

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の配置がスイッチに従属するか独立するかをユーザーが決め、ノードにするかを決める