Моделирование упаковки с использованием API SolidWorks

от автора

Одна из задач, встречающаяся при разработке новых изделий – это задача компоновки их упаковки.
image
В качестве иллюстрации этого утверждения приведем пример, в котором с такой задачей столкнулись даже IT-специалисты. Как раз на момент написания этой статьи программисты одного из подразделений ООО «Специальный технологический центр» занимались подбором комплектующих для комплекса радиоэлектронной аппаратуры, в состав которого входили серверы и автоматизированные рабочие места. Мне как конструктору в этот момент пришлось принять участие в выборе тары для укладки ЗИП (первое изображение под катом). Как могут решаться подобного рода задачи – см. далее.


Чтобы выбрать ящик, необходимо узнать габариты упаковываемых изделий, а затем скомпоновать их.

К настоящему времени задачи упаковки уже решались в ряде исследований. В терминологии теории алгоритмов эти задачи относятся к классу NP-полных задач, не имеющих точных алгоритмов ее решения за полиноминальное время [1]. С примером решения данной задачи с помощью эвристического алгоритма можно также ознакомиться в работе [2], а применение частного случая эвристического алгоритма – генетического алгоритма – увидеть в работе [3]. Многие из этих решений включают в себя разработку приложений, визуализирующих результаты работы алгоритмов. Однако в перечисленных источниках не упоминается о передаче результатов работы таких программ в CAD-систему SolidWorks (или другую систему с аналогичной функциональностью) для дальнейшего оформления конструкторской документации. Фрагмент чертежа упаковки, оформленного в программе Компас, показан ниже на рисунке.

Другой причиной, побудившей автора написать данную статью являются затраты времени, с которыми сталкивается разработчик при поиске методов решения типовых задач программирования с использованием API SolidWorks. Документация на API указанной программы на английском языке, а примеры решения таких задач часто встречаются на англоязычных форумах.

Таким образом, основными задачами, решаемыми в данной статье являются:

  1. Показать принципиальную возможность моделирования упаковки с использованием API SolidWork.
  2. Продемонстрировать некоторые практические примеры решения типовых задач программирования.

Отдельные примеры, относящиеся ко второй задаче, были рассмотрены в статье [4].

Формализуем описание исходных данных для моделирования.

Имеется множество n размещаемых объектов (изделий), i=1, 2,…, n. Каждый i-й блок характеризуют три параметра – размеры по осям $ L_x $, $ L_y $ и $ L_z $. Все изделия смещены относительно начала координат 3D-модели сборки на неотрицательные величины:

по оси X: $ [0, D_{xi}]; $

по оси Y: $[0, D_{yi}]; $

по оси Z: $[0, D_{zi}]$

Добавим также в описание задачи одно условие, которое следует учитывать при моделировании. В некоторых из упаковок встречается задача консервации изделия с использованием силикагеля. Силикагель в мешочках закладывается в полиэтиленовые чехлы, которые затем завариваются. Эти мешочки имеют определенный объем. Для равномерной укладки предлагается использовать прокладки из пенопласта с вырезами, которые накладываются на места укладки силикагеля и фиксируются стрейч-пленкой.

Таким образом, имеется множество m размещаемых прокладок, j=1, 2,…, m.

Каждая j-я прокладка аналогичным образом характеризуется размерами по осям $ L_x $, $ L_y $ и $ L_z $, неотрицательным смещением вдоль каждой из осей, а также вырезом вдоль одной из осей. Размеры выреза заданы так, как показано трех рисунках. Применение прокладок необязательно.


Также вдоль стенок ящика, в который упаковываются изделия, могут устанавливаться прокладки из пенопласта.

Эти прокладки моделируются одной деталью, которая также задается тремя размерами $ L_x $, $ L_y $ и $ L_z $ по осям, толщиной стенок S и смещением в отрицательном направлении относительно осей:

по оси X: $[D_x, 0);$

по оси Y: $[D_y, 0);$

по оси Z: $[D_z, 0).$

Помимо этого в сборке может размещаться модель ящика, задаваемая отрицательными смещениями по осям, по аналогии с предыдущей прокладкой. Ящик спроектирован в программе, рассмотренной в статье [4].

Данное формализованное описание сохраняется в виде списка в текстовом файле с кодировкой ANSI. Такая кодировка нужна для корректного отображения результатов чтения с помощью C++\CLI.

Синтаксис записи в текстовом файле приведен ниже.

#Путь к результатам Путь к папке для сохранения результатов работы Наименование файла компоновки (без расширения) #Конец #Упаковываемые изделия Наименование упаковываемого изделия (без расширения) 0 – без группы, больше нуля – номер группы упаковываемых одинаковых изделий Lx Ly Lz Dx Dy Dz #Конец #Пенопласт Наименование прокладки (без расширения) Lx Ly Lz X, Y или Z – ось, вдоль которой выполнен вырез d1 d2 L1 L2 Dx Dy Dz #Конец #Пенопласт у стенок Lx Ly Lz S Dx Dy Dz #Конец #Ящик Путь к файлу 3D-модели сборки ящика Dx Dy Dz #Конец

