Compare commits

..
3 Commits
Author SHA1 Message Date
ewdernaandClaude Opus 5 fdd3c7def1 workflow: 既存フローとの対応だけを残し、確定した仕様に追従させる
解決策・プロトコル・次のアクションの各節は layers と phase1 の重複だったため削除し、
工程分析とその課題だけの文書にした。レイヤーの定義は layers を正とする旨を冒頭に置く。
工程の対応先は、回路設計をELCのみ、ファームウェア基本設定をPHY+IDX+ELCに修正。
PCB製造は品種とフットプリントを持たないため対応なしとした。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 22:02:39 +09:00
ewdernaandClaude Opus 5 d858361586 schema: IDX/ELCスキーマを確定した仕様に追従させる
ELCをELCレイヤー.mdの保存形式で書き直した。microcontrollerとmatrixの列挙は
捨てたモデルなので削除し、提供者・端子・LEDチェーンに置き換え。参照先もIDXからPHYへ。
IDXからはrow/colとラベルを外し、キーIDとキー番号の対応だけにした。
PHYはcompatibilityブロックを、キー側と同じ形のファイル単位kleCompatibilityに置換。
clusterのnameは保存形式に無いため必須から外した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 21:56:32 +09:00
ewdernaandClaude Opus 5 8c47e547b4 layers: レイヤー構造を確定した仕様に追従させる
ELCがPHYのノードIDを直接参照すると決めたので、IDX→ELCの直列フローを
PHY→ELC / PHY→IDX の並列に改めた。row/colとLED番号をIDXの出力から外し、
KLEをビュワーとして扱う記述に合わせた。ツール名2つが捨てたモデルを
含んでいたため改名。アナログ値の解釈を持つ層が未定なのでP-1に立てた。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 21:48:43 +09:00
3 changed files with 212 additions and 176 deletions
+45 -29
View File
@@ -11,30 +11,38 @@
### 設計思想
- 「Better KLE」ではなく「Beyond KLE」: UIではなくデータモデルとワークフロー全体の再設計
- UNIX哲想の適用: 小さな役割のツールがそれぞれしっかり機能する
- UNIX哲学の適用: 小さな役割のツールがそれぞれしっかり機能する
- 統合環境(IDE)の提供: 独立したツール群をオーケストレート
## レイヤー構造
レイヤーは一列に積み上がらない。ELCとIDXはそれぞれ独立にPHYを参照する。
ELCはIDXを参照せず、IDXもELCを参照しない。
他レイヤーからキーや部品を指す参照には、PHYのノードIDを使う。
### 1. PHYレイヤー (物理配置)
- **役割**: キーの物理的な位置、サイズ、回転
- **役割**: キーと部品の物理的な位置、サイズ、回転
- **対応ツール**: PCBエディタ、KLE
- **出力**: 座標とキーサイズの配列
- **出力**: 相対座標の木(キー・クラスター・部品ノード)。各ノードはIDを持つ
### 2. ELCレイヤー (電気配線)
- **役割**: マイコンのpinと各キーの対応
- **役割**: ピン提供者が提供する論理ピンと、各キーの端子・LEDの対応
- **入力**: PHYのノードID
- **対応ツール**: 回路図エディタ、ファームウェア
- **出力**: ピン配列定義、マトリックス配線情報
- **備考**: charlieplexingなど非標準的な実装にも対応
- **出力**: 提供者定義、キーごとの端子の接続先、LEDチェーン
- **備考**: 配線方式(マトリクス / direct / charlieplexing)を区分として選ばせず、端子の接続先の組み合わせとして表すため、非標準的な実装も同じ形で書ける
- **備考**: row / col は正本に持たない。QMKなどが要求する形は出力時に割り当てる
### 3. IDXレイヤー (キー識別)
- **役割**: 物理位置と"キー番号"の対応付け
- **役割**: PHYのキーと"キー番号"の対応付け
- **入力**: PHYのキーID
- **重要性**: 物理世界と論理世界を繋ぐ最も重要な抽象化層
- **出力**: `{x, y, matrix:[row,col], label}[]`
- **出力**: キーIDとキー番号の対応
- **備考**: 現状のエコシステムで最も欠けている層
- **備考**: マトリックス座標とLEDの識別番号はIDXが持たない(どちらも配線で決まるためELCが持つ)
### 4. MAPレイヤー (キーマップ)
@@ -55,26 +63,25 @@
#### PHY Editor
- 物理配置の視覚的編集
- KLE互換フォーマット対応
- KLE JSONの読み込み・書き出し
- 出力: PHY JSON
#### Matrix Mapper
#### Key Indexer
- PHY Editorの出力を入力
- キーにrow/colを割り当て
- 視覚的にマトリックス配線を確認
- PHY JSONを入力
- キーにキー番号を割り当て
- 出力: IDX JSON
#### Pin Configurator
#### Wiring Editor
- マトリックス定義を入力
- マイコンのピン配置を指定
- 配線図を出力
- PHY JSONを入力
- ピン提供者(マイコン、マルチプレクサ等)を置き、各キーの端子の接続先を指定
- 視覚的に配線を確認
- 出力: ELC JSON
#### Keymap Designer
- キー識別子リストを入力
- キー番号のリストを入力
- レイヤー別キーコード割り当て
- VIA/Remapとの互換性
- 出力: MAP JSON
@@ -82,6 +89,7 @@
#### Firmware Generator
- 全レイヤーの情報を統合
- row / col など、ターゲットが要求する派生情報をここで割り当てる
- QMK/VIA/KMK等へ変換
- 出力: ターゲット固有の設定ファイル
@@ -97,17 +105,17 @@
### レイヤー間インターフェース
```txt
PHY → IDX
Input: KLE JSON (or compatible)
Output: Augmented layout (coordinates + key IDs)
PHY → ELC
Input: ノードID + 配置
Output: 提供者定義 + 端子の接続先 + LEDチェーン
IDX → ELC
Input: Key ID list
Output: Matrix definition + Pin mapping
PHY → IDX
Input: キーID + 配置
Output: キーIDとキー番号の対応
IDX → MAP
Input: Key ID list
Output: Keymap arrays
Input: キー番号のリスト
Output: レイヤー別キーコード配列
All → Firmware
Output: QMK keyboard.json / VIA JSON / KMK .py
@@ -124,7 +132,7 @@ All → Firmware
### Phase 1: プロトコル策定
- JSON Schemaでフォーマット定義
- TypeScriptでリファレンス実装
- リファレンス実装(言語・構成は `implementation-plan.md` で選定)
- CLIツールとして動作確認
### Phase 2: 個別ツール開発
@@ -141,7 +149,7 @@ All → Firmware
## 既存ツールとの関係
- **KLE**: PHY Editorの一実装、インポート対応
- **KLE**: PHYデータを表示できる既存のビュワー。KLE JSONの読み書きで連携する
- **VIA/Remap**: MAP Layerクライアントとして連携
- **QMK Configurator**: Firmware Generatorのターゲット
@@ -155,7 +163,7 @@ All → Firmware
### 互換性
- 既存KLE JSONの完全サポート
- 既存KLE JSONの読み込み(PHYデータがなくても読める)
- 段階的移行パスの提供
- レガシーツールとの共存
@@ -165,3 +173,11 @@ All → Firmware
2. GitHubでRFCリポジトリ立ち上げ
3. 小規模コミュニティでフィードバック収集
4. リファレンス実装の開発
## 未確認事項
### P-1 アナログ値の解釈をどの層が持つか
- 位置づけ: 未解決の問い。ELCは配線だけを持つと決めたため、生値から押下深さを出す変換の置き場が空いている
- 現状の認識: センサの品種と出力特性はPCB設計ツール側、キャリブレーションは実機ごとの実測値で設計データではない、とまでは決まっている。残りをMAPに寄せるか、別の層を立てるかは未定
- 格上げ条件: アナログ入力のキーボードを1つ通しで設計し、変換に必要な情報と、それを置く層をユーザーが決める
+11 -69
View File
@@ -1,5 +1,8 @@
# 自作キーボード制作ワークフロー分析
既存の制作フローの各工程が、どのレイヤーに当たるかを見る文書。
レイヤーの定義と役割は `keyboard-design-layers.md` を正とする。
## 現在の一般的な制作手順
### 1. デザイン・設計段階
@@ -23,7 +26,7 @@
- ダイオード配置の検討
- **出力**: 回路図、ピン配置表
- **現在の課題**: KLEからマトリックス情報への変換が手動
- **Beyond KLE対応**: **ELCレイヤー** + **IDXレイヤー**
- **Beyond KLE対応**: **ELCレイヤー**。行列構成という工程は持たず、キーの端子とピンの対応として書く
### 2. PCB設計段階
@@ -35,7 +38,7 @@
- スイッチフットプリントの配置
- マイコン・コネクタ等の部品配置
- **現在の課題**: KLEとPCBツール間の座標変換
- **Beyond KLE対応**: **PHYレイヤー** → PCBツール連携
- **Beyond KLE対応**: **PHYレイヤー** → PCBツール連携。渡すのは配置であって、フットプリントの選択はPCBツール側に残る
#### b) 配線・ルーティング
@@ -54,10 +57,9 @@
- マトリックス定義(ROW/COL)
- ピン配置設定
- 物理レイアウト定義
- **現在の課題**:
- KLEとファームウェア設定の手動変換
- VIAではlabelフィールドに"1,5"等を記入してmatrix座標を表現
- **Beyond KLE対応**: **IDXレイヤー** + **ELCレイヤー** → ファームウェア自動生成
- **現在の課題**: KLEとファームウェア設定の手動変換
- **Beyond KLE対応**: **PHY** + **IDX** + **ELC** → ファームウェア自動生成。
ROW/COLはELCの配線から出力時に割り当てる
#### b) キーマップ設定
@@ -73,7 +75,7 @@
#### a) PCB製造
- **出力**: Gerberファイル、BOM、Pick&Place
- **Beyond KLE対応**: PHY/ELCレイヤーからの自動生成
- **Beyond KLE対応**: なし。部品の品種とフットプリントを持たないため、この段階はPCB設計ツールが担う
#### b) 部品調達・組み立て
@@ -86,72 +88,12 @@
- **問題**: KLE → PCB → ファームウェアで毎回手動変換
- **影響**: 一箇所変更時の全体への反映が困難
### 2. マトリックス情報の欠落
- **問題**: KLEは物理配置のみ、論理構造(マトリックス)は別管理
- **影響**: VIAでのhackyな対応(labelフィールド悪用)
### 3. 設計変更時のトレーサビリティ不足
### 2. 設計変更時のトレーサビリティ不足
- **問題**: どのレイヤーでの変更が他に影響するかが不明確
- **影響**: デバッグ・修正作業の複雑化
### 4. ツール間連携の脆弱性
### 3. ツール間連携の脆弱性
- **問題**: 手動変換によるヒューマンエラー
- **影響**: 設計ミス、製造後の修正コスト
## Beyond KLEによる解決策
### 1. 統一データモデル
```
物理設計(PHY) → キー識別(IDX) → 電気設計(ELC) → キーマップ(MAP)
↓ ↓ ↓ ↓
PCBツール ファームウェア 回路図 VIA/Remap
```
### 2. レイヤー間の明確な責任分離
- **PHY**: 物理配置のみに集中
- **IDX**: 物理と論理の橋渡し(最重要レイヤー)
- **ELC**: 電気的接続の明確化
- **MAP**: キーマップロジックの分離
### 3. 双方向の依存関係管理
- 上流レイヤーの変更が下流に自動反映
- 下流での制約が上流設計にフィードバック
### 4. 既存ツールとの互換性維持
- KLE JSONの完全サポート
- VIA/QMK等への出力対応
- 段階的移行の実現
## Phase 1で策定すべきプロトコル
### 1. レイヤー間インターフェース仕様
- 各レイヤーの入出力JSON Schema
- 依存関係の明確化
- エラーハンドリング規則
### 2. 既存フォーマットとの変換仕様
- KLE JSON → PHY変換
- QMK設定 ← IDX+ELC+MAP変換
- VIA JSON ← 全レイヤー統合
### 3. 拡張性設計
- 非標準マトリックス(charlieplexing等)対応
- 3D配置への拡張可能性
- カスタムキーコードサポート
## 次のアクション
1. **JSON Schema策定**: 各レイヤーのデータ構造定義
2. **変換ロジック設計**: レイヤー間の変換アルゴリズム
3. **リファレンス実装**: TypeScript/Rust等でのプロトタイプ
4. **テストケース作成**: 代表的なキーボード設計での検証
+156 -78
View File
@@ -2,11 +2,16 @@
## レイヤー間データフロー
```txt
PHY (物理配置)
├─→ ELC (電気配線)
└─→ IDX (キー識別)
└─→ MAP (キーマップ)
```
PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キーマップ)
↓ ↓
ファームウェア生成 VIA/Remap出力
```
ELCとIDXはどちらもPHYを参照する。ELCはIDXを参照しない。
ファームウェアやVIA/Remap向けの出力は、各レイヤーの情報を統合して生成する。
他レイヤーからキーや部品を指す参照には、PHYのノードIDを使う。
## 1. PHYレイヤー JSON Schema
@@ -38,23 +43,10 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
"modified": { "type": "string", "format": "date-time" }
}
},
"compatibility": {
"kleCompatibility": {
"type": "object",
"description": "Information for external tool compatibility",
"properties": {
"kleJson": {
"type": "object",
"properties": {
"source": { "type": "string" },
"checksum": { "type": "string" },
"preservedFields": { "type": "array", "items": { "type": "string" } }
}
},
"originalFormat": {
"type": "string",
"enum": ["kle", "via", "qmk", "native"]
}
}
"description": "File-level opaque KLE fields kept for round-trip output (switchMount, switchBrand, switchType, backcolor, radii, background, css). The owning layer is undecided; see P-6 in PHYレイヤー.md",
"additionalProperties": true
},
"profiles": {
"type": "array",
@@ -196,7 +188,7 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
},
"cluster": {
"type": "object",
"required": ["type", "id", "name", "transform", "children"],
"required": ["type", "id", "transform", "children"],
"properties": {
"type": {
"type": "string",
@@ -324,6 +316,10 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
## 2. IDXレイヤー JSON Schema
IDXが持つのは、PHYのキーとキー番号の対応だけとする [推測:P-1]。
マトリックス座標(row/col)とLEDの識別番号はここに置かない。どちらも配線で決まる情報で、
row/col はELCの配線から導く派生情報、LEDの番号はELCが正本を持つ。
### 基本構造
```json
@@ -331,7 +327,7 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://beyond-kle.org/schemas/idx-layer.json",
"title": "IDX Layer - Key Identification",
"description": "Mapping between physical keys and logical identifiers",
"description": "Mapping between PHY keys and key numbers",
"type": "object",
"required": ["version", "phyReference", "keyMap"],
"properties": {
@@ -354,26 +350,16 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
"$defs": {
"keyMapping": {
"type": "object",
"required": ["physicalId", "logicalId"],
"required": ["keyId", "index"],
"properties": {
"physicalId": {
"keyId": {
"type": "string",
"description": "Reference to PHY layer key ID"
},
"logicalId": {
"type": "object",
"required": ["index"],
"properties": {
"index": { "type": "integer", "minimum": 0 },
"matrix": {
"type": "object",
"properties": {
"row": { "type": "integer", "minimum": 0 },
"col": { "type": "integer", "minimum": 0 }
}
},
"label": { "type": "string" }
}
"index": {
"type": "integer",
"minimum": 0,
"description": "Key number"
}
}
}
@@ -383,19 +369,21 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
## 3. ELCレイヤー JSON Schema
各フィールドの意味は `ELCレイヤー.md` を正とする。
### 基本構造
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://beyond-kle.org/schemas/elc-layer.json",
"title": "ELC Layer - Electrical Configuration",
"description": "Electrical wiring and pin mapping",
"title": "ELC Layer - Electrical Wiring",
"description": "Wiring between provider pins and key terminals",
"type": "object",
"required": ["version", "idxReference", "microcontroller", "matrix"],
"required": ["version", "phyReference", "providers", "keys"],
"properties": {
"version": { "type": "string" },
"idxReference": {
"phyReference": {
"type": "object",
"required": ["source", "checksum"],
"properties": {
@@ -403,41 +391,124 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
"checksum": { "type": "string" }
}
},
"microcontroller": {
"providers": {
"type": "array",
"items": { "$ref": "#/$defs/provider" }
},
"keys": {
"type": "array",
"items": { "$ref": "#/$defs/keyWiring" }
},
"ledChains": {
"type": "array",
"items": { "$ref": "#/$defs/ledChain" }
}
},
"$defs": {
"pinRef": {
"type": "string",
"pattern": "^(VCC|GND|[^.]+\\.[^.]+)$",
"description": "\"<provider id>.<pin name>\", or the reserved power rails VCC / GND"
},
"provider": {
"oneOf": [
{ "$ref": "#/$defs/mcuProvider" },
{ "$ref": "#/$defs/analogMuxProvider" }
]
},
"mcuProvider": {
"type": "object",
"required": ["type", "pinMapping"],
"required": ["id", "kind", "part"],
"properties": {
"type": { "type": "string" },
"pinMapping": {
"id": { "type": "string" },
"kind": { "const": "mcu" },
"part": {
"type": "string",
"description": "Part number. Used to interpret pin names"
}
}
},
"analogMuxProvider": {
"type": "object",
"required": ["id", "kind", "channels", "select", "common"],
"properties": {
"id": { "type": "string" },
"kind": { "const": "analog-mux" },
"channels": {
"type": "integer",
"minimum": 1,
"description": "Number of logical pins provided. Pin names are \"0\"..\"channels-1\""
},
"select": {
"type": "array",
"items": { "$ref": "#/$defs/pinRef" },
"description": "Select pins, least significant bit first"
},
"common": { "$ref": "#/$defs/pinRef" },
"enable": { "$ref": "#/$defs/pinRef" }
}
},
"keyWiring": {
"oneOf": [
{ "$ref": "#/$defs/contactKey" },
{ "$ref": "#/$defs/analogKey" }
]
},
"contactKey": {
"type": "object",
"required": ["key", "detect", "terminals"],
"properties": {
"key": {
"type": "string",
"description": "Reference to PHY layer key ID"
},
"detect": { "const": "contact" },
"terminals": {
"type": "object",
"description": "Non-polar. a and b carry no ordering meaning",
"required": ["a", "b"],
"properties": {
"rows": {
"type": "array",
"items": { "type": "string" }
},
"cols": {
"type": "array",
"items": { "type": "string" }
}
"a": { "$ref": "#/$defs/pinRef" },
"b": { "$ref": "#/$defs/pinRef" }
}
},
"diode": {
"type": "string",
"enum": ["a-to-b", "b-to-a"],
"description": "Anode side comes first. Omitted means no diode"
}
}
},
"analogKey": {
"type": "object",
"required": ["key", "detect", "terminals"],
"properties": {
"key": {
"type": "string",
"description": "Reference to PHY layer key ID"
},
"detect": { "const": "analog" },
"terminals": {
"type": "object",
"required": ["out", "vcc", "gnd"],
"properties": {
"out": { "$ref": "#/$defs/pinRef" },
"vcc": { "$ref": "#/$defs/pinRef" },
"gnd": { "$ref": "#/$defs/pinRef" }
}
}
}
},
"matrix": {
"ledChain": {
"type": "object",
"required": ["type", "dimensions"],
"required": ["id", "data", "order"],
"properties": {
"type": {
"type": "string",
"enum": ["standard", "charlieplexing", "direct"]
},
"dimensions": {
"type": "object",
"required": ["rows", "cols"],
"properties": {
"rows": { "type": "integer", "minimum": 1 },
"cols": { "type": "integer", "minimum": 1 }
}
"id": { "type": "string" },
"data": { "$ref": "#/$defs/pinRef" },
"order": {
"type": "array",
"items": { "type": "string" },
"description": "PHY node IDs. The position in the array is the LED number"
}
}
}
@@ -505,25 +576,32 @@ PHY (物理配置) → IDX (キー識別) → ELC (電気配線) + MAP (キー
### PHY → IDX変換
1. PHYレイヤーから物理キーリストを取得
2. 各キーに論理IDを割り当て
3. マトリックス座標の自動生成(行列最適化)
1. PHYレイヤーからキーのリストを取得
2. 各キーにキー番号を割り当て
### IDX → ELC変換
### PHY → ELC変換
1. マトリックス次元を算出
2. ピン配置の最適化提案
3. 配線効率の検証
1. ピン提供者を置き、各提供者が消費する上位ピンを指定
2. 各キーの端子の接続先を指定
3. LEDチェーンの並びを指定
### IDX + ELC → MAP変換
### IDX + ELC + MAP → ファームウェア出力
1. キーインデックス配列の生成
2. デフォルトキーマップの提案
1. ELCの配線から、ターゲットが要求する row / col を割り当て
2. キー番号の配列とキーマップ配列の生成
3. VIA/QMK形式への出力
## 次のステップ
1. **TypeScriptでの型定義作成**
1. **型定義の作成**(言語は `implementation-plan.md` で選定)
2. **変換ロジックのプロトタイプ実装**
3. **テストケース(60%、Split等)での検証**
4. **既存KLE JSONからの変換機能**
## 未確認事項
### P-1 IDXがキー番号以外に持つものがあるか
- 位置づけ: 本文「2. IDXレイヤー JSON Schema」が前提にしている。IDXには仕様ドキュメントがなく、
決定済みの情報(row/col と LEDの番号はELC)から引き算した最小形として書いている
- 格上げ条件: IDXレイヤーの仕様をユーザーと決め、`IDXレイヤー.md` に書く