Fusin360 CAMポストプロセッサ徹底解説・onSectionEnd( ) & onClose( )

Fusion360

いよいよ最後の締めくくりです。
今回検討している、NCデータ仕様では、各セクション(工程)の終了と、NCプログラム全体の終了処理を担当します。

加工後の終了処理

セクション(工程)の終了

①M09 (クーラント停止)
②M05 (主軸回転停止)
③G91G28Z0. (リファレンス点へ退避)
④G49 (工具長補正キャンセル)
⑤G90G00G17 (モーダル情報リセット)
⑥M01 (単工程再加工考慮、オプショナルストップ)

ポスト処理終了

⑦M30
⑧%

工程と全体の終了処理です。
各工程の終了時には、クーラントや主軸回転停止、退避処理、を行い、機械側で一旦停止ができるように「M01」を出力させます。
全体では「M30」と「%」で終了とします。

現状の状態

まずは、現状で出力させてみます。

N0001
・
・
(---- onSectionEnd ----)
(---- End of onSectionEnd ----)
・
N0002
・
・
(---- onSectionEnd ----)
G17
(---- End of onSectionEnd ----)
・
N0003
・
・
(---- onSectionEnd ----)
(---- End of onSectionEnd ----)
(---- onClose ----)

M09
G91G28Z0.
G49
G90G00G17
G49
G91G28X0.Y0.
G90G00G17
M30
%
(---- End of onClose ----)

オリジナルの「fanuc.cps」では、今回やらせたいキャンセル処理などは、「onSection( )」が担当しているので、「onSectionEnd( )」では、ほとんど出力されていませんね。
したがって、「onSection( )」でのキャンセル処理を「onSectionEnd( )」に移行させます

最初のG17 の削除

2工程目(N0002)のセクションでは、1工程目の加工データが「G19」モードで終了しているため、「G17」コードが出力されています。
今回は、
⑤G90G00G17 (モーダル情報リセット)
で事前のモーダル状態にかぎらず、無条件にリセットコードを出力させようと思っているので、ここでは無効にします。

function onSectionEnd() {
//kazuban 2021/01/08
writeln("(---- onSectionEnd ----)");
if (typeof inspectionProcessSectionEnd == "function") {
inspectionProcessSectionEnd();
}
//kazuban 2021/02/14
//writeBlock(gPlaneModal.format(17));

①M09(クーラント停止)

次に、「M09」を出力させます。
これは簡単ですね。
onSection( )でも使用した、「setCoolant( )」を利用します。

setCoolant(COOLANT_OFF);

を追加する事で、「M09」を出力する事ができます。

②M05(主軸回転停止)

こちらは、出力させる関数は見当たりませんね。
単純に「writeln(“M05”)」とするだけで、「M05」を出力させる事はできますが、「fanuc.cps」では結構面倒な事しています。
「onCommand( )」関数で出力させています。

onCommand( )関数

ただし、この関数がまた、複雑です。
なんでこんなプログラムにしたのか?よくわかりません。
簡単に分析してみると、引数で「コマンド」のキーワードを受け取り、
「COMMAND_COOLANT_OFF」など「switch文」でいくつかのコマンドは分類されます。
ただし、「switch文」に当てはまらない場合には、
var stringId = getCommandStringId(command)
というパブリック関数でキーワードに変換し、
さらに、mapCommand[stringId]という連想配列で、Mコード番号を取り込み
writeBlock(mFormat.format(mcode)) でやっと出力させています。

う~ん、ここまで複雑にする必要があるのだろうか・・・
いずれにしても、
onCommand(COMMAND_STOP_SPINDLE);
のコードで、「M05」が出力できるみたいです。

ここで、「ZENKYU」さんのコメントにあるように、「M03」コードが出力されないバグがありました。
一つは「onSection( ) No2」での単純なミスでした。
ここは元記事を直しています。
もう一つは、「同じ工具(同じ回転数)」の場合、省略されるようです。
いろいろ方法はあるかと思いますが、私は「onCommand( )」関数を修正する方法とします。
この関数の最後に、「COMMAND_STOP_SPINDLE」の場合の定義を追加して、この場合は強制的にスピンドル指令をださせるようにします。

  ・
  ・
  case COMMAND_PROBE_OFF:
    return;
  //kazuban 2021/01/21
  case COMMAND_STOP_SPINDLE:
    forceSpindleSpeed=true;
}

これで、同じ回転数の場合でも強制的に主力されると思います。
今回は、上述のG17出力をコメントにした、行の次に下記コードを追加する事で「M09」「M05」を出力できます。

setCoolant(COOLANT_OFF);
onCommand(COMMAND_STOP_SPINDLE);

③G91G28Z0. (リファレンス点へ退避)④G49(工具長補正キャンセル)⑤G90G00G17(モーダル情報リセット)

このコードは、「onSection( )」の最初にも出てきました。

