Fusin360 CAMポストプロセッサ徹底解説・onSection( )の編集 No2

Fusion360

onSection( )改造の第二弾です。
前回は、シーケンス番号、工具情報、リファレンス点へ退避、工具長補正キャンセル、モーダル初期化、まで行いました。
今回は、⑥~⑪ 工具交換、工具長補正、主軸回転、クーラント、ドゥウェルのコードの出力を行います。

onSection( )編集 第二弾

セクション(工程)の始まり

①N0001 (工程番号と同じシーケンス番号)
②(工具情報)
③G91G28Z0. (途中再開時の安全を考慮して工具退避)
④G49 (工具長補正キャンセル)
⑤G90G00G17 (とりあえずモーダルコードリセット)

⑥T01 (工具番号)
⑦M06 (行を分け工具交換、Tと同じ行ではNGな機種への対応)
⑧G00G43Z30.H01 (工具長補正、この例では、T番号とH番号は同じ)⑨S2300M03 (スピンドル回転)
⑩M08 (クーラントコード、飛び散り防止で回転の後で指令)
⑪G04X10. (クーラントの安定を待つ、PとXでの指令あり)

前回までの改造で、一度NCデータを出力させてみます。
使用工具の情報により、3パターンありましたが、全ての要素が含まれている、3パターン目(2回目以降で前工具と違う工具の場合)を見てみましょう。

 (--- onSection ---)
 N0003
 (T21 D=6.000 R=0.000 ZMIN=-16.000 )
 ( NSB-Drill )
 G91G28Z0.
 G49
 G90G00G17

 (6)
 M09
 M01
 T21M06
 (NSB-DRILL)
 S2650M03
 G54
 M08
 G00X-40.Y15.
 G43Z30.H21
 (---- End of onSection ----)

これを基本に、希望の出力に改造していきましょう。

不要コード削除

前回「G90G00G17」までは完成しています。
次に⑥工具呼び出しですが、その前に、今回には不要なコードが出力されています
まず、「改行」がありますが、これは省きたいと思います
次に、「(6)」と言うコメントが出力されています。
これは、Fusion360 CAMで、ドリル機能を設定した時の名前です。

テスト的に何度かドリルを定義したので、「6」は自動的につけられた番号です。
「ドリル」が日本語(2バイト文字)なので、ポストにより日本語部が省かれたのだと思います。
次に「M01」が出力されています。
これは、 onSectionEnd( ) にやられようと思っているので、ここでは無効にします。

if (hasParameter("operation-comment")) {
     var comment = getParameter("operation-comment");
     if (comment && ((comment !== lastOperationComment) || !patternIsActive || insertToolCall)) {
       //kazuban 2021/01/30
       //writeln("");
       //writeComment(comment);
       lastOperationComment = comment;
     } else if (!patternIsActive || insertToolCall) {
       //writeln("");
     }
   } else {
     //writeln("");
   }

改造中の「fanuc_new.cps」の、1204行付近の「hasParameter( )」以降のブロック内で、
「writeln( )」「writeComment( )」関数で出力させていますので、「//」でコメント化して無効にしました。

注釈(notes)

次に工具交換指令ですが、その前に1218行付近に hasParameter(“notes”) という条件判断がありますね。

if (properties.showNotes && hasParameter("notes")) {
 ・
 ・
}

これは、定義済みのセクションをマウス右ボタンで表示されるダイアログの「注釈を変更」で定義した文字列をNCデータへコメント文として出力する定義です。

デフォルトでは、「showNotes」プロパティが「false」になっているため、無視されますが、「true」にする事でNCデータにコメント文を追加できます。
このブロック内に、「RegExp(“^[\s]+”, “g”)」のようなコードがありますが、これは「正規表現」を利用する関数です。
文字列から指定したルールで希望の文字列のみを取り出す事ができます。
この例では、前後の「 」(スペース)を削除するために、利用しています。
もし、「正規表現」に興味ありましたら、検索してみてください。
非常に奥が深く、パズルみたいで面白そうですが筆者もあまり理解していません。

⑥、⑦ 工具交換指令

1233行付近の「insertToolCall」で判定しているブロックでは、ポストが新しい工具挿入を確認したらこのブロックを実行します。
クーラント指令や工具交換指令などの出力を制御しています。

if (insertToolCall) {
   forceWorkPlane();

   onCommand(COMMAND_COOLANT_OFF);
  ・
  ・
}

クーラントOFF指令

工具交換指令の前に、このブロックでは、「クーラントOFF」の定義を行っています。
今回は「クーラントOFF」に関しては、セクション(工程)の終了時に指令する予定なので、ここでは不要ですが
事前にOFFに設定されていればモーダルなのでここでは無視されます。
あえて、無効にする必要はないと思います。

オプショナルストップ

次に1239行付近で「オプショナルストップ」の定義になっています。
今回はここは出力させない予定なので、「//」で無効にします。

if (!isFirstSection() && properties.optionalStop) { 
  //kazuban 2021/01/31
  //onCommand(COMMAND_OPTIONAL_STOP);
}

工具番号の制限

if (tool.number > 99) この条件判断で99番以上の指令では、ワーニングを出力するように定義しています。
最近は、3桁指令でも受け入れる制御機も多いので、その場合には、「99」を変更してください。

disableLengthCompensation()

次に、disableLengthCompensation() 関数が定義されています。
これは、工具長補正キャンセル(G49)を出力させるコードですが、
事前の④ですでに出力させているので、ここではモーダルが効いているので無視されます。

工具交換指令

1248行付近、やっと工具交換指令が出てきました。
オリジナルでは、「T03 M06」と一行で工具呼出しと工具交換指令を行っていますが、 機種によっては、2行に分割しなければエラーになる機械もありますし
逆に一行制限やどちらでもいい場合
もあります。
今回は、2行にしてみます。
Tool Comment も②で書き出しているので、ここでは、出力させません。

//kazuban 2021/01/31
writeBlock("T" + toolFormat.format(tool.number)); 
writeBlock(mFormat.format(6));
//writeBlock("T" + toolFormat.format(tool.number), mFormat.format(6));
if (tool.comment) {
   //writeComment(tool.comment);
}

次の「showToolZMin」のブロックは「false」なので実行されません。
次の条件判断「if (properties.preloadTool)」もpropertiesで「false」に設定してあるので実行されません。
さて、工具交換も含めて上記の処理は、「insertToolCall」判定によるブロック内(1233~1285)で行われています。
insertToolCall」判定なので、違う工具が設定された場合のみ工具交換コードが出力されるようになっていますが、今回は 同じ工具でも出力させたいと思っています。
しかし、主軸と同じ工具を呼び出すとエラーになる機種もあるので、
オプショナルスキップ「/」を付加して機械側で対応する仕様とします。
1285付近の「if (insertToolCall){ }」ブロックの最後に、「else」処理を追加して、「insertToolCall」でなくても、「/」付きで工具交換指令を出力するようにします。

if (insertToolCall) {
   ・・
   ・・
}else{
  //kazuban 2021/01/31
  writeBlock("/T" + toolFormat.format(tool.number));
  writeBlock("/",mFormat.format(6));
}

新しい工具であれば・・のブロックを処理し、ない場合でも「/」を付加して工具交換指令を出力するように、追加しています。

⑨回転指令を移動処理

1291行付近、次で始まる長~い条件判断ブロック内で、スピンドル回転指令を出力させてます。

if (!isProbeOperation() && 
・
・

このブロック内の1313付近の「writeBlock( )」関数で、出力させています。

if (!tapping || (tapping && !(properties.useRigidTapping == "without"))) {
  writeBlock(
    sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4)
  );
}

今回やりたいのは、⑨回転指令は、⑧G00G43Z30.H01 の後へ移動させたいのでこの長いブロックを全て⑧の後方へ移動すればいいのですが、
コピペなどで⑧の後ろへ移動させるのは、ミスも出やすく結構大変です。
このような場合には、前回説明した関数化するのも一つの方法です。
ただし、関数化するにしても、このブロック全部を新規の関数内へ移動する事になるので同様に大変です。
今回は、 writeBlock( ) で書き出している部分を、 変数へ代入するような仕様に変更し、その変数を出力させたい場所でwriteBlock( ) させるようにします。
まず、1291行付近の、この if文 の直前に、適当な名前(spindleCode)のグローバル変数を宣言しておきます。

