From 23f336d0f94c1ffb567dc0cdfdcf6ecbee814151 Mon Sep 17 00:00:00 2001 From: Nicogene Date: Fri, 5 Apr 2024 11:19:06 +0200 Subject: [PATCH 1/5] First draft of creo2urdf headless --- src/creo2urdf/include/creo2urdf/Creo2Urdf.h | 10 +++++ src/creo2urdf/src/Creo2Urdf.cpp | 47 ++++++++++++++------- src/creo2urdf/src/main.cpp | 42 ++++++++++++++++++ 3 files changed, 83 insertions(+), 16 deletions(-) diff --git a/src/creo2urdf/include/creo2urdf/Creo2Urdf.h b/src/creo2urdf/include/creo2urdf/Creo2Urdf.h index 892121a..13d918f 100644 --- a/src/creo2urdf/include/creo2urdf/Creo2Urdf.h +++ b/src/creo2urdf/include/creo2urdf/Creo2Urdf.h @@ -61,6 +61,13 @@ class Creo2Urdf : public pfcUICommandActionListener { */ void OnCommand() override; + Creo2Urdf() = default; + ~Creo2Urdf() = default; + Creo2Urdf(const std::string& yaml_path, const std::string& csv_path, const std::string& output_path, pfcModel_ptr asm_model_ptr) : m_yaml_path(yaml_path), + m_csv_path(csv_path), + m_output_path(output_path), + m_asm_model_ptr(asm_model_ptr) { } + private: /** * @brief Export the iDynTree model to URDF format if it is valid. @@ -137,7 +144,10 @@ class Creo2Urdf : public pfcUICommandActionListener { std::array originXYZ {0.0, 0.0, 0.0}; /**< Offset of the root link in XYZ (meters) wrt the world frame. */ std::array originRPY {0.0, 0.0, 0.0}; /**< Orientation of the root link in Roll-Pitch-Yaw wrt the world frame. */ bool warningsAreFatal{ true }; /**< Flag indicating whether warnings are treated as fatal errors. */ + std::string m_yaml_path{ "" }; /**< Path to the YAML configuration file. */ + std::string m_csv_path{ "" }; /**< Path to the CSV file containing joint information. */ std::string m_output_path{ "" }; /**< Output path for the exported URDF file. */ + pfcModel_ptr m_asm_model_ptr{ nullptr }; /**< Handle to the Creo model. */ }; class Creo2UrdfAccess : public pfcUICommandAccessListener { diff --git a/src/creo2urdf/src/Creo2Urdf.cpp b/src/creo2urdf/src/Creo2Urdf.cpp index b08a1ab..ec9ea69 100644 --- a/src/creo2urdf/src/Creo2Urdf.cpp +++ b/src/creo2urdf/src/Creo2Urdf.cpp @@ -19,7 +19,17 @@ void Creo2Urdf::OnCommand() { pfcSession_ptr session_ptr = pfcGetProESession(); - pfcModel_ptr model_ptr = session_ptr->GetCurrentModel(); + if (!session_ptr) { + printToMessageWindow("Failed to get the session", c2uLogLevel::WARN); + return; + } + if (!m_asm_model_ptr) { + m_asm_model_ptr = session_ptr->GetCurrentModel(); + if (!m_asm_model_ptr) { + printToMessageWindow("Failed to get the current model", c2uLogLevel::WARN); + return; + } + } // TODO Principal units probably to be changed from MM to M before getting the model properties @@ -31,23 +41,28 @@ void Creo2Urdf::OnCommand() { auto yaml_file_open_option = pfcFileOpenOptions::Create("*.yml,*.yaml"); yaml_file_open_option->SetDialogLabel("Select the yaml"); - auto yaml_path = session_ptr->UIOpenFile(yaml_file_open_option); - - if (!loadYamlConfig(string(yaml_path))) + // YAML file path + if (m_yaml_path.empty()) { + m_yaml_path = string(session_ptr->UIOpenFile(yaml_file_open_option)); + } + if (!loadYamlConfig(m_yaml_path)) { printToMessageWindow("Failed to run Creo2Urdf!", c2uLogLevel::WARN); return; } - auto csv_file_open_option = pfcFileOpenOptions::Create("*.csv"); - csv_file_open_option->SetDialogLabel("Select the csv"); - - auto csv_path = session_ptr->UIOpenFile(csv_file_open_option); - - rapidcsv::Document joints_csv_table(string(csv_path), rapidcsv::LabelParams(0, 0)); - auto output_folder_open_option = pfcDirectorySelectionOptions::Create(); - output_folder_open_option->SetDialogLabel("Select the output dir"); - - m_output_path = string(session_ptr->UISelectDirectory(output_folder_open_option)); + // CSV file path + if (m_csv_path.empty()) { + auto csv_file_open_option = pfcFileOpenOptions::Create("*.csv"); + csv_file_open_option->SetDialogLabel("Select the csv"); + m_csv_path = string(session_ptr->UIOpenFile(csv_file_open_option)); + } + rapidcsv::Document joints_csv_table(m_csv_path, rapidcsv::LabelParams(0, 0)); + // Output folder path + if (m_output_path.empty()) { + auto output_folder_open_option = pfcDirectorySelectionOptions::Create(); + output_folder_open_option->SetDialogLabel("Select the output dir"); + m_output_path = string(session_ptr->UISelectDirectory(output_folder_open_option)); + } printToMessageWindow("Output path is: " + m_output_path); @@ -56,7 +71,7 @@ void Creo2Urdf::OnCommand() { bool ret; - auto asm_component_list = model_ptr->ListItems(pfcModelItemType::pfcITEM_FEATURE); + auto asm_component_list = m_asm_model_ptr->ListItems(pfcModelItemType::pfcITEM_FEATURE); if (asm_component_list->getarraysize() == 0) { printToMessageWindow("There are no FEATURES in the asm", c2uLogLevel::WARN); return; @@ -117,7 +132,7 @@ void Creo2Urdf::OnCommand() { elem_tree.populateJointInfoFromElementTree(feat, joint_info_map); - pfcComponentPath_ptr comp_path = pfcCreateComponentPath(pfcAssembly::cast(model_ptr), seq); + pfcComponentPath_ptr comp_path = pfcCreateComponentPath(pfcAssembly::cast(m_asm_model_ptr), seq); auto component_handle = session_ptr->RetrieveModel(pfcComponentFeat::cast(feat)->GetModelDescr()); diff --git a/src/creo2urdf/src/main.cpp b/src/creo2urdf/src/main.cpp index 8c93d9f..2ed11f4 100644 --- a/src/creo2urdf/src/main.cpp +++ b/src/creo2urdf/src/main.cpp @@ -8,6 +8,36 @@ #include #include +#include +#include + + + /*! @brief Do batch mode stuff + */ +ProError evaluateBatchMode(const std::string& asm_path, const std::string& yaml_path, const std::string& csv_path, const std::string& output_path) { + if (asm_path.empty() || yaml_path.empty() || csv_path.empty() || output_path.empty()) { + return PRO_TK_BAD_INPUTS; // to be safe + } + ProError err = PRO_TK_NO_ERROR; + + pfcBaseSession* session = pfcGetProESession(); + if (!session) { + ProTKPrintf("Creo2Urdf: impossible to retrieve the session"); + return PRO_TK_GENERAL_ERROR; + } + + auto asm_model_ptr = session->RetrieveModel(pfcModelDescriptor::CreateFromFileName(asm_path.c_str())); + + if (!asm_model_ptr) { + ProTKPrintf("Creo2Urdf: impossible to retrieve the model located in %s", asm_path); + return PRO_TK_GENERAL_ERROR; + } + + + Creo2Urdf creo2urdfApp(yaml_path, csv_path, output_path, asm_model_ptr); + creo2urdfApp.OnCommand(); + return err; +} /** * @brief Initializes the buttons by associating them with the corresponding functions @@ -23,6 +53,18 @@ extern "C" int user_initialize( { auto session = pfcGetProESession(); + if (argc > 4) { + std::string asm_path = argv[1]; + std::string yaml_path = argv[2]; + std::string csv_path = argv[3]; + std::string output_path = argv[4]; + ProError err = evaluateBatchMode(asm_path, yaml_path, csv_path, output_path); + ProEngineerEnd(); + return (int)err; // or whatever you want + } + + ProTKPrintf("Creo2Urdf version %s build %s\n", version, build); + auto cmd = session->UICreateCommand("Creo2Urdf", new Creo2Urdf()); cmd->AddActionListener(new Creo2UrdfAccess()); // To be checked it is odd cmd->Designate("ui.txt", "Run Creo2Urdf", "Run Creo2Urdf", "Run Creo2Urdf"); From 3f7dd29104fd4a827bb4d0ccf32696728f74979c Mon Sep 17 00:00:00 2001 From: Nicogene Date: Fri, 5 Apr 2024 11:40:15 +0200 Subject: [PATCH 2/5] Fix multiple clicks --- src/creo2urdf/src/Creo2Urdf.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/creo2urdf/src/Creo2Urdf.cpp b/src/creo2urdf/src/Creo2Urdf.cpp index ec9ea69..1714030 100644 --- a/src/creo2urdf/src/Creo2Urdf.cpp +++ b/src/creo2urdf/src/Creo2Urdf.cpp @@ -373,6 +373,12 @@ void Creo2Urdf::OnCommand() { exportModelToUrdf(idyn_model, export_options); + // Let's clear the map in case of multiple click TODO UNIFY + m_yaml_path.clear(); + m_csv_path.clear(); + m_output_path.clear(); + m_asm_model_ptr = nullptr; + return; } From fb66d208893a8cac017fc03cb60072bdf7f67be9 Mon Sep 17 00:00:00 2001 From: Nicogene Date: Fri, 5 Apr 2024 12:52:13 +0200 Subject: [PATCH 3/5] First working version --- src/creo2urdf/src/main.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/creo2urdf/src/main.cpp b/src/creo2urdf/src/main.cpp index 2ed11f4..7cf3514 100644 --- a/src/creo2urdf/src/main.cpp +++ b/src/creo2urdf/src/main.cpp @@ -10,6 +10,7 @@ #include #include #include +#include /*! @brief Do batch mode stuff @@ -26,13 +27,18 @@ ProError evaluateBatchMode(const std::string& asm_path, const std::string& yaml_ return PRO_TK_GENERAL_ERROR; } - auto asm_model_ptr = session->RetrieveModel(pfcModelDescriptor::CreateFromFileName(asm_path.c_str())); + pfcModel_ptr asm_model_ptr{ nullptr }; - if (!asm_model_ptr) { - ProTKPrintf("Creo2Urdf: impossible to retrieve the model located in %s", asm_path); - return PRO_TK_GENERAL_ERROR; + try { + asm_model_ptr = session->RetrieveModel(pfcModelDescriptor::CreateFromFileName(asm_path.c_str())); } - + xcatchbegin + xcatchcip(defaultEx) + { + ProTKPrintf("Exception caught: %s", pfcXPFC::cast(defaultEx)->GetMessage()); + return PRO_TK_E_NOT_FOUND; + } + xcatchend Creo2Urdf creo2urdfApp(yaml_path, csv_path, output_path, asm_model_ptr); creo2urdfApp.OnCommand(); @@ -58,6 +64,16 @@ extern "C" int user_initialize( std::string yaml_path = argv[2]; std::string csv_path = argv[3]; std::string output_path = argv[4]; + + // We need to remove the '+' character from the paths + asm_path.erase(std::find(asm_path.begin(), asm_path.end(), '+')); + yaml_path.erase(std::find(yaml_path.begin(), yaml_path.end(), '+')); + csv_path.erase(std::find(csv_path.begin(), csv_path.end(), '+')); + output_path.erase(std::find(output_path.begin(), output_path.end(), '+')); + + ProTKPrintf("Running in batch mode"); + auto debug_msg = "Assembly path: " + asm_path + " yaml path " + yaml_path + " csv_path " + csv_path + " output_path " + output_path; + ProTKPrintf("%s\n", debug_msg.c_str()); ProError err = evaluateBatchMode(asm_path, yaml_path, csv_path, output_path); ProEngineerEnd(); return (int)err; // or whatever you want From 89a77b18eee3d9c6fcc4170b80be9eb1cc3f81f1 Mon Sep 17 00:00:00 2001 From: Nicogene Date: Fri, 5 Apr 2024 14:42:16 +0200 Subject: [PATCH 4/5] Cleanup spaces/tabs --- src/creo2urdf/src/Creo2Urdf.cpp | 26 +++++++++++++------------- src/creo2urdf/src/main.cpp | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/creo2urdf/src/Creo2Urdf.cpp b/src/creo2urdf/src/Creo2Urdf.cpp index 1714030..b6ad8e4 100644 --- a/src/creo2urdf/src/Creo2Urdf.cpp +++ b/src/creo2urdf/src/Creo2Urdf.cpp @@ -20,15 +20,15 @@ void Creo2Urdf::OnCommand() { pfcSession_ptr session_ptr = pfcGetProESession(); if (!session_ptr) { - printToMessageWindow("Failed to get the session", c2uLogLevel::WARN); - return; - } + printToMessageWindow("Failed to get the session", c2uLogLevel::WARN); + return; + } if (!m_asm_model_ptr) { m_asm_model_ptr = session_ptr->GetCurrentModel(); if (!m_asm_model_ptr) { - printToMessageWindow("Failed to get the current model", c2uLogLevel::WARN); - return; - } + printToMessageWindow("Failed to get the current model", c2uLogLevel::WARN); + return; + } } @@ -43,8 +43,8 @@ void Creo2Urdf::OnCommand() { // YAML file path if (m_yaml_path.empty()) { - m_yaml_path = string(session_ptr->UIOpenFile(yaml_file_open_option)); - } + m_yaml_path = string(session_ptr->UIOpenFile(yaml_file_open_option)); + } if (!loadYamlConfig(m_yaml_path)) { printToMessageWindow("Failed to run Creo2Urdf!", c2uLogLevel::WARN); @@ -52,10 +52,10 @@ void Creo2Urdf::OnCommand() { } // CSV file path if (m_csv_path.empty()) { - auto csv_file_open_option = pfcFileOpenOptions::Create("*.csv"); - csv_file_open_option->SetDialogLabel("Select the csv"); - m_csv_path = string(session_ptr->UIOpenFile(csv_file_open_option)); - } + auto csv_file_open_option = pfcFileOpenOptions::Create("*.csv"); + csv_file_open_option->SetDialogLabel("Select the csv"); + m_csv_path = string(session_ptr->UIOpenFile(csv_file_open_option)); + } rapidcsv::Document joints_csv_table(m_csv_path, rapidcsv::LabelParams(0, 0)); // Output folder path if (m_output_path.empty()) { @@ -239,7 +239,7 @@ void Creo2Urdf::OnCommand() { if (joint_info.second.type == JointType::Revolute) { joint_sh_ptr = std::make_shared(); dynamic_cast(joint_sh_ptr.get())->setAxis(iDynTree::Axis(axis, parent_H_child.getPosition())); - } + } else if (joint_info.second.type == JointType::Linear) { joint_sh_ptr = std::make_shared(); dynamic_cast(joint_sh_ptr.get())->setAxis(iDynTree::Axis(axis, parent_H_child.getPosition())); diff --git a/src/creo2urdf/src/main.cpp b/src/creo2urdf/src/main.cpp index 7cf3514..2d902bb 100644 --- a/src/creo2urdf/src/main.cpp +++ b/src/creo2urdf/src/main.cpp @@ -24,8 +24,8 @@ ProError evaluateBatchMode(const std::string& asm_path, const std::string& yaml_ pfcBaseSession* session = pfcGetProESession(); if (!session) { ProTKPrintf("Creo2Urdf: impossible to retrieve the session"); - return PRO_TK_GENERAL_ERROR; - } + return PRO_TK_GENERAL_ERROR; + } pfcModel_ptr asm_model_ptr{ nullptr }; From aa25cc4dc07b6361bf1c6459ca80d904a917678e Mon Sep 17 00:00:00 2001 From: Nicogene Date: Fri, 5 Apr 2024 15:10:07 +0200 Subject: [PATCH 5/5] Add run_creo2urdf.ps1 --- scripts/run_creo2urdf.ps1 | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 scripts/run_creo2urdf.ps1 diff --git a/scripts/run_creo2urdf.ps1 b/scripts/run_creo2urdf.ps1 new file mode 100644 index 0000000..80ebe2e --- /dev/null +++ b/scripts/run_creo2urdf.ps1 @@ -0,0 +1,63 @@ +<# +.SYNOPSIS + Converter for Creo assembly to URDF format. +.DESCRIPTION + This script converts Creo assembly to URDF format using the creo2urdf plugin. +.PARAMETER asmPath + The path of the .asm file to be converted. +.PARAMETER yamlPath + The path of the YAML configuration file will be used. +.PARAMETER csvPath + The path of the CSV configuration file will be used. +.PARAMETER outputPath + The path where the final output will be saved. +.EXAMPLE + .\run_creo2urdf.ps1 -asmPath "C:\path\to\asm_file.asm" -yamlPath "C:\path\to\yaml_file.yaml" -csvPath "C:\path\to\csv_file.csv" -outputPath "C:\output\path" + This command converts the Creo file to URDF format using the specified paths. +#> + +param ( + [string]$asmPath, + [string]$yamlPath, + [string]$csvPath, + [string]$outputPath +) + +Write-Host "Using asm path: $asmPath" +Write-Host "Using yaml path: $yamlPath" +Write-Host "Using csv path: $csvPath" +Write-Host "Using output path: $outputPath" + + +if ([string]::IsNullOrEmpty($env:CREO9_INSTALL_PATH)) { + Write-Host "CREO9_INSTALL_PATH not set, exiting." + Exit +} +if ([string]::IsNullOrEmpty($asmPath)) { + Write-Host "asm path not specified, exiting." + Exit +} +if ([string]::IsNullOrEmpty($yamlPath)) { + Write-Host "yaml path not specified, exiting." + Exit +} +if ([string]::IsNullOrEmpty($csvPath)) { + Write-Host "csv path not specified, exiting." + Exit +} +if ([string]::IsNullOrEmpty($outputPath)) { + Write-Host "output path not specified, exiting." + Exit +} + +$parametricExe = "$env:CREO9_INSTALL_PATH\..\Parametric\bin\parametric.exe" +Start-Process -FilePath $parametricExe -ArgumentList "-g:no_graphics", "-batch_mode", "creo2urdf", "+$asmPath", "+$yamlPath", "+$csvPath", "+$outputPath" -Wait + +# Check if model.urdf exists in the output path +$urdfPath = Join-Path -Path $outputPath -ChildPath "model.urdf" +if (Test-Path -Path $urdfPath) { + Write-Host "Conversion completed successfully. The URDF file is located at: $urdfPath" +} +else { + Write-Host "Conversion failed. The URDF file was not generated." +}