Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CREO2URDF – Retrieve the joint info from the mechanism #57

Closed
Nicogene opened this issue Oct 9, 2023 · 6 comments · Fixed by #66
Closed

CREO2URDF – Retrieve the joint info from the mechanism #57

Nicogene opened this issue Oct 9, 2023 · 6 comments · Fixed by #66
Assignees
Labels
domain-software Related to Software team-fix Related to Team Fix

Comments

@Nicogene
Copy link
Member

Nicogene commented Oct 9, 2023

Either via ElementTree or ProMech toolkit, we should retrieve the joints' information from creo directly (e.g. link parent and child, type of mechanism etc.)

Right now we consider:

  • Revolute joint if two parts are mounted on an axis with the same name
  • Fixed joint if two parts are mounted on a csys with the same name.

With these assumptions, we are not considering the prismatic joint case, and joints/csys w/ the same names could give problems

Related to #55

cc @pattacini @mfussi66

@Nicogene Nicogene added domain-software Related to Software team-fix Related to Team Fix labels Oct 9, 2023
@mfussi66
Copy link
Member

mfussi66 commented Oct 9, 2023

Ideally, it should be simple to get relevant data from the element tree without the Toolkit for Mechanica, see the example called OTKXCreateSweep.cxx in C:\Program Files\PTC\Creo 9.0.4.0\Common Files\otk\otk_cpp\otk_examples\otk_examples_feat:

  wfcElemPathItems_ptr sketchItems =  wfcElemPathItems::create();
  wfcElemPathItem_ptr sketchItem0 =  wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID,wfcPRO_E_SWEEP_PROF_COMP);
  sketchItems->append(sketchItem0);
  wfcElemPathItem_ptr sketchItem1 =  wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID,wfcPRO_E_SWEEP_SECTION);
  sketchItems->append(sketchItem1);
  wfcElemPathItem_ptr sketchItem2 =  wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID,wfcPRO_E_SKETCHER);
  sketchItems->append(sketchItem2);
  
  wfcElementPath_ptr sketchPath = wfcElementPath::Create(sketchItems);
  
  wfcElement_ptr element = elemTree->GetElement(sketchPath);

@mfussi66
Copy link
Member

mfussi66 commented Nov 8, 2023

Playing around a little bit with the assembly I was able to get the information of joint type (pin) and limits with this code:

void getLimits(pfcFeature_ptr feat)
{
    wfcWFeature_ptr wfeat = wfcWFeature::cast(feat);
    wfcElementTree_ptr tree = wfeat->GetElementTree(nullptr, wfcFEAT_EXTRACT_NO_OPTS);

    wfcElemPathItems_ptr elemItems = wfcElemPathItems::create();
    wfcElemPathItem_ptr Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SETS);
    elemItems->append(Item);
    Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SET);
    elemItems->append(Item);
    Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SET_TYPE);
    elemItems->append(Item);

    wfcElementPath_ptr constraintPath = wfcElementPath::Create(elemItems);

    wfcElement_ptr element = tree->GetElement(constraintPath);

    if (element->GetValue()->GetIntValue() != PRO_ASM_SET_TYPE_PIN)
        printToMessageWindow("found something that is not pin");
    else
    {
        printToMessageWindow("found pin");
        elemItems->clear();

        Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SETS);
        elemItems->append(Item);
        Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SET);
        elemItems->append(Item);
        Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_SETS);
        elemItems->append(Item);
        Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_SET);
        elemItems->append(Item);
        Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_MAX_LIMIT);
        elemItems->append(Item);
        Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_MAX_LIMIT_VAL);
        elemItems->append(Item);

        wfcElementPath_ptr limitpath = wfcElementPath::Create(elemItems);

        element = tree->GetElement(limitpath);

        printToMessageWindow(to_string(element->GetValue()->GetDoubleValue()));
    
    }


    return;
}

Basically one needs to create a vector of element path items, which are the xml tags of the element tree:

For the joint type, for example:

<PRO_E_COMPONENT_SETS type="array">
    <PRO_E_COMPONENT_SET type="compound">
		...
      <PRO_E_COMPONENT_SET_TYPE type="int">1</PRO_E_COMPONENT_SET_TYPE>

We could use the element tree to get the parent and child parts as suggested by @Nicogene

<PRO_E_COMPONENT_CONSTRAINTS type="array">
    <PRO_E_COMPONENT_CONSTRAINT type="compound">
      <PRO_E_COMPONENT_CONSTR_TYPE type="int">2</PRO_E_COMPONENT_CONSTR_TYPE>
      <PRO_E_COMPONENT_COMP_CONSTR_REF type="selection">
        <PRO_XML_REFERENCE type="reference">
          <PRO_XML_REFERENCE_OWNER type="owner">SIM_ECUB_1-1_TORSO_1.prt</PRO_XML_REFERENCE_OWNER>

@mfussi66
Copy link
Member

Heres is an example of an ElementTree dump: SIM_ECUB_1-1_TORSO_1.xml.txt

@mfussi66
Copy link
Member

mfussi66 commented Nov 21, 2023

Latest commit retrieves also the child name inside the element tree, and adds some small robustness checks. This might be useful since it's not needed to pass around the name of the part currently examined by the main loop.

Though there is ambiguity if parents and child have the same name, maybe it's better to check the feature ID instead of the simple model name.

@mfussi66
Copy link
Member

mfussi66 commented Dec 1, 2023

Today @Nicogene and I successfully used the information of parent-child links of the element tree to simplify the processing of each part of the assembly.

In the past, all the parts were iterated over to:

  1. Find information regarding the rotation axes or the csys of the joints
  2. Use the collected info to find matches between axes names
  3. Use the matches to define which parts compose a joint

Now:

  1. We iterate over each part (the child) and get the element tree
  2. We extract the parent link
  3. We look for an axis (in case of revolute joint) or csys (in case of fixed joint) with the same name between parent and child
  4. We use that axis as direction for the joint

This new method greatly simplifies the search for useful information, by avoiding pointless loops. In fact, we do not have any more warnings regarding missing axes for fixed joints, and the code is faster:

image

Work done in: 819ce65

@mfussi66
Copy link
Member

mfussi66 commented Dec 1, 2023

In this next one e89d3c9 we can avoid the matching altogether 🎉

@Nicogene Nicogene linked a pull request Dec 1, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain-software Related to Software team-fix Related to Team Fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants