icub-tech-iit / creo2urdf

Generate URDF models from CREO mechanisms
https://icub-tech-iit.github.io/creo2urdf/
BSD 3-Clause "New" or "Revised" License
28 stars 3 forks source link

CREO2URDF – Choose the technology #4

Closed pattacini closed 1 year ago

pattacini commented 1 year ago

We have available several options:

We need to pick the right option considering the following aspects:

DoD

We have a candidate

pattacini commented 1 year ago

Quoting @traversaro:

How to use iDynTree::Model to create a model using C++ code and export it as URDF

Lately with several persons/teams we have been discussing about tools used to generate URDF models (typically, because the URDF libraries adopted was not maintained or created problems). One option that may not be well known/well documented is to use iDynTree for this: build an iDynTree::Model instance with C++/Python/MATLAB (and eventually Java) code, and then export the constructed instance to URDF via iDynTree::ModelExporter.

Unfortunately most examples of such workflow are only available in non-open source repos of our Technology Transfer collaboration, but if you want to check them you can find them in the following. All examples are in C++, but the API for Python/MATLAB is quite similar.

If you do not have access but are curious about this, please let me know so that I can provide you access.

mfussi66 commented 1 year ago

This is the only example I was able to find of C++ toolkit usage: https://github.com/agalex1974/ProToolkitLExtrusion

Nicogene commented 1 year ago

I start digging in the c++ API documentation I found some pieces of code that can be useful for us:

    wfcWSession_ptr ses = wfcWSession::cast (pfcGetCurrentSession() );
    wfcWSolid_ptr solid = wfcWSolid::cast(ses->GetCurrentModel());

Then with the pointer to the model, we can retrieve the items as follow:

immagine

Then all the items can be accessed via: immagine

Unfortunately, the documentation is not online, ~then I cannot link it, moreover, it has no search bar so it is particularly difficult to find what you need~. This is something that we could take into account in the decision

PS: I found how to open the searchbar: file:///C:/Program%20Files/PTC/Creo%209.0.2.0/Common%20Files/otk_cpp_doc/objecttoolkit_Creo/manual0/loadApiWizard.html

mfussi66 commented 1 year ago

I started digging into the documentation and I found that there are :

All of these are in Creo 9.

Widest CREO features coverage.

The opening chapters of each document explain briefly the capabilities of the alternatives

The Creo Toolkit in C lists the following features:


The VB api lists the following:

These do not seem to match our use case.


The Javascript one for some reason does not have a quick and easy summary, but it basically leverages the embedded browser features to create web interfaces. I can try more to find some info.

In order to make the learning curve as flat as possible, I'd avoid anything that is not C or C++, because at least there is familiarity with the language. If we use C++ we can leverage natively iDynTree too. Also, we can be sure that we have the whole feature set at our disposal.

mfussi66 commented 1 year ago

This morning me and @Nicogene tried to work on the C++ API.


First, we wanted to build a Hello world example provided by the documentation: a simple form with text. The example was in C++ with a Visual Studio solution for running and compilation. We had to set up environment variables with Creo paths, and we were able to compile the program into an executable. However, if we wanted to use it, we had to "unlock it", a necessary procedure for distribution to who does not have the Object Toolkit installed. We tried to do it, but we needed another toolkit called "Toolkit for 3D drawings". It is not provided in our Creo Parametric install, and we would need an advanced license for that. In the end, we failed to run this simple example.


Secondly, we found some other examples, already compiled as a .dll . The examples created a new tab in the ribbon interface with a bunch of buttons with exemplary functions, see: image image

We tried some functions, some worked some didn't. Maybe we had to perform some preliminary actions first (like selecting a part, for example). Nonetheless, the good thing is that all these examples provided the source code, which could be a useful skeleton to build our application.

The documentation seems a bit sparse and to make it quickly usable we would need to make our own docs. The terrible thing is that the Knowledge Base website of PTC is locked behind a login. We do not have the customer credentials. The people in IIT who have them are ones who manage the license or mech designers, probably.

pattacini commented 1 year ago

Well done guys! 🚀

The terrible thing is that the Knowledge Base website of PTC is locked behind a login. We do not have the customer credentials. The people in IIT who have them are ones who manage the license or mech designers, probably.

I would say that this is the first thing we ought to address, at once. Failing to solve this would mean that we will be doomed! Let's ask @Mick3Lozzo for assistance on this.

mfussi66 commented 1 year ago

For completeness, I also had the chance to explore a bit Creoson. By itself, Creoson is a Java application that uses the Object Toolkit, and acts as a server. As such, it handles JSON requests written by clients, and replies with JSON responses. The application can be installed with the Setup.exe, and as of last week, it officially supports creo 9.0: https://github.com/SimplifiedLogic/creoson/releases The installation was straightforward, and the repo seems regularly updated

The only official client libraries seems to be two:

To test it, I installed creopyson which was only a pip install away. It was very very simple to connect to the server and retrieve info from the opened assembly with two parts:

import creopyson as cps

c = cps.connect()
myassembly = '2bars.asm'
c.feature_list(myassembly)
# prints out
[{'status': 'ACTIVE', 'name': 'ASM_CSYS', 'type': 'COORDINATE SYSTEM', 'feat_id': 1}, {'status': 'ACTIVE', 'name': 'ASM_FRONT', 'type': 'DATUM PLANE', 'feat_id': 4}, {'status': 'ACTIVE', 'name': 'ASM_RIGHT', 'type': 'DATUM PLANE', 'feat_id': 6}, {'status': 'ACTIVE', 'name': 'ASM_TOP', 'type': 'DATUM PLANE', 'feat_id': 8}, {'status': 'ACTIVE', 'name': 'BAR.prt', 'type': 'COMPONENT', 'feat_id': 59}, {'status': 'ACTIVE', 'name': 'BAR.prt', 'type': 'COMPONENT', 'feat_id': 60}]

mypart = 'bar.prt'
cps.file.massprops(c, mypart ) 

# prints out
{'surface_area': 1396.9911184184132, 'density': 2.8e-06, 'coord_sys_inertia_tensor': {'z_axis': {'x': 0.0, 'z': 2.622963637415443, 'y': 0.3895174735103448}, 'y_axis': {'x': 0.0, 'z': 0.3895174735103448, 'y': 0.17980471005198828}, 'x_axis': {'x': 2.6855253551696983, 'z': 0.0, 'y': 0.0}}, 'ctr_grav': {'x': 0.0, 'z': 3.5, 'y': 
-15.0}, 'mass': 0.00741938044781609, 'volume': 2649.7787313628896, 'coord_sys_inertia': {'z_axis': {'x': -0.0, 'z': 0.12118321390312169, 'y': -0.3895174735103448}, 'y_axis': {'x': -0.0, 'z': -0.3895174735103448, 'y': 2.5643421412665766}, 'x_axis': {'x': 0.0586214961488666, 'z': -0.0, 'y': -0.0}}, 'ctr_grav_inertia_tensor': {'z_axis': {'x': 0.0, 'z': 0.9536030366568228, 'y': 0.0}, 'y_axis': {'x': 0.0, 'z': 0.0, 'y': 0.0889172995662412}, 'x_axis': {'x': 0.9252773439253308, 'z': 0.0, 'y': 0.0}}}

c.feature_list(mypart) 

# prints out
[{'status': 'ACTIVE', 'name': 'CSYS', 'type': 'COORDINATE SYSTEM', 'feat_id': 8}, {'status': 'ACTIVE', 'name': 'TOP', 'type': 'DATUM PLANE', 'feat_id': 15}, {'status': 'ACTIVE', 'name': 'RIGHT', 'type': 'DATUM PLANE', 'feat_id': 13}, {'status': 'ACTIVE', 'name': 'FRONT', 'type': 'DATUM PLANE', 'feat_id': 11}, {'status': 'ACTIVE', 'name': 'CS0', 'type': 'COORDINATE SYSTEM', 'feat_id': 106}]

# Note that the COORDINATE SYSTEM NAMED CS0 is one i created on the fly

It seems really easy and quite powerful. The only two big doubts I have are 1 - It's a third party thing, what appens if they change the license (now it's MIT) and make it closed source? 2 - Does the server expose features that can be useful to build a urdf? (we need to check the docs and study what we actually need for creating a urdf)

pattacini commented 1 year ago

Super!

Concur with your two points @mfussi66 👍🏻

Nicogene commented 1 year ago

For reference, here is the repo of creopyson: https://github.com/Zepmanbc/creopyson

mfussi66 commented 1 year ago

Here is the assembly that we can use as toy case: two links and a pin (revolute joint). twolinks.zip

Nicogene commented 1 year ago

Here is the assembly that we can use as toy case: two links and a pin (revolute joint). twolinks.zip

Added via PR https://github.com/icub-tech-iit/creo2urdf/pull/5

Nicogene commented 1 year ago

I converted the example of @mfussi66 to a python script https://github.com/icub-tech-iit/creo2urdf/pull/6

mfussi66 commented 1 year ago

Today I tried to compile the example that creates the group of buttons, as above. It was a bit tricky as no VS solution was provided.

By googling I found the knowledge base post : https://www.ptc.com/en/support/article/CS242273

After replacing the source files, the solution could not compile. I had to include <OTKXUtils.h> in the sources (one of the already included files), to fix compilation. I switched compilation to .dll and tried to load it just like the one already provided that worked, but the launch failed. Maybe it was a problem with the paths I used to include the library.

Nicogene commented 1 year ago

Today, alongside @mfussi66, we continued to analyze which functionalities are available in creopyson, in #7 there is the updated code with what we discovered.

✅ Mesh exportation

We managed to export the meshes of the parts of the twolinks assembly, firstly exporting it as STEP

client.interface_export_file(file_=mypart,file_type="STEP")

and then using cadquery we converted the STEP into stl

afile = cadquery.importers.importStep(client.creo_pwd()+'bar.stp')
cadquery.exporters.export(afile,'bar.stl')

And here are the meshes exported immagine

✅ /❌ Get transform between entites

We tried then to play around with the functionalities for getting the transform between entites in the assembly. The only function we found in the creopyson api to compute a transform is get_transform, it has these arguments:

asm (str, optional):
    Assembly name. Defaults is currently active model.
path (list:int, optional):
    Path to a component in the assembly. Defaults is the transform is calculated for the assembly itself.
csys (str, optional):
    Coordinate system on the component to calculate the transform for. Defaults is the component’s default coordinate system.

In particular, we tried to compute the transform of the part in the assembly. Given that the part is listed in the features of the asm as:

{'status': 'ACTIVE', 'name': 'BAR.prt', 'type': 'COMPONENT', 'feat_id': 59}

This means that path is [59], then client.file_get_transform(path=[59]) gives the transform we wanted.

After that, we wanted to get the orientation of an axis we defined called A_1 with respect to a csys. First of all we get all the axes in the part:

axes_list = client.feature_list(mypart,type_="DATUM AXIS")

and we get

[{'status': 'ACTIVE', 'name': 'A_1', 'type': 'DATUM AXIS', 'feat_id': 110}]

Since thi axis is a child of the part of before we tried to

client.file_get_transform(path=[59,110])

but this does not work, get_transform works only between COMPONENTs.

We could overcome this limitation computing the transform wrt a csys with one axis in the direction of our target axis, but we are not sure it works.

Conclusion

