OMKJointExtension.cpp

Go to the documentation of this file.
00001 /************************************************************************/
00002 /* This file is part of openMask(c) INRIA, CNRS, Universite de Rennes 1 */
00003 /* 1993-2002, thereinafter the Software                                 */
00004 /*                                                                      */
00005 /* The Software has been developped within the Siames Project.          */
00006 /* INRIA, the University of Rennes 1 and CNRS jointly hold intellectual */
00007 /* property rights                                                      */
00008 /*                                                                      */
00009 /* The Software has been registered with the Agence pour la Protection  */
00010 /* des Programmes (APP) under registration number                       */
00011 /* IDDN.FR.001.510008.00.S.P.2001.000.41200                             */
00012 /*                                                                      */
00013 /* This file may be distributed under the terms of the Q Public License */
00014 /* version 1.0 as defined by Trolltech AS of Norway and appearing in    */
00015 /* the file LICENSE.QPL included in the packaging of this file.         */
00016 /*                                                                      */
00017 /* Licensees holding valid specific licenses issued by INRIA, CNRS or   */
00018 /* Universite Rennes 1 for the software may use this file in            */
00019 /* acordance with that specific license                                 */
00020 /************************************************************************/
00021                 
00022 #include "OMKJointExtension.h"
00023 #include "OMKJoint.h"
00024 #include "OMKExtensibleSimulatedObject.h"
00025 #include "OMKInteractorExtension.h"
00026 #include "OMKParametersAccessor.inl"
00027 #include "OMKInputNT.h"
00028 #include "OMKSessionPrm.h"
00029 #include "OMKTransformType.h"
00030 
00031 namespace OMK  
00032 {
00033   namespace Iii 
00034   {
00035 //=================================================================
00036 // JointInteractorExtension
00037 //=================================================================
00046 class JointInteractorExtension : public InteractorExtension 
00047 {
00048   friend class JointExtension ;
00050 
00051 public:
00053   virtual ~JointInteractorExtension() ;
00054 protected:
00056   JointInteractorExtension( JointExtension* jointExtension ) ;
00058 
00059   virtual bool loadObjectParameters( const ConfigurationParameterDescriptor * node ) ;
00060   virtual bool loadExtensionParameters( const ConfigurationParameterDescriptor * node ) ;
00062   virtual void postComputeParameters() ;
00063   void startRetroPropagation() ;
00064   void stopRetroPropagation() ;
00065   Name _referenceId ;
00066   Name _positionId ;
00067   bool _connected ;
00068   JointExtension* _jointExtension ;
00069 } ;
00070     
00071 //-----------------------------------------------------------------
00072 JointInteractorExtension::JointInteractorExtension( JointExtension* jointExtension ) 
00073 : InteractorExtension( jointExtension->_owner, std::string( jointExtension->_id.getCString() ) + "Interactor", false ),
00074   _connected( false ),
00075   _jointExtension( jointExtension ) 
00076 {
00077   _access._level = 0 ;
00078 }
00079 //-----------------------------------------------------------------
00080 JointInteractorExtension::~JointInteractorExtension() 
00081 {
00082 }
00083 //-----------------------------------------------------------------
00084 bool JointInteractorExtension::loadObjectParameters( const ConfigurationParameterDescriptor * node ) 
00085 {
00086   bool ok = true ;
00087 
00088   std::pair< Name, Name > connection ;
00089   ok = ok && ParametersAccessor::get( node, "refPositionConnect", connection, _owner ) ;
00090   if( ok )
00091   {
00092     _referenceId = connection.first ;
00093     _positionId = connection.second ;
00094   }
00095 
00096   return ok  ;
00097 }
00098 //-----------------------------------------------------------------
00099 bool JointInteractorExtension::loadExtensionParameters( const ConfigurationParameterDescriptor * node ) 
00100 {
00101   ParametersAccessor::get( node, "Level", _access._level ); 
00102   OMTRACEID( OMK_DEBUG_III, "The interactor " <<  OMK::debugMsg( this, _owner ) << " has the level " << _access._level ) ;
00103   startInteractor() ;
00104   
00105   // Try to read the category in the configuration of the reference object
00106   bool found  = false ; // flag to know if the search is ok
00107   std::string category( "absolute" ) ; // The default value
00108   // 1/ Search in the current configuration the category
00109   if( ParametersAccessor::get( node, "Category", category ) )
00110   {
00111     OMTRACEID( OMK_DEBUG_III, "The category for the reference is \"" << category << "\" and it " << ( found ? "was found in configuration" : "is the default value" ) ) ;
00112   }
00113   else
00114   {
00115     // 2/ search the extensions configuration of the reference object
00116     const ConfigurationParameterDescriptor *extNodeForRef = _owner->getController().getObjectDescriptorOfObject( _referenceId ).getExtensionsParameters() ;
00117     int nbItems = extNodeForRef ? extNodeForRef->getNumberOfSubItems() : 0 ;
00118     for( int i = 0 ; i < nbItems && !found ; ++i )
00119     { 
00120       // Retrieves configuration for each extension
00121       const ConfigurationParameterDescriptor * extNode = extNodeForRef->getSubDescriptorByPosition( i ) ;
00122       // Try to found "Connectors" in it
00123       const ConfigurationParameterDescriptor * connectorsNode = extNode->getSubDescriptorByName( "Connectors" ) ;
00124       // Try to found the connector with the same id than the output which is the reference for the joint
00125       const ConfigurationParameterDescriptor * connectorNode = connectorsNode ? connectorsNode->getSubDescriptorByName( _positionId.getCString() ) : 0 ;
00126       if( connectorNode )
00127       { // Ok, so try to read the "Category" field
00128         ParametersAccessor::get( connectorNode, "Category", category ) ;
00129         found = true ;
00130         break ;
00131       }
00132       else
00133       { // Not ok, no connectors has this id
00134         int nbItems2 = connectorsNode ? connectorsNode->getNumberOfSubItems() : 0 ;
00135         for( int j = 0 ; j < nbItems2 ; ++j )
00136         { // Look for connector which has the "Attribute" field equals to the id
00137           std::string id ;
00138           const ConfigurationParameterDescriptor * connectorNode = connectorsNode->getSubDescriptorByPosition( j ) ;
00139           if( ParametersAccessor::get( connectorNode, "Attribute", id ) && id == _positionId )
00140           { // The "Attribute" field is ok => try to read the "Category" field
00141             ParametersAccessor::get( connectorNode, "Category", category ) ;
00142             found = true ;
00143             break ;
00144           }
00145         }
00146       }
00147     }
00148     OMTRACEID( OMK_DEBUG_III, "The category for the reference is \"" << category << "\" and it " << ( found ? "was found in configuration" : "is the default value" ) ) ;
00149   }
00150     
00151   // Creates the interactor output
00152   InteractorOutput::create( _jointExtension->_referencePosition.getId(), _jointExtension->_referencePosition.getId(), this, category, OMK::Type::AccessGroupLevel(), false ) ;
00153 
00154   return true ;
00155 }
00156 //-----------------------------------------------------------------
00157 void JointInteractorExtension::postComputeParameters() 
00158 {
00159 }
00160 //-----------------------------------------------------------------
00161 void JointInteractorExtension::startRetroPropagation() 
00162 {
00163   if( !getSessionWith( _referenceId ) )
00164   {
00165     startSessionWith( _referenceId ) ;
00166     OMMESSAGE( "start session" ) ;
00167   }
00168   else if( !_connected )
00169   {
00170     (*getSessionWith( _referenceId )).c( _jointExtension->_referencePosition.getId() ).c( OMK::Iii::controlTakeOverAndGetCurrentValues ) ;
00171     _connected = true ;
00172     OMMESSAGE( "start retro propagation" ) ;
00173   }
00174 }
00175 //-----------------------------------------------------------------
00176 void JointInteractorExtension::stopRetroPropagation() 
00177 {
00178   if( _connected ) 
00179   {
00180     (*getSessionWith( _referenceId )).c( _jointExtension->_referencePosition.getId() ).c( OMK::Iii::controlRelease ) ;
00181     _connected = false ;
00182     OMMESSAGE( "stop retro propagation" ) ;
00183   }
00184 }
00185 //-----------------------------------------------------------------
00186 
00187 //=================================================================
00188 // JointExtension
00189 //=================================================================
00190     
00191 REGISTER_EXTENSION_FACTORY( JointExtension, "Joint" ) ;
00192 //-----------------------------------------------------------------
00193 
00194 // Default constructor
00195 JointExtension::JointExtension( ExtensibleSimulatedObject* owner, const Name& id, bool registerExtension )
00196 : ExtensionT< ExtensibleSimulatedObject >( owner, id, registerExtension ),
00197   _objectPosition( 0 ),
00198   _referencePosition( "refPosition", OMK::Type::Transform::sk_identity ),
00199   _jointPosition( "jointPosition", OMK::Type::Transform::sk_identity ),
00200   _connected( false ),
00201   _interactor( 0 ),
00202   _joint( 0 )
00203 {
00204   // add the attributes to the object
00205   _owner->addAttribute( _referencePosition ) ;
00206   _owner->addAttribute( _jointPosition ) ;
00207   // Look for the retrto propagation flag
00208   const ConfigurationParameterDescriptor * node = _owner->getObjectDescriptor().getExtensionsParameters() ;
00209   const ConfigurationParameterDescriptor * extNode = node ? node->getSubDescriptorByName( _id.getCString() ) : 0 ;
00210   bool retroAction = false ; // Default is false
00211   ParametersAccessor::get( extNode, "Retro", retroAction ) ;
00212   if( retroAction )
00213   {
00214     // For retro-propagation the extension must declare the output for the reference position
00215     _referencePosition.createOutput() ;
00216     // And create the interactor to update the reference position
00217     _interactor = new JointInteractorExtension( this ) ;
00218   }
00219 }
00220 
00221 //-----------------------------------------------------------------
00222 
00223 // Destructor
00224 JointExtension::~JointExtension()
00225 {
00226   // delete the associated interactor
00227   delete _interactor ;
00228 }
00229 //-----------------------------------------------------------------
00230 
00231 bool JointExtension::loadObjectParameters( const ConfigurationParameterDescriptor * node ) 
00232 {
00233   // Calls the interactor loader if neccessary
00234   return !_interactor || _interactor->loadObjectParameters( node ) ;
00235 }
00236 //-----------------------------------------------------------------
00237 
00238 bool JointExtension::loadExtensionParameters( const ConfigurationParameterDescriptor * node ) 
00239 {
00240   // Gets the name of the position attribute of the object
00241   Name attributeName( "Position" ) ; // by default "Position"
00242   ParametersAccessor::get( node, "PositionName", attributeName ) ;
00243   // Gets the attribute accessor
00244   _objectPosition = _owner->getBaseAttribute< OMK::Type::Transform >( attributeName ) ;
00245   bool ok = _objectPosition != 0 ;
00246   
00247   // Calls the interactor loader if neccessary
00248   ok = ok && ( !_interactor || _interactor->loadExtensionParameters( node ) ) ;
00249   
00250   // The joint
00251   std::string jointClass( "Lock" ) ;
00252   
00253   ok = ok && ParametersAccessor::get( node, "Joint", jointClass ) ;
00254   _joint = OMK::Iii::JointFactory::getInstance().create( jointClass )( this, node ) ;
00255   OMASSERTM( _joint, "Joint  [" << jointClass << "] cannot be created, may be not registered in the main !" ) ;
00256   
00257   return ok ;
00258 }
00259 //-----------------------------------------------------------------
00260 
00261 void JointExtension::postComputeParameters() 
00262 {
00263   OMASSERTM( _joint, "The joint must be created" ) ;
00264   // To be linked the joint must found the position, see if the reference position declares an input and if this one is connected
00265   bool updatedLinkstate = _objectPosition 
00266                        && _referencePosition.getInput() 
00267                        && _referencePosition.getInput()->getConnectedOutput() ;
00268   if( _connected )
00269   { 
00270     if( !updatedLinkstate )
00271     { // Change the state => no more connected
00272       _connected = false ;
00273       // Nothing else to do
00274       OMMESSAGE( "release" ) ;
00275     }
00276     else
00277     { // Connected and still connected
00278       // Calculates the new joint position based on the reference position
00279       _joint->currentJointPosition() ;
00280       // Does the object move ?
00281       
00282       // Retro propagation is activated
00283       // the object moves itself (by an interactor, its own behavior,...)
00284       // => calculates the the ideal position for the reference position
00285       if( _objectPosition->isUpdated() && _joint->retroPropagation() )
00286       { 
00287         // Starts retro-propagation
00288         if( _interactor ) _interactor->startRetroPropagation() ;
00289       }
00290       else
00291       {
00292         // The object doesn't move itself => it follows the reference, no more retro-propagation
00293         if( _interactor ) _interactor->stopRetroPropagation() ;
00294       }
00295       // Calculates the new joint position based on the joint position
00296       _joint->currentObjectPosition() ;
00297     }
00298   }
00299   else
00300   {
00301     if( updatedLinkstate )
00302     { // Change the state => The connection has just been connected
00303       OMMESSAGE( "linked" ) ;
00304       _connected = true ;
00305       _joint->establishLink() ;
00306     }
00307     // else unconnected and still unconnected => nothing to do
00308   }
00309 }
00310 
00311   }// namespace Iii
00312 }// namespace OMK

logo OpenMask

Documentation generated on Mon Jun 9 11:45:56 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007