PHPプログラムで制御する3Dプリンタ入門

第2回3Dプリンタが苦手な形をプログラミングで作るには

前回は穴のある立体を扱いました。今回は、いわゆる3Dプリンタではうまく出力できないケースを取り上げてみたいと思います。

その前に、出力したデータがどうなっているのか、画面上で確認してみましょう。

前回作ったキートップは、上の画面のようになっています(マウスでドラッグして回転させることができます⁠⁠。すべて、小さな三角形に分割されているのがわかります。この画面はデータの確認に便利なよう、三角形と三角形のあいだに隙間を作ってありますが、実際にはぴったりとつながっています。そして、面が手前を向いていると太い線で、面が逆を向いている場合は細い線で表示されます。これも、データ中のベクトルが正しいかどうかを確認するためのものです。

ルーバーの部品を作る

今回作るのは、下の画面のような形です。これを使って写真1のようなルーバーを作ることができます。ホームセンターなどでアクリル板を5cm幅に切ってもらい、3Dプリンタで出力した部品にはめ込みます。プラダンのような不透明なものを使えば、風は通すのに中は見えない、といった使い方ができます⁠。

写真1 完成したもの
写真1 完成したもの
※)
実際に使うときは、強風で壊れて人にケガなどさせないよう十分にご注意ください。

さて、この形を3Dプリンタで作ると、どこが問題になるでしょうか。それは、ネジ棒を通す横穴の部分です。下の層から積み重ねていくと、この部分は下の支えがありません。そこで、図1のような六角形にしました。もし図2のような向きにすると、狭まるところが45°よりも浅くなるため、出力できなくなります。

図1 横穴の形状
図1 横穴の形状
図2 向きがずれると出力できない
図2 向きがずれると出力できない

