Как стать автором
Обновить

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

Время на прочтение11 мин
Количество просмотров4.2K
Одна из задач, встречающаяся при разработке новых изделий – это задача компоновки их упаковки.

image

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



Чтобы выбрать ящик, в простейшем случае (по утверждению Stratum, приведенному в комментариях, случаи могут быть сложнее) необходимо узнать габариты упаковываемых изделий, а затем скомпоновать их.

К настоящему времени задачи упаковки уже решались в ряде исследований. В терминологии теории алгоритмов эти задачи относятся к классу 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-модели ящика. В модели ящика был построен трехмерный эскиз и на трех гранях были размещены с помощью справочной геометрии три точки. Таким образом, для указания сопряжений необходимо было выделить плоскости системы координат и вышеуказанные точки, лежащие на гранях.

UPD

Внимание!

В процессе дальнейшей работы с описанным в статье приложением в некоторых случаях по необъяснимой причине сопряжения не добавлялись должным образом. Ниже приводится альтернативный работоспособный вариант кода, в котором выделялись плоскости системы координат сборки и вставляемой детали.
//Сопряжения со смещениями вдоль оси Х
if (sPackaged_cargo[i].dbl_Dx == 0) //Сопряжение совпадения
{
   swModelDocExt->SelectByID2("Справа", "PLANE", 0, 0, 0, false, 0, nullptr, 0);
   swModelDocExt->SelectByID2(gcnew System::String(("Справа@" + sPackaged_cargo[i].str_Name + "-1@" + sOutput_data.str_Name).c_str()), "PLANE", 0, 0, 0, true, 0, nullptr, 0);

   swAssemblyDoc->AddMate3(0, 0, 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(gcnew System::String(("Справа@" + sPackaged_cargo[i].str_Name + "-1@" + sOutput_data.str_Name).c_str()), "PLANE", 0, 0, 0, true, 0, nullptr, 0);

   swAssemblyDoc->AddMate3(5, 0, 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();
}


Конец текста UPD

В заключение отметим, что в результате проделанной работы показана принципиальная возможность моделирования упаковки с использованием 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).
Теги:
Хабы:
Всего голосов 4: ↑4 и ↓0+4
Комментарии2

Публикации

Информация

Сайт
www.stc-spb.ru
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия