Equipment & Systems Engineering

Electrical Harness Installation

Managing Branchable Bundle Segments

How to create, split, and merge bundle segments of a branchable bundle segment
Use Case

Abstract

This article discusses the CAAEhiCreateBranchableBundleSegment use case. This use case explains how to create a geometrical bundle, how to create a branchable bundle segment, how to split a bundle segment defined in a branchable bundle segment, and how to merge two bundle segments into one..


What You Will Learn With This Use Case

This use case is intended to show you how to create geometrical bundle and a branchable bundle segments, how split a bundle segment in two bundle segments and merge two bundle segments in one bundle segment.

Following operations are detailed is this use case:

[Top]

The CAAEhiCreateBranchableBundleSegment Use Case

CAAEhiCreateBranchableBundleSegment is a use case of the CAAElecHarnessItf.edu framework that illustrates the ElecHarnessItf framework capabilities.

[Top]

What Does CAAEhiCreateBranchableBundleSegment Do

The goal of CAAEhiCreateBranchableBundleSegment is to create a geometrical bundle in a new CATProduct document. branchable Bundle segments are created under geometrical bundle. Last step shows how to split  and merge bundle segments.

[Top]

How to Launch CAAEhiCreateBranchableBundleSegment?

To launch CAAEhiCreateBranchableBundleSegment, you will need to set up the build time environment, then compile CAAEhiCreateBranchableBundleSegment.cpp along with its prerequisites, set up the run time environment, and then execute the sample. This is fully described in the referenced article [2].

To launch the use case, execute the following command:

mkrun -c "CAAEhiCreateBranchableBundleSegment PathDir GbnName Bns1Name Bns2Name Bns3Name"

[Top]

Where to Find the CAAEhiCreateBranchableBundleSegment Code?

CAAEhiCreateBranchableBundleSegment code is located in the CAAEhiCreateBranchableBundleSegment.m use case module of the CAAElecHarnessItf.edu framework:

Windows InstallRootDirectory/CAAElecHarnessItf.edu/CAAEhiCreateBranchableBundleSegment.m
Unix InstallRootDirectory\CAAElecHarnessItf.edu\CAAEhiCreateBranchableBundleSegment.m

where InstallRootDirectory is the root directory of your CAA V5 installation. It is made of a unique source file named CAAEhiCreateBranchableBundleSegment.cpp.

[Top]

Step-by-Step

There are seven main logical steps in CAAEhiCreateBranchableBundleSegment:

  1. Prolog
  2. Initializing Electrical Environment.
  3. Creating a Geometrical Bundle.
  4. Creating three Branchable Bundle Segments.
  5. Splitting the first Bundle Segment in two Bundle Segments.
  6. Merging in one Bundle Segment the two Bundle Segments resulting from split.
  7. Epilog.

We will now comment each of those sections by looking at the code.

[Top]

Prolog

Once the current session has been created, the CATProduct document is created into the session . pGbnDoc is a pointer to this document.

The root product of the document is retrieved . piRootProduct is a CATIProduct handle to the root product .

Methodology describing how to create a CATProduct document and how to retrieve the root product is described in [1].

 [Top]

Initialize Electrical Environment

...
CATIEleDocServices * piElecDocServices = NULL;
  
  rc = pDoc->QueryInterface(IID_CATIEleDocServices,(void**) &piElecDocServices );
  if ( SUCCEEDED(rc) && piElecDocServices )
  {
    rc = piElecDocServices->Initialize();
  }

...

Initializing the electrical environment is mandatory to enable access to electrical objects or electrical attributes .

[Top]

Creating Geometrical Bundle

Geometrical Bundle is created using CATEhiFactory interface on root product piRootProduct.

...
CATIEhiGeoBundle * piGeoBundle = NULL;  // the geometrical bundle
  //
  CATIEhiFactory * piEhiFactory = NULL;   // the factory
  //
  rc = piRootProduct->QueryInterface(IID_CATIEhiFactory,(void**) &piEhiFactory );
  //     
...  
  rc = piEhiFactory->CreateGeometricalBundle(&piGeoBundle);

...

piGeoBundle is the pointer to geometrical bundle.

[Top]

Creating three Bundle Segments under a Multi Branchable.

 

First step is the creation a multi branchable bundle

A new CATPart document is created and added into the product structure.

...
CATIEhiMultiBranchable * piMultiBranchable = NULL;
rc = piGeoBundle->CreateMultiBranchable (& piMultiBranchable );


...

A branchable with a bundle segment are created.

 

Second step is the creation of three bundle segments.

The first bundle segment has been created with the branchable.

...
CATIEhiBranchable* piNewBranchable=NULL;
rc = piMultiBranchable->AddBranchable(&piNewBranchable);

...
rc = piMultiBranchable->AddBranchable(&piNewBranchable);

...

Two new branchables with two bundle segments are created under the multi branchable.

 

Third step is the retrieving the three bundle segments under the multi branchable.

...
CATListValCATBaseUnknown_var* pListBundleSegment = NULL;
rc = piMultiBranchable->ListBundleSegments(&pListBundleSegment);

...
CATIEhiBundleSegment * piBundleSegment1 = NULL;
CATIEhiBundleSegment * piBundleSegment2 = NULL;
CATIEhiBundleSegment * piBundleSegment3 = NULL;
rc = (*pListBundleSegment)[1]->QueryInterface(IID_CATIEhiBundleSegment,(void**) &piBundleSegment1);
...
rc = (*pListBundleSegment)[2]->QueryInterface(IID_CATIEhiBundleSegment,(void**) &piBundleSegment2);
...
rc = (*pListBundleSegment)[3]->QueryInterface(IID_CATIEhiBundleSegment,(void**) &piBundleSegment3);

...

 

Fourth step is the definition of bundle segment computation parameters .

Bundle segment centre curve is computed according geometrical parameters ( minimum bend radius, constraint points, tangency constraints ) and physical parameter ( gravity)

Two design methodologies are available : distributed slack or length mode.

  1. Distributed slack : a percentage of extra length is added to minimum length computed by the system ( according minimum bend radius ).
  2. Length : it is the length the user wants to respect for a given bundle segment. Input length must be greater than minimum length.

Following attributes have to be defined :

Bundle segment 1 is created with Slack mode.

...
  double diameter, bend_radius;
  CATUnicodeString mode;

 //    + set attributes for bundle segment 1
  diameter = 0.025;
  bend_radius=0.03;
  mode="Slack";
  rc = SetBundleSegmentAttributes ( piBundleSegment1, mode,  bend_radius, diameter );
  
...

Bundle segment 2 is created with slack mode.

...
//    + set attributes for bundle segment 2
  bend_radius=0.050;
  mode="Slack";
  rc = SetBundleSegmentAttributes ( piBundleSegment2, mode,  bend_radius, diameter );
  
...

CATIElecAttrAccess interface is used in SetBundleSegmentAttributes ( CAAEhiBundleSegment internal method ) to define bundle segment attribute values..

...
HRESULT SetBundleSegmentAttributes ( CATIEhiBundleSegment * piBundleSegment, CATUnicodeString & mode,
                                     double & bend_radius, double & diameter )
{
 HRESULT rc = E_FAIL;
 //
 if (!piBundleSegment) return rc;        // pointer not valuated : exit E_FAIL
 if ( mode != "Slack" && mode != "Length" && mode != "Bend" ) return rc; // invalid mode : exit E_FAIL
 // 
 CATIElecAttrAccess * piElecAttr = NULL;
 rc = piBundleSegment->QueryInterface(IID_CATIElecAttrAccess,(void**) &piElecAttr );
 if ( FAILED(rc) || !piElecAttr )  return rc; // Query Interface CATIElecAttrAccess failed : exit E_FAIL
 //
 CATUnicodeString attribute;
 // --- set build mode 
 attribute = "Elec_Creation_Mode";
 rc = piElecAttr->Set(attribute,mode);
 if ( FAILED(rc) ) return rc; // set attribute Elec_Creation_Mode failed : exit E_FAIL

  // --- set bend radius
 attribute = "Elec_Bend_Radius";
 rc = piElecAttr->Set(attribute,bend_radius);
 if ( FAILED(rc) ) return rc; // set attribute Elec_Bend_Radius failed : exit E_FAIL

 // --- set diameter
 attribute = "Elec_Diameter";
 rc = piElecAttr->Set(attribute,diameter);
 if ( FAILED(rc) ) return rc; // set attribute Elec_Diameter failed : exit E_FAIL

 //
 rc = S_OK;
 //
 piElecAttr->Release(); // release pointer
 piElecAttr=NULL;       // reset pointer value to NULL
 //
 return rc; // exit S_OK;
}

 

...

 

 

Fifth step is the definition of bundle route.

Using CATIGSMFactory, points are created in bundle segment part ( points coordinates are given in MKS unit )

SetBundleSegmentRoute is a sample internal method used to create and to add points on bundle segment curve. Input of method is the bundle segment and the coordinates of the points defining bundle segment route.

...
  double points[9];
  int nb_point = 3;

  //   +- P0
  points[0]=0.88;
  points[1]=-0.27;
  points[2]=0.47;
  
  //
  //   +- P1
  points[3]=0.47;
  points[4]=0.125;
  points[5]=-0.178;
  
  //
  //   +- P2
  points[6]=0.;
  points[7]=0.;
  points[8]=0.;
  
  rc = SetBundleSegmentRoute ( piBundleSegment1, points, nb_point ); 
  
...

Bundle segment curve is retrieved using CATIEhiBundleSegment::GetElecCurve and points are added to curve with CATIGSMSpline::AddPoint

...
HRESULT SetBundleSegmentRoute ( CATIEhiBundleSegment * piBundleSegment, double * point_coord,
                                           int & nb_point )
{
 HRESULT rc = E_FAIL;
 //
 if (!piBundleSegment) return rc; // pointer not valuated : exit E_FAIL 
 if ( nb_point < 2 ) return rc;   // number of points < 2 : exit E_FAIL;

 // -- retrieving electrical curve
 CATIGSMSpline * pElecCurve = NULL;
 rc = piBundleSegment->GetElecCurve(& pElecCurve );
 if ( FAILED (rc) || !pElecCurve ) return rc; // electrical curve not found : exit E_FAIL

 // -- retrieving container
 CATIContainer_var spCont;   // the container 
 CATISpecObject_var spObj = pElecCurve;
 if ( NULL_var != spObj ) spCont = spObj->GetFeatContainer();

 // -- retrieving factories : 
 //             -   litteral feature factory
 //             -   GSM factory
 CATICkeParmFactory_var spCKEfacto = spCont;  // litteral feature factory
 CATIGSMFactory_var spGSMfacto = spCont;      // GSM factory
 if ( NULL_var == spCKEfacto || NULL_var == spGSMfacto )
 {
  pElecCurve->Release(); // release pointe
  pElecCurve=NULL;       // reset pointer value to NULL
  return rc;             // cannot retrieve factories : exit E_FAIL
 }

 // -- retrieving GSM Body :
 // 
 CATBaseUnknown_var spGSMBody = NULL_var; // the GMS body 

 CATIPartRequest * pPartAsRequest = NULL;
 CATIPrtContainer_var spPartCont = spCont;
 if ( NULL_var == spPartCont ) return rc;
 CATISpecObject_var spPart = spPartCont->GetPart();
 if ( NULL_var == spPart ) return rc;
 // 
 if( SUCCEEDED(spPart->QueryInterface(IID_CATIPartRequest, (void**)&pPartAsRequest)) )
 {
   
   const CATUnicodeString stdContext(" "); // Sets the context for  bodies lookup 
   
   // retrieve GSM open body
   CATLISTV(CATBaseUnknown_var) surfBodies;  // List of GSM bodies in pPartAsRequest
   pPartAsRequest->GetSurfBodies(stdContext, surfBodies);
   
   // select first body found to create points
   spGSMBody = surfBodies[1];

   pPartAsRequest->Release();
   pPartAsRequest=NULL;
 }
 if ( NULL_var == spGSMBody ) return rc;  // GSM body not found
 CATIDescendants_var spFather = spGSMBody; 
 if ( NULL_var == spFather ) return rc; 

 // -- create and add points to curve
 // 
 CATICkeParm_var X;
 CATICkeParm_var Y; 
 CATICkeParm_var Z;  
 CATIGSMPointCoord_var spPoint;
 //
 for ( int i=1; i<=nb_point; i++ )
 {
   X = spCKEfacto->CreateLength  ( "X", point_coord[  3*(i-1)] );
   Y = spCKEfacto->CreateLength  ( "Y", point_coord[1+3*(i-1)] );
   Z = spCKEfacto->CreateLength  ( "Z", point_coord[2+3*(i-1)] );
   spPoint = spGSMfacto->CreatePoint(X,Y,Z);   
   if ( NULL_var != spPoint ) // --- point created 
   {   
    spFather->Append(spPoint); // add point under GSM body in tree 
    CATISpecObject_var (spPoint)->Update(); // compute point geometry  
    // --- add constraint point to electrical curve
    pElecCurve->Add(spPoint);
   }
   else
   {
   // --- point creation failed
     pElecCurve->Release(); // release pointer
     pElecCurve=NULL;       // reset pointer value to NULL
     return rc;             // GSM point creation failed : exit E_FAIL   
   }
 }
 //
 // -- update curve geometry
 spObj->Update();
 //
 pElecCurve->Release(); // release pointer
 pElecCurve=NULL;       // reset pointer value to NULL
 //
 rc = S_OK;
 //
 return rc; // exit S_OK;
}


...

 

 

 

 

 

Sixth step is the computation of bundle segment representation.

CATIEhiGeoBundle::ComputeBundleSegment is used to compute bundle segment shape ( part design RIB ). This method may be used to re-compute shape after parameter modification.

...
  //   + compute bundle segment 1 
  //         
  rc = piGeoBundle->ComputeBundleSegment ( piBundleSegment1 ); 
..

 

[Top]

Splitting  the  first Bundle Segment in two Bundle Segments.

Firstly we create a point on first bundle segment .

...
  CATIGSMPointOnCurve_var spGSMPointOnCurve;
  double distance = 0.5;
  rc = CreatePointOnBundleSegment(piBundleSegment1, distance,spGSMPointOnCurve);
...

The creation of this point is defined in the following services : 

...
//      piBundleSegment : bundle segment instance 
//      distance : distance from first extremity
//      spPointOnCurve : the point created on the curve of piBundleSegment 
...
 HRESULT CreatePointOnBundleSegment ( CATIEhiBundleSegment * piBundleSegment, double & distance,CATIGSMPointOnCurve_var & spPointOnCurve)
{
  HRESULT rc(E_FAIL);
  if(!piBundleSegment) return rc;

  CATIGSMSpline * pGSMSpline  = NULL;
  rc = piBundleSegment->GetElecCurve(&pGSMSpline);
  
  // -- retrieving container
  CATIContainer_var spFeatContainer;   // the container 
  CATISpecObject_var spObjectCurve = pGSMSpline;
  if ( NULL_var != spObjectCurve ) spFeatContainer = spObjectCurve->GetFeatContainer();
  
  // -- retrieving factories : 
  //             -   litteral feature factory
  //             -   GSM factory
  CATICkeParmFactory_var spCKEfactory = spFeatContainer;  // litteral feature factory
  CATIGSMFactory_var spGSMfactory = spFeatContainer;      // GSM factory
  if ( NULL_var == spGSMfactory || NULL_var == spCKEfactory )
  {
    if(pGSMSpline) pGSMSpline->Release(); // release pointe
    pGSMSpline=NULL;       // reset pointer value to NULL
    return rc;             // cannot retrieve factories : exit E_FAIL
  }
  CATICkeParm_var spDistance   = spCKEfactory->CreateLength  ( "Distance", 0.5);
  CATIGSMPointOnCurve::DistanceType Type = CATIGSMPointOnCurve::Geodesic;
  CATGSMOrientation Orientation = CATGSMSameOrientation;
  spPointOnCurve = spGSMfactory ->CreatePoint( spObjectCurve, 
                                               NULL_var,
                                               spDistance,
                                               Orientation,
                                               Type);
  if(!spPointOnCurve) 
  {
    cout << "> spPointOnCurve not created " << endl << flush;
    return 10; // revoir le numéro a retourner
  }

  
 // -- retrieving GSM Body :
 // 
 CATBaseUnknown_var spGSMBody ; // the GMS body 

 CATIPartRequest * pPartAsRequest = NULL;
 CATIPrtContainer_var spPartCont = spFeatContainer;
 if ( NULL_var == spPartCont ) return rc;
 CATISpecObject_var spPart = spPartCont->GetPart();
 if ( NULL_var == spPart ) return rc;
 // 
 if( SUCCEEDED(spPart->QueryInterface(IID_CATIPartRequest, (void**)&pPartAsRequest)) )
 {
   
   const CATUnicodeString stdContext(" "); // Sets the context for  bodies lookup 
   
   // retrieve GSM open body
   CATLISTV(CATBaseUnknown_var) surfBodies;  // List of GSM bodies in pPartAsRequest
   pPartAsRequest->GetSurfBodies(stdContext, surfBodies);
   
   // select first body found to create points
   spGSMBody = surfBodies[1];

   pPartAsRequest->Release();
   pPartAsRequest=NULL;
 }
 if ( NULL_var == spGSMBody ) return rc;  // GSM body not found
 CATIDescendants_var spFather = spGSMBody; 
 if ( NULL_var == spFather ) return rc; 
 spFather->Append(spPointOnCurve);
 CATISpecObject_var (spPointOnCurve)->Update(); // conmpute point geometry  

 //
 // -- update curve geometry
 spObjectCurve->Update();

 if(pGSMSpline) pGSMSpline->Release();
 pGSMSpline = NULL;

 return rc;
}

