5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ある日、基板を編集していました。

スクリーンショット 2023-10-24 22.13.19.png

うーん...

スクリーンショット 2023-10-24 22.16.51.png

あれ

スクリーンショット 2023-10-24 22.17.32.png

素敵じゃん。

ということで、ビアで星空を作ります。

方針

星の数ほどのビアを手動で配置するのは大変なので、KiCadのPython Scriptingを使って自動化してみようと思います。

流れはこんな感じ

  1. データベースから星の座標を取得
  2. Python Scriptingでビアを配置

Python Scriptingを触ってみる

Python Scriptingでは、フットプリントのオブジェクトにアクセスして配置やプロパティの変更ができます。スクリプトはKiCadのスクリプトコンソールから実行します。

下記のサイトを参考にさせていただきました。

KiCadのPython scripting機能を使ってみる : 東京工業大学 ロボット技術研究会
KiCad PCBNew Python Scripting Cheat Sheet | atomic14
KiCad Pcbnew Python Scripting: pcbnew Namespace Reference

スクリプトを作る

まずは、スクリプトコンソールを立ち上げます。

PCBエディターのツール > スクリプトコンソールまたはツールバーのスクリーンショット 2023-10-24 234548.pngボタンから起動できます。

こんな画面が出てくるので、適当にprintでもしてみます。

Shell
>>> print("Hello, World!")
Hello, World!

スクリーンショット 2023-10-24 235416.png

よくある対話型シェルですね。

ただ、このままでは使い勝手がよくないので、pyファイルを作って実行してみます。

KiCadプロジェクトのルート(kicad_proファイルと同階層)にpyファイルを作り、適当なプログラムを書き込みます。

main.py
print("Hello, py file!")

実行するには下のようにimport <ファイル名>をスクリプトコンソールで実行します。

Shell
>>> import main
Hello, py file!

以降はこのファイルを編集していきます。

ビアを作成する

pythonから基板を編集するにはpcbnewを使います。KiCadのPCBエディタはpcbnewをラップしているようです。

Pcbnew | 5.1 | 日本語 | Documentation | KiCad

まずは、pcbnewインポートしてBOARDオブジェクトを取得します。

main.py
import pcbnew


board = pcbnew.GetBoard()

取得したBOARDオブジェクトを介してパーツの追加や移動ができるようになります。注意としては、PCB図面全体をボードとして扱うため、Edge.Cutsで囲んでいなくても図面全体がボードとなります。

次に、新しいビアを作成してみます。APIを参考にしてPCB_VIAオブジェクトをインスタンス化します。

KiCad Pcbnew Python Scripting: pcbnew.PCB_VIA Class Reference

main.py
import pcbnew


board = pcbnew.GetBoard()

+ via = pcbnew.PCB_VIA(board)
+ via.SetX(int(0 * 1_000_000))
+ via.SetY(int(0 * 1_000_000))
+ via.SetWidth(int(1.5 * 1_000_000))
+ via.SetDrill(int(1.0 * 1_000_000))

コンストラクタの引数には親要素を渡します。今回は先ほど取得したBOARDオブジェクトです。

__init__(PCB_VIA self, BOARD_ITEM aParent) -> PCB_VIA

ついでに位置と穴径、ランド系も指定します。

位置指定にはPCB_VIAクラスが継承しているEDA_ITEMクラスにSetPosition()関数があるほか、BOARD_ITEMクラスにSetX() SetY()関数があります。SetX() SetY()は引数がint型で使い勝手がいいため、今回はこちらで指定しています。

classpcbnew_1_1PCB__VIA__inherit__graph.png (261×411)

また、pcbnewでは位置や径などの長さをnmで管理しているため、関数の引数もnmに換算してから渡す必要があります。

最後に、作成したビアをボードに追加します。

main.py
import pcbnew


board = pcbnew.GetBoard()

via = pcbnew.PCB_VIA(board)
via.SetX(int(0 * 1_000_000))
via.SetY(int(0 * 1_000_000))
via.SetWidth(int(1.5 * 1_000_000))
via.SetDrill(int(1.0 * 1_000_000))

+ board.Add(via)
+ pcbnew.Refresh()

実行してみましょう。

Shell
>>> import main

スクリーンショット 2023-10-25 141243.png

位置(0, 0)に穴径1mm、ランド系1.5mmのビアが追加されました。これで任意の位置にビアを配置できるようになったので、次は配置する座標を決めていきます。

星の座標を取得する

星の座標としてAstro Commonsさんのヒッパルコス星座線恒星データを使わせていただきます。このデータセットには赤道座標を含む690個の恒星が収録されています。

pythonからダウンロードしたcsvファイルを読み込み、赤経と赤緯を抽出してみます。

main.py
import csv


with open('hip_constellation_line_star.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        ra = (float(row[1]) * 15) + (float(row[2]) * (15 / 60)) + (float(row[3]) * (15 / 3600))
        dec = float(row[4]) + (float(row[5]) * (1 / 60)) + (float(row[6]) * (1 / 3600))

raが赤経、decが赤緯です。赤緯は° " 'で表すのに対し、赤経はh m sで表し、1 hは15°なので注意が必要です。

完成

raをx座標にdecをy座標に指定して等級によって径を変えれば完成です。

全てのコード
main.py
import pcbnew
import csv
import math


board = pcbnew.GetBoard()

with open('hip_constellation_line_star.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        # 行から必要なデータを抽出
        ra = (float(row[1]) * 15) + (float(row[2]) * (15 / 60)) + (float(row[3]) * (15 / 3600))
        dec = float(row[4]) + (float(row[5]) * (1 / 60)) + (float(row[6]) * (1 / 3600))
        magnutude = float(row[7])
        number = row[0]

        # 平面座標に変換
        x = -ra * 1_000_000
        y = -dec * 1_000_000

        # 等級を適当な曲線でサイズに変換
        size = (2 * math.e ** (-0.2 * magnutude)) * 1_000_000

        via = pcbnew.PCB_VIA(board)
        via.SetX(int(x))
        via.SetY(int(y))
        via.SetWidth(int(size))
        via.SetDrill(int(size * (1 / 1.5)))
        board.Add(via)

        text = pcbnew.PCB_TEXT(board)
        text.SetX(int(x + (size / 2 + 1)))
        text.SetY(int(y))
        text.SetHorizJustify(pcbnew.GR_TEXT_H_ALIGN_LEFT)
        text.SetLayer(pcbnew.F_Fab)
        text.SetText(number)
        board.Add(text)


        pcbnew.Refresh()

いでよ!

Animation.gif

それでは観察していきましょう。

オリオン座

スクリーンショット 2023-10-25 171203.png

いいですねぇ。若干ゼータ星がずれてますがオリオン座になってます。左上の大きなビアがベテルギウス、右下がリゲルですね。

おおいぬ座

スクリーンショット 2023-10-25 171525.png

これは完全におおいぬ座ですね。ひときわ大きなシリウスが目立ちます。

こいぬ座

スクリーンショット 2023-10-25 171725.png

これは...線にしか見えない

冬の大三角形

スクリーンショット 2023-10-25 171921.png

最後に冬の大三角形です。大電流にも対応できそうです。

おしまい

いかがでしたか?

私はとても癒されました。Python Scriptingは情報が少なく、ここまで難儀する部分もありましたが、今回のビア配置を応用すれば様々な作業をPythonで自動化することができます。

今回のプロジェクトはGithubで公開しています。

waiwai2525/vianetarium

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?