よくある備忘録的なにか

自作キーボード、写真メインにその他諸々と

Adobe Illustratorで描いた基板部品の座標を簡単にKiCADへ移入する手順

背景と目的

私が自作キーボードを設計する際は、ガジェット全体のデザインや、基板の外形、電子パーツの配置は 扱いが慣れているAdobe Illustrator(AI)で行うことが多いです。

全体のデザインが決まったら、KiCAD上でPCBのフットプリントの配置と配線を行っていくのですが、KiCADで細かい部品の配置をAIで設計したとおりに並べていくのは操作性や機能の違いからなかなか大変です。
またKiCADで頑張って並べ終わったフットプリントも、AIでデザインの変更を行うとまた全て並べ替えが必要となるので、デザインとコーディングのイテレーションをうまく回すことができませんでした。

本記事は、そんな中で見つけたAIで描いたパーツの位置情報を簡単にKiCADのフットプリントに反映するための小さなTIPSです。

全体的な手順の概要

概要はこんな感じになります

  1. AIで作図する際、位置を移出したい図形にKiCAD側でアノテーションしたパーツ名と同じ名前を付与する。
  2. Adobe ExtendScript Toolkit CCでJavaScriptスクリプトを実行し、AIで選択した図形の位置情報を出力する
  3. KiCADのPcbnewツール上で、Pythonスクリプトを実行しフットプリントの場所と角度を定義の位置に決定する。

準備(Adobe ExtendScript Toolkit CCをインストール)

公式サイトから無償でダウンロードできます。

www.adobe.com

AIから位置情報を移出するJavaScriptを準備

任意のフォルダにスクリプトを作成しておきます。

#target "illustrator"
(function(){
    var convMilli = 1 / (25.4 / 72);  
    try {
        if (app.documents.length > 0 ) {
            app.coordinateSystem = CoordinateSystem.DOCUMENTCOORDINATESYSTEM;
          for(i = 0; i < app.selection.length; i++){
            obj = app.selection[i];
            prop = obj.property;
            x1 = pt2mm(obj.geometricBounds[0]);
            y1 = pt2mm(obj.geometricBounds[1] * -1.0);
            x2 = pt2mm(obj.geometricBounds[2]);
            y2 = pt2mm(obj.geometricBounds[3] * -1.0);
            cx = x1 + (x2-x1)/2.0 ;
            cy = y1 + (y2-y1)/2.0 ;
            var rad = 0.0;
            if(obj.tags.length > 0 && obj.tags[0].name == "BBAccumRotation"){
                rad = obj.tags[0].value; //in radians
            }   
            var angle = rad * 180.0 / Math.PI;
            $.writeln( obj.name + "\t" + cx + "\t" + cy + "\t" + angle);
            }
        }
        else{
            throw new Error('no document');
        }
    }
    catch(e) {
        alert( e.message, "script error", true);
    }
   function mm2pt(mm) {
      return mm * convMilli;
   }
   function pt2mm(pt) {
      return pt / convMilli;
   }
})()

AIで描画した部品に名前を付与する

AIで作図する際、位置を移出したい図形にKiCAD側でアノテーションしたのと同じ名前を付与しておきます。
f:id:coal_layer:20201206104519p:plain

Adobe ExtendScript Toolkit CCでJavaScriptを実行する

Adobe ExtendScript Toolkit CCでJavaScriptスクリプトを実行し、AIで選択した図形の位置情報を出力します。
結果はToolkitウィンドウの中に表示されるので結果を選択してコピーします。
f:id:coal_layer:20201206104553p:plain

Pythonスクリプト化する

上記の出力はただの座標情報なので、これをPythonプログラムのデータとして移入側のスクリプトに仕込みます。

import pcbnew

OFFSET_X = 0.0
OFFSET_Y = 0.0

pcb = pcbnew.GetBoard()

def set_footprint_position(name, xp, yp, rot):
    module = pcb.FindModuleByReference(name)
    module.SetPosition(pcbnew.wxPointMM(xp  + OFFSET_X, yp + OFFSET_Y))
    module.SetOrientationDegrees(rot)  

parts = [
('SW-R1', 	40.03, 	98.339,	3.9),
('SW-R2', 	58.578, 	86.67,	2.4),
('SW-R3', 	77.673, 	78.188,	0),
('SW-R4', 	96.956, 	82.355,	1),
('SW-R5', 	116.147, 	83.246,	1.8),
]

for p in parts:
    set_footprint_position(p[0], p[1], p[2], p[3])

parts = [ ] の部分に部品名、X座標、Y座標、回転角を埋めます。
どのようにスクリプト化するかは人それぞれの得意とする方法があると思うのでここでは触れませんが、私は表計算ソフトを使ってデータの管理も兼ねてスクリプト化するような方式をとっています。
例では SW-R1からSW-R5までですが実際はパーツの数ぶんのデータが並ぶような感じになります。

PcbnewからPythonスクリプトを実行する

Pcbnewでネットリストを読み込んだ直後の状態。(これを一つ一つ正確に並べると思うと辟易してきます)
f:id:coal_layer:20201206114323p:plain

Pcbnewのツールバーにあるコンソールのボタンを押してPythonスクリプトウィンドウを開き、プロンプトに対して、スクリプト実行の命令を打ち込みます。
f:id:coal_layer:20201206105019p:plain

エラーがでなければ、これでフットプリントの配置が完了です。再描画が行われないので、マウスで選択するかPcbnewを再起動するかして反映させてください。

うまく行っていればこんな感じに綺麗に並んでいるはずです。
f:id:coal_layer:20201206114326p:plain

よくあるエラー

AttributeError: 'NoneType' object has no attribute 'SetPosition'

AI側の部品名とKiCAD側の部品名が一致していない場合によく発生します。よく見直してください。

追加TIP 1

私はクイックハックのスクリプトは作り込みすぎないことが肝要かと思ってますので、文字の整形や自動的な連携は作り込んでいません。また大量の数値が並んだデータは表計算ソフトに任せるのが便利で安心できると思うタイプです。
なので JavaScriptで出力した位置情報は一度Excelに貼り付けて管理しています。
有効桁数を揃えたり、Pythonスクリプトにコピペできる形に整形したりといった作業は全部Excel上でやっています。

追加TIP 2

自作キーボードの場合、キースイッチと一緒にダイオードやRGB LEDも実装することが多いですが、AI上でそれらも描画するのは面倒です。
Excel上で、スイッチ座標を元にダイオードとLEDの座標も自動的に算出するようにしています。

点Aから 距離(a,b)離れた点Bを、Aを中心にθ回転させた際の点Cの座標を求めなさい

というやつの復習ですね。
この計算もExcelのセルで行っています。

この記事は以上です。