Для реализации моделирования данной упаковки было разработано приложение на языке C++\CLI. Приложение читает вышеупомянутый текстовый файл, путь к которому передается программе через аргумент командной строки. Приложение разработано в IDE Microsoft Visual Studio 2022 (64-разрядная версия). Программа запускалась на компьютере с операционной системой Windows 10. Компьютер имел следующие характеристики: процессор Intel® Core(TM) i5-7600 CPU 3.50 ГГц, оперативная память 16 Гб. CAD-система – SolidWorks 2019 (64-разрядная). Время моделирования одной компоновки, состоящей из семи упаковываемых изделий, одной прокладки, одной прокладки у стенок ящика и самого ящика составило 1 мин 34 с.

Если рассматривать задачу укрупненно, то последовательность моделирования следующая:

  1. Чтение файла с данными.
  2. Копирование необходимых файлов шаблонов деталей в папку с результатом моделирования.
  3. Вставка моделей в компоновку.

В свою очередь, вставка моделей в компоновку реализована в следующей последовательности (на примере моделей упаковываемых изделий), представленной ниже. В скобках указаны задачи, решение которых рассматривалось в статье [4].

  1. Получение доступа к объекту типа SldWorks^ (см. статью).
  2. Отключение видимости приложения (см. задачи ускорения работы макроса в статье)
  3. Открытие файла 3D-модели компоновки.
  4. Вставка в цикле 3D-моделей упаковываемых изделий.
  5. Указание сопряжений для вставленной модели.

Вставка 3D-моделей упаковываемых изделий иллюстрируется фрагментом программного кода соответствующей функции.

//Значения переменных // swApp - объект SldWorks^, переданный по ссылке в функцию IModelDoc2^ swModel; int ok; //Результат изменения свойств. Функция SetActiveConfigProperty рассмотрена в статье [4]. ModelView^ modView; DesignTable^ DesTbl; //Таблица параметров bool bool_D; //Результаты обращения к таблице параметров AssemblyDoc^ assemb; ModelDocExtension^ swModelDocExt;  //Откроем файл модели груза swApp->OpenDoc6(gcnew System::String(str_Cargo_output_full_path.c_str()), 1, 0, "", swErrors, swWarnings);                  //Проведем процедуры инициализации переменных для работы со свойствами swApp->ActivateDoc2(gcnew System::String(sPackaged_cargo[i].str_Name.c_str()) +".SLDPRT", false, longstatus); swModel = (IModelDoc2^)swApp->ActiveDoc;                  //Пропишем в документ необходимые свойства //Х – размер по оси Х s_property = "X"; ok = Packing_wizard::SetActiveConfigProperty(swModel, s_property, mylib::to_string(sPackaged_cargo[i].dbl_Lx), 1); //Y – размер по оси Y s_property = "Y"; ok = Packing_wizard::SetActiveConfigProperty(swModel, s_property, mylib::to_string(sPackaged_cargo[i].dbl_Ly), 1); //Z – размер по оси Z s_property = "Z"; ok = Packing_wizard::SetActiveConfigProperty(swModel, s_property, mylib::to_string(sPackaged_cargo[i].dbl_Lz), 1);                                                   //Отключаем регенерацию графического окна modView = (ModelView^)swModel->ActiveView; modView->EnableGraphicsUpdate = false; //Отключаем регенерацию  //Получаем доступ к таблице параметров DesTbl = (DesignTable^)swModel->GetDesignTable(); bool_D = DesTbl->Attach();  //Обновляем таблицу параметров и отключаемся от нее bool_D = DesTbl->UpdateTable(2, true); DesTbl->Detach();  //Сохраняем документ swModel->Save();   //Активируем модель компоновки swApp->ActivateDoc2(gcnew System::String(sOutput_data.str_Name.c_str()) + ".SLDASM", false, longstatus);  //Готовим интерфейс для вставки модели assemb = (AssemblyDoc^)swApp->ActiveDoc;  //Вставляем модель за пределами максимальных габаритов ящика 2850х1500х2000 мм assemb->AddComponent(gcnew System::String(str_Cargo_output_full_path.c_str()), 1.5, 2.85, 2.0);                  //Закрываем модель груза swApp->CloseDoc(gcnew System::String((sPackaged_cargo[i].str_Name + ".SLDPRT").c_str()));  //Активируем модель компоновки swApp->ActivateDoc2(gcnew System::String(sOutput_data.str_Name.c_str()) + ".SLDASM", false, longstatus); swModel = swApp->IActiveDoc2;  //Перестраиваем модель компоновки swModel->EditRebuild3();  //Если компонент, вставленный в сборку, первый, отключаем его фиксацию if (i == 0) {   swModel = (ModelDoc2^)swApp->ActiveDoc;   swModelDocExt = swModel->Extension;   swModelDocExt->SelectByID2(gcnew System::String((sPackaged_cargo[i].str_Name + "-1@" + sOutput_data.str_Name).c_str()),"COMPONENT", 0, 0, 0, false, 0, nullptr, 0);   assemb->UnfixComponent();   swModel->ClearSelection2(true); } 