creopyson gave us the possibility to easily retrieve a lot of information from the assembly, but seems missing some functionalites that are necessary for creating the urdf (such as the axis definition), and I am afraid that more limitations will be discovered in the future. We could open issues and ask for support in the repo (they seem very responsive) but I don't know if this tool will be sufficient to reach our goals.

In the next days we will try to focus more on the C++ API, that for sure expose all the features we would need, but right now we are still stuck to the phase of having a working hello world that we can use as starting point.

cc @traversaro @fiorisi @salvi-mattia @Mick3Lozzo @pattacini

pattacini commented 1 year ago

Agree with your accurate analysis!

fiorisi commented 1 year ago

Just adding a side comment. Recently playing with chatGPT I was surprised to see that can generate J-Link code to interact with PTC Creo. As an example it generated the code to retrieve the mass properties of a part and use this code in a python script that stores the data in a URDF (knows also this). Might be useful to explore the different interfaces (knows also the other APIs).

fiorisi commented 1 year ago

Here two PTC articles that detail when is a TOOLKIT license required:

In case you have to create the account, use the credentials in this Teams message.

Nicogene commented 1 year ago

Lookin at this thread the relevant info are:

immagine

immagine

I followed their instructions:

You can check if you have the Creo Object TOOLKIT C++ license option in the Creo user interface. Click File ▶ Help ▶ System Information. In the INFORMATION WINDOW, under Configured Option Modules check for the license option ObjectToolkitCpp. In case the license is not available please contact your system administrator

And I got

immagine

We are missing the so-called advanced object toolkit (highlighted in green above) licence, that is needed for unlocking the addons. Here is what unlock means:

Before you distribute your application executable to the end user, you must unlock it. This enables the end user to run your applications without having Creo Object TOOLKIT C++ as an option. To unlock a Creo Object TOOLKIT C++ application, you must have both the Creo Object TOOLKIT C++ license and the Creo TOOLKIT license.

There is a side note that states:

The Creo Object TOOLKIT C++ license is now a part of the Creo TOOLKIT license pack. If you are unable to unlock the Creo Object TOOLKIT C++ applications, request for the updated license pack from the Technical Support page.

Maybe we can contact the technical support for unlock us the possibility to unlock 😵

We checked with @davidelasagna and both TOOLKIT and C++ Object Toolkit (OTK) are included in our PROE_Educ1 licence. The strange thing is that they states that developers should not distribute not unlocked addons, and then they states also "must unlock" before distributing. For what I understood unlocked addons can be used also without having the OTK license, but maybe for us is ok have this requirement, since it is included in our current license

In any case, I requested an offer and some information about licensing to Software Factory

PS: I have now access to the PTC knowledge base cc @mfussi66 @fiorisi

cc @maggia80

mfussi66 commented 1 year ago

Today I tried to compile the example that creates the group of buttons, as above. It was a bit tricky as no VS solution was provided.

By googling I found the knowledge base post : ptc.com/en/support/article/CS242273

* With the response (thanks to @Mick3Lozzo ):

* Unzip the sample zip file from Creo 3.0 \Common Files\otk\otk_cpp\x86e_win64\obj\otk_install.zip

* Open the otk_install.sln in Visual Studio 2012

* Remove the existing source file from the project

* From the sub folders of Creo \Common Files\otk\otk_cpp\otk_examples folder, Include all the *.cxx source code files with file name defined in lower case letters

* Compile the application as an EXE or DLL as per your requirement

After replacing the source files, the solution could not compile. I had to include <OTKXUtils.h> in the sources (one of the already included files), to fix compilation. I switched compilation to .dll and tried to load it just like the one already provided that worked, but the launch failed. Maybe it was a problem with the paths I used to include the library.

For Completeness, the application did not launch with an error called PROTK_GENERAL_ERROR. Here is what the knowledge base says regarding the error:

Possible resolutions, : Licensing:

To understand the differences between the libraries see the following article CS237146 What is the usage of the six libraries of Creo Parametric TOOLKIT

mfussi66 commented 1 year ago

In my quest to make a Hello World example I studied what kind of libraries need to be linked to created a working application.

Here below a page of the documentation that summarizes the concepts. The most important part is the usage of otk_222.lib and otk_no222.lib. 222 refers to the advanced license code. I think we should use otk_no222.llib since we do not have an advanced license. Also, I think we should focus on the row DLL mode library

image

Sadly even though the application compiles successfully, it still returns the PRO_TK_GENERAL_ERROR. The quest continues.

pattacini commented 1 year ago

For Completeness, the application did not launch with an error called PROTK_GENERAL_ERROR. Here is what the knowledge base says regarding the error:

Possible resolutions, : Licensing:

  • check that the correct license has been configured for the auxiliary application in the client.

    • If the application is from PTC, contact PTC by opening a license case.
    • If the application is from third party, reach out to them to request license support.

This is a bit scary. @Nicogene, did you check this in light of what we said yesterday? Are we aligned on the licensing part?

traversaro commented 1 year ago

Let me know if at some point you need/want (probably once you created a working hello world) to understand how to handle the linking with this libraries for replicating the hello world in CMake. It should be relatively simple, just create a FindCreoObjectTOOLKIT.cmake or similar, but if you never did this it can be a bit tricky, so feel free to ask.

Nicogene commented 1 year ago

Let me know if at some point you need/want (probably once you created a working hello world) to understand how to handle the linking with this libraries for replicating the hello world in CMake. It should be relatively simple, just create a FindCreoObjectTOOLKIT.cmake or similar, but if you never did this it can be a bit tricky, so feel free to ask.

Thank you @traversaro ! The idea was indeed to start working with CMake as soon as we managed to compile a built-in example

This is a bit scary. @Nicogene, did you check this in light of what we said yesterday? Are we aligned on the licensing part?

We aligned yesterday and my suspicion is that the example in the otk links libraries that are not included in our license, as mentioned by @mfussi66. The same addon delivered in the installation works probably because they have unlocked it.

mfussi66 commented 1 year ago

I downloaded an example C toolkit VS solution from this knowledge base article (choose the link near "Creo 9" ), and was able to compile it with no problem after a little test change 👀

image

mfussi66 commented 1 year ago

As a further test, I added two header files belonging to the C++ Object Toolkit:

#include <wfcSession.h>
#include <wfcGlobal.h>

But I'm not using them yet.

Then, I included in the linker the library otk_cpp_md.lib , together with the following ones that were already present:

protk_dllmd_NU.lib  
ucore.lib
udata.lib

The md acronym is necessary when you want to compile the plugin as a multithreaded DLL (aka using the /MD flag).

The plugin compiles correctly as before, and runs with no problem. Note that I haven't linked any library related to licensing (otk_222.lib or otk_no222.lib).

Regarding the redistributability , at the moment I could get away with creating an environment variable CREO9_INSTALL_PATHthat points to C:\Program Files\PTC\Creo 9.0.2.0\Common Files\. All the paths I used to include the toolkit headers use that variable as prefix.

The working solution can be found here: https://github.com/icub-tech-iit/creo2urdf/tree/vscpp/src/examples/otk_toolkit_cpp/Creo9_x64_tkSynctemplate_DLL

I think a next useful test could be actually using functions in the included headers.

mfussi66 commented 1 year ago

Today the task force @Nicogene @martinaxgloria and me was able to upgrade the project to use some C++ functions, get the name of the current model and its mass. The information can be displayed in the message window of Creo (see highlight), which can be useful for debugging purposes. Here the retrieved mass is the one of the whole assembly.

image

pattacini commented 1 year ago

Fantastic team work!

Nicogene commented 1 year ago

I think that the definition of done has been met, we go for C++ Toolkit 💪🏻

Relying on yet another third-party software (e.g. Creoson) could lead to the same situation lead here.

The example has been added in #9

🎖️ @mfussi66 🎖️ @martinaxgloria