Именованные параметры CLData
Из CAM-системы в постпроцессор приходит набор данных, называемый CLData, на основе которого постпроцессор формирует G-код. Данные внутри CLData могут описывать множество различных параметров, относящихся к совершенно разным сложным объектам: технологической операции, траектории, инструменту, проекту, заготовке и т. д. Поэтому внутри CLData они непременно структурированы и фактически являются не простым списком, а деревом параметров. Доступ к этим параметрам из кода постпроцессора выполняется по строковому имени. Поскольку мы имеем дерево параметров, обычно полное имя параметра — это составная строка из нескольких идентификаторов, разделённых точками, а иногда и скобками, то есть
GroupName.SubGroupName.ParameterName.SubParameterName и т. д. Уровень вложенности параметров может быть разным — от одного до нескольких идентификаторов, разделённых точками. Пример реального имени параметра, отвечающего за радиус сглаживания траектории внутри операции: "Operation.Smoothing.Radius".
Доступ из sppx
Синтаксис доступа к параметру из кода программы постпроцессора следующий.
ObjectKeyWord.TypeKeyWord["ParameterName"]
Здесь ObjectKeyWord — ключевое слово, указывающее, у какого объекта из CLData мы запрашиваем параметры. Сейчас в качестве ObjectKeyWord могут быть:
- Cmd — текущая команда CLData.
- CLDFile[index1].Cmd[index2]. Команда CLData с индексом index2 из cld-файла с индексом index1. Здесь index1 и index2 — любые целые числа.
- Project — проект CAM-системы, в котором сгруппированы параметры, относящиеся ко всем операциям, а не к отдельной операции, например заготовка.
TypeKeyWord — ключевое слово, определяющее форму (строка, число и т. д.) получения значения параметра. Параметры могут быть разных типов: string (строка), integer (целое), floating-point (число с плавающей точкой), complex (параметры этого типа не имеют собственного значения, но могут иметь дочерние свойства любого из описанных здесь типов; нужны для объединения нескольких параметров в группу), array (как и сложные, не имеют собственных значений и могут иметь дочерние свойства, однако дочерние свойства массивов, как правило, имеют общий тип и, следовательно, одинаковое имя, поэтому доступ к дочерним свойствам массивов выполняется не по имени, а по индексу).
Доступны следующие ключевые слова.
Str["ParameterName"]— возвращает значение параметра команды с именем ParameterName в виде текстовой строки String.Int["ParameterName"]— возвращает значение параметра команды с именем ParameterName в виде целого числа Integer.Flt["ParameterName"]— возвращает значение параметра команды с именем ParameterName в виде вещественного числа Real (числа с плавающей точкой).Ptr["ParameterName"]— возвращает ссылку (не значение) на параметр команды с именем ParameterName. Удобно использовать для доступа к параметрам типа complex и array. Если параметра с таким именем в этой команде не существует, оператор возвращает значение 0, иначе — ненулевое число. Таким образом, проверку на равенство нулю можно использовать для проверки существования параметра.
if cmd.Ptr["Axes(AxisCPos)"]<>0 then begin
C = cmd.Flt["Axes(AxisCPos).Value"]
end
От полученной ссылки через точку можно обратиться либо к значению этого параметра, либо к одному из дочерних параметров. Для этого после точки снова нужно указать одну из команд, описанных здесь: Str, Int, Flt, Ptr, Item, ItemCount, Name. Если в последующих инструкциях имя параметра не указано, это означает, что речь идёт о самом этом параметре. Например, инструкция Cmd.Ptr["Parameter1"].Int означает взять значение параметра с именем Parameter1 как целое число. Запись Cmd.Ptr["Parameter1"].Int["SubParameter1"] означает взять целочисленное значение дочернего параметра SubParameter1 внутри параметра Parameter1.
Cmd.Item[Index] — возвращает ссылку на дочерний параметр по индексу. Индексация параметров начинается с 1.
Cmd.ItemCount — возвращает число дочерних параметров в списке.
Для параметров типа array все дочерние параметры на один уровень ниже могут иметь одинаковое имя. В этом случае доступ по имени невозможен; вместо него нужно использовать доступ по индексу.
ObjectKeyWord.Ptr["NameOfArrayParameter"].Item[Index]— возвращает ссылку на дочерний параметр по индексу. Индексация параметров начинается с 1.ObjectKeyWord.Ptr["NameOfArrayParameter"].ItemCount— возвращает число дочерних параметров в списке.
Помимо доступа по индексу, доступ к дочерним параметрам массива в некоторых случаях может выполняться по ключу. Если у массива определён параметр Key, задающий имя ключевого поля в дочерних параметрах, то для доступа к конкретному элементу массива после имени массива нужно указать значение ключа в скобках. Например, инструкция Cmd.Ptr["ArrayName(KeyValue)"] означает взять параметр ArrayName из текущей команды, где найти дочернее свойство с ключевым полем, равным KeyValue.
В качестве имени параметра в них может быть не только строковая константа, как показано здесь, но и строковые переменные и выражения.
Есть удобный способ сформировать строку доступа к нужному параметру. Все параметры объектов CLData показаны отдельным деревом на вкладке CLData в её правой части. Нужно выбрать необходимую команду в списке или проект в списке операций. При этом в дереве справа будут показаны параметры выбранного объекта. Затем нужно найти в этом дереве нужный параметр и дважды щёлкнуть по нему. Строка доступа к указанному параметру будет вставлена в текущую позицию курсора в окне редактирования кода.