Здесь следует отметить несколько моментов. Один из них – чтобы можно было задать сопряжения с неотрицательными величинами между плоскостями системы координат 3D-модели сборки и гранями вставляемых изделий, изделия вставляются с координатами, лежащими на границе внутренних габаритов ящика. Другой момент – для вставки компонента в сборку с помощью метода AddComponent он должен быть предварительно открыт методом OpenDoc6. Некоторые из показанных в коде методов уже были приведены в статье [4].

Рассмотрим теперь принятые подходы к автоматическому указанию сопряжений в модели сборки.

Для их реализации в 3D-моделях вставляемых в сборку изделий была предварительно выполнена специальная разметка с использованием справочной геометрии.

Рассмотрим первый способ автоматического указания сопряжений и первый способ разметки, показанной на рисунке ниже.

Точкой O обозначено начало координат. Точка 1 лежит на оси X, точка 2 на оси Y, точка 3 – на оси Z.

Точки 13 в системе координат сборки будут иметь координаты с индексами 13 соответственно.

Для автоматизированного задания сопряжений между плоскостями системы координат сборки и поверхностями упаковываемых изделий необходимо выделить методами API. Для выделения поверхностей достаточно указать координаты любой точки, расположенной на поверхности и не лежащей на ребрах 3D-модели.

Один из вариантов – это указать точки, лежащие в центре трех отрезков, соединяющих точки 13.

При задании сопряжений 3D-модель упаковываемого изделия будет перемещаться гранями параллельно плоскостям системы координат сборки. Поэтому точки на середине отрезков будут иметь следующие координаты.

Точка, служащая для указания сопряжений вдоль оси X:

$x_x = x_3; \\ y_x = 0,5\cdot(y_2 + y_3); \\ z_x = 0,5\cdot(z_2 + z_3).$

Точка, служащая для указания сопряжений вдоль оси Y:

$x_y = 0,5\cdot(x_1 + x_3);\\ y_y = y_1;\\ z_y = 0,5\cdot(x_1 + x_2). $

Точка, служащая для указания сопряжений вдоль оси Z:

$x_z = 0,5\cdot(x_1 + x_2);\\ y_z = 0,5\cdot(y_1 + y_2);\\ z_z = z_1. $

