Ре-процессинг.


Ре-процессинг - это процесс повторного процессирования выведенной УП.
Вообще, начиная его употреблять в 2002 году -  я этот процесс называл повторным постпроцессом, но с легкой руки граждан из фирмы Csoft - с 2007 году к нему приклеилось название которое я привел в заголовке.

Для чего нужен данный механизм?

 Прежде всего он необходим для вывода в УП информации, которая становиться известной только в конце постпроцесса. Это - информация об используемом инструменте, времени выполнения УП, min\max - координаты точек УП, и многая другая вспомогательная информация, часто являющаяся "украшательством". Её ценность, порой субъективна, и часто она оценивается только со слов цеховых технологов и операторов ЧПУ, которые открывая УП в текстовом редакторе ЧПУ, могут сразу увидеть какой инструмент используется в УП, кто сделал, название детали (карты настройки) и т.д.

 Как и функция MOM_before_motion, реализация "ре-процесса"  является "узким местом" постпроцессора, с точки зрения производительности и быстродействия.

Существует 2-а типа "ре-процесса".

   Это самый простой распространенный тип. Сущность его проста. В основном она реализуется в тексте процедуры [MOM_end_of_program].
<=

 В этом алгоритме есть небольшое слабое звено. Его я выделил красным цветом.
 Именно, когда происходит процесс переименовывания выходного файла во временный, может случиться ошибка 'Ввода\Вывода'. Эта ошибка напрямую связана с Vericut (другими внешними программами), в которых выводимая УП может быть открыта. В итоге, внешняя программа, с одной стороны может не дать команде Tcl переименовать файл, а с другой, в начале вывода постпроцесса - Юниграфика откроет выводимый файл не в режиме нового файла, а в режиме 'дополнения'. То-есть, в одном файле, вы можете получить 2-.3...4... одинаковых УП.

Пример процедуры. #=============================================================
proc PB_CMD_reprocess { } {
#=============================================================
 
global ptp_file_name mom_definition_file_name mom_output_file_full_name 
global mom_output_file_directory mom_output_file_basename mom_output_file_suffix 
global mom_warning_info 
global mom_machine_time mom_group_name mom_operation_name mom_part_name
global mom_tool_count mom_tool_use
global mom_logname mom_ug_version mom_date mom_machine_name 

set tm1 [clock seconds]
set tm2 [clock format $tm1 -format "%M:%S"]
MOM_log_message "MOM Start = $tm2 "

set tmp_file_name "${ptp_file_name}_"
if {[file exists $tmp_file_name]} {
  MOM_remove_file $tmp_file_name
}
MOM_close_output_file $ptp_file_name
file rename $ptp_file_name $tmp_file_name

set ifile [open $tmp_file_name r]
set ofile [open $ptp_file_name w]

set temp ";%_N_"
set temp1 $mom_output_file_basename
set temp2 _MPF
set stroka [concat $temp$temp1$temp2]
puts $ofile "$stroka"

set temp ";$"
set temp1 "PATH=/_N_WKS_DIR/_N_WORK_PROGRAMS\_WPD"
set stroka [concat $temp$temp1]
puts $ofile "$stroka"

puts $ofile " "
set path $mom_part_name
puts $ofile ";(PART: $path)"

if {[info exists mom_operation_name] == 0} { set mom_operation_name "" }
if {[info exists mom_group_name] == 0} { set mom_group_name $mom_operation_name }
puts $ofile ";(Program: $mom_group_name)" 
puts $ofile ";(Date:$mom_date User:$mom_logname)"
puts $ofile ";(MACHINE: $mom_machine_name, Siemens CNC)"

puts $ofile ";(MACHINE TIME: [format "%.2f" $mom_machine_time] MIN)"
puts $ofile " "

puts $ofile ";(----------- TOOL LIST -----------)"
for { set nn 0 } { $nn < 99 } {incr nn} {
  if {[hiset mom_tool_use($nn,0)] && [hiset mom_tool_use($nn,1)]} {
    set a [scan $mom_tool_use($nn,0) %d tn]
    set str [format "%s %.2f" $tn $mom_tool_use($nn,1)]
    puts $ofile ";(TOOL NUMBER $str MIN)"
  }
}
puts $ofile ";(--------- END TOOL LIST ---------)"

while { [gets $ifile buf] > 0 } {
   puts $ofile $buf
}

close $ifile
close $ofile
MOM_remove_file $tmp_file_name

set tm1 [clock seconds]
set tm2 [clock format $tm1 -format "%M:%S"]
MOM_log_message "MOM End = $tm2 "

MOM_open_output_file $ptp_file_name
  }

Вы знаете, всё это конечно хорошо, но однажды я задумался. Я задал себе вопрос: "сколько строк я вывожу таким образом?" Получилось, что максимум 40-50. Выходит, что после вывода этих 40-50-и строк, я заново, просто - так, переписываю содержимое с одного файла в другой! Но на это затрачивается время! Получалось, как то неправильно, нерационально. Я решил провести тестирование. Для этого я взял обычную УП размером 16-18 мб. Создал скрипт на Tcl и написал небольшое приложение, используя STL.

 Тест копирования.

 Файл УП для тестирования: UG57_002.rar (~16 мб)

 

Tcl-скрипт: file_read.tcl

Exe-файл: file_read_vc.zip

 

Результаты:

T~14...15 секунд

 T=10 секунд

После я расширил MOM и создал MOM-команду:

set ret [ MOM_file $name_file $str1 $str2 $str3 $str4 $str5 $str6 $str7 ... ] 

Команда дополняет в начало файла name_file строками $str1 $str2 ..... $strN

Исходники MOM-расширения: mom_file_read.zip
Пример процедуры.
и постпроцессора:
mill3ax_fr.zip
#=============================================================
proc PB_CMD_reprocess_dll { } {
#=============================================================
 
global cam_post_dir ;
global ptp_file_name mom_definition_file_name mom_output_file_full_name 
global mom_output_file_directory mom_output_file_basename mom_output_file_suffix 
global mom_warning_info 
global mom_machine_time mom_group_name mom_operation_name mom_part_name
global mom_tool_count mom_tool_use
global mom_logname mom_ug_version mom_date mom_machine_name 

set file_name "mom_file_read"

set suff [VNC_ask_shared_library_suffix]
if { ![file exists ${cam_post_dir}${file_name}.$suff] } {
   set suff so
}
if { ![file exists ${cam_post_dir}${file_name}.$suff] } {
   set __msg "ERROR in [info script] :\n\
      \nShared library \"${file_name}\" is not found in ${cam_post_dir}."
   MOM_abort $__msg
}

catch {
   MOM_run_user_function ${cam_post_dir}${file_name}.$suff ufusr
}

set temp ";%_N_"
set temp1 $mom_output_file_basename
set temp2 _MPF
set stroka1 [concat $temp$temp1$temp2]

set temp ";$"
set temp1 "PATH=/_N_WKS_DIR/_N_WORK_PROGRAMS\_WPD"
set stroka2 [concat $temp$temp1]

set stroka3 " "
set path $mom_part_name
set stroka4 ";(PART: $path)"

if {[info exists mom_operation_name] == 0} { set mom_operation_name "" }
if {[info exists mom_group_name] == 0} { set mom_group_name $mom_operation_name }
set stroka5 ";(Program: $mom_group_name)" 
set stroka6 ";(Date:$mom_date User:$mom_logname)"
set stroka7 ";(MACHINE: $mom_machine_name, Siemens CNC)"

set stroka8 ";(MACHINE TIME: [format "%.2f" $mom_machine_time] MIN)"
set stroka9 " "

set stroka10 ";(----------- TOOL LIST -----------)"
set stroka11 ""
for { set nn 0 } { $nn < 99 } {incr nn} {
  if {[hiset mom_tool_use($nn,0)] && [hiset mom_tool_use($nn,1)]} {
    set a [scan $mom_tool_use($nn,0) %d tn]
    set mom_tool_use($nn,1) [expr $mom_tool_use($nn,1) * 1]
    append stroka11 ";(TOOL NUMBER [format "%s %.2f" $tn $mom_tool_use($nn,1)] MIN)\n"
  }
}
set stroka12 ";(--------- END TOOL LIST ---------)"

MOM_close_output_file $ptp_file_name

MOM_file $ptp_file_name $stroka1 $stroka2 $stroka3 $stroka4 $stroka5 $stroka6 \
                        $stroka7 $stroka8 $stroka9 $stroka10 $stroka11 $stroka12

MOM_open_output_file $ptp_file_name
  }