Пример обработки команды MultiGoto с использованием различных способов доступа к элементам параметра-массива Axes (по индексу, по ключу и по составному имени):
program MultiGoto
i: Integer
AxisName: String
for i = 1 to Cmd.Ptr["Axes"].ItemCount do begin
AxisName = cmd.Ptr["Axes"].Item[i].Str["AxisID"]
if AxisName="AxisXPos" then begin
X = cmd.Ptr["Axes"].Item[i].Flt["Value"]
end else
if AxisName="AxisYPos" then begin
Y = cmd.Ptr["Axes("+Str(i)+")"].Flt["Value"]
end else
if AxisName="AxisZPos" then begin
Z = cmd.Flt["Axes("+Str(i)+").Value"]
end else
if cmd.Ptr["Axes(AxisCPos)"]<>0 then begin
C = cmd.Flt["Axes(AxisCPos).Value"]
end
end
OutBlock
end
Больше примеров доступа к именованным параметрам приведено в разделе Текущая команда.
Доступ из .NET
.NET использует ту же модель именованных параметров, предоставляемую интерфейсом INamedProperty. Её реализует каждый объект CLData, несущий именованные параметры — текущая команда (ICLDCommand), произвольная команда, взятая через CLDFile, и проект (ICLDProject). Ключевые слова соответствуют sppx-овским один к одному:
| sppx | .NET | Описание |
|---|---|---|
Str["Name"] |
Str["Name"] |
значение параметра как строка |
Int["Name"] |
Int["Name"] |
значение параметра как целое число |
Flt["Name"] |
Flt["Name"] |
значение параметра как число с плавающей точкой |
| - | Bol["Name"] |
значение параметра как логическое значение |
Ptr["Name"] |
Ptr["Name"] |
ссылка на (сложный) параметр как INamedProperty |
| - | Arr["Name"] |
ссылка на параметр-массив как INamedPropertiesCollection |
Item[i] |
Arr["Name"][i] |
i-й дочерний элемент параметра-массива (0-based в .NET) |
ItemCount |
Arr["Name"].TopItem |
максимальный индекс в параметре-массиве |
Name |
Name |
собственное имя параметра |
База индексации. Когда дочерние элементы параметра-массива адресуются по индексу, нумерация различается между двумя подсистемами: она 1-based в sppx (
Item[1]...Item[ItemCount]) и 0-based в .NET (Arr["Name"][0]...Arr["Name"][TopItem]). Соответственно, sppx-овскийItemCount— это число дочерних элементов, тогда как .NET-овскийTopItem— максимальный индекс, на единицу меньше числа, поэтому цикл в .NET выполняется какfor (int i = 0; i <= coll.TopItem; i++). (Это касается только дочерних элементов именованных параметров-массивов; числовой массив CLD 1-based в обеих подсистемах.)
Как и в sppx, имя может быть составной строкой с точками и скобками — Ptr["StartPoint.X"], Ptr["Axes(AxisCPos).Value"] — разрешаемой на любую глубину вложенности; регистр символов не имеет значения. Кроме того, INamedProperty предлагает FindChild(name), GetNextChild(child), Parent, SimpleType (тип NamedParamType значения) и типизированные средства доступа к значению ValueAsString / ValueAsInteger / ValueAsDouble / ValueAsBoolean.
public override void OnMultiGoto(ICLDMultiGotoCommand cmd, CLDArray cld)
{
var axes = cmd.Arr["Axes"];
for (int i = 0; i <= axes.TopItem; i++) {
string axisName = axes[i].Str["AxisID"];
double value = axes[i].Flt["Value"];
// ... вывод оси
}
// или обратиться к отдельной оси напрямую по её ключу:
if (cmd.Ptr["Axes(AxisCPos)"] != null)
C = cmd.Flt["Axes(AxisCPos).Value"];
}