Приведем программный код, иллюстрирующий измерение координат точек 13 и указания сопряжений вдоль оси Х. Этот код является продолжением кода, приведенного выше.

        //Координаты точек         Coordinates sC_point_1; //Точка 1 компонента         Coordinates sC_point_2; //Точка 2 компонента         Coordinates sC_point_3; //Точка 3 компонента         Coordinates sC_X; //Характерная точка для задания сопряжения по оси X         Coordinates sC_Y; //Характерная точка для задания сопряжения по оси Y         Coordinates sC_Z; //Характерная точка для задания сопряжения по оси Z   AssemblyDoc^ swAssemblyDoc;  //Измерение координат точек                 //Получение координат точки 1 во вставляемой детали                 swModelDocExt->SelectByID2(gcnew System::String(("Точка1@"+ sPackaged_cargo[i].str_Name + "-1@" + sOutput_data.str_Name).c_str()), "DATUMPOINT", 0, 0, 0, false, 0, nullptr, 0);                 Measure = swModelDocExt->CreateMeasure();                 Measure->ArcOption = 0;                 Measure->Calculate(nullptr);                 sC_point_1.dbl_X = Measure->X;                 sC_point_1.dbl_Y = Measure->Y;                 sC_point_1.dbl_Z = Measure->Z;                 swModel->ClearSelection2(true);                 //Получение координат точки 2                 swModelDocExt->SelectByID2(gcnew System::String(("Точка2@" + sPackaged_cargo[i].str_Name + "-1@" + sOutput_data.str_Name).c_str()), "DATUMPOINT", 0, 0, 0, false, 0, nullptr, 0);                 Measure = swModelDocExt->CreateMeasure();                 Measure->ArcOption = 0;                 Measure->Calculate(nullptr);                 sC_point_2.dbl_X = Measure->X;                 sC_point_2.dbl_Y = Measure->Y;                 sC_point_2.dbl_Z = Measure->Z;                 swModel->ClearSelection2(true);                 //Получение координат точки 3                 swModelDocExt->SelectByID2(gcnew System::String(("Точка3@" + sPackaged_cargo[i].str_Name + "-1@" + sOutput_data.str_Name).c_str()), "DATUMPOINT", 0, 0, 0, false, 0, nullptr, 0);                 Measure = swModelDocExt->CreateMeasure();                 Measure->ArcOption = 0;                 Measure->Calculate(nullptr);                 sC_point_3.dbl_X = Measure->X;                 sC_point_3.dbl_Y = Measure->Y;                 sC_point_3.dbl_Z = Measure->Z;                 swModel->ClearSelection2(true);                  //Переходим к расчету координат характерных точек                 //Точка для задания смещений вдоль оси Х                 sC_X.dbl_X = sC_point_3.dbl_X;                 sC_X.dbl_Y = 0.5 * (sC_point_2.dbl_Y + sC_point_3.dbl_Y);                 sC_X.dbl_Z = 0.5 * (sC_point_2.dbl_Z+ sC_point_3.dbl_Z);                  //Переходим к указанию сопряжений                 //Подготовка интерфейса                 swModel = (IModelDoc2^)swApp->ActiveDoc;                 swAssemblyDoc = (AssemblyDoc^)swModel;                                  //Сопряжения со смещениями вдоль оси Х                 if (sPackaged_cargo[i].dbl_Dx == 0) //Сопряжение совпадения                 {                     swModelDocExt->SelectByID2("Справа", "PLANE", 0, 0, 0, false, 0, nullptr, 0);                     swModelDocExt->SelectByID2("", "FACE", sC_X.dbl_X, sC_X.dbl_Y, sC_X.dbl_Z, true, 0, nullptr, 0);                                          swAssemblyDoc->AddMate3(0, 1, false, 0, 0, 0, 0, 0, 0, 0, 0, false, longstatus);                                          swModel->ClearSelection2(true);                     //Перестраиваем модель компоновки                     swModel->EditRebuild3();                 }                 else //Сопряжение на расстоянии                 {                     swModelDocExt->SelectByID2("Справа", "PLANE", 0, 0, 0, false, 0, nullptr, 0);                     swModelDocExt->SelectByID2("", "FACE", sC_X.dbl_X, sC_X.dbl_Y, sC_X.dbl_Z, true, 0, nullptr, 0);                      swAssemblyDoc->AddMate3(5, 1, false, sPackaged_cargo[i].dbl_Dx * 0.001, sPackaged_cargo[i].dbl_Dx * 0.001, sPackaged_cargo[i].dbl_Dx * 0.001, 0, 0, 0, 0, 0, false, longstatus);                      swModel->ClearSelection2(true);                     //Перестраиваем модель компоновки                     swModel->EditRebuild3();                 }  

Второй способ автоматического указания сопряжений был применен для позиционирования в сборке 3D-модели ящика. В модели ящика был построен трехмерный эскиз и на трех гранях были размещены с помощью справочной геометрии три точки. Таким образом, для указания сопряжений необходимо было выделить плоскости системы координат и вышеуказанные точки, лежащие на гранях.

В заключение отметим, что в результате проделанной работы показана принципиальная возможность моделирования упаковки с использованием API SolidWorks. Разработанное приложение может быть использовано с существующими приложениями, решающими задачи трехмерной упаковки (при условии их доработки), а также с вновь разработанным приложением, которое могло бы, например, учитывать при расчетах использование силикагеля для консервации. Предложен вариант описания информации для обмена данными между разработанным приложением и приложениями, решающими задачи трехмерного моделирования упаковки. Представлены варианты решения некоторых типовых задач взаимодействия с API SolidWorks.

Библиографический список

  1. А. А. Гиля-Зетинов, К. К. Панкратов, А. В. Хельвас Разработка алгоритма укладки паллет на полностью автоматизированном складе // Труды МФТИ .– 2019 .– т. 11 .– №1(41) .– С. 20-30.
  2. Нужнов Е.В., Барлит А.В. Трехмерная упаковка на основе эвристических процедур // Перспективные информационные технологии и интеллектуальные системы. – 2002. – № 3.– С. 95-101.
  3. Луцан М.В., Нужнов Е.В. Решение задачи трехмерной упаковки с палетированием контейнеров // Известия ЮФУ. Технические науки .– 2014 .– № 7 (156) .– С. 196-204.
  4. Опыт применения API SolidWorks для автоматизированного проектирования тары [Электронный ресурс] .– URL: habr.com/ru/company/stc_spb/blog/645115 .– (дата обращения 18.03.2022).


ссылка на оригинал статьи https://habr.com/ru/company/stc_spb/blog/656439/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *