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

Fusion360

前回は、NCプログラムの始まりを担当する、onOpen( )関数を編集しました。
今回は、各セクション(工程)ごとの始まりを担当する、onSection( )を編集していきます。

オリジナルポストの確認

前回、オリジナル(fanuc.cps)のonOpen部分を改造し「fanuc_new.cps」として保存しました。
onSection( )はオリジナルのままなので、このファイルでポスト処理させてみます。
実際に処理させてわかりましたが、状況により3パターンの違いがみられました。

1.最初のセクション(工程)の場合
2.2回目以降で、直前工程と同じ工具を使用する場合
3.2回目以降で、直前工程と違う工具を使用する場合

1.最初のセクション(工程)の場合

(---- onSection ----)
 G28G91Z0.
 G90

 (3)
 T1M06
 (AP0.02D AE1D)
 S2300M03
 G54
 M08
 G00X-44.303Y-9.527
 G43Z30.H01
 (---- End of onSection ----)

2.2回目以降で、直前工程と同じ工具を使用する場合

(---- onSection ----)
(2D 7)
G00X-37.2Y11.2
(---- End of onSection ----)

3.2回目以降で、直前工程と違う工具を使用する場合

(---- onSection ----)
 M05
 G28G91Z0.
 G90
 G49

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

3パターンから考察

最初のセクション(工程)の始まりは、
・工具退避
・G90、相対座標系
・加工機能コメント表示
・工具交換
・工具コメント、コメント表示
・主軸回転
・ワーク座標
・クーラント
・加工位置へ位置決め
・工具長補正
このようになっていますが、直前の工具と同じ工具を使用する場合には、
工具交換を省略するようで、ほとんど一つの工程として処理されています。
直前の工具と違う場合には、ほぼ最初の工程の場合と同じ処理ですが、
回転やクーラントのキャンセルが追加になっています。

変更点

今回考えているNCプログラム構成は、先頭でワーク座標系指示を行い、
各セクション(工程)へは、「GOTO」の無条件ジャンプ指示で任意の工程からでもスタートできるようにしたいと考えています。
ジャンプ先番号は、デフォルトでは「GOTO 1」と「N0001」へのジャンプするコードにしますが、変更したければ、機械側で編集する仕様とします。
したがって、直前と同じ工具だからといって、工具交換などの処理を省略してしまうと、途中スタートで問題が出てきます。
使用工具の状態にはとらわれず、工程終了時には、一旦すべてキャンセルするような処理をさせたいと思います。
このキャンセル処理は、オリジナルの「funuc.cps」では、「onSection( )」でやらせているようですが、今回は「onSection( )」でのキャンセル」処理は無効にして「onSectionEnd( )」に担当させようと思っています。
ただし、工作機械によっては、主軸にある工具と同じ工具番号をT指令で指定するとアラームなる機械も存在します。
そのような場合、無理やりダミー工具と交換させる事も一つの方法として考えられますが、今回は、同じ工具だった場合には、「/」を追加して、オプショナルスキップで機械側での対応にしようかと思います。

NCプログラムの構成

上記を考慮して、NCプログラム構成を再検討します。
筆者は基本的には使用工具状態にはとらわれず、全ての工程で下記のようなコードが出力するようにポストを改造していきます。
ただし、同じ工具だった場合には、「/T01」「/M06」とオプショナルスキップコードにしようと思います。
また、スピンドル回転やクーラント作動は、フルカバーでない機械は、クーラントが飛び散る場合もあるので、主軸が下りてきて工具長補正が完了した後とし、クーラントの安定と暖気を兼ねて、ドウェル指令を追加します。

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

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

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

onSection( )の改造 No1

オリジナルと見比べながら改造していきます。
ちょっと前置きが長くなってしまったので、実際の編集作業の説明は、今回は①~⑤までとします。

①シーケンス番号

いきなり、オリジナルにはないコードが必要になりました。
①は、ジャンプさせるための番地としてシーケンス番号を追加します。
番号は、セクション(工程)番号と同じ番号とします。
例えば、2工程目であれば、N0002 となります。

