Product Synthesis & Knowledgeware

DMU Kinematics Simulator

Reading a Mechanism in a Document

From a mechanism to its description written in a file
Use Case

Abstract

This article discusses the CAAKiiReadMechanism use case. This use case explains how to open a CATProduct document and explore its content from a Kinematics perspective, down to the basic entities that capture technology of a mechanism contained in the document.


What You Will Learn With This Use Case

This use case is intended to help you make your first steps in programming the CATIA kinematics modeler. Its main intent is to introduce the API of the kinematics modeler, and ways to use it.

The scenario is based on an industrial process:

  1. The end-user defines and validates interactively a mechanism within CATIA
  2. When mechanism is validated, a batch utility translate them in another system
  3. Translated data are used to perform a task.

To perform the first and last operations, the user works with on-the-shelf softwares. But a utility to translate mechanism structure from any system to another does not exist on the shelf.

The target of this use case is to learn how to build such utility. To simplify explanations, we suppose the other system read a text file with a dedicated format.

This picture represents a CATProduct document containing a mechanism.

This picture represents a text file which results from the use of the sample on the CATProduct document.

[Top]

Kinematics Concepts

Before getting to the use case itself, it is important to get an understanding of some of the concepts that are at the heart of the Kinematics, since the use case basically navigates among objects that represent those concepts. They are presented in Kinematics Overview [1].

These concepts are:

[Top]

The CAAKiiReadMechanism Use Case

CAAKiiReadMechanism is a use case of the CAAKinematicsInterfaces.edu framework that illustrates KinematicsInterfaces framework capabilities.

[Top]

What Does CAAKiiReadMechanism Do

The goal of CAAKiiReadMechanism is to:

[Top]

How to Launch CAAKiiReadMechanism

To launch CAAKiiReadMechanism, you will need to set up the build time environment, then compile CAAKiiReadMechanism along with its prerequisites, set up the run time environment, and then execute the use case [2].

Launch the use case as follows:

where:

inputDirectory The directory in which inputFile.CATProduct is located
inputFile.CATProduct The file that contains the use case CATProduct document
outputFile The file that will contain the resulting file

[Top]

Where to Find the CAAKiiReadMechanism Code

The CAAKiiReadMechanism use case is made of a C++ main named CAAKiiReadMechanism whose source file is located in the CAAKiiReadMechanism.m module of the CAAKinematicsInterfaces.edu framework:

Windows InstallRootDirectory\CAAKinematicsInterfaces.edu\CAAKiiReadMechanism.m\
Unix InstallRootDirectory/CAAKinematicsInterfaces.edu/CAAKiiReadMechanism.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed. The CAAKiiReadMechanism class derives from CATInteractiveApplication. The described code is located in the BeginApplication method.

[Top]

Where to Find the CATProduct sample document for CAAKiiReadMechanism

You will find a CATProduct sample document in the following directory:

Windows InstallRootDirectory\CAADoc\CAAKinematicsInterfaces.edu\CNext\resources\graphic\
Unix InstallRootDirectory/CAADoc/CAAKinematicsInterfaces.edu/CNext/resources/graphic/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed. The sample is called CAAKiiReadMechanism.CATProduct.

[Top]

Step-by-Step

There are six steps in CAAKiiReadMechanism:

  1. Prolog
  2. Getting Access to the Mechanisms of the Document
  3. Getting Access to All the Joints
  4. Getting Access to All the Commands
  5. Reading the General Information
  6. Epilog
We will now comment each of those sections by looking at the code.

[Top]

Prolog

The use case is the CAAKiiReadMechanism batch which runs in one shot. The described code is located in the C++ main method. It begins by creating a session, and by opening the use case CATProduct document passed as an argument: pDocument refers to it. This is the usual sequence for creating a document [3]. It also opens the output file: outputFile refers to it.

[Top]

Getting Access to the Mechanisms of the Document

...
CATIKinMechanismFactory* piMechanismFactoryOnDocument = NULL;
  HR = pDocument->QueryInterface(IID_CATIKinMechanismFactory,(void**)&piMechanismFactoryOnDocument);
  if (SUCCEEDED(HR))
  {
    CATLISTP(CATBaseUnknown)* ListOfMechanisms = NULL;
    HR = piMechanismFactoryOnDocument->ListInstances (&ListOfMechanisms);
    if (SUCCEEDED(HR))
      {
	// Read all the mechanisms of the document
	int nbMechanisms = ListOfMechanisms->Size();
	for (int i = 1;i<=nbMechanisms;i++)
	 {
	  CATIKinMechanism* piMechanism = NULL;
	  (*ListOfMechanisms)[i]->QueryInterface(IID_CATIKinMechanism,(void**)&piMechanism);
	    
	  // Print the name of the mechanism
	  CATIAlias* piAliasOnMechanism = NULL;

          if (SUCCEEDED(piMechanism->QueryInterface(IID_CATIAlias,(void**)&piAliasOnMechanism)))
           {
             outputFile << "Mechanism " << piAliasOnMechanism->GetAlias().ConvertToChar() <<endl << flush;
             piAliasOnMechanism->Release();
             piAliasOnMechanism = NULL;
           }  
...

A CATProduct document contains from zero to many mechanisms. Access to the list of all the mechanisms included in the document is made through the factory method CATIKinMechanismFactory::ListInstances, using QueryInterface on pDocument to retrieve the factory. As a result, it provides a list of CATBaseUnknown objects representing the existing mechanisms. The number of mechanisms in the list is given by the CATLISTP(CATBaseUnknown)::Size method. The CATIAlias interface is used to retrieve the name of the mechanism to be output on the file.

This produces the following output:

Mechanism Mechanism.1

[Top]

Getting Access to All the Joints

...
	    CATLISTP(CATBaseUnknown)* jointList=NULL;
	    HR = piMechanism->GetJointList(&jointList);
	    if (SUCCEEDED(HR))
	      {
		outputFile << "   Joint" <<endl << flush;
		
		int nbJoints = jointList->Size();
		for (int j = 1;j<=nbJoints; j++)
		  {
		    outputFile << "      " << j << " : ";
		    
		    // Get the type of joint
		    CATIKinJoint* piJoint = NULL;
		    (*jointList)[i]->QueryInterface(IID_CATIKinJoint,(void**)&piJoint);
		    const char* JointType = NULL;
		    HR = piJoint->GetType(&JointType);
		    if (SUCCEEDED(HR)) {outputFile << JointType << "; ";}
        
                    // Get the parts involved in the joint
                    int nbPartInJoint = 0;
		    CATLISTP(CATBaseUnknown)* productList=NULL;
		    HR = piJoint->GetProductList(&productList);
		    if (SUCCEEDED(HR))
		      { 
			nbPartInJoint = productList->Size();
			
			outputFile << nbPartInJoint << " products; ";
		      }
		    // Get the first frame from the joint definition
		    double** axis1 = NULL;
		    HR = piJoint->GetFrame(1,axis1);
		    
		    // Get the second frame from the joint definition
		    double** axis2 = NULL;
		    HR = piJoint->GetFrame(2,axis2);
		    
		    // Get the ratio of the joint
		    
		    double ratio;
		    HR = piJoint->GetRatio(&ratio);
		    
		    // Get the parameters of the joint
		    double* parm = NULL;
		    int oSize = 0;
		    
		    HR = piJoint->GetJointValues(&parm,&oSize);
       
                    //  Get the constraints of the joint
                    int nbConstraints = 0;
		    CATLISTP(CATBaseUnknown)* paConstraints = NULL;
		    HR = piJoint->GetConstraints(&paConstraints);
		    if (SUCCEEDED(HR))
		      {
			nbConstraints = paConstraints->Size();
			outputFile << nbConstraints << " constraints; "; 
		      }
		    
		    //  Get the connectors of the joint
		    int nbConnectors = 0;
		    CATLISTP(CATBaseUnknown)* paConnectors = NULL;
		    HR = piJoint->GetConnectors(&paConnectors);
		    if (SUCCEEDED(HR)) 
		      {
			nbConnectors = paConnectors->Size();
			outputFile << nbConnectors << " connectors; "; 
		      }
		    
		    outputFile << endl << flush;
		  }
		outputFile << "   EndJoint" <<endl << flush;
	      }
          }
...

A mechanism contains from zero to many joints. Access to the list of all the joints included in the mechanism is made through the GetJointList method of the CATIKinMechanism interface. As a result, it provides a CATLISTP(CATBaseUnknown) collection. The type of the joint is given by the GetType method of the CATIKinJoint interface. All other methods from the CATIKinJoint interface are exercised to learn about them.

This produces the following output:

   Joint
      1 : Revolute; 2 products; 2 constraints; 4 connectors;
      2 : Revolute; 2 products; 2 constraints; 4 connectors;
      3 : Revolute; 2 products; 2 constraints; 4 connectors;
      4 : Revolute; 2 products; 2 constraints; 4 connectors;
   EndJoint

[Top]

Getting Access to All the Commands

...
     CATLISTP(CATBaseUnknown)* cmdList = NULL;
     HR = piMechanism->GetCmdList(&cmdList);
if (SUCCEEDED(HR)) { outputFile << " Command" <<endl << flush; int nbCmds = cmdList->Size(); for (int l = 1;l<=nbCmds;l++) { outputFile << " " << l << " : "; CATIKinCmd* piCmd = NULL; (*cmdList)[l]->QueryInterface(IID_CATIKinCmd,(void**)&piCmd);; // Get the command type const char* cmdType = NULL; HR =piCmd->GetType(&cmdType); if (SUCCEEDED(HR)) {outputFile << cmdType << "; ";} // Get the joint associated to the command CATIKinJoint* papiAssociatedJoint = NULL; HR =piCmd->GetJoint(&papiAssociatedJoint); if (SUCCEEDED(HR)) { outputFile << "joint X;"; } outputFile << endl << flush; } outputFile << " EndCommand" << endl << flush; ...

A mechanism contains from zero to many commands. Access to the list of all the commands included in the mechanism is made through the GetCmdList method of the CATIKinMechanism interface. As a result, it provides a CATLISTP(CATBaseUnknown) collection. The type of the joint is given by the GetType method of the CATIKinCmd interface. All other methods from the CATIKinCmd interface are exercised to learn about them.

This produces the following output:

   Command
      1 : Angle; joint 1;
   EndCommand
   Command values :

[Top]

Reading the General Information

...
    // Get the fixed product of the mechanism
    CATIProduct* piProductOnFixedProduct = NULL;
    if (SUCCEEDED(piMechanism->GetFixedProduct(&piProductOnFixedProduct)))
    {
      CATIAlias* piAliasOnFixedProduct = NULL;
      if (SUCCEEDED(piProductOnFixedProduct->QueryInterface(IID_CATIAlias,(void**)&piAliasOnFixedProduct)))
      {
        outputFile << "   Fixed part : " << piAliasOnFixedProduct->GetAlias().ConvertToChar() << endl << flush;
        piAliasOnFixedProduct->Release();
        piAliasOnFixedProduct = NULL;
      }
      piProductOnFixedProduct->Release();
      piProductOnFixedProduct = NULL;
    }

    // Get the list of the products involved in the mechanism
    int nbInvolvedProducts = 0;
    CATLISTP(CATBaseUnknown)* papiProductOfMechanism = NULL;
    HR = piMechanism->GetProductList (&papiProductOfMechanism);
    if (SUCCEEDED(HR))
    {
      nbInvolvedProducts = papiProductOfMechanism->Size();

      outputFile << "   Products involved : " << nbInvolvedProducts << "; " << endl << flush;
    }
    
    // Clean the environment
    piMechanism->Release();
    piMechanism = NULL;
    
    outputFile << "EndMechanism" <<endl << flush;
  }
}
...

A mechanism has one fixed product. Access to it is made thru the GetFixedProduct method of the CATIKinMechanism interface. The list of products involved in the mechanism is build using the GetProductList method of  CATIKinMechanism. At each step the sample cleans the environment and releases all resources. The technique is fairly simple : all references to interfaces have to be released using CATBaseUnknown::Release() and then the list is deleted. All pointer are nullified.

This produces the following output:

   Fixed part : rod2.3
   Products involved : 4;
EndMechanism

[Top]

Epilog

The document is closed using its LifeCycleObject interface and more specifically the remove method. The environment is cleaned, and the session is deleted by the Delete_Session global function, which is passed the same identifier that was used to open it. This is the usual sequence for closing a CATIA document, and for deleting the session [3].

[Top]


In Short

This use case has demonstrated the way to programmatically navigate a CATProduct document, from the document itself down to the entities that hold the mechanism definition.

More specifically, you have learn how to access:

[Top]


References

[1] Kinematics Overview
[2] Building and Launching a CAA V5 Use Case
[3] Creating a New Document
[Top]

History

Version: 1 [Jan 2000] Document created
Version: 2 [Jan 2001] Interface reviewed; exposing only KinematicsInterfaces
Version: 3 [Aug 2002] Added CATProduct sample document
[Top]

Copyright © 2000-2001, Dassault Systèmes. All rights reserved.