nasa / TrickHLA

TrickHLA: An IEEE 1516 High Level Architecture (HLA) Simulation Interoperability Standard Implementation for Trick Base Simulations

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ownership Transfer will break Latency Compensation

dandexter opened this issue · comments

Ownership transfer of object attributes can break latency compensation because the data flow between sim-data and lag-comp data will be broken.

This example will illustrate the issue.

  1. Federate-1 is configured to publish and subscribe all attributes of an object names Test.
  2. Federate-1 is configured to create the Test object instance (i.e. owns the privilege to delete).
  3. Federate-1 is configured to do send-side lag-compensation. It is wired to compensate sim-data and the output is the lag-comp data state.
  4. When ownership of the Test attributes are transferred to another federate, Federate-1 will now be receiving Test data reflections.
  5. Because Federate-1 was configured for send-side lag-compensation the receive-side lag-compensation API is not called, resulting in the reflected Test data received on the lag-comp data variables not being transferred to the sim-data. The return data flow is broken.

Need an API to detect the ownership transfer and bypass lag-compensation so that data still goes in or out of the federate.

The ability to bypass lag-compensation should also allow a user to disable lag-compensation at runtime without having to change the simulation or the input file configuration for the object attributes.

The LagCompensation API has been updated to add two functions the user must implement to bypass both send and receive side lag-compensation. This will also allow lag-compensation to be disabled at runtime in the input file without having to change the S_define file.

/*! @brief When lag compensation is disabled, this function is called to
 * bypass the send side lag compensation and your implementation must copy
 * the sim-data to the lag-comp data to effect the bypass. */
virtual void bypass_send_lag_compensation() = 0;

/*! @brief When lag compensation is disabled, this function is called to
 * bypass the receive side lag compensation and your implementation must
 * copy the lag-comp data to the sim-data to effect the bypass. You must
 * make sure to check the lag-comp data was received before copying to
 * the sim-data otherwise you will be copying stale data. */
virtual void bypass_receive_lag_compensation() = 0;

From the SIM_sine/RUN_a_side/input.py file, to disable lag-compensation, set the lag_comp_type to trick.LAG_COMPENSATION_NONE without having to change the lag_comp callback setting.

THLA.manager.objects[0].lag_comp      = A.lag_compensation
THLA.manager.objects[0].lag_comp_type = trick.LAG_COMPENSATION_NONE

From the SineLagCompensation.cpp file showing example bypass functions to ensure data continues to flow even when lag-compensation is bypassed in the event of it being disabled or ownership transfer:

void SineLagCompensation::bypass_send_lag_compensation()
{
   // Bypass send lag compensation by copying the current sim-data to the
   // lag-comp data structure. We need to ensure the lac-comp data structure
   // is updated to ensure any downstream calculations still get data.
   this->set_name( sim_data->get_name() );
   this->set_time( sim_data->get_time() );
   this->set_value( sim_data->get_value() );
   this->set_derivative( sim_data->get_derivative() );
   this->set_phase( sim_data->get_phase() );
   this->set_frequency( sim_data->get_frequency() );
   this->set_amplitude( sim_data->get_amplitude() );
   this->set_tolerance( sim_data->get_tolerance() );
}

void SineLagCompensation::bypass_receive_lag_compensation()
{
   // If the HLA time attribute has changed and is remotely owned (i.e. is
   // coming from another federate) then override our simulation state with the
   // incoming value. If we locally own the attribute then we do not want to
   // override it's value. If we did not do this check then we would be
   // overriding state of something we own and publish with whatever value
   // happen to be in the local variable, which would cause data corruption of
   // the state. We always need to do this check because ownership transfers
   // could happen at any time or the data could be at a different rate.
   // Because of ownership transfers and attributes being sent at different
   // rates we need to check to see if we received data for each attribute.

   // Bypass receive lag compensation by copying lag-comp data to sim-data.
   if ( name_attr->is_received() ) {
      sim_data->set_name( this->get_name() );
   }
   if ( time_attr->is_received() ) {
      sim_data->set_time( this->get_time() );
   }
   if ( value_attr->is_received() ) {
      sim_data->set_value( this->get_value() );
   }
   if ( dvdt_attr->is_received() ) {
      sim_data->set_derivative( this->get_derivative() );
   }
   if ( phase_attr->is_received() ) {
      sim_data->set_phase( this->get_phase() );
   }
   if ( freq_attr->is_received() ) {
      sim_data->set_frequency( this->get_frequency() );
   }
   if ( amp_attr->is_received() ) {
      sim_data->set_amplitude( this->get_amplitude() );
   }
   if ( tol_attr->is_received() ) {
      sim_data->set_tolerance( this->get_tolerance() );
   }
}