function onSection() {
   //kazuban 2021/01/05
   writeln("(---- onSection ----)");
   //kazuban 2021/01/23
   var nFormat = createFormat({prefix:"N", width:4, zeropad:true});
   writeln(nFormat.format(getCurrentSectionId()+1));
  ・
  ・

シーケンス番号用として、「N」+「4桁数字」の出力用で、Format関数を作成しました。
Format関数は、グローバルセッション編で詳しく説明しています、ので、
まだ理解されていない場合にはこちらを参照してください。
また、シーケンス番号は、セクション番号と同じ番号にしたいため、
getCurrentSectionId()」関数で、現在のセクション番号を取得しています。
ただし、この関数が返す現在のセクション番号は、「0」から始まるため
「+1」
としています。

②工具情報

②は工具情報をコメントとして入れてみようと思います。
onOpen( )でも、先頭で出力されますが、ここには、各工程で使用する工具の情報とします。
工具深さ情報は、onOpen( )では、別の工程で同じ工具を使用する場合には、使用工程全体で最小深さの情報を出力しますが、ここでは、この工程のみの最小深さを出力しようと思います。
この仕様もオリジナルにはないので、工具情報を得るコードを書く必要があります。
onSection( )内に直接書いてもいいですが、行数も多いので、関数を作成したほうが、読みやすく後に修正しやすくなります。

//kazuban 2021/01/23
//Tool Infomation
function writeToolInfo(){
  var section = getSection(getCurrentSectionId());
  var tool = section.getTool();
  var number = tool.number;
  var diameter = tool.diameter;
  var cornerRadius = tool.cornerRadius;
  var zRange = section.getGlobalZRange();
  var zMin = zRange.getMinimum();

  var tFormat = createFormat({decimals:3,trim:false,forceDecimal:true,decimals:3});
  var tOutput = createFormat({prefix:"T",width:2, zeropad:true});
  var tdiaOutput = createVariable({prefix:" D="}, tFormat);
  var trOutput = createVariable({prefix:" R="}, tFormat);
  var zminOutput = createVariable({prefix:" ZMIN="}, tFormat);
  write("(");
  write(tOutput.format(number));
  write(tdiaOutput.format(diameter));
  write(trOutput.format(cornerRadius));
  write(zminOutput.format(zMin));
  writeln(" )");
  writeln("( "+tool.comment+" )");
}

ちょっと長くなってしまいましたが、この工具情報を取得するコードは他でも参考になるかもしれません。
まず、
var section = getSection(getCurrentSectionId());
「getSection( getCurrentSectionId() )」関数で、現在のセクションオブジェクトを、「section」という変数に代入しています。
次に、
var tool = section.getTool();
では、現在のセクションの工具情報オブジェクトで「tool」変数を定義しました。
さらに、「tool」オブジェクトから、
「tool.number」「tool.diameter」「 tool.cornerRadius」で、
「工具番号」「工具径」「工具角R」を取得できます。
var zRange = section.getGlobalZRange();
では、現在のセクションの「Z範囲」情報オブジェクトを定義して
var zMin = zRange.getMinimum();
「getMinimum()」で、このセクションでの最小Z値を取り出せます。

次に、「T01」「D=12.000」 「R=0.000」 「ZMIN=-9.995」など、工具情報を出力する、Format を定義しています。
工具のコメントは、「tool.comment」で取り出せます。
最後は、write( )とwriteln( )関数で、コメントとして出力させる関数です。
writeComment( ) 関数も用意されていますが、大文字にしたり、( )を省いたり、
なんだか面倒そうな処理をしているので、ここでは、自前で書き込ませます。
この関数を、先ほどのシーケンス番号を出力するコードの次の行に追加します。
onSection( )内は、この一行で済みますから、読みやすくなります。

function onSection() {
  //kazuban 2021/01/05
  writeln("(---- onSection ----)");
  //kazuban 2021/01/23
  var nFormat = createFormat({prefix:"N", width:4, zeropad:true});
  writeln(nFormat.format(getCurrentSectionId()+1));
  writeToolInfo();
  ・
  ・

スピンドル回転停止

次は、オプショナルスキップや、工具交換の状態などの定義がされていますが、
1186行目付近で、工具交換されて、最初のセクションでない場合には、
回転停止指令(M05)を出すように定義されています。
ただし今回は、このような終了処理は、onSectionEnd( )関数にやらせようと思っているので、ここでは無効にしておこうと思います。

if (insertToolCall && !isFirstSection()) {
    //kazuban 2021/01/23
    //onCommand(COMMAND_STOP_SPINDLE);
  }

③G91G28Z0.④G49⑤G90G00G17

「G28」は主軸リファレンス点復帰指令です。
とりあえず、安全位置へ退避させる場合によく使用されるGコードです。
2工程目以降のセクション(工程)の場合に、前セクション終了時、すでにこの指令が実行されていて重複する可能性もありますが、プログラム途中スタートなどの場合も考慮して、セクション(工程)初めにはこの指令を入れるようにします。
また、「G49」は、工具長補正キャンセルコードです。
機種によっては、「G28」に「G49」機能も含まれている機種もあります。
その場合「G49」は不要ですが、あっても問題はないので、多少冗長であってもこの3行はセットで出力させようと思います。
余談ですが、「G49」指令は、キャンセルに動作を伴う機種もあります。
その場合、補正値によっては、Z軸がマイナス側へ下がったり、逆に上がってZ軸がオーバートラベルになる場合も、まれにあります。
そのような場合には、動作を伴わないよう現在位置でキャンセルさせるの意味で「G91G49Z0.」の指令とする場合もあります。
今回は、「G49」のみの出力とします。

「G28」の指令は、「writeRetract(Z)」の関数で出力させています。
ここまで編集してきた「fanuc_new.cps」では、1183行付近のこの条件判断のブロックの中で定義されています。

if (insertToolCall || newWorkOffset || newWorkPlane || forceSmoothing) {
  ・
  ・
}

これは主に新しい工具が挿入された場合の条件判断で書かれていますが、今回はセクション(工程)が変われば、同じ工具であっても無条件でこの指令は出力さてたいと思います。
無条件で実行させたい方法は、条件判断文を「true(真)」にすればいいので、方法はいろいろありますが、なるべくオリジナルのコードは崩したくないので、この条件判断に「真」の条件を一つ加える方法で対応します。
具体的には、「var  runWriteRetract = true」の変数を追加して、条件判断に追加します。

//kazuban 2021/01/23
 var runWriteRetract = true; 
 if (insertToolCall || newWorkOffset || newWorkPlane || forceSmoothing || runWriteRetract) {
   ・
   ・
 }

これで無条件にこのブロックを実行します。
この条件判断内のブロックの中で、「writeRetract(Z)」と言う関数を呼び出しています。

// retract to safe plane
writeRetract(Z); // retract 
forceXYZ(); 
if ((insertToolCall && !isFirstSection()) || forceSmoothing) { 
  disableLengthCompensation();   
  setSmoothing(false); 
}

この関数が「G28」関連の出力をさせていますので、「writeRetract(Z)」関数を確認してみます。
③、④、⑤の3行は、セットで出力させたいと思っているので、この関数で出力させるように改造します。
writeRetract()関数は2696行付近にあります。

function writeRetract() {
   // initialize routine
   var _xyzMoved = new Array(false, false, false);
   var _useG28 = properties.useG28; // can be either true or false
    ・
    ・

この関数の、2758付近に「_useG28」の条件判断で「G28G91Z0.」「G90」を出力させるコードがあります。

// output move to home
if (words.length > 0) {
  if (_useG28) {
    gAbsIncModal.reset();
    writeBlock(gFormat.format(28), gAbsIncModal.format(91), words);
    writeBlock(gAbsIncModal.format(90));
  } else {
    gMotionModal.reset();
    writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words);
  }
   ・
   ・

この部分を、このように編集します。

if (words.length > 0) {
  if (_useG28) {
    gAbsIncModal.reset();
    //kazuban 2021/01/23
    writeBlock(gAbsIncModal.format(91), gFormat.format(28), words);
    disableLengthCompensation();
    gMotionModal.reset();
    gPlaneModal.reset();
    writeBlock(gAbsIncModal.format(90),gMotionModal.format(0),gPlaneModal.format(17));
    //writeBlock(gFormat.format(28), gAbsIncModal.format(91), words);
    //writeBlock(gAbsIncModal.format(90));
  } else {
    gMotionModal.reset();
    writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words);
  }

まず、writeBlock( )を少し修正して「G28G91Z0.」を「G91G28Z0.」に編集しています。
順番を変えるのは特に意味はありません。
気分の問題と編集の参考になるかも、と言うだけで、NC的には意味はないです。
次に、「disableLengthCompensation()」関数で、「G49」を出力させています。
上に書いた、「G91G49Z0.」などにしたい場合には、この関数を編集する事になりますが、今回は省略します。
次の2行「gMotionModal.reset()」「gPlaneModal.reset()」は、「G00」「G17」を必ず出力させるために、事前のモーダル情報をキャンセルさせています。
基本的に、モーダルコードは、事前の状態で出力の有無が変わりますが、無条件に出力させたい場合には、「reset()」関数でモーダル情報を初期化します。

まとめ

onSection( )、まだ半分ですね。
シーケンス番号(N番号)を出力するために、Formatを利用してみました。
工具情報を出力するために、sectionオブジェクトの使用例を紹介しました。
また、モーダルコードをリセットして、強制的に出力させてみました。
次回は残りを編集してみたいと思います。


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

コメント

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