icub-tech-iit / creo2urdf

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

CREO2URDF – Retrieve the joint info from the mechanism #57

Closed Nicogene closed 10 months ago

Nicogene commented 11 months ago

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:

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

mfussi66 commented 11 months ago

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 commented 10 months ago

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 commented 10 months ago

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

mfussi66 commented 10 months ago

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 commented 10 months ago

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: https://github.com/icub-tech-iit/creo2urdf/commit/819ce65b419e801034360b873b0302223788113d

mfussi66 commented 10 months ago

In this next one https://github.com/icub-tech-iit/creo2urdf/commit/e89d3c9bcaddca2e9865fbcf56e75554bb43cbc8 we can avoid the matching altogether 🎉