図3の向きであれば、45°より深くなりますし、上に乗る層は平らなので写真2のようにまたがる形で出力することができます(これは出力ソフトが自動的にやってくれます⁠⁠。この穴に、3mm(M3)の全ネジの棒を通します。

図3 幅が狭ければ、またがって出力できる
図3 幅が狭ければ、またがって出力できる
写真2 実際の3Dプリンタ出力
写真2 実際の3Dプリンタ出力

横穴のあるデータの作り方は、2つの方法があります。1つめは、図4のように、最初の段階で余分な点を登録しておき、これを曲げて島を分離させる方法です。前回説明したように、同じ座標を往復する線は自動的に相殺されますので、きちんと島だけ残ります。今回使うのはこの方法です。

図4 方法1:CDとHIは相殺される
図4 方法1:CDとHIは相殺される

もう1つの方法は、幅ゼロの隙間を用意しておき、あとで広げる方法です図5⁠。これも、同じ座標を往復する線は互いに相殺されますので、最初の時点では分割されずに出力されます。

図5 方法2:BCとDEは相殺される
図5 方法2:BCとDEは相殺される

あとは、1mm上げてから横穴を作ります図6⁠。2mm上げるときに1mm広げ、いったん外周を6mm上げて、今と逆の順序で穴を閉じればできあがりです。また、板をはさむ溝の部分は、誤差があっても大丈夫なように、奥に行くほど狭くなるように作りました。ネジを締める力で板をはさむような位置に溝を配置しました。リストは以下のようになりましたリスト1⁠。ループを使い、10個並べて出力していますが、これはお使いになる3Dプリンタの出力サイズに合わせて修正してください。

図6 横穴の出力方法
図6 横穴の出力方法
リスト1 ルーバー部品を作るためのプログラム
$s0 =& new stl_solid();
print $s0->output(1);

$p = array();
$q = array();
$p[] =& $s0->addpoint(0, 0, 0);
$q[] =& $s0->addpoint(2, 0, 0);
$q[] =& $s0->addpoint(4, 0, 0);
$p[] =& $s0->addpoint(6, 0, 0);
$p[] =& $s0->addpoint(6, 1.5, 0);
$p[] =& $s0->addpoint(8, 4, 0);
$p[] =& $s0->addpoint(6, 6, 0);

$p[] =& $s0->addpoint(6, 30, 0);
$p[] =& $s0->addpoint(8, 32, 0);
$p[] =& $s0->addpoint(44, 32, 0);
$p[] =& $s0->addpoint(46, 30, 0);
$p[] =& $s0->addpoint(48.5, 32, 0);

$q[] =& $s0->addpoint(52, 32, 0);
$q[] =& $s0->addpoint(52, 32, 0);
$q[] =& $s0->addpoint(54, 32, 0);
$q[] =& $s0->addpoint(54, 32, 0);
$p[] =& $s0->addpoint(56, 32, 0);
$p[] =& $s0->addpoint(56, 65, 0);
$q[] =& $s0->addpoint(54, 65, 0);
$q[] =& $s0->addpoint(52, 65, 0);
$p[] =& $s0->addpoint(50, 65, 0);
$p[] =& $s0->addpoint(50, 63.5, 0);
$p[] =& $s0->addpoint(48, 61, 0);
$p[] =& $s0->addpoint(50, 59, 0);

$p[] =& $s0->addpoint(50, 35, 0);
$p[] =& $s0->addpoint(48, 33, 0);
$p[] =& $s0->addpoint(12, 33, 0);
$p[] =& $s0->addpoint(10, 35, 0);
$p[] =& $s0->addpoint(7.5, 33, 0);
$q[] =& $s0->addpoint(4, 33, 0);
$q[] =& $s0->addpoint(4, 33, 0);
$q[] =& $s0->addpoint(2, 33, 0);
$q[] =& $s0->addpoint(2, 33, 0);
$p[] =& $s0->addpoint(0, 33, 0);

for ($i=0; $i<6; $i++) {
	$q[$i]->moveadd(0, 0, 1);
	$q[11 - $i]->moveadd(0, 0, 1);
}
$q[3]->moveadd(0, 33, 0);
$q[4]->moveadd(0, 33, 0);
$q[9]->moveadd(0, -33, 0);
$q[10]->moveadd(0, -33, 0);

$q[0]->moveadd(-1, 0, 2);
$q[1]->moveadd(1, 0, 2);
$q[2]->moveadd(-1, 0, 2);
$q[3]->moveadd(-1, 0, 2);
$q[4]->moveadd(1, 0, 2);
$q[5]->moveadd(1, 0, 2);
$q[11]->moveadd(-1, 0, 2);
$q[10]->moveadd(-1, 0, 2);
$q[9]->moveadd(1, 0, 2);
$q[8]->moveadd(1, 0, 2);
$q[7]->moveadd(-1, 0, 2);
$q[6]->moveadd(1, 0, 2);

foreach ($p as $key => $dummy)
	$p[$key]->moveadd(0, 0, 6);

$q[0]->moveadd(1, 0, 2);
$q[1]->moveadd(-1, 0, 2);
$q[2]->moveadd(1, 0, 2);
$q[3]->moveadd(1, 0, 2);
$q[4]->moveadd(-1, 0, 2);
$q[5]->moveadd(-1, 0, 2);
$q[11]->moveadd(1, 0, 2);
$q[10]->moveadd(1, 0, 2);
$q[9]->moveadd(-1, 0, 2);
$q[8]->moveadd(-1, 0, 2);
$q[7]->moveadd(1, 0, 2);
$q[6]->moveadd(-1, 0, 2);

$q[3]->moveadd(0, -33, 0);
$q[4]->moveadd(0, -33, 0);
$q[9]->moveadd(0, 33, 0);
$q[10]->moveadd(0, 33, 0);

for ($i=0; $i<6; $i++) {
	$q[$i]->moveadd(0, 0, 1);
	$q[11 - $i]->moveadd(0, 0, 1);
}

for ($i=0; $i<10; $i++)
	print $s0->output(0, -$i * 10, $i * 10);

print $s0->output(2);

もっとしっかりしたものがいいという場合は、アクリル板に穴を開け、そこに全ネジの棒を通す構造にするとよいでしょう。

このデータでは、横穴を六角形にすることで、出力の問題を回避することができました。では、これではうまくいかない場合は、どうしたらいいでしょうか。

プーリーを作る

写真3をご覧ください。これは、モーターの軸に取り付けたプーリーです。この形を下から出力していくと、いったん径が細くなり、そのあと太くなります。この太くなる部分が問題で、支えがないため出力することができません。また、角度を浅くして45°以下にすると、プーリーとして機能しなくなるため、これもできません。

写真3 プーリーの全体
写真3 プーリーの全体

そこで、このプーリーは写真4のように分割して出力しました。

写真4 分割したところ
写真4 分割したところ

データの作り方は図7の通りです。モータの軸径は8mmで、切り欠きがあります。小さい方の部品は、まず底面を定義します。前回と同じように、軸穴は0.5mm太くなっていますが、これはあとで1mm持ち上げながら本来の径に戻します。

図7 底面の形状
図7 底面の形状

中間にワイヤーを通せる穴を用意します。外周は、1mmはまっすぐに持ち上げて、そのあと径を6mm絞りながら3mm持ち上げます。軸穴は、1mm持ち上げたあと、真横に3mm広げます。ここに、大きい方の部品の出っぱりが入ることになります図8⁠。まっすぐに2mm持ち上げて、完成です。

図8 断面(小さい部品)
図8 断面(小さい部品)

大きい方の部品のうち、外周は先ほどとまったく同じです。軸穴の方は、0.5mm絞ったあとまっすぐ持ち上げ、さらに2mm広げます。最後に外周と同じ高さまで下げて完成です図9⁠。

図9 断面(大きい部品)
図9 断面(大きい部品)

作るのは簡単でしたが、問題は、モーターの軸の切り欠きにぴったりと押し込めるかどうかです。そこで、プログラムを使い、切り欠きの深さが異なるものをいくつも作れるようにしました。切り欠きの部分は、図10のように円の一部を折り返して実現しています。この方法だと、切り欠き部の厚さを簡単に変えられるという利点があります。

図10 切り欠きの形
図10 切り欠きの形

こうして、プログラムはリスト2のようになりました。完成形はその下の画面です。筆者は、まず小さい部品を寸法を変えて5つ出力し、切り欠きの厚さが確定したら、その値を使って大きい部品を出力する、という順番で作業しました。写真4に見える黒いマークは、3Dプリンタから取りだすときにサインペンで印をつけて、あとで区別がつくようにしたものです。

リスト2 プーリー作成元プログラム
$s0 =& new stl_solid();
$first = 1;

for ($i=0; $i<2; $i++) {
#    $cut = 0.25 + $i * 0.15;
    $cut = 0.6 + $i * 0.1;
    for ($j=0; $j<2; $j++) {
        $s0 =& new stl_solid();
        
        $circle_inner = array();
        set_circle($s0, $circle_inner, $r_inner + 0.5, 0, $cut);
        
        $hole = array();
        $hole[] =& $s0->addpoint($r_body + 1, 0, 0);
        $hole[] =& $s0->addpoint($r_body + 2, -1, 0);
        $hole[] =& $s0->addpoint($r_body + 3, 0, 0);
        
        $circle_outer = array();
        set_circle($s0, $circle_outer, -$r_rim, 0);
        
        $hole[2]->addchild();
        $hole[] =& $s0->addpoint($r_body + 2, 1, 0);
        $hole[0]->addchild();
        
        set_circle($s0, $circle_inner, $r_inner, 1, $cut);
        if ($j == 0) {
            set_circle($s0, $circle_inner, $r_inner, 2, $cut);
            set_circle($s0, $circle_inner, $r_body + 0.5, 2);
            set_circle($s0, $circle_inner, $r_body + 0.5, 4);
        } else {
            set_circle($s0, $circle_inner, $r_inner, 4 + $h_body + 2, $cut);
            set_circle($s0, $circle_inner, $r_body, 4 + $h_body + 2);
            set_circle($s0, $circle_inner, $r_body, 4);
        }
        
        set_circle($s0, $circle_outer, -$r_rim, 1);
        set_circle($s0, $circle_outer, -($r_body + 3), 4);
        
        foreach ($hole as $key => $dummy)
            $hole[$key]->moveadd(0, 0, 4);
        
        if (($first)) {
            $first = 0;
            print $s0->output(1);
        }
        print $s0->output(0, $unit * $i, $unit * $j);
    }
}
print $s0->output(2);

ここまで、3Dプリンタの弱点と、その回避方法を説明しました。では、ほかにどんな弱点があるでしょうか。

3Dプリンタの弱点

この連載で扱っている3Dプリンタは、フィラメントと呼ばれるプラスチック材を融かして、小さなノズルから押し出します。こうしてできた、シャープペンシルの芯くらいの太さの融けたプラスチックを積み重ねていくことで、立体を出力します。このため、注意しないといけない点が3つあります。最後に、この3つの弱点を紹介しましょう。

1つめは、もう何度も書いていますが、下の層から順に積み重ねていくため、下に何もないところには材料が置けないという点です。たとえば、⁠ワ」という文字の形を出力する場合を考えてみます図11⁠。下の層から順に出力するので、⁠ワ」の右下の部分が下から上に向かって出力されていきます。その後、⁠ワ」の左の部分が突然現れますが、下には何もありません。出力しても下に落ちてしまいます。

図11 下に何もないと出力できない
図11 下に何もないと出力できない

この場合は、向きを変える、上下を逆にするなど、下から順に出力していける配置にする方法があります。また、2つの部品に分けたり、宙に浮いている部分を支えるダミーの部品(サポートと呼ばれます)を一緒に出力して後で取り除くといった方法もあります。

今回のように穴を閉じる場合も、下に何もありません。しかしあまり幅がなければ、またぐように出力することは可能です。

2つめは、層が重なっている構造なので、層を引き剥がす方向の力には弱いという問題があります。たとえば、⁠L」の形を垂直に出力する場合を考えてみます。もし、⁠L」の縦の棒を曲げる力がかかると、応力が付け根のところに集中し、層が剥がれるように折れてしまいます。この場合は、⁠L」を横倒しにして水平にすると、丈夫になります図12⁠。ですから、たとえばネジ穴を作る場合、ネジ穴を広げる方向に力がかかるかどうかで、向きを決める必要があります。

図12 向きを変えると丈夫になる
図12 向きを変えると丈夫になる

3つめは、材質の特性です。今回の3Dプリンタでは、PLAという素材とABSという素材の2種類が使えます。PLAは60℃前後から軟化しますので、高温になる場所で使う場合は注意が必要です。

筆者が使用している3Dプリンタの場合、出力物は、プリンタのベッド部の上にただ乗っているだけです。融かしたプラスチックが出てきますので、固まるとベッド部に貼り付きますが、完全に冷えると弱い力で剥がれてしまいます。出力中に出力物がベッドから剥がれてしまうと、出力物が高温のノズルにくっついて、台無しになってしまいます。これを起こりにくくするため、筆者の3Dプリンタでは、ベッドを電気で温めて、出力物が完全には冷えないようになっています(ヒーターベッドと呼んでいます⁠⁠。

しかし逆に、ベッドの温度が高すぎると、出力物がなかなか冷えず、やわらかいままになります。すると今度は、ノズルに引っ張られる力で少しずつ反りが発生し、これまたベッドから出力物が剥がれてしまうことになります。このため、収縮による反りが発生しやすい大きいものや、ノズルの力がテコの原理で拡大される背の高いものは、失敗することがあるので注意が必要です。対策としては、小さい部品に分割して、市販の棒や板材を使って並べるといった方法があります(今回のルーバーでも、ネジ棒を使っています⁠⁠。

ちなみに筆者は、室温40℃の部屋を閉め切って3Dプリンタを動かしていたところ、ヘッドやモーターからの発熱で3Dプリンタそのものが歪んでしまった経験があります(この3Dプリンタは組み立てキットで、主な部品は3Dプリンタで出力したPLA材なのです⁠⁠。前回、FabCafeで出力したパーツをご紹介しましたが、これはこのときに作ってもらったパーツです。このパーツと適当な材料を組み合わせて応急処理をほどこし、とりあえず出力ができるようにしました。これで、歪んだ部品のかわりを出力できるようになりましたので、熱源の近くにある部品の予備を自分自身で出力して交換し、修理することができました。

次回は、今回使ってきたライブラリの仕組みを解説し、3Dプリンタの選び方にも触れてみようと思います。ご期待ください。

おすすめ記事

記事・ニュース一覧