Кстати, можно попытаться обойтись и без использования копирования файлов. А попытаться завести 'буфер' переменную - buffer_up .

#=============================================================
proc PB_CMD_before_output { } {
#=============================================================
 global mom_o_buffer

 if {$mom_o_buffer!=""} {
     global buffer_up buffer_cnt buffer_flag
     if { ![ info exists buffer_flag ] } { set buffer_flag 0 ; }
     if {$buffer_flag!=0} { return; }
     if { ![ info exists buffer_cnt ] } { set buffer_cnt 0 ; }
     set buffer_up($buffer_cnt) $mom_o_buffer
     incr buffer_cnt
     set mom_o_buffer  ""
 }

}

В итоге, в событии [MOM_end_of_program] - процедура для "ре-процесса" будет выглядеть по-другому.

#=============================================================
proc PB_CMD_reprocess { } {
#=============================================================
global ptp_file_name mom_definition_file_name mom_output_file_full_name 
global mom_output_file_directory mom_output_file_basename mom_output_file_suffix 
global mom_warning_info 
global mom_machine_time mom_group_name mom_operation_name mom_part_name
global mom_tool_count mom_tool_use
global mom_logname mom_ug_version mom_date mom_machine_name 

set tm1 [clock seconds]
set tm2 [clock format $tm1 -format "%M:%S"]
MOM_log_message "MOM Start = $tm2 "

; # файл - ptp_file_name - пустой ,
; # вся УП находиться в буфере - buffer_up

global buffer_flag
set buffer_flag 1 ; # отключаем буфферизацию в функции  PB_CMD_before_output

MOM_output_literal ";%_N_${mom_output_file_basename}_MPF"
MOM_output_literal ";$$PATH=/_N_WKS_DIR/_N_WORK_PROGRAMS\_WPD"
MOM_output_literal " "
MOM_output_literal "; (PART:$mom_part_name)"

if {[info exists mom_operation_name] == 0} { set mom_operation_name "" }
if {[info exists mom_group_name] == 0} { set mom_group_name $mom_operation_name }
MOM_output_literal ";(Program: $mom_group_name)" 
MOM_output_literal ";(Date:$mom_date User:$mom_logname)"
MOM_output_literal ";(MACHINE: $mom_machine_name, Siemens CNC)"

MOM_output_literal ";(MACHINE TIME: [format "%.2f" $mom_machine_time] MIN)"
MOM_output_literal " "

MOM_output_literal ";(----------- TOOL LIST -----------)"
for { set nn 0 } { $nn < 99 } {incr nn} {
  if {[hiset mom_tool_use($nn,0)] && [hiset mom_tool_use($nn,1)]} {
    set a [scan $mom_tool_use($nn,0) %d tn]
    set str [format "%s %.2f" $tn $mom_tool_use($nn,1)]
    MOM_output_literal ";(TOOL NUMBER $str MIN)"
  }
}
MOM_output_literal ";(--------- END TOOL LIST ---------)"

global buffer_up buffer_cnt
for { set i 0 } { $i < buffer_cnt } { incr i } {
  MOM_output_literal $buffer_up($i)
}

set tm1 [clock seconds]
set tm2 [clock format $tm1 -format "%M:%S"]
MOM_log_message "MOM End = $tm2 "

}

Второй тип применения "ре-процесса" сложнее. Как бы написать.. Он является более интеллектуальным, в отличие от простого копирования файлов. Редактирование УП происходит практически на всем пути её "ре-процесса". Предварительно, при первом прогоне с УП мы расставляем специальные метки, для последующего просмотра и редактирования.

Как пример могу привести постпроцессор SGPost. Перед запуском модуля постпроцесса, запускается модуль пре-процесса, задача которого состоит в открытие файла CLS - просматривание его и расстановки специальных операторов SG...... (SGROT, SGPLAN,...), путем создания временного файла tmp. Дальше, этот временный файл поступает на вход модуля постпроцесса, для формирования УП. Данные операторы SG:SGROT, SGPLAN,... -  необходимы для формирования операторов ROT\TRANS, возможности работы УП в повернутой плоскости. Также это необходимость формирования подпрограмм.

 


Copyright © 2001—2009 че