//kazuban 2021/02/06
var spindleCode;   
if (!isProbeOperation() &&
・
・

そうして、1313付近の「writeBlock( )」関数で書き出す予定のコードを書き出す代わりに、writeBlock をコメント化で無力化し、出力予定のコードをこの変数へ代入させます。

 ・
if (!tapping || (tapping && !(properties.useRigidTapping == "without"))) {
  //kazuban 2021/02/06
  //writeBlock(
  //kazuban 2021/02/21
  //spindleCode = output.format(spindleSpeed),mFormat.format(tool.clockwise ? 3 : 4);
spindleCode = output.format(spindleSpeed) + mFormat.format(tool.clockwise ? 3 : 4);
  //);
}
 ・

これで、回転指定は書き出されずに、変数「spindleCode」へ代入されました。
spindleCode = sOutput.format(spindleSpeed) , mFormat.format(tool.clockwise ? 3 : 4);
このコード間違っていました。
spindleCode = sOutput.format(spindleSpeed) + mFormat.format(tool.clockwise ? 3 : 4);
こちらにしないと、「M03」が出力させません。
writeBlock(spindleCode)とする事で、任意の箇所へ書き出せるようになります。

⑧G00G43Z30.H01・工具長補正指令

次に、工具長補正指令の処理をしている場所を探しますが、その前に、「ワーク座標指令」と「クーラント指令」が見つかりました。
今回の構成では「ワーク座標系」指定は「onOpen( )」関数で、NCデータの最初でのみの指令としているので、ここでの出力は行いません。
また、「クーラント指令」は「スピンドル回転」の後にしたいので、やはりここでは出力させません。
1350付近と

    if (workOffset != currentWorkOffset) {
      //kazuban 2021/02/06
      //writeBlock(gFormat.format(54.1), "P" + p); // G54.1P
      currentWorkOffset = workOffset;
    }

1357付近の「writeBlock」をコメント化します。

  if (workOffset != currentWorkOffset) {
    //kazuban 2021/02/06
    //writeBlock(gFormat.format(53 + workOffset)); // G54->G59
    currentWorkOffset = workOffset;
  }

さらに、1372付近のクーラント指令もコメントにします

// set coolant after we have positioned at Z
//kazuban 2021/02/06
//setCoolant(tool.coolant);

さて、工具長補正指令は、1398行付近のこのブロック内で定義されています。

if (insertToolCall || !lengthCompensationActive || retracted || (!isFirstSection() && getPreviousSection().isMultiAxis())) {
・
var offsetCode = 43;

「offsetCode」変数へ、Gコードを代入し、後で出力させていますが、その前に、1420行付近で加工スタート位置へ位置決めさせています。
今回は、今後サブプロ化も考慮してここでは位置決めさせたくないので、このコードはコメントにします。
ただし注意が必要です。
工具交換後移動しないで、工具長補正位置まで下りてくるので、
機械の工具交換位置へ高いクランプなどがある場合、ぶつかってしまいます。
工具長補正する高さは、確実に安全な高さに設定してください。
場合によっては、工具長補正前に、「G90G00X0Y0」と加工原点への移動指令を追加したほうがいいかもしれません。

if (!machineConfiguration.isHeadConfiguration()) {
   //kazuban 2021/02/06
   //writeBlock(
   //  gAbsIncModal.format(90),
   //  gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y)   
  //);
   writeBlock(
     gMotionModal.format(0),
     gFormat.format(offsetCode),
     zOutput.format(initialPosition.z),
     hFormat.format(lengthOffset)
   );
   lengthCompensationActive = true; } else {
  ・
  ・


位置決めはモーダルなので、ここで移動させなくても、実際の加工データ出力の際、必要であれば自動的に出力されます。
ここで、「!machineConfiguration.isHeadConfiguration()」の条件判断がでてきます。
詳細はよくわかりませんが、ヘッド軸がX,Y,Z以外の機械の事のようです。
特にマシンライブラリを定義していない筆者の環境では、この判断は否定(!)との判断で常にこのブロックを通りますので、このブロック内を修正します。
出力させたい、工具長補正指令は、1426行付近の「writeBlock( )」関数で出力させています。

if (!machineConfiguration.isHeadConfiguration()) {
   //kazuban 2021/02/06
   //writeBlock(
   //  gAbsIncModal.format(90),
   //  gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y)   
  //);
   writeBlock(
     gMotionModal.format(0),
     gFormat.format(offsetCode),
     zOutput.format(initialPosition.z),
     hFormat.format(lengthOffset)
   );
   lengthCompensationActive = true; } else {
  ・
  ・

⑨スピンドル回転⑩クーラントコード⑪ドゥウェル

ここまでで、⑧工具長補正指令まで終了しました。
⑧を定義していた、ブロックの次、1455行付近にこの3つの指令を追加します。

if (insertToolCall || !lengthCompensationActive || retracted || (!isFirstSection() && getPreviousSection().isMultiAxis())) {
・
・
}
//kazuban 2021/02/06
writeBlock(spindleCode);
setCoolant(tool.coolant);
writeBlock(gFormat.format(4), "X10.");

onSection( ) 改造終了

やっと、終了しました。
ポスト処理させてみます。

 (--- onSection ---)
 N0001
 (T01 D=12.000 R=0.000 ZMIN=-9.995 )
 ( ap:0.02D ae:1D )
 G91G28Z0.
 G90G00G17
 T1
 M06
 G00G43Z30.H01
 S2300
 M08
 G04X10.
 (---- End of onSection ----)
    ・
    ・
 (--- onSection ---)
 N0002
 (T01 D=12.000 R=0.000 ZMIN=-9.980 )
 ( ap:0.02D ae:1D )
 G91G28Z0.
 G49
 G90G00G17
 /T1
 /M06
 G00G43Z30.H01
 G04X10.
 (---- End of onSection ----)
   ・
   ・
 (--- onSection ---)
 N0003
 (T21 D=6.000 R=0.000 ZMIN=-16.000 )
 ( NSB-Drill )
 G91G28Z0.
 G49
 G90G00G17
 M09
 T21
 M06
 G00G43Z30.H21
 S2650
 M08
 G04X10.
 (---- End of onSection ----)

まとめ

だいたい、希望のデータになっていると思いますが、スピンドル回転と冷却指令が、N0002 の工程と N0003の工程 では思うように出力されていません。
これは、モーダルコードが効いているからで、次回、onSectionEnd( ) 関数で、各セクション(工程)の終了時に、回転と冷却指令のキャンセルコードを追加する予定です。
それでおそらく、この省略されているコードは出力されるようになると思います。
今回は、スピンドル回転指令の長いブロック処理を移動する方法が、ポイントの一つだったと思います。
このように、条件判断文が長く複雑な、ブロック全体を移動させるのは、面倒だしミスるリスクもあります。
プログラミング的には、関数化するのがいいのではないかと思いますが、今回は変数への代入方法でやってみました。


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 より:

    かずばんさん、どもありがとうございます。

    ほんと文章書きは苦手でうまく説明できませんが

    > 5. ⑨回転指令を移動処理

    > if (!tapping || (tapping && !(properties.useRigidTapping == “without”))) {
    > //kazuban 2021/02/06
    > //writeBlock(
    > //kazuban 2021/02/21
    > //spindleCode = output.format(spindleSpeed),mFormat.format(tool.clockwise ? 3 : 4);
    > spindleCode = output.format(spindleSpeed) + mFormat.format(tool.clockwise ? 3 : 4);
    > //);
    > }

    「writeBlock(spindleCode)」とする事で、任意の箇所へ書き出せるようになります。

    となっていますが、送っていただいた fanuc_new.cps は

    if (!tapping || (tapping && !(properties.useRigidTapping == “without”))) {
    //kazuban 2021/02/06
    //writeBlock(
    spindleCode = sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4);
    //);
    }

    となってるので変更前のものですね。たぶん…

    ところで

    //spindleCode = output.format(spindleSpeed),mFormat.format(tool.clockwise ? 3 : 4);
    spindleCode = output.format(spindleSpeed) + mFormat.format(tool.clockwise ? 3 : 4);

    のように “,” を “+” に変更した場合 spindleCode には S2300M03 か S2300M04 が代入されて
    writeBlock(spindleCode) とした時に必ず M03 か M04 の回転指令がくっついてくるのでしょうか?

    それとも if 文で RigidTapping がなんたらと書いてあるので ソリッドタップの時は
    Sコードのみ出力するような処理になってるんでしょうか。

    また、工具を選択したときにクーラントの選択ができるわけですがこれを有効にするには
    別のやり方が必要になってくるわけですか?

    じつはしばらくずっとFusionを起動せずさぼっていたんですよね。
    関連ファイルの階層が深かったり、パス名がやたら長かったりでわけワカらん状態です(^-^;;)。

    • kazuban kazuban より:

      ZENKYUさん
      ありがとうございます
      サーバーのキャッシュがきいているのか、編集して入れ直したのですが
      修正前のデータがダウンロードされてしまうようです???
      Fanuc_new ⇒ Fanuc_new02 に変更して再度ダウンロードしてみてください。

      “,”だと、以降が無視されてしますので、おっしゃるように”+”で回転指令がくっつきます。
      「tool.clockwise ? 3 : 4」これは、工具設定で、右回りにしていれば「3」でしていなければ「4」にするの意味となります。
      「RigidTapping がなんたら」は、リジットタップじゃない時はSコードもM03もだしませんとなります。
      クーラントはまた別の処理でやってます。
      var coolants = [・・・・]
      この変数で、どのコードを出すかを設定しているようです。

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