【pythonで動くG-codeビルダー】gcoordinatorから円筒曲面上にパンチングホールパターンを形成してみる


※ 当ページには【広告/PR】を含む場合があります。
2024/04/05
【pythonで動くG-codeビルダー】G-coordinatorユーザーのための3Dプリンターで前処理・後処理をG-codeで考察する
蛸壺の中の工作室|gcoordinatorから円筒曲面上にパンチングホールパターンを形成してみる



以前、FreeCADを使った円筒に
「パンチングホール」 を空けるためのモデリング方法を、Curvesワークベンチを使って紹介させていただきました。

合同会社タコスキングダム|蛸壺の技術ブログ
【FreeCAD初心者ガイド】Curvesワークベンチで自由曲面へパンチングパターンを作成する

FeeCADで使える高度な自由曲面上3Dモデリングを可能とした「Curves」ワークベンチの使い方



そのモデリング工程も結構面倒で、しかもCurvesワークベンチの使い方を理解してからでないと思うように曲面上にホールパターンが貼り合わせできないなどの躓きポイントがいくつかありました。
今回はPython製の3Dプリンター用G-code生成ライブラリ・
「gcoordinator」 を使って、3Dプリンターを使ったパンチングホールありの円筒を出力する方法を解説します。
なお、
G-coordinator および gcoordinator の利用環境については以下の記事にまとめてあります。

合同会社タコスキングダム|蛸壺の技術ブログ
【pythonで動くG-codeビルダー】G-coordinator/gcoordinatorをLinuxにインストール&動作確認してみる

Pythonソースコードで3Dプリンター向けのgcodeが生成できる・『G-coordinator』をLinuxへ導入します。


円筒曲面上のパンチングホールパターンの数式モデル



gcoordinatorで3Dプリンター可能なG-codeを直接作成するためには、事前に数式モデル化の作業が必要となります。
gcoordinatorでのG-gode生成までのスクリプト実装作業よりも、数式を導く作業のほうが長い時間をとられるかもしれませんが、しっかりと考えていきましょう。

Z軸(鉛直)方向の構造周期性を定義する



3Dプリンターでの出力を考慮したとき、Z軸は出力開始位置となるノズルとベッドとの相対高さとなります。
463x568
合同会社タコスキングダム|蛸壺の技術ブログ


造形物の最終的な高さを
HH としたときに、Z軸方向に対して NN 回の繰り返し構造をもつとすると、

NT=H \displaystyle { NT = H } Eq. (Z軸方向の周期性)


ここでの
TT は1周期の高さになります。
周期性を表現するためには角度を使ったほうが扱いやすいので、
TT を以下のように変換しておきます。

T=2πA \displaystyle { T = 2 \pi A } Eq. (1周期分の高さ)


この式での
AA1[rad] あたりの換算高さです。
ということで、1周期範囲内(角度
θ , (0θ<2π)\theta\ ,\ (0 \leqq \theta \lt 2\pi) )での、相対換算z座標 tt

t=θA=θT2π=θH2πN \displaystyle { t = \theta A = \frac{\theta T}{2 \pi} = \frac{\theta H}{2 \pi N} } Eq. (1周期分のz座標)


で表されます。
ということで、周期性を備えた全体的なz座標は以下の式になります。

z=nt=nθH2πN \displaystyle { z = n t = \frac{n \theta H}{2 \pi N} } Eq. (z座標)


ここでの正の整数
n (n=1,2,3,...)n\ (n = 1,2,3,...) は周期数です。



1周期上の円を定義



先程の内容でZ軸方向の周期性の表現ができたので、次は周期的に現れる円の一つをどう表現するかを考えてみます。
538x466
合同会社タコスキングダム|蛸壺の技術ブログ


任意のXY平面上にある半径1の単位円を考え、その円周反時計回りに沿う方向をr軸とします。
ここで
r - tr\ \textrm{-}\ t 平面に存在する半径 CC 、中心 (r0,t0)(r_0,\,t_0) の円から、任意の tt の位置に対する、円の rr 座標の断面長さ Δ\Delta を調べていきます。
この円の円周上の任意の点を
(r,t)(r,\,t) とすると、円周角 φ\varphi を使って、

{rr0=Ccosφtt0=Csinφ \displaystyle { \begin{cases} r - r_0 &= C \cos\varphi \\ t - t_0 &= C \sin\varphi \end{cases} } Eq. (円周上の座標)


これを三角関数の公式から順次式変形をしていくと、

cos2φ+sin2φ=1(rr0C)2+(tt0C)2=1(rr0)2+(tt0)2=C2(rr0)2=C2(tt0)2(rr0)2=(Ct+t0)(Ct0+t)rr0=±(Ct+t0)(Ct0+t)r=r0±(Ct+t0)(Ct0+t)rr0±Δ2   Δ=2(Ct+t0)(Ct0+t) \displaystyle { \begin{gather} \cos^2\varphi + \sin^2\varphi = 1 \nonumber \\ \biggl(\frac{r - r_0}{C}\biggr)^2 + \biggl(\frac{t - t_0}{C}\biggr)^2 = 1 \nonumber \\ (r - r_0)^2 + (t - t_0)^2 = C^2 \nonumber \\ (r - r_0)^2 = C^2 - (t - t_0)^2 \nonumber \\ (r - r_0)^2 = (C - t + t_0) (C - t_0 + t) \nonumber \\ r - r_0 = \pm \sqrt{(C - t + t_0) (C - t_0 + t)} \nonumber \\ r = r_0 \pm \sqrt{(C - t + t_0) (C - t_0 + t)} \nonumber \\ r \equiv r_0 \pm \frac{\Delta}{2} \nonumber \\ \therefore\ \ \ \Delta = 2 \sqrt{(C - t + t_0) (C - t_0 + t)} \nonumber \end{gather} } Eq. (t座標の断面長さ)


が得られます。
上式をもう少し扱いやすくするために、1周期の長さの半分にあたる
θ=π\theta = \pi のときを t0t_0 にすると、

t0=π H2πN=H2N t_0 = \pi \ \frac{H}{2\pi N} = \frac{H}{2 N} Eq. (円の中心のt座標)


となるため、このとき
Δ\Delta は、

Δ=2(Ct+H2N)(Ct0+H2N) \displaystyle { \begin{gather} \Delta = 2 \sqrt{\Big(C - t + \frac{H}{2 N}\Big) \Big(C - t_0 + \frac{H}{2 N}\Big)} \nonumber \end{gather} } Eq. (t座標の断面長さ)


という式に整理できます。
ここでは、z軸を固定したときのxy平面上に存在する単位円の
Δ/2π\Delta/2\pi [rad]分の範囲を、3Dプリンターで印刷しないギャップとして計算に利用します。
ただし、実際の印刷時には、単位円ではなく半径
RR の任意の円に拡張して考えるので、円周の比率を考慮して、 Δ/R\Delta/R で補正します。


gcoordinatorによる数式モデリング



では、前節で構築した数式モデルをPythonコードに落とし込んでいきましょう。
ここでは「gcoordinator」を利用しますが、GUIアプリの「G-coordinator」とは少しだけ関数の扱いが違いますので、詳しくは公式のリファレンスを良く読んでください。

参考|G-coordinator/gcoordinatorへようこそ

まずgcoordinatorを任意の作業フォルダ内で実行するためには、
start_gcode.txtend_gcode.txt の2つのファイルを作業フォルダのルートにおいておく必要があります。


            $ touch start_gcode.txt end_gcode.txt

        

gcoordinatorを動かすだけなら、この2つのファイルは空でも構いません。
次にいよいよモデリング用のスクリプトを実装します。

holes_pattern.py というファイルを新規作成し、以下のような内容で編集します。

            import gcoordinator as gc
import numpy as np

def split_circle(gap_rad, N):
    start_pos = 0
    end_pos = 0
    routes = []
    if gap_rad <= 0:
        route = np.linspace(0, 2*np.pi, 50)
        routes.append(route)
        return routes

    for gap_num in range(N):
        start_pos = 2*np.pi*gap_num/N + gap_rad/2
        end_pos = 2*np.pi*(gap_num + 1)/N - gap_rad/2
        route = np.linspace(start_pos, end_pos, 100)
        routes.append(route)
    return routes

def opt_gap(C, H, N, t):
    A = H/N
    t = t % A
    diff = t - H/(2*N)
    tmp = (C + diff)*(C - diff)
    if C <= np.abs(diff) or tmp <= 0:
        return 0
    delta = 2*np.sqrt(tmp)
    return delta

def rot_holes(H, N, t):
    A = H/N
    t = t // A
    return t

full_object = []

Z_LAYERS = 1000
Z_T = 0.2
H = Z_LAYERS * Z_T #円筒の高さ
C = 3.0 #ホールの半径
N = 12 #Z方向のホールパターン周期
R = 100 #円筒の有効径
SPLIT_N = 42 #円筒周りのホールパターン個数
TILT = np.pi/3 #Z方向に対するホールパターンの配列方向の傾き角

for height in range(Z_LAYERS):
    #積層レイヤーのz座標
    t = height * Z_T
    #マージン(単位円上の周方向距離[mm])
    margin = opt_gap(C, H, N, t)

    #円筒外径から算出したmargin[rad]
    margin = margin/R
    routes = split_circle(margin, SPLIT_N)
    for route in routes:
        x = R * np.cos(route)
        y = R * np.sin(route)
        z = np.full_like(x, (height+1) * Z_T)
        wall = gc.Path(x, y, z)
        wall = gc.Transform.rotate_xy(wall, rot_holes(H, N, t) * TILT)
        full_object.append(wall)

gc.show(full_object)

gcode = gc.GCode(full_object)
gcode.start_gcode("start_gcode.txt")
gcode.end_gcode("end_gcode.txt")

gcode.save('test.gcode')

        

細かい実装ポイントの解説はここでは割愛しますが、gcoordinatorのプログラミングテンプレートに、構築した数式を素直に計算式に落とし込んでいるだけです。
ここらへんは、Pythonの学習も兼ねて、ご自身の手でポチポチとコードを書きながらじっくり考えてみてください。

では、このスクリプトをPythonから実行してみましょう。

            $ python holes_pattern.py

        


853x624
合同会社タコスキングダム|蛸壺の技術ブログ


出力したgcodeファイルが3Dプリントできるか他のGcodeビュアーでも確認します。
800x576
合同会社タコスキングダム|蛸壺の技術ブログ


ちゃんと出力もできることが確認できました。
単純なパンチングホールパターンだけなら、gcoordinatorでの数式モデリングが早いし確実です。


まとめ



今回はgcoordinatorを使って、パンチングホールパターンを持った円筒形状を作製する手順を紹介していきました。
数式モデルからパターンを生成しているため、FreeCADのような3DCADソフトほど感覚的で柔軟なモデリングとはなりませんが、その分を差し引いても、Pythonコードで一発出力できるため、モデリング作業時間が圧倒的に圧縮できるという大きなアドバンテージがあります。