AliExpressのこのショップだけなぜかレーザーが安い。5Wで16,658円。
いま5%OFFみたいで、ついに$150以下。他のショップだと$200以上すると思うんだけど。
予備用にもう一台欲しいところ。
Mac+Arduino:自作CNCマシンの記録。作業エリア940x740mm、NEMA23ステッピングモーター4個、ボールスクリュー+リニアスライド、スピンドル(350W)、レーザー(5.5W)、制作費10万円
grbl1.1+Arduino CNCシールドV3.5+bCNCを使用中。
BluetoothモジュールおよびbCNCのPendant機能でスマホからもワイヤレス操作可能。
その他、電子工作・プログラミング、機械学習などもやっています。
MacとUbuntuを使用。
CNCマシン全般について: ・国内レーザー加工機と中国製レーザー加工機の比較 ・中国製レーザーダイオードについて ・CNCミリングマシンとCNCルーターマシンいろいろ その他: | 利用例や付加機能など: CNCルーター関係: |
2016年5月20日金曜日
2016年5月19日木曜日
CNCマシン:WebベースのCNC制御アプリ
現在は、Arduino Unoにgrbl0.9を入れてbCNCでGコードを読み込んで制御しています。Bluetoothをつけて無線化もできたし、bCNCのPendantでスマホやタブレットからの無線操作もできるので便利な環境になったのですが、個人的にはWebベースのCNCブラウザアプリが気になっていて、いろいろと試していました。
今までもいくつかリストアップしていましたが、
・LaserWeb2
・cheton/cnc
・GRBLWeb
・Easel
・ChiliPeppr Grbl Workspace
などあります。
今回はChiliPeppr Grbl Workspaceを試してみました。以下がサイトの入り口ですが、ここにも書いてあるように、Javascriptを使ってブラウザ上でシリアル通信を行えるような仕組みになっているようです。Grbl以外にもTinyG、そしてArduinoなどもすべてJavascript化してしまう感じです。
今はアプリもブラウザ上ですべて出来るような感じになってきたので、これもそんな感じでしょうか。
とりあえずGrbl Workspaceをクリックするとすぐに以下の画面が出ます。
そして、CNCマシン(Arduino)とシリアル通信しなければいけないのですが、右下の画面に「Download Serial Port JSON Server」というのがあり、そこをクリック。
今までもいくつかリストアップしていましたが、
・LaserWeb2
・cheton/cnc
・GRBLWeb
・Easel
・ChiliPeppr Grbl Workspace
などあります。
今回はChiliPeppr Grbl Workspaceを試してみました。以下がサイトの入り口ですが、ここにも書いてあるように、Javascriptを使ってブラウザ上でシリアル通信を行えるような仕組みになっているようです。Grbl以外にもTinyG、そしてArduinoなどもすべてJavascript化してしまう感じです。
今はアプリもブラウザ上ですべて出来るような感じになってきたので、これもそんな感じでしょうか。
とりあえずGrbl Workspaceをクリックするとすぐに以下の画面が出ます。
そして、CNCマシン(Arduino)とシリアル通信しなければいけないのですが、右下の画面に「Download Serial Port JSON Server」というのがあり、そこをクリック。
右下の画面を少し下へスクロールしていくと、JSON ServerのVesion 1.86(Mac OS x x64)があるのでMacならそれをクリックするとシリアル通信用のファイルがダウンロードされます。
ダウンロードされたファイルを解凍すると中には、
こんな感じで二つ入っています。
ここで、CNCマシンとUSB接続しておいてから、右側の「serial-port-json-server」をクリックすると、以下のように自動的にTerminalが起動します。
こんな感じでずらずらとシリアルポートが出て来ます。
これでシリアルポートのほうはつながる準備ができたようです。
また画面右下のウィンドウにいくと、Port Listタブで、接続しているArduinoボードのシリアルポートが出ているので、上画面のようにgrbl、115200を選んで左側のチェックを入れるとこのように緑色になってつながります。ダメな場合は上に並んでいる5個のボタンの左端のボタンが更新なので、何回か押してみるとポート内容が更新されて出てきます。それでもダメならブラウザで再度読み込み。
つながれば、以下のように左下のウィンドウにGrbl 0.9j ['$' for help]と設定内容がでます。
あとはこの↑「Type serial port command」のところに$Xを入力してロック解除したり、また右上のウィンドウの「Axes」(右から2番目のボタンを押すとウィンドウがひろがる)でジョグ操作したりできます。
マシンの設定が違っているかもしれないので、いちおう$$で設定内容をチェックして必要なら再設定しておいたほうがいいと思います。
それから画面上中央にあるSimulatorボタンで加工パスを動かしてみることもできるようです。
左上のウィンドウにはいくつか機能のボタンもあって、Auto-LevelやEagle BRDで基板加工をしたり、JScutを呼び出してGコード生成したり、GPIOでPaspberry Piとつないだりもできそうです。
おそらくTinyG(TinyG Workspace)のほうがgrblより性能が上なので、もっといろいろできるのかもしれません。とは言ってもgrblでも基本的なことは出来るので充分だとは思います。
こんな感じでブラウザ上でCNC制御できるのはお手軽な感じで面白そうです。ブラウザベースだとwifiを使っていればワイヤレス化も容易なので便利かもしれません。
関連:
ラベル:
G-Code Seder,
wifi,
ワイヤレス
2016年5月18日水曜日
Inkscape Laser Tool Plug-inのエラー
InkscapeのExtensionである「Laser Tool Plug-in」は、レーザー加工するときには便利なのですが毎回最後のGコードでエラーがでます。工程の最後にエラーがでるようなので、作業自体には問題ないのですが、作業終了後毎回ロックがかかってしまいます。
「Laser Tool Plug-in」で簡単なGコード(画像上:20mmの円を描くGコード)を生成すると、以下のような感じ。
M05 S0
G90
G21
G1 F600
G1 X27.6603 Y17.0556
G4 P0
M03 S500
G4 P0
G1 F400.000000
G2 X24.7314 Y9.9845 I-10. J0.
G2 X17.6603 Y7.0556 I-7.0711 J7.0711
G2 X10.5892 Y9.9845 I-0. J10.
G2 X7.6603 Y17.0556 I7.0711 J7.0711
G2 X10.5892 Y24.1266 I10. J-0.
G2 X17.6603 Y27.0556 I7.0711 J-7.0711
G2 X24.7314 Y24.1266 I-0. J-10.
G2 X27.6603 Y17.0556 I-7.0711 J-7.0711
G1 X27.6603 Y17.0556
G4 P0
M05 S0
G1 F600
G1 X0 Y0
M18
この最後のM18がたぶんエラーの原因になっているのだと思います。
M18を調べてみると、RepRapのGコードでは、「全てのモーター停止」となっているので、このことなのかもしれません。しかしgrblでは、M18は対応してないようなのでエラーがでるのだと思います。
「プログラム終了」というMコードであれば、M30が一般的のようです。grblでもM0、M2、M30がポーズと終了になっています(このページのNice featuresの欄に書いてあります)。しかしRepRapだとM30は「SDカード上のファイルを削除する」のようです。
おそらくLaser Tool Plug-inはRepRapよりの設定なのかもしれません。
ということで、M18をM30に書き換えてから実行してみたらエラーはでませんでした。
生成されたGコードファイルをTextEditで開いて訂正してもいいし、bCNCなら以下のようにEditorで編集してもいいと思います。
それなら、Laser Tool Plug-inのファイルを開いてプログラムを書き換えればいいのかもしれないと思ってApplication/Inkscape.app/Contents/Resources/share/inkscape/extensions/laser.pyをTextEdit(行数が表示されないのでSublime Text)で開いてみました(Inkscape.appを右クリックでパッケージの内容を表示、もしくはcontrol+クリックでパッケージの内容を表示でContentsフォルダ内を見ることができます)。
そうすると、
laser.pyの91行目にM18がありますね。どうやらfooterとして挿入しているようです。おそらくこのM18をM30に書き換えればgrblでもエラーがでなくなるのではないでしょうか。
さっそくM18を上画像のようにM30に書き換えました。これでlaser.pyを保存し直して、Inkscapeで試してみます。Inkscapeを開いてLaser Tool Plug-inで簡単なGコードを生成してみます。以下。
M05 S0
G90
G21
G1 F600
G1 X58.0571 Y43.5429
G4 P0
M03 S500
G4 P0
G1 F400.000000
G2 X52.6251 Y30.4288 I-18.546 J0.
G2 X39.5111 Y24.9968 I-13.114 J13.114
G2 X26.3971 Y30.4288 I-0. J18.546
G2 X20.9651 Y43.5429 I13.114 J13.114
G2 X22.3768 Y50.6401 I18.546 J0.
G2 X26.3971 Y56.6569 I17.1343 J-7.0973
G2 X32.4139 Y60.6772 I13.114 J-13.114
G2 X39.5111 Y62.0889 I7.0973 J-17.1343
G2 X46.6084 Y60.6772 I0. J-18.546
G2 X52.6251 Y56.6569 I-7.0973 J-17.1343
G2 X56.6454 Y50.6401 I-13.114 J-13.114
G2 X58.0571 Y43.5429 I-17.1343 J-7.0973
G1 X58.0571 Y43.5429
G4 P0
M05 S0
G1 F600
G1 X0 Y0
M30
最後がM30になってますね。これでgrblを使っている場合はエラーがでないはずです。これでひとつ問題解決しました。よかった。
それから前にも書きましたが、Laser Tool Plug-inの上から5個目のLaser Power S#は0-256 or 0-10000となっていますが、grblだとデフォルトが0-1000なので、ここも違います。数値入力するので、ここはプログラム自体を書き換える必要はないかと思いますが。
grbl0.9のconfig.hの254行目を見ると、
#define SPINDLE_MAX_RPM 1000.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM.
#define SPINDLE_MIN_RPM 0.0 // Min spindle RPM. This value is equal to (1/256) duty cycle on the PWM.
となっているので、スピンドル最高1000(100%)、最低0がデフォルトのようです。
grblの今後の開発予定(Development Path and Future Needs)では、リアルタイムに調整可能なフィードレート、クーラントやスピンドルのオーバーライドなどが挙げられているので、bCNC上にあるオーバーライド機能はまだ使えないということなのかもしれません。
追記:Grbl1.1からはオーバーライド機能に対応しました(こちらのページ中程)。
「Laser Tool Plug-in」で簡単なGコード(画像上:20mmの円を描くGコード)を生成すると、以下のような感じ。
M05 S0
G90
G21
G1 F600
G1 X27.6603 Y17.0556
G4 P0
M03 S500
G4 P0
G1 F400.000000
G2 X24.7314 Y9.9845 I-10. J0.
G2 X17.6603 Y7.0556 I-7.0711 J7.0711
G2 X10.5892 Y9.9845 I-0. J10.
G2 X7.6603 Y17.0556 I7.0711 J7.0711
G2 X10.5892 Y24.1266 I10. J-0.
G2 X17.6603 Y27.0556 I7.0711 J-7.0711
G2 X24.7314 Y24.1266 I-0. J-10.
G2 X27.6603 Y17.0556 I-7.0711 J-7.0711
G1 X27.6603 Y17.0556
G4 P0
M05 S0
G1 F600
G1 X0 Y0
M18
この最後のM18がたぶんエラーの原因になっているのだと思います。
M18を調べてみると、RepRapのGコードでは、「全てのモーター停止」となっているので、このことなのかもしれません。しかしgrblでは、M18は対応してないようなのでエラーがでるのだと思います。
「プログラム終了」というMコードであれば、M30が一般的のようです。grblでもM0、M2、M30がポーズと終了になっています(このページのNice featuresの欄に書いてあります)。しかしRepRapだとM30は「SDカード上のファイルを削除する」のようです。
おそらくLaser Tool Plug-inはRepRapよりの設定なのかもしれません。
ということで、M18をM30に書き換えてから実行してみたらエラーはでませんでした。
生成されたGコードファイルをTextEditで開いて訂正してもいいし、bCNCなら以下のようにEditorで編集してもいいと思います。
それなら、Laser Tool Plug-inのファイルを開いてプログラムを書き換えればいいのかもしれないと思ってApplication/Inkscape.app/Contents/Resources/share/inkscape/extensions/laser.pyをTextEdit(行数が表示されないのでSublime Text)で開いてみました(Inkscape.appを右クリックでパッケージの内容を表示、もしくはcontrol+クリックでパッケージの内容を表示でContentsフォルダ内を見ることができます)。
そうすると、
laser.pyの91行目にM18がありますね。どうやらfooterとして挿入しているようです。おそらくこのM18をM30に書き換えればgrblでもエラーがでなくなるのではないでしょうか。
さっそくM18を上画像のようにM30に書き換えました。これでlaser.pyを保存し直して、Inkscapeで試してみます。Inkscapeを開いてLaser Tool Plug-inで簡単なGコードを生成してみます。以下。
M05 S0
G90
G21
G1 F600
G1 X58.0571 Y43.5429
G4 P0
M03 S500
G4 P0
G1 F400.000000
G2 X52.6251 Y30.4288 I-18.546 J0.
G2 X39.5111 Y24.9968 I-13.114 J13.114
G2 X26.3971 Y30.4288 I-0. J18.546
G2 X20.9651 Y43.5429 I13.114 J13.114
G2 X22.3768 Y50.6401 I18.546 J0.
G2 X26.3971 Y56.6569 I17.1343 J-7.0973
G2 X32.4139 Y60.6772 I13.114 J-13.114
G2 X39.5111 Y62.0889 I7.0973 J-17.1343
G2 X46.6084 Y60.6772 I0. J-18.546
G2 X52.6251 Y56.6569 I-7.0973 J-17.1343
G2 X56.6454 Y50.6401 I-13.114 J-13.114
G2 X58.0571 Y43.5429 I-17.1343 J-7.0973
G1 X58.0571 Y43.5429
G4 P0
M05 S0
G1 F600
G1 X0 Y0
M30
最後がM30になってますね。これでgrblを使っている場合はエラーがでないはずです。これでひとつ問題解決しました。よかった。
それから前にも書きましたが、Laser Tool Plug-inの上から5個目のLaser Power S#は0-256 or 0-10000となっていますが、grblだとデフォルトが0-1000なので、ここも違います。数値入力するので、ここはプログラム自体を書き換える必要はないかと思いますが。
#define SPINDLE_MAX_RPM 1000.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM.
#define SPINDLE_MIN_RPM 0.0 // Min spindle RPM. This value is equal to (1/256) duty cycle on the PWM.
となっているので、スピンドル最高1000(100%)、最低0がデフォルトのようです。
grblの今後の開発予定(Development Path and Future Needs)では、リアルタイムに調整可能なフィードレート、クーラントやスピンドルのオーバーライドなどが挙げられているので、bCNC上にあるオーバーライド機能はまだ使えないということなのかもしれません。
追記:Grbl1.1からはオーバーライド機能に対応しました(こちらのページ中程)。
これはbCNCのControl画面ですが、画像の下のほうにFeed OverrideとSpindleのスライダーがあり、ここでリアルタイムに調整可能にはなっていますが、grblではまだということだと思います。
フィードやスピンドル(PWM)の値は、あらかじめ何回か素材に合わせてテストしてから実行しているので、それほど使うわけでもないのですが、たしかにあったほうが可変的に実験もできるので便利です。
まあオープンソースなので、この辺りは各自でやっていくしかないでしょう。
ラベル:
G-Code Generator,
Inkscape,
Python,
TTL PWM,
レーザー
2016年5月17日火曜日
CNCマシン:Bluetoothでワイヤレス化(その2:完成)
前回からの配線のつづき:
こんな感じでコントロールボックス内部にBluetoothモジュールをつけたあとからの作業。
ワイヤーストリッパーのおかげ:
面倒な配線作業なのですが、先日届いたワイヤーストリッパーのおかげで少しははかどりました。いつものAliExpressで1000円(送料込み)。ガシャンと勢い良く皮膜が剥けます。
AliExpress.com Product - Free Shipping hc-06 HC 06 RF Wireless Bluetooth Transceiver Slave Module RS232 / TTL to UART converter and adapter327円(送料込み)安いので追加で2個買っておきました。こんな感じでコントロールボックス内部にBluetoothモジュールをつけたあとからの作業。
ワイヤーストリッパーのおかげ:
面倒な配線作業なのですが、先日届いたワイヤーストリッパーのおかげで少しははかどりました。いつものAliExpressで1000円(送料込み)。ガシャンと勢い良く皮膜が剥けます。
非常停止ボタンの見直し:
とはいっても、いろいろ考えることがあって、この際、機能が中途半端だった非常停止ボタンの配線も変えることにしました。40mmもある巨大なボタンなのに、Arduinoのリセットをするだけだったので、コンセントから来ているAC100Vも遮断できるようにすべき。幸いこの非常停止ボタン(これもAliExpressで139円送料無料)、内部に二回路入っていて、ひとつは普段オープン、もうひとつはクローズドになっています。いままでは、普段オープンのほうだけをCNCシールドのE-STOP端子につないでいましたが、普段クローズドのほうもAC100V電源の非常時遮断に使うことにしました。
まずはこの非常停止ボタンを配線することに。ただ、これとは別に主電源スイッチもあるのですが、それもAC100VをON/OFFできます。機能がダブっていそうですが、実はMacBookとArduinoをUSB接続しているときに、主電源を落としてもArduinoはMacBookのUSBケーブルから電源供給されているため電源が落ちるというがありません。非常停止ボタンの場合は、Arduinoもリセットするのでより確実という感じです。ということで非常停止ボタンのほうは何とか片付きました。
新たにスイッチ追加:
今回はBluetoothのON/OFFのスイッチもつけなければいけません。Bluetoothの送受信ピンは、Arduinoのシリアル通信用のピン(D0とD1)とつながっているために、そのままだとUSB接続の際にMacBookから送受信すると干渉してしまいます。
ということで、一個余っていたスイッチを正面のパンチングメタル上につけることにして、これを主電源スイッチに変更。LED付きスイッチなので電源が入っているかどうかも確認しやすいです。面倒ですが、いままでの主電源スイッチの配線を移動。非常停止ボタンとも絡んでいる部分なのでちょうどよかったのかもしれません。それでいままでの主電源スイッチをBluetooth用に。
しかし、配線がかなり複雑になってきてやや混乱気味です。間違うと大変なので、一応紙に配線図を描きながらダブルチェックしつつ作業しました。
Arduinoへの別電源供給:
もうひとつ面倒なのが、Arduinoへの電源供給。これまではMacBookとUSB接続で電源供給されていたけれども、ワイヤレスなので別に電源を確保しなければいけません。レーザー用のDC12V電源があるので、そこからつなげることにしました。Arduinoにも外部電源用ソケットがついているのですが、それは使わないで裏側から直にケーブルをハンダづけしました。上画像でも分かるように、Arduinoボードがケーブルに埋もれているので、取り出すにはケーブル全部とCNCシールドを外さないといけません。これが面倒に感じてしまって後回しにしていましたが、やる気を出して作業続行。
なんとか配線終了:
下の画像のように、この部分はスイッチ類や配線ですごいことに。特に面倒なのがLED付きスイッチ。大抵のLEDつきスイッチは、ただ単にスイッチボタンにLEDが入っているだけでスイッチ部分と連動もしないので、必要な抵抗や配線は自分で考えてつけなければいけません。
LED付きだとON/OFFの確認がしやすくなるし、光ってた方が見た目もいいし、という理由で選んだので作業量が増えても仕方ないですが。
動作確認:
とりあえず、両側の板をつけるまえに動作確認。主電源スイッチは手前パンチングメタル上の赤く光っている丸い押しボタンスイッチです。上画像は、USB接続でも大丈夫か確認しているときのものです。特に問題なさそうです。
正面からみるとこんな感じ。手前パンチングメタル上の赤い主電源スイッチの下にやや緑色に光っているのがBluetooth通信中ということです(通信が切れると赤)。パンチングメタル裏にBluetoothモジュールは入っています。上面の3個並んでいる一番手前がBluetooth用スイッチです(以前は主電源スイッチだったもの)。真ん中がLED照明用スイッチ(まだLED照明はつけてない)。一番奥がレーザー用スイッチ。
一応、BluetoothでもUSB接続でも動くことを確認できたので、両側面の板もつけて作業終了。
ワイヤレス化と言っても、主電源スイッチとBluetoothスイッチをON、そしてbCNCでBluetoothのSerial Portを選んでOpenを押すだけです(上画像左下のConnect on startupにチェックを入れておけば、bCNCを立ち上げたときに記憶しておいたポートに自動で接続されます)。仕組み的にも、シリアル通信のパイプ役になっているだけなので単純です。このBluetoothモジュールはClass1(通信最大距離100m)で強力なので多少のノイズにも強いかもしれません。
これで、パソコン作業しているテーブルの上からもワイヤレス操作可能です。それとbCNCのPendant機能で、他のパソコン、スマホ、タブレットのブラウザ上からもワイヤレス操作可能です。
MacBookをわざわざCNCマシンのそばに持って行かなくてもよくなったので、かなり便利です。ポートマッピングすれば外出先からも操作できますが、そこまではいまのところ必要ないです。
あと残っているのは、トリマーにつける集塵カバー(LED照明付き)くらいでしょうか。以前AliExpressに注文したリング型LEDがまだ届いていないので、それが届いてからつくることになると思います。
ラベル:
bluetooth,
ワイヤーストリッパー,
ワイヤレス,
配線,
非常停止ボタン
CNCマシン:SketchUcamについて
3DモデリングならSketchupを使っている人も多いと思います。とても使いやすいソフトだとは思うのですが、個人的にはソリッドモデルばかり使っていたので、あのペラペラな感じに違和感があって、あまり使っていませんでした。
ちょっと調べてみると、ブーリアン演算も簡単にできるようなので、使ってみてもいいかなと思いました。少なくてもBlenderに比べればずっと使いやすいです。
そのままダウンロードするだけだと、あまりプラグインが入っていないようで、3Dの出力は.daeと.kmzだけ。なので、SketchupでCNCマシンを使っている人は、「Export to DXF or STL」というプラグインを使っているようでした。
しかし、同時に「SketchUcam」というプラグインもあるようで、それならそのままGコードを書き出せるようです。以下の動画がチュートリアル。
けっこうこれも使いやすそうです。
ということで、Fusion360、Blendercam、SketchUcamあたりという感じでしょうか。
一応ここにメモっておいたという感じです。
ちょっと調べてみると、ブーリアン演算も簡単にできるようなので、使ってみてもいいかなと思いました。少なくてもBlenderに比べればずっと使いやすいです。
そのままダウンロードするだけだと、あまりプラグインが入っていないようで、3Dの出力は.daeと.kmzだけ。なので、SketchupでCNCマシンを使っている人は、「Export to DXF or STL」というプラグインを使っているようでした。
しかし、同時に「SketchUcam」というプラグインもあるようで、それならそのままGコードを書き出せるようです。以下の動画がチュートリアル。
ということで、Fusion360、Blendercam、SketchUcamあたりという感じでしょうか。
一応ここにメモっておいたという感じです。
ラベル:
3Dモデリング,
G-Code Generator
登録:
投稿 (Atom)
人気の投稿
-
Gコードについてはまだまとめていないので、とりあえず覚書程度に書いておこうと思います。 普段Gコードや$コマンドについては、やっているうちに覚えるだろうと思って、それほど深く勉強はしていません。作業の効率化が必要というほどでもないので、だいたい動けば問題ないという程度です。全...
-
追記: 2017年現在では、このページの内容はやや古いものとなっています(Grbl0.9以前のもの)。 現行のGrbl1.1ならびにそれに対応したG Code Senderを使用する場合は、 こちらのページ を参考にして下さい。 ーーーーーーーーーーーーーーーーーーーーー...
-
追記: *リミットスイッチの配線については、Grblサイトの Wiring Limit Switches に追記されたので参考にするといいと思います。ノイズフィルターの有無、ノーマルオープン/ノーマルクローズドなど画像付きで詳しく書かれています(英語)。 G-Code-S...
-
今のところ2D加工は以下のような感じ。 ・2Dレーザーカット:Inkscape(Laser Tool Plug-in)→Gコード→bCNC ・2Dルーターカット:Inkscape→svgファイル→Jscut(Outside)→Gコード→bCNC そのうち3Dカットもする必...
-
普段は、G Code Sender(PC上のGコード送信ソフト)として bCNC を使用しています。Grblのサイト Using Grbl に掲載されているGrbl1.1対応ソフトの一つでもあります。 bCNCの特長: ・Grbl1.1に対応(頻繁にアップデートさ...
-
今回は、Pythonでヒルベルト曲線を描いてみます。 ヒルベルト曲線の性質上、再帰アルゴリズムで解く方法がありますが、今回は再帰アルゴリズムを使わず、そのまま通常ループで解いていこうと思います(個人的にはそのほうが分かりやすいので)。 追記: 再帰アルゴリズムを後半に追加しました...