//////////////////////////////////////////////// // TEST: testReflectTSOWithInvalidAttribute() // //////////////////////////////////////////////// void ReflectAttributesTest::testReflectTSOWithInvalidAttribute() { RTI::AttributeHandleValuePairSet *set = defaultFederate->createAHVPS( 2 ); set->add( aaHandle, "aa", 3 ); set->add( 10000000, "na", 3 ); try { RTIfedTime time = 10.0; defaultFederate->rtiamb->updateAttributeValues( theObject, *set, time, "NA" ); delete set; failTestMissingException( "AttributeNotDefined", "updating attributes with invalid attribute" ); } catch( RTI::AttributeNotDefined& attnd ) { // success delete set; } catch( RTI::Exception& e ) { delete set; failTestWrongException( "AttributeNotDefined", e, "updating attributes with invalid attribute" ); } }
/* * This method will update all the values of the given object instance. It will * set each of the values to be a string which is equal to the name of the * attribute plus the current time. eg "aa:10.0" if the time is 10.0. * <p/> * Note that we don't actually have to update all the attributes at once, we * could update them individually, in groups or not at all! */ void ExampleCPPFederate::updateAttributeValues( RTI::ObjectHandle objectHandle ) { /////////////////////////////////////////////// // create the necessary container and values // /////////////////////////////////////////////// // create the collection to store the values in, as you can see // this is quite a lot of work RTI::AttributeHandleValuePairSet *attributes = RTI::AttributeSetFactory::create( 3 ); // generate the new values // we use EncodingHelpers to make things nice friendly for both Java and C++ char aaValue[16], abValue[16], acValue[16]; sprintf( aaValue, "aa:%f", getLbts() ); sprintf( abValue, "ab:%f", getLbts() ); sprintf( acValue, "ac:%f", getLbts() ); attributes->add( aaHandle, aaValue, (RTI::ULong)strlen(aaValue)+1 ); attributes->add( abHandle, abValue, (RTI::ULong)strlen(abValue)+1 ); attributes->add( acHandle, acValue, (RTI::ULong)strlen(acValue)+1 ); ////////////////////////// // do the actual update // ////////////////////////// rtiamb->updateAttributeValues( objectHandle, *attributes, "hi!" ); // note that if you want to associate a particular timestamp with the // update. here we send another update, this time with a timestamp: RTIfedTime time = fedamb->federateTime + fedamb->federateLookahead; rtiamb->updateAttributeValues( objectHandle, *attributes, time, "hi!" ); // clean up delete attributes; }
void Attribute<RTIObjectIdArrayStruct>::reflectAttribute(const RTI::AttributeHandleValuePairSet& theAttributes, int idx) throw (RTI::FederateInternalError) { unsigned char *data = new unsigned char[theAttributes.getValueLength(idx)]; copyData(theAttributes, idx, data, theAttributes.getValueLength(idx)); unsigned int len = fromNet<unsigned short>(data+0); char* string = (char *)(data+2); unsigned int i = 0; while( *string && i<len ) { value.push_back(std::string(string)); while( *string && i<len ) { string++; i++; } string++; i++; } delete [] data; std::cout << "Object IDs"; for( i=0; i<value.size(); i++ ) { std::cout << " " << value[i]; } std::cout << std::endl; }
//----------------------------------------------------------------- // // METHOD: // RTI::AttributeHandleValuePairSet* Country::CreateNVPSet() // // PURPOSE: // Create a name value pair set (aka handle value pair) for // the changed attributes of this country object. // // RETURN VALUES: // RTI::AttributeHandleValuePairSet* containing the // attributes that have changed in the instance of Country. // // HISTORY: // 1) Created 11/6/96 // 2) Updated to RTI 1.3 3/26/98 // //----------------------------------------------------------------- RTI::AttributeHandleValuePairSet* Country::CreateNVPSet() { RTI::AttributeHandleValuePairSet* pCountryAttributes = NULL; // Make sure the RTI Ambassador is set. if ( ms_rtiAmb ) { //------------------------------------------------------ // Set up the data structure required to push this // object's state to the RTI. //------------------------------------------------------ pCountryAttributes = RTI::AttributeSetFactory::create( 2 ); if ( hasNameChanged == RTI::RTI_TRUE ) { // We don't do any encoding here since the name type // is a string. pCountryAttributes->add( this->GetNameRtiId(), (char*) this->GetName(), ((strlen(this->GetName())+1)*sizeof(char)) ); } if ( hasPopulationChanged == RTI::RTI_TRUE ) { // Here we are encoding the double so that it is in a // common format so that federates on other platforms // know how to read it. #if defined(_X86_) || defined(i386) double tmp; *((long*)&tmp) = htonl(*(((long*)&this->GetPopulation()) + 1)); *(((long*)&tmp) + 1) = htonl(*((long*)&this->GetPopulation())); pCountryAttributes->add( this->GetPopulationRtiId(), (char*)&tmp, sizeof(double) ); #elif defined(__alpha) double x; double pop = this->GetPopulation(); cvt_ftof(&pop, CVT_BIG_ENDIAN_IEEE_T, &x, CVT_IEEE_T, 0); pCountryAttributes->add( this->GetPopulationRtiId(), (char*)&x, sizeof(double)); #else pCountryAttributes->add( this->GetPopulationRtiId(), (char*) &this->GetPopulation(), sizeof(double) ); #endif } } // pCountryAttributes is allocated on the heap and must be // deallocated by the federate. return pCountryAttributes; }
//----------------------------------------------------------------- // // METHOD: // void Country::Update( const AttributeHandleValuePairSet& theAttributes ) // // PURPOSE: // Update the new attribute values. If this is being called // then this object is either a remote object that was // discovered or it has some attributes that are owned by // another federate. // // Note: This version does not implement any ownership // transfer - the above was a generic statement. // // RETURN VALUES: // None. // // HISTORY: // 1) Created 11/6/96 // 2) Updated to RTI 1.3 3/26/98 // //----------------------------------------------------------------- void Country::Update( const RTI::AttributeHandleValuePairSet& theAttributes ) { RTI::AttributeHandle attrHandle; RTI::ULong valueLength; // We need to iterate through the AttributeHandleValuePairSet // to extract each AttributeHandleValuePair. Based on the type // specified ( the value returned by getHandle() ) we need to // extract the data from the buffer that is returned by // getValue(). for ( unsigned int i = 0; i < theAttributes.size(); i++ ) { attrHandle = theAttributes.getHandle( i ); if ( attrHandle == Country::GetPopulationRtiId() ) { // When we run this over multiple platforms we will have // a problem with different endian-ness of platforms. Either // we need to encode the data using something like XDR or // provide another mechanism. double population; theAttributes.getValue( i, (char*)&population, valueLength ); #if defined(_X86_) || defined(i386) long x = ntohl(*(long*)&population); *(long*)&population = ntohl(* (((long*)&population) + 1)); *(((long*)&population)+1) = x; #elif defined(__alpha) double x; cvt_ftof(&population, CVT_IEEE_T, &x, CVT_BIG_ENDIAN_IEEE_T, 0); population = x; #endif // __alpha SetPopulation( (double)population ); } else if ( attrHandle == Country::GetNameRtiId() ) { // Same as above goes here... char name[ 1024 ]; theAttributes.getValue( i, (char*)name, valueLength ); SetName( (const char*)name ); } } }
/////////////////////////////////////////////// // TEST: testReflectROWithUnownedAttribute() // /////////////////////////////////////////////// void ReflectAttributesTest::testReflectROWithUnownedAttribute() { RTI::AttributeHandleValuePairSet *set = defaultFederate->createAHVPS( 1 ); set->add( aaHandle, "aa", 3 ); try { listenerFederate->rtiamb->updateAttributeValues( theObject, *set, "NA" ); delete set; failTestMissingException( "AttributeNotOwned", "updating attributes not owned" ); } catch( RTI::AttributeNotOwned& ano ) { // success delete set; } catch( RTI::Exception& e ) { delete set; failTestWrongException( "AttributeNotOwned", e, "updating attributes not owned" ); } }
RTI::AttributeHandleValuePairSet* CFellow::CreateNVPSet() { RTI::AttributeHandleValuePairSet *pCFellowAttrs = NULL; if (ms_rtiAmb) { pCFellowAttrs = RTI::AttributeSetFactory::create(3); if (m_bNameChanged) { pCFellowAttrs->add(this->GetFellowNameRtiId(), (char*)this->GetFellowName(), ((strlen(this->GetFellowName()) + 1) * sizeof(char))); } if (m_bColorChanged) { RTI::ULong tmp; *((long*)&tmp) = htonl(*(((long*)&this->GetFellowColor()) + 1)); *(((long*)&tmp) + 1) = htonl(*((long*)&this->GetFellowColor())); pCFellowAttrs->add(this->GetFellowColorRtiId(), (char*)&tmp, sizeof(RTI::ULong)); } if (m_bPortraitChanged) { RTI::ULong tmp; *((long*)&tmp) = htonl(*(((long*)&this->GetFellowPortrait()) + 1)); *(((long*)&tmp) + 1) = htonl(*((long*)&this->GetFellowPortrait())); pCFellowAttrs->add(this->GetFellowPortraitRtiId(), (char*)&tmp, sizeof(RTI::ULong)); } } return pCFellowAttrs; }
void CFellow::UpdateFellow(CFellow *pCFellow) { char fellowName[256] = {'\0'}; RTI::ULong fellowColor = 0; RTI::ULong fellowPortrait = 0; RTI::AttributeHandleValuePairSet *theAttrs = NULL; try { theAttrs = RTI::AttributeSetFactory::create(3); if (pCFellow->GetFellowNameUpdate()) { strcpy(fellowName, pCFellow->GetFellowName()); theAttrs->add(pCFellow->GetFellowNameRtiId(), (char*)fellowName, sizeof(fellowName)); pCFellow->SetFellowNameUpdate(RTI::RTI_FALSE); } if (pCFellow->GetFellowColorUpdate()) { fellowColor = pCFellow->GetFellowColor(); theAttrs->add(pCFellow->GetFellowColorRtiId(), (char*)&fellowColor, sizeof(fellowColor)); pCFellow->SetFellowColorUpdate(RTI::RTI_FALSE); } if (pCFellow->GetFellowPortraitUpdate()) { fellowPortrait = pCFellow->GetFellowPortrait(); theAttrs->add(pCFellow->GetFellowPortraitRtiId(), (char*)&fellowPortrait, sizeof(fellowPortrait)); pCFellow->SetFellowPortraitUpdate(RTI::RTI_FALSE); } if (theAttrs->size()) { ms_rtiAmb->updateAttributeValues(pCFellow->GetInstanceId(), *theAttrs, "FellowUpdate"); //ms_rtiAmb->tick(0.1, 2.0); } if (theAttrs) { theAttrs->empty(); delete theAttrs; } } catch (RTI::Exception& e) { AfxMessageBox((CString)e._name); } }
//----------------------------------------------------------------- // // METHOD: // void Country::Update( RTIfedTime& newTime ) // // PURPOSE: // Update the state of the Country's population based on // the new time value. The deltaTime is calculated based // on the last time the Country object was updated and // the newTime passed in. The deltaTime is multiplied by // the growth rate and current population to determine the // number of births in the deltaTime. The population is // increased by the number of births. // // RETURN VALUES: // None. // // HISTORY: // 1) Created 11/6/96 // 2) Updated to RTI 1.3 3/26/98 // //----------------------------------------------------------------- void Country::Update( RTI::FedTime& newTime ) { //------------------------------------------------------ // we have advanced in time so calculate my next state. //------------------------------------------------------ RTI::FedTime *pTime = RTI::FedTimeFactory::makeZero(); (*pTime) = newTime; (*pTime) -= this->GetLastTime(); // Set last time to new time this->SetLastTime( newTime ); if ( !(pTime->isZero())) { SetPopulation( GetPopulation() + (GetPopulation()*ms_growthRate) ); } if ( ms_rtiAmb ) { //------------------------------------------------------ // Update state of country //------------------------------------------------------ try { //------------------------------------------------------ // In order to send the values of our attributes, we must // construct an AttributeHandleValuePairSet (AHVPS) which // is a set comprised of attribute handles, values, and // the size of the values. CreateNVPSet() is a method // defined on the Country class - it is not part of the RTI. // Look inside the method to see how to construct an AHVPS //------------------------------------------------------ RTI::AttributeHandleValuePairSet* pNvpSet = this->CreateNVPSet(); //------------------------------------------------------ // Send the AHVPS to the federation. // // this call returns an event retraction handle but we // don't support event retraction so no need to store it. //------------------------------------------------------ (void) ms_rtiAmb->updateAttributeValues( this->GetInstanceId(), *pNvpSet, this->GetLastTimePlusLookahead(), NULL ); // Must free the memory pNvpSet->empty(); delete pNvpSet; } catch ( RTI::Exception& e ) { cerr << "FED_HW: Error:" << e << endl; } // Periodically send an interaction to tell everyone Hello static int periodicMessage = 0; if ( (periodicMessage++%100) == 0 ) { RTI::ParameterHandleValuePairSet* pParams = NULL; //------------------------------------------------------ // Periodically stimulate an update of the "Name" // attribute for the benefit of late-arriving federates. // It would be more correct to use // "requestClassAttributeValueUpdate" and // "provideAttributeValueUpdate", but let's keep things // simple. //------------------------------------------------------ hasNameChanged = RTI::RTI_TRUE; //------------------------------------------------------ // Set up the data structure required to push this // objects's state to the RTI. The // ParameterHandleValuePairSet is similar to the AHVPS // except it contains ParameterHandles instead of // AttributeHandles. //------------------------------------------------------ pParams = RTI::ParameterSetFactory::create( 1 ); char *pMessage = "Hello World!"; pParams->add( this->GetMessageRtiId(), (char*) pMessage, ((strlen(pMessage)+1)*sizeof(char)) ); try { //------------------------------------------------------ // this call returns an event retraction handle but we // don't support event retraction so no need to store it. //------------------------------------------------------ (void) ms_rtiAmb->sendInteraction( GetCommRtiId(), *pParams, this->GetLastTimePlusLookahead(), NULL ); } catch ( RTI::Exception& e ) { cerr << "FED_HW: Error:" << e << endl; } //------------------------------------------------------ // Must free the memory: // ParameterSetFactory::create() allocates memory on // the heap. //------------------------------------------------------ delete pParams; } } delete pTime; }
//------------------------------------------------------------------------------ // reflectAttributeValues() -- (Input support) // Called by our FederateAmbassador to update the attribute values for // this object instance. (Also handles the network to host byte swapping) //------------------------------------------------------------------------------ void Nib::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& theAttrs) { NetIO* netIO = static_cast<NetIO*>(getNetIO()); if (netIO != nullptr && baseEntity != nullptr) { // PhysicalEntity pointer PhysicalEntity* physicalEntity = dynamic_cast<PhysicalEntity*>(baseEntity); RTI::ULong length; char netBuffer[1000]; for (RTI::ULong j = 0; j < theAttrs.size(); j++ ) { // get the attribute's handle and data (network byte order) RTI::AttributeHandle theAttr = theAttrs.getHandle(j); theAttrs.getValue(j, netBuffer, length); // Process the attribute switch ( netIO->findAttributeIndex(theAttr) ) { // Update Federate ID case NetIO::ENTITY_IDENTIFIER_AI : { EntityIdentifierStruct* net = reinterpret_cast<EntityIdentifierStruct*>(&netBuffer); base::NetHandler::fromNetOrder(&baseEntity->entityIdentifier.federateIdentifier.applicationID, net->federateIdentifier.applicationID ); base::NetHandler::fromNetOrder(&baseEntity->entityIdentifier.federateIdentifier.siteID, net->federateIdentifier.siteID ); base::NetHandler::fromNetOrder(&baseEntity->entityIdentifier.entityNumber, net->entityNumber ); setAttributeUpdateRequiredFlag(NetIO::ENTITY_IDENTIFIER_AI, true); } break; // Update Entity Type case NetIO::ENTITY_TYPE_AI : { EntityTypeStruct* net = reinterpret_cast<EntityTypeStruct*>(&netBuffer); // All bytes except for country baseEntity->entityType = *net; base::NetHandler::fromNetOrder(&baseEntity->entityType.countryCode, net->countryCode ); setAttributeUpdateRequiredFlag(NetIO::ENTITY_TYPE_AI, true); } break; // Update Spatial case NetIO::SPATIAL_AI : { // NIB's base entity structure pointers SpatialStruct* spatial = &(baseEntity->spatial); SpatialRVStruct* spatialRvw = &(baseEntity->spatialRvw); WorldLocationStruct* worldLocation = &spatialRvw->worldLocation; OrientationStruct* orientation = &spatialRvw->orientation; VelocityVectorStruct* velocityVector = &spatialRvw->velocityVector; AccelerationVectorStruct* accelerationVector = &spatialRvw->accelerationVector; AngularVelocityVectorStruct* angularVelocity = &spatialRvw->angularVelocity; // Net buffer component pointers SpatialStruct* netSpatial = reinterpret_cast<SpatialStruct*>(&netBuffer[0]); WorldLocationStruct* netWorldLocation = nullptr; OrientationStruct* netOrientation = nullptr; VelocityVectorStruct* netVelocityVector = nullptr; AccelerationVectorStruct* netAccelerationVector = nullptr; AngularVelocityVectorStruct* netAngularVelocity = nullptr; // Dead reckoning spatial->deadReckoningAlgorithm = netSpatial->deadReckoningAlgorithm; // find network components based on dead reckoning algorithm // (and set the isFrozen flag) switch (spatial->deadReckoningAlgorithm) { case DRM_STATIC : { SpatialStaticStruct* netSpatialStatic = reinterpret_cast<SpatialStaticStruct*>(&netBuffer[sizeof(SpatialStruct)]); spatialRvw->isFrozen = netSpatialStatic->isFrozen; netWorldLocation = &netSpatialStatic->worldLocation; netOrientation = &netSpatialStatic->orientation; } break; case DRM_FPW : { SpatialFPStruct* netSpatialFpw = reinterpret_cast<SpatialFPStruct*>(&netBuffer[sizeof(SpatialStruct)]); spatialRvw->isFrozen = netSpatialFpw->isFrozen; netWorldLocation = &netSpatialFpw->worldLocation; netOrientation = &netSpatialFpw->orientation; netVelocityVector = &netSpatialFpw->velocityVector; } break; case DRM_RPW : { SpatialRPStruct* netSpatialRpw = reinterpret_cast<SpatialRPStruct*>(&netBuffer[sizeof(SpatialStruct)]); spatialRvw->isFrozen = netSpatialRpw->isFrozen; netWorldLocation = &netSpatialRpw->worldLocation; netOrientation = &netSpatialRpw->orientation; netVelocityVector = &netSpatialRpw->velocityVector; netAngularVelocity = &netSpatialRpw->angularVelocity; } break; case DRM_RVW : { SpatialRVStruct* netSpatialRvw = reinterpret_cast<SpatialRVStruct*>(&netBuffer[sizeof(SpatialStruct)]); spatialRvw->isFrozen = netSpatialRvw->isFrozen; netWorldLocation = &netSpatialRvw->worldLocation; netOrientation = &netSpatialRvw->orientation; netVelocityVector = &netSpatialRvw->velocityVector; netAccelerationVector = &netSpatialRvw->accelerationVector; netAngularVelocity = &netSpatialRvw->angularVelocity; } break; case DRM_FVW : { SpatialFVStruct* netSpatialFvw = reinterpret_cast<SpatialFVStruct*>(&netBuffer[sizeof(SpatialStruct)]); spatialRvw->isFrozen = netSpatialFvw->isFrozen; netWorldLocation = &netSpatialFvw->worldLocation; netOrientation = &netSpatialFvw->orientation; netVelocityVector = &netSpatialFvw->velocityVector; netAccelerationVector = &netSpatialFvw->accelerationVector; } break; } // end dead rec switch if (netWorldLocation != nullptr) { base::NetHandler::fromNetOrder(&worldLocation->x, netWorldLocation->x); base::NetHandler::fromNetOrder(&worldLocation->y, netWorldLocation->y); base::NetHandler::fromNetOrder(&worldLocation->z, netWorldLocation->z); } else { worldLocation->x = 0; worldLocation->y = 0; worldLocation->z = 0; } if (netOrientation != nullptr) { base::NetHandler::fromNetOrder(&orientation->phi, netOrientation->phi); base::NetHandler::fromNetOrder(&orientation->theta, netOrientation->theta); base::NetHandler::fromNetOrder(&orientation->psi, netOrientation->psi); } else { orientation->phi = 0; orientation->theta = 0; orientation->psi = 0; } if (netVelocityVector != nullptr) { base::NetHandler::fromNetOrder(&velocityVector->xVelocity, netVelocityVector->xVelocity); base::NetHandler::fromNetOrder(&velocityVector->yVelocity, netVelocityVector->yVelocity); base::NetHandler::fromNetOrder(&velocityVector->zVelocity, netVelocityVector->zVelocity); } else { velocityVector->xVelocity = 0; velocityVector->yVelocity = 0; velocityVector->zVelocity = 0; } if (netAccelerationVector != nullptr) { base::NetHandler::fromNetOrder(&accelerationVector->xAcceleration, netAccelerationVector->xAcceleration); base::NetHandler::fromNetOrder(&accelerationVector->yAcceleration, netAccelerationVector->yAcceleration); base::NetHandler::fromNetOrder(&accelerationVector->zAcceleration, netAccelerationVector->zAcceleration); } else { accelerationVector->xAcceleration = 0; accelerationVector->yAcceleration = 0; accelerationVector->zAcceleration = 0; } if (netAngularVelocity != nullptr) { base::NetHandler::fromNetOrder(&angularVelocity->xAngularVelocity, netAngularVelocity->xAngularVelocity); base::NetHandler::fromNetOrder(&angularVelocity->yAngularVelocity, netAngularVelocity->yAngularVelocity); base::NetHandler::fromNetOrder(&angularVelocity->zAngularVelocity, netAngularVelocity->zAngularVelocity); } else { angularVelocity->xAngularVelocity = 0; angularVelocity->yAngularVelocity = 0; angularVelocity->zAngularVelocity = 0; } setAttributeUpdateRequiredFlag(NetIO::SPATIAL_AI, true); } break; case NetIO::FORCE_IDENTIFIER_AI : { unsigned char* net = reinterpret_cast<unsigned char*>(&netBuffer); physicalEntity->forceIdentifier = ForceIdentifierEnum8( *net ); //std::cout << "Recv force: " << physicalEntity->forceIdentifier << std::endl;; setAttributeUpdateRequiredFlag(NetIO::FORCE_IDENTIFIER_AI, true); } break; } // end -- process attribute switch } // end -- for each attribute pair // Update the basic NIB state data with this new data entityState2Nib(); } }