その時に「writeRetract()」関数を編集したので、この関数を呼び出す事で、同じコードを出力させる事ができます。

function onSectionEnd() {
  //kazuban 2021/01/08
  writeln("(---- onSectionEnd ----)");
  if (typeof inspectionProcessSectionEnd == "function") {
    inspectionProcessSectionEnd();
   }
   //kazuban 2021/02/14
   //writeBlock(gPlaneModal.format(17));
   setCoolant(COOLANT_OFF);
   onCommand(COMMAND_STOP_SPINDLE);
   writeRetract(Z); // retract
    ・
    ・

⑥M01(オプショナルストップ)

実際の加工においては、一つの工程が終了した時点で、ストップし加工状況や加工精度を確認したい場合があります。
確実に停止したい場合には、「M00」のコードを使用しますが、状況による場合には「M01」コードを使用します。
これは、機械側でこのオプションスイッチを有効にした場合のみ停止させるコードです。
今回のNCデータ構成においては、各工程の先頭に工程と同じシーケンス番号を追加し、NCデータの最初のGOTO 文」で任意の工程へジャンプさせるような仕様にしています。
仕上げ工程などの場合、一旦加工を停止し、測定などした後に再度この工程を行いたい場合に、このオプションを利用します。

具体的には、2716行付近の、onSectionEnd( )関数のブロックの最後に下記のコードを追加します。

    ・
    ・
  //kazuban 2021/02/20
  if (properties.optionalStop) {
    onCommand(COMMAND_OPTIONAL_STOP);
  }
  //kazuban 2021/01/08
  writeln("(---- End of onSectionEnd ----)");
}

ポストのプロパティで出力制御が可能なように、「properties.optionalStop」が「true」な場合のみ、「M01」を出力する仕様にしています。
ここまでで、「onSectionEnd( )」関数の改造は終了です。

⑦M30⑧%

後は、onClose( )関数です。
不要な改行を削除し
リトラクト、工具長補正キャンセルは、onSectionEnd( )で、各工程の終了でやらせる仕様としたので、ここでは無効にします。
「M30」と「%」の出力はオリジナルのコードをそのまま使用します。

function onClose() {
 //kazuban 2021/01/05
 writeln("(---- onClose ----)");
 nullProbeAngle(false);
 //kazuban 2021/02/20
 //writeln("");
 optionalSection = false;
 onCommand(COMMAND_COOLANT_OFF);
 //kazuban 2021/02/20
 //writeRetract(Z); // retract
 //disableLengthCompensation(true);
 setSmoothing(false);
 zOutput.reset();
 setWorkPlane(new Vector(0, 0, 0)); // reset working plane
 if (isG54x4Used) {
   writeBlock(gFormat.format(54.4), "P0");
 }
 //kazuban 2021/02/20
 //writeRetract(X, Y); // return to home
 onImpliedCommand(COMMAND_END);
 onImpliedCommand(COMMAND_STOP_SPINDLE);
 writeBlock(mFormat.format(30)); // stop program, spindle stop, coolant off
 if (subprograms.length > 0) {
   writeln("");
   write(subprograms);
 }
 writeln("%");
 //kazuban 2021/01/05
 writeln("(---- End of onClose ----)");
}

終了です。

早速ポスト処理させてみましょう!

%
 O1001 (M10)
 (T1 D=12. CR=0. - ZMIN=-9.995 - FLAT END MILL)
 (T21 D=6. CR=0. TAPER=140DEG - ZMIN=-16. - DRILL)
 G90G94G17G49G40G80
 G54
 GOTO 1
 (---- End of onOpen ----)
 (--- onSection ---)
 N0001
 (T01 D=12.000 R=0.000 ZMIN=-9.995 )
 ( ap:0.02D ae:1D )
 G91G28Z0.
 G90G00G17
 T1
 M06
 G00G43Z30.H01
 S2300M03
 M08
 G04X10.
 (---- End of onSection ----)
 G00X-44.303Y-9.527
 Z5.
 ・
 ・ (加工データ)
 ・
 X-39.768Z0.205
 G00Z30.
 (---- onSectionEnd ----)
 M09
 M05
 G91G28Z0.
 G49
 G90G00G17
 M01
 (---- End of onSectionEnd ----)
 (--- onSection ---)
 N0002
 (T01 D=12.000 R=0.000 ZMIN=-9.980 )
 ( ap:0.02D ae:1D )
 G91G28Z0.
 G90G00G17
 /T1
 /M06
 G00G43Z30.H01
 S2300M03
 M08
 G04X10.
 (---- End of onSection ----)
 G00X-37.2Y11.2
 Z5.
 ・
 ・ (加工データ)
 ・
 G19G02Y8.8Z-8.78K1.2
 G00Z30.
 (---- onSectionEnd ----)
 M09
 M05
 G91G28Z0.
 G49
 G90G00G17
 M01
 (---- End of onSectionEnd ----)
 (--- onSection ---)
 N0003
 (T21 D=6.000 R=0.000 ZMIN=-16.000 )
 ( NSB-Drill )
 G91G28Z0.
 G90G00G17
 T21
 M06
 G00G43Z30.H21
 S2650M03
 M08
 G04X10.
 (---- End of onSection ----)
 G00X-40.Y15.
 ・
 ・ (加工データ)
 ・
 Z30.
 (---- onSectionEnd ----)
 M09
 M05
 G91G28Z0.
 G49
 G90G00G17
 M01
 (---- End of onSectionEnd ----)
 (---- onClose ----)
 M30
 %
 (---- End of onClose ----)

いかがでしょうか?
ほぼ思い通りに出力されていますが、最初の初期化コード
「G90G94G17G49G40G80」を編集忘れていました。
「G94」は「G00」にする予定でした。
ここが気になる方は、「onOpen( )」を編集してみてください。
また、今回のポスト構成は、「—- End of onSection —-」と「—- onSectionEnd —-」の間に実際の加工プログラムが出力されます。
この部分を、サブプロファイルとして別ファイルい出力させ、「M98」や「M198」で呼び出す仕様にすれば、メイン・サブ構成のNCプログラムにも変化させる事も可能です。
サブプロ化のポストプロセッサは、要望あれば検討します。

完成ポストファイル

参考までに、完成したポストファイルを公開しようと思いましたが、
やはりオリジナルの著作権などもあると思うのでここでの公開は
やめようと思います。
このトレーニングガイドの「1-6」ページ
1.5 Creating/Modifying a Post Processor」の中に

The good news is, all of posts are open source and can be modified without limitation to create the post you need.

とあるので、おそらく大丈夫だとは思うのですが、ブログでの公開でなく配布形式にしようと思います。
Fusion360 ポストの改造を検討している方であれば、何かしらの参考になるかと思います。
もし興味ある方がいらっしゃれば、こちらまで問い合わせいただければ、Eメール経由で配布いたします。


Fusion360 ポストの情報


  1. 概要編
  2. 構成編
  3. 変数
  4. グローバルセクション
  5. 関数
  6. NCプログラム仕様検討
  7. onOpen( )
  8. onSection( ) No1
  9. onSection( ) No2
  10. onSectionEnd( ) & onClose( )

1 2 3 4 5 6 7 8 9 10

コメント

  1. ZENKYU より:

    かずばんさん、こんにちは。
    毎回有益な記事を書いていただきありがとうございます。

    出力されたNCデータに

    S2300 とスピンドルコードは出力されていますが
    全体を通して M03 の回転指令は一度も出力されていないので

    >う~ん、ここまで複雑にする必要があるのだろうか・・・
    >いずれにしても、
    >onCommand(COMMAND_STOP_SPINDLE);
    >のコードで、「M05」が出力できるみたいです。

    この部分を見直す必要があるかもしれませんね。
    ぼくは全体が全く見えていないのでなんとも出来ないのですが…
    関数のスコープなども関係すると思いますがどうしたらいいのかわかりません。

    ところで今回の記事中

    >5. ②M05(主軸回転停止)

    >こちらは、出力させる関数は見当たりませんね。
    >単純に「writeln(“M09”)」とするだけで、「M09」を出力させる事はできますが、

    とありますが
    <—// ここは M05 ですかね?//

    • kazuban kazuban より:

      ありがとうございます。
      たすかります
      「M03」が全くでない件は、単純なミスでした
      「onSection( ) No2」の記事を編集しました。

      同じ条件の場合は、モーダルだからなのか、全然出力されませんね
      ここは、強制的に出力させるように、この記事を編集しました

      またなにかありましたら、お願いします。(^^ゞ

  2. kantoku より:

    非常に今更なのですが、cpsファイルのデバッグの方法が分かり
    入口ぐらいのレベルですが試してみました。

    https://kantoku.hatenablog.com/entry/2021/11/16/161140
    https://kantoku.hatenablog.com/entry/2021/11/17/164041

    結局はプリントデバッグしか方法が無いようですが、CAMデータを
    作らなくても、Fusion360を起動しなくてもデバッグが出来るようです。

    • kazuban kazuban より:

      情報ありがとうございます
      私も、VSCode始めた時に、デバックを試した事がありましたが
      なかなかうまくいかず、未だにFusion360ポストを実行している状態です
      今度、時間見つけてやってみます!

      • kazuban kazuban より:

        やってみました。
        うまくいくと、ポスト処理されたNCデータがでてきました。
        リアルタイムに確認できるので、上手につかうと威力を発揮しそうです
        ただ、私の場合、「onTerminate」や「onSectionEnd」で、ファイルを読み込んだり
        コピーさせたりしているので、いろいろとエラーが出てしまいました。
        やり方はあるのでしょうが、なかなか、使いこなせませんね~

タイトルとURLをコピーしました