UCI Example

The following is an example showing how the AFSIM UCI could be used to communicate with Non-AFSIM programs. A platform one AFSIM instance (ship1) will send periodic commands via UCI messages to move the center of an ESM sensor volume to a given azimuth and elevation to point at different targets on a second instance (ship2). These instances will communicate via the dis_interface. This example can be found in wsf_oms_uci/data/esm_demo.

The CAL_ACTIVEMQ_CONFIG environment variable should be set to ./RefCppCalConfiguration.xml. This allows each instance of AFSIM to handle it’s own RefCAL.

../_images/uci_example_scenario.png

Ship1

Reference CAL config file (ship1/RefCppCalConfiguration.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2012 rel. 2 sp1 (x64) (http://www.altova.com)-->
<RefCppCalConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <ActiveMQBroker>tcp://127.0.0.1:61616</ActiveMQBroker>
   <ActiveMQNoEchoMode>1</ActiveMQNoEchoMode>
   <ReaderQueueMax>1000</ReaderQueueMax>
   <ReaderSleepMicroseconds>1000</ReaderSleepMicroseconds>

   <ServiceList>
      <Service Name="ship1" UUID="CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCD">
         <System Label="uci" UUID="AA020000-0000-0000-0000-000000000000"/>
         <Domain ID="10"/>
      </Service>
   </ServiceList>
</RefCppCalConfiguration>

Startup file (ship1/test_scenario_afsim_ship1.txt):

# UCI ESM Test Scenario (non-AFSIM simulation proxy)
# Run this scenario concurrently in Warlock with esm_test_scenario_ship2.txt

include ../test_scenario_non_afsim_proxy.txt

Non-AFSIM Proxy (test_scenario_non_afsim_proxy.txt):

# Platform "sense" is internally moved. ESM UCI messages are received
# for platform "sense" in the other simulation.
# The ESM sensor on platfom sense is run in the other simulation.

include ./test_scenario_common.txt

dis_interface
   application 1

   // Entity type SIMPLE_SENSE maps to SENSE type in uci-enabled app
   entity_type SIMPLE_SENSE 1:2:225:1:12:0:0

   entity_id sense 1
   entity_id target_1 2
   entity_id target_2 3
   entity_id target_3 4

end_dis_interface

uci_interface
   service_name ship1
   service_descriptor SHIP1
end_uci_interface

platform sense SIMPLE_SENSE

   radar_signature FIGHTER_RADAR_SIGNATURE
   position 39:30n 86:31w
   altitude  1000 feet

   edit uci_component computer
      processor esm_command
      debug
   end_uci_component

   add processor esm_command WSF_SCRIPT_PROCESSOR
      internal_link computer
      on_message

         type UCI_ESM_CAPABILITY_MESSAGE // esm capability message
         script
            SuppressMessage();
            writeln_d(TIME_NOW, ": Received UCI esm capability message!!");

            UCI_ESM_CapabilityMessage msg = (UCI_ESM_CapabilityMessage)MESSAGE;

            if (msg.IsValid())
            {
               RequestControl(msg);
            }
            else
            {
               writeln_d("Invalid UCI_ESM_CapabilityMessage");
            }
         end_script

         type UCI_CONTROL_REQUEST_STATUS_MESSAGE // Control request status
         script
            SuppressMessage();
            UCI_ControlRequestStatusMessage msg = (UCI_ControlRequestStatusMessage)MESSAGE;
            if (msg.IsApproved())
            {
               writeln_d("Control request ", msg.UUID(), " has been accepted!");
            }
            else if (msg.IsRejected())
            {
               writeln_d("Control request ", msg.UUID(), " was rejected because ",
                         msg.GetRemarks());
            }
            else if (msg.IsDeleted())
            {
               writeln_d("Control request ", msg.UUID(), " was deleted because ",
                         msg.GetRemarks());
            }
            else if (msg.IsPending())
            {
               writeln_d("Control request ", msg.UUID(), " is pending.");
            }
         end_script

         type UCI_ESM_CAPABILITY_STATUS_MESSAGE
         script
            SuppressMessage();
            UCI_ESM_CapabilityStatusMessage msg = (UCI_ESM_CapabilityStatusMessage)MESSAGE;
            for (int i = 0; i < msg.Size(); i = i + 1)
            {
               string status;
               UCI_CapabilityStatus capStatus = msg.CapabilityStatus(i);
               if (capStatus.IsAvailable())
               {
                  status = "AVAILABLE";
               }
               else if (capStatus.IsDisabled())
               {
                  status = "DISABLED";
               }
               else if (capStatus.IsExpended())
               {
                  status = "EXPENDED";
               }
               else if (capStatus.IsFaulted())
               {
                  status =  "FAULTED";
               }
               else if (capStatus.IsTemporarilyUnavailable())
               {
                  status = "TEMPORARILTY_UNAVAILABLE";
               }
               else if (capStatus.IsUnavailable())
               {
                  status = "UNAVAILABLE";
               }
               else
               {
                  status = "UNKNOWN";
               }

               writeln_d("Capability ", i, " status: ", status);
            }
         end_script

         default
         script
            writeln_d("Received message: ", MESSAGE.Type());
         end_script

      end_on_message

      execute at_interval_of 10 seconds
         if (!capabilities.Empty())
         {
            UpdateDirection();
            SendCommand();
            UpdateMode();
         }
      end_execute

   end_processor

end_platform

platform target_1 TARGET
   side red
   position 39:31n 86:31w altitude 1000 ft
   heading 180 deg
end_platform

platform target_2 TARGET
   side red
   position 39:30n 86:30w altitude 2500 ft
   heading -90 deg

end_platform

platform target_3 TARGET
   side red
   position 39:30n 86:32w altitude 4000 ft
   heading 90 deg
end_platform

realtime

Ship2

Reference CAL config file (ship1/RefCppCalConfiguration.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2012 rel. 2 sp1 (x64) (http://www.altova.com)-->
<RefCppCalConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <ActiveMQBroker>tcp://127.0.0.1:61616</ActiveMQBroker>
   <ActiveMQNoEchoMode>1</ActiveMQNoEchoMode>
   <ReaderQueueMax>1000</ReaderQueueMax>
   <ReaderSleepMicroseconds>1000</ReaderSleepMicroseconds>

   <ServiceList>
      <Service Name="ship2" UUID="CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC">
         <System Label="uci" UUID="AA020000-0000-0000-0000-000000000000"/>
         <Domain ID="10"/>
      </Service>
   </ServiceList>
</RefCppCalConfiguration>

Startup file (ship2/test_scenario_afsim_ship2.txt):

# UCI ESM Test Scenario (AFSIM simulation)
# Run this scenario concurrently in Warlock with esm_test_scenario_non_afsim_proxy.txt
# platform "sense" is externally controlled through DIS (see map_external_entity) in the other simulation,
# whereas the ESM sensor on platfom "sense" is run in this process.

include ../test_scenario_afsim.txt

AFSIM (test_scenario_afsim.txt)

# Platform "sense" is externally controlled through DIS (see map_external_entity) in the other simulation,
# whereas the ESM sensor on platfom "sense" is run in this process.

include ./test_scenario_common.txt

dis_interface
   application 2

   // platform sense is externally controlled
   // Entity type SIMPLE_SENSE maps to SENSE type
   entity_type SENSE 1:2:225:1:12:0:0
   map_external_entity 1:1:1
end_dis_interface

uci_interface
   service_name ship2
   service_descriptor SHIP2
end_uci_interface

platform_availability
   type TARGET availability 0.0
end_platform_availability

realtime

Common

Common (test_scenario_common.txt):

include sensor_definitions.txt
include weapon_definitions.txt

//Uncomment to turn on debug output
//script_debug_writes true

platform_type SIMPLE_SENSE WSF_PLATFORM
   side blue
   icon f-18

   uci_component computer COMPUTER
   end_uci_component

   script_variables
      Set<string> systemIds = {};
      Map<string, UCI_CapabilityId> controlRequests = {};
      Array<UCI_CapabilityId> capabilities = {};
      int currentMode = 0;
      double currentAz = 0;
      double currentEl = 0;
      bool enable = true;
   end_script_variables

   mover WSF_AIR_MOVER
   end_mover

   script void SendSettingsCommand()
      WsfProcessor sp = PLATFORM.Processor("esm_command");
      UCI_CapabilityState state = UCI_CapabilityState.DISABLE();
      if (enable)
      {
         state = UCI_CapabilityState.ENABLE();
      }

      UCI_CapabilityId id = capabilities[currentMode];
      UCI_ESM_SettingsCommandMessage scMsg = UCI_ESM_SettingsCommandMessage.Construct(id,
                                                                                    state);
      sp.SendMessage(scMsg);
   end_script

   script void RequestControl(UCI_ESM_CapabilityMessage aMsg)
      WsfProcessor sp = PLATFORM.Processor("esm_command");
      UCI_SystemId systemId = aMsg.Header().SystemId();
      if (!systemIds.Exists(systemId.UUID()))
      {
         int size = aMsg.Size();
         for(int i = 0; i < size; i += 1)
         {
            UCI_CapabilityId capabilityId = aMsg.Capability(i).CapabilityId();
            string uuid = capabilityId.UUID();
            string description = capabilityId.Descriptor();
            writeln_d(i, " : ", uuid, " : ", description);

            // send a esm control request message
            UCI_Control controlType = UCI_Control.CAPABILITY_PRIMARY();
            UCI_ControlRequest requestType = UCI_ControlRequest.ACQUIRE();
            UCI_ControlRequestMessage crm = UCI_ControlRequestMessage.Construct(controlType,
                                                                              requestType,
                                                                              systemId,
                                                                              capabilityId);

            controlRequests.Set(crm.UUID(), capabilityId);
            sp.SendMessage(crm);
            systemIds.Insert(systemId.UUID());
            capabilities.PushBack(capabilityId);

            //Initialize capabilities to desired state
            int initialMode = currentMode;
            for (int i = 0; i < capabilities.Size(); i += 1)
            {
               currentMode = i;
               SendSettingsCommand();
            }
            currentMode = initialMode;
         }
      }
   end_script

   script void UpdateDirection()
      if (currentAz == 0)
      {
         currentAz = -Math.PI_OVER_2();
         currentEl = 36 * Math.RAD_PER_DEG();
      }
      else if (currentAz == -Math.PI_OVER_2())
      {
         currentAz = Math.PI_OVER_2();
         currentEl = 18 * Math.RAD_PER_DEG();
      }
      else
      {
         currentAz = 0;
         currentEl = 0;
      }

   end_script

   script void SendCommand()
      WsfProcessor sp = PLATFORM.Processor("esm_command");
      UCI_LOS_Reference losRef = UCI_LOS_Reference.INERTIAL();
      UCI_ElevationScanStabilization stabilization = UCI_ElevationScanStabilization.CENTER_ALTITUDE();
      UCI_SubCapabilityDetails details = UCI_SubCapabilityDetails.Construct(losRef,
                                                                           stabilization,
                                                                           currentAz,
                                                                           currentEl);
      UCI_SubCapabilitySelection selection = UCI_SubCapabilitySelection.Construct(details);

      UCI_CapabilityId id = capabilities[currentMode];
      UCI_ESM_CapabilityCommand capCommand = UCI_ESM_CapabilityCommand.Construct(id,
                                                                                 selection);

      UCI_ESM_Command esmCommand = UCI_ESM_Command.Construct(capCommand);
      UCI_ESM_CommandMessage ecm = UCI_ESM_CommandMessage.Construct(esmCommand);

      string status = "enabled";
      if (!enable)
      {
         status = "disabled";
      }
      writeln_d("New command:");
      writeln_d("   Az: ", currentAz);
      writeln_d("   El: ", currentEl);
      writeln_d("   Mode: ", currentMode);
      writeln_d("   Status: ", status);
      sp.SendMessage(ecm);
   end_script

   script void UpdateMode()
      if (currentAz == 0)
      {
         currentMode = MATH.Mod(currentMode + 1, capabilities.Size());
         if (currentMode == 0)
         {
            enable = !enable;
         }
      }
      SendSettingsCommand();
   end_script

end_platform_type

platform_type SENSE WSF_PLATFORM
   side blue
   icon f-18

   uci_component esm_uci_component ESM
      sensor esm
      update_message_interval 5 seconds
      debug
      internal_link computer
   end_uci_component

   uci_component computer COMPUTER
      internal_link esm_uci_component
   end_uci_component

   sensor esm ESM_SENSOR
      on
      processor track_manager
      ignore_same_side
   end_sensor

   uci_component weapons WEAPON
      update_message_interval 5 s
      capability missile
         uuids
            8BEDF810-EC9D-40E4-8F4A-000000000000
            8BEDF810-EC9D-40E4-8F4A-000000000001
         end_uuids
      end_capability
      debug
   end_uci_component

   add weapon missile missile
      quantity 2
   end_weapon

   processor track_manager WSF_TRACK_MANAGER
   end_processor

   mover WSF_AIR_MOVER
   end_mover
end_platform_type

platform_type TARGET EW_RADAR_SITE
end_platform_type

dis_interface
   exercise 1
   site 1
   autostart
   connections
      broadcast 255.255.255.255 port 3000
   end_connections

   entity_type TARGET 1:2:222:1:19:11:0
   emitter_type EW_RADAR 5

end_dis_interface

start_time_now
end_time 1 hour

Sensor Definitions (sensor_definitions.txt):

radar_signature FIGHTER_RADAR_SIGNATURE
   constant 10 m^2
end_radar_signature

antenna_pattern EW_RADAR_ANTENNA
rectangular_pattern
   peak_gain           35 dB
   minimum_gain       -20 dB
   azimuth_beamwidth   10 deg
   elevation_beamwidth 45 deg
end_rectangular_pattern
end_antenna_pattern

# A simple EW radar

sensor EW_RADAR WSF_RADAR_SENSOR

   frame_time                1  sec

   # Specify the location and orientation of the sensor on the platform.
   location                  0.0 0.0 -30 m

   # The sensor sweeps only in azimuth
   scan_mode                 azimuth
   azimuth_scan_limits       -180 deg 180 deg

   # The field of view, minimum_range and maximum_range are not required.
   # They are simply used for quick culling and should be generous.
   # (i.e. the field_of_view limits should be probably be larger than the
   # corresponding slew limit because the beam can probably detect things
   # outside the slew limit).
   elevation_field_of_view  -2.5 deg 42.5 deg

   minimum_range        0 nm
   maximum_range        4 km

   one_m2_detect_range 225 km

   transmitter
      power           750 kw
      frequency       900 mhz
      bandwidth       0.1 mhz
      pulse_width                  10  usec
      pulse_repetition_interval    750 usec // max PRI range of 225 km
      antenna_pattern EW_RADAR_ANTENNA
      antenna_tilt     10 deg
   end_transmitter

   receiver
      antenna_pattern EW_RADAR_ANTENNA
      antenna_tilt     10 deg
      frequency       900 mhz
      bandwidth         1 mhz
   end_receiver

   hits_to_establish_track   3 5   # 3 of last 5 scans to establish track
   hits_to_maintain_track    1 4   # 1 of last 4 scans to maintain  track

   reports_location
   reports_velocity
   reports_signal_to_noise
   reports_range
   reports_bearing
   reports_elevation
end_sensor

# ************************************************************************
#                       ESM Detector

antenna_pattern ESM_ANTENNA
   uniform_pattern
   azimuth_beamwidth 45 deg
   elevation_beamwidth 10 deg
end_antenna_pattern

sensor ESM_SENSOR WSF_ESM_SENSOR

   mode_template
      frame_time              4 sec
      maximum_range           4 km

      receiver
         antenna_pattern      ESM_ANTENNA
         detection_threshold  5 db
         noise_power          -180 dbw
         internal_loss        0 db
      end_receiver

      frequency_band          0.1 ghz  20 ghz

      reports_location
      reports_type
      reports_frequency
      scan_stabilization pitch_and_roll

   end_mode_template

   mode firstMode
      reports_iff
   end_mode

   mode secondMode
      reports_bearing
   end_mode

   slew_mode both

end_sensor

# ************************************************************************
# Define the platform types
# ************************************************************************

platform_type EW_RADAR_SITE WSF_PLATFORM
   icon Ground_Radar

   mover WSF_GROUND_MOVER end_mover

   sensor ew_radar EW_RADAR
      on
      processor track_manager
      ignore_same_side
   end_sensor

   processor track_manager WSF_TRACK_MANAGER
   end_processor
end_platform_type

Weapon Definitions (weapon_definitions.txt):

antenna_pattern MISSILE_RDR_RX_ANTENNA
   uniform_pattern
      peak_gain                20 db
      azimuth_beamwidth       360 degrees
      elevation_beamwidth     180 degrees
   end_uniform_pattern
end_antenna_pattern

antenna_pattern MISSILE_RDR_TX_ANTENNA
   uniform_pattern
      peak_gain                20 db
      azimuth_beamwidth       360 degrees
      elevation_beamwidth     180 degrees
   end_uniform_pattern
end_antenna_pattern

sensor MISSILE_RADAR WSF_RADAR_SENSOR
one_m2_detect_range          25 km

hits_to_establish_track      3 3

frame_time                   1 sec

maximum_request_count        1
search_while_track

scan_mode                    both

maximum_range                25 km

transmitter
   antenna_pattern            MISSILE_RDR_TX_ANTENNA
   power                      1 mw
   frequency                  14.8 ghz
   pulse_repetition_frequency 250 hz
   internal_loss              10 db
end_transmitter

receiver
   antenna_pattern            MISSILE_RDR_RX_ANTENNA
   bandwidth                  1.6 mhz
   detection_threshold        3 db
   noise_power                -160 dbw
   internal_loss              10 db
end_receiver

# for now the filter is required if we're to report velocity
filter WSF_ALPHA_BETA_FILTER
   alpha 0.6
   beta  0.2
end_filter

reports_location
reports_velocity
reports_bearing
reports_type
end_sensor

aero MISSILE_AERO WSF_AERO
   cd_zero_subsonic    0.12
   cd_zero_supersonic  0.35
   mach_begin_cd_rise  0.95
   mach_end_cd_rise     1.3
   mach_max_supersonic  3.3  // max speed of 994 m/sec
   reference_area      0.09 m2
   cl_max               5.0
   aspect_ratio         1.5
end_aero

platform_type MISSILE WSF_PLATFORM
icon SA-10_Missile

sensor missile_radar MISSILE_RADAR
   on
   processor track_processor
   ignore ignored-by-iads-radar
end_sensor

mover WSF_GUIDED_MOVER
   //show_status
   initial_mass        500 kg
   fuel_mass           200 kg
   specific_impulse    300 sec
   thrust            44000 nt
   aero          MISSILE_AERO
end_mover

processor track_processor WSF_TRACK_PROCESSOR
   purge_interval 1 min
end_processor

processor missile_guidance_computer WSF_GUIDANCE_COMPUTER
   proportional_navigation_gain   10.0
   velocity_pursuit_gain          4.0
   g_bias                         1.2
   maximum_commanded_g            40.0 g
   guidance_delay                  4.0 sec
end_processor

processor fuze WSF_AIR_TARGET_FUSE
   time_of_flight_to_arm            10.0 sec     // Don't arm during the boost phase
   coast_time_on_loss_of_target      4.0 sec
end_processor

category ignored-by-bomber-radar
category ignored-by-iads-radar
end_platform_type

weapon_effects MISSILE_WARHEAD WSF_GRADUATED_LETHALITY
use_3d_radius

radius_and_pk  100 m  0.75
radius_and_pk  500 m  0.55
radius_and_pk 5000 m  0
end_weapon_effects

weapon missile WSF_EXPLICIT_WEAPON
   launched_platform_type  MISSILE
   weapon_effects          MISSILE_WARHEAD
   launch_delta_v          50.0 0.0 0.0 m/s

   slew_mode               both

   //elevation_slew_limits   30 deg 80 deg
   elevation_slew_limits   60 deg 89.5 deg
end_weapon