...

 

Secondly, we can split the first bundle segment in two bundle segments as follows :

...
 CATIEhiBundleSegment * pElecBundleSegment = NULL;
 rc = piBundleSegment1-> Split(spGSMPointOnCurve, pElecBundleSegment);
...

And we compute the new bundle segment created by split functionality :

...
 diameter = 0.02;
 bend_radius=0.03;
 mode="Slack";
 rc = SetBundleSegmentAttributes ( pElecBundleSegment, mode,  bend_radius, diameter );
...   
   rc = piGeoBundle->ComputeBundleSegment ( pElecBundleSegment );
...

[Top]

Merging in one Bundle Segment the two Bundle Segments resulting from the split

We merge the two bundle segments as follows :

...
 rc = piBundleSegment1->Merge (pElecBundleSegment);

...

[Top]

Epilog

The four created documents are saved into the directory defined as input. Name of file is the part number.

3 bundle segment parts are saved first.

...
CATIGSMSpline * pGSMFirstSpline  = NULL;
CATDocument * pBnsPartDoc = NULL;
CATILinkableObject_var spLinkable;
  rc = piBundleSegment1->GetElecCurve(&pGSMFirstSpline);
if( pGSMFirstSpline)
    spLinkable = pGSMFirstSpline;
if (NULL_var != spLinkable) pBnsPartDoc = spLinkable->GetDocument();
...
  rc = CATDocumentServices::SaveAs (*pBnsPartDoc , PathOutput+Bns1File );
...

Geometrical bundle is saved at the end.

...
rc = CATDocumentServices::SaveAs (*pGbnDoc , PathOutput+GbnFile );

...

Document is removed and session is deleted before exit.

...
rc = CATDocumentServices::Remove(*pGbnDoc);
...
rc = ::Delete_Session(sessionName);
...

[Top]

 


In Short

This use case is has demonstrated how to create geometrical bundle and bundle segments, how to connect and disconnect bundle segment.

Following operations have been detailed is this use case :

[Top]


References

[1] Adding Components to a Product Structure
[2] Building and Launching a CAA V5 Use Case
[Top]

History

Version: 1 [Jan 2003] Document created
[Top]

Copyright © 2002, Dassault Systèmes. All rights reserved.