Script demo 2.txtΒΆ

################################################################################
#                           Script Demo 2
#
# This is a script example that demonstrates many of the features
# of the scripting language. It is not a lesson in tactics.
#
# In this scenario we have:
# a) an air platform with a 'perfect' ESM device which gives the precise
#    location of an emitter.
# b) another air platform that is acting as a strike platform.
# c) a ground platform that is an enemy threat radar.
#
# The air platform will detect the threat radar and send a track to the striker
# which will drop bombs on it.  The route is already planned for the striker.
#
################################################################################

event_output
   file output/script_demo_2.evt
   enable all
end_event_output

script_interface
#   debug
end_script_interface

dis_interface
  record output/script_demo_2.rep
  mover_update_timer            5.0 seconds
  entity_position_threshold    10 m  # default is 1 m
  heartbeat_timer              5.0 seconds
end_dis_interface

# tps-1d
antenna_pattern TPS-1D_RADAR_ANTENNA
  constant_pattern
     peak_gain  28 dB
     azimuth_beamwidth  4 deg
     elevation_beamwidth  10 deg
  end_constant_pattern
end_antenna_pattern

sensor TPS-1D_SENSOR WSF_RADAR_SENSOR
  frame_time  10 sec
  location  0.0 0.0 -30 ft
  scan_mode  azimuth
  minimum_range    0 nm
  maximum_range  160 nm
  transmitter
     antenna_pattern TPS-1D_RADAR_ANTENNA
     antenna_tilt  5 deg
     power  500 kw
     pulse_width                 2.0e-6 sec
     pulse_repetition_frequency  400 hz
     frequency  1285 mhz
  end_transmitter
  receiver
     antenna_pattern TPS-1D_RADAR_ANTENNA
     antenna_tilt  5 deg
     bandwidth  1 mhz
     internal_loss  19 dB
  end_receiver
  swerling_case  1
  number_of_pulses_integrated  44
  detector_law  square
  probability_of_false_alarm  1.0e-6
  azimuth_error_sigma  0.5 deg
  elevation_error_sigma  0.0 deg
  range_error_sigma  1.2 nm
  filter WSF_ALPHA_BETA_FILTER
    alpha  0.6
    beta   0.2
  end_filter
  hits_to_establish_track  3 5
  hits_to_maintain_track  1 3
  reports_location
  reports_signal_to_noise
  reports_range
  reports_bearing
end_sensor

#GBU.txt
processor GBU_GUIDANCE_COMPUTER WSF_GUIDANCE_COMPUTER
  proportional_navigation_gain  10.0
  velocity_pursuit_gain         10.0
  g_bias                         1.0
  max_commanded_g              25.0 g
  guidance_delay                0.0 sec
  time_between_GPS_fixes      600.0 sec
  IMU_drift_rate                0.0 m/s
  update_interval               0.5 s
end_processor

processor CONTACT_FUSE WSF_GROUND_TARGET_FUSE
   proximity_cancel_on_loss_of_target
end_processor

aero GBU_1000_LB_AERO WSF_AERO
  reference_area      1.078 ft2 # 14.06 in dia
  cd_zero_subsonic    0.100
  cd_zero_supersonic  0.40
  mach_begin_cd_rise  0.800
  mach_end_cd_rise    1.200
  mach_max_supersonic 2.000
  cl_max             10.400    # unknown
  aspect_ratio        4.000    # unknown
end_aero

aero GBU_1000_LB_PENETRATOR_AERO WSF_AERO
  reference_area      1.078 ft2 # 14.06 in dia
  cd_zero_subsonic    0.100
  cd_zero_supersonic  0.40
  mach_begin_cd_rise  0.800
  mach_end_cd_rise    1.200
  mach_max_supersonic 2.000
  cl_max             10.400    # unknown
  aspect_ratio        4.000    # unknown
end_aero

platform_type GBU_1000_LB WSF_PLATFORM
  icon gbu-15
  mover WSF_GUIDED_MOVER
    aero GBU_1000_LB_AERO
    mass 1015.0 lbm
    update_interval 0.5 s
  end_mover
  processor guidance_computer GBU_GUIDANCE_COMPUTER
  end_processor
  processor detonator CONTACT_FUSE
  end_processor
end_platform_type

platform_type GBU_1000_LB_PENETRATOR WSF_PLATFORM
  icon gbu-15
  mover WSF_GUIDED_MOVER
    aero GBU_1000_LB_PENETRATOR_AERO
    mass 1015.0 lbm
    update_interval 0.5 s
  end_mover
  processor guidance_computer GBU_GUIDANCE_COMPUTER
  end_processor
  processor detonator CONTACT_FUSE
  end_processor
end_platform_type

weapon_effects GBU_1000_LB_EFFECT WSF_SPHERICAL_LETHALITY
  allow_incidental_damage
  minimum_radius   30.0 m
  maximum_radius   35.0 m
  maximum_damage   1.0
  minimum_damage   0.1
  threshold_damage 0.2
  exponent         1.0
end_weapon_effects
#################################################################################
#                           Define the weapon types
#################################################################################
weapon GBU_1000_LB WSF_EXPLICIT_WEAPON
   launched_platform_type GBU_1000_LB
   weapon_effects         GBU_1000_LB_EFFECT
   category               1000_POUNDER
   category               glide_bomb_unit
end_weapon

weapon GBU_1000_LB_PENETRATOR WSF_EXPLICIT_WEAPON
   launched_platform_type GBU_1000_LB_PENETRATOR
   weapon_effects         GBU_1000_LB_EFFECT
   category               1000_POUNDER
   category               penetrator
   category               glide_bomb_unit
end_weapon

processor GBU_1000_LB_LAUNCH_COMPUTER WSF_TASK_PROCESSOR
   script_debug_writes on
   show_state_transitions
   show_task_messages

   script_variables
      string WEAPON_NAME               = "jdam-1000";
      int SALVO_SIZE                   = 1;
      # the following are used internally and should not be modified by the
      # user
      string mShootTaskStr      = "Shoot";
   end_script_variables

    script bool InInterceptEnvelopeOf(WsfWeapon aWeapon)
       bool canIntercept = false;
       double maxRng = 19000;
       double minRng = 300;
       WsfTrackId id = TRACK.TrackId();
       double targetrange = PLATFORM.SlantRangeTo(TRACK);
       writeln("Target range is " , targetrange);
       if ((targetrange > minRng) && (targetrange < maxRng))
       {
         canIntercept = true;
         writeln("Intercept is true");
       }
       return canIntercept;
   end_script

   script bool LaunchWeapon()
      WsfWeapon   weapon;
      weapon = PLATFORM.Weapon(WEAPON_NAME);
      bool canInterceptNow = false;
      if (weapon.QuantityRemaining() >= SALVO_SIZE)
      {
         canInterceptNow = InInterceptEnvelopeOf(weapon);
      }
      bool launched = false;
      if (canInterceptNow)
      {
         launched = FireAt(TRACK, mShootTaskStr, weapon, SALVO_SIZE);
         if (launched)
         {
            writeln_d("*** T=", TIME_NOW, " ", PLATFORM.Name(), " ",
                      TRACK.TargetName(), " R=", PLATFORM.SlantRangeTo(TRACK),
                      " FIRE!!!!");
         }
      }
      return launched;
   end_script


# State Machine
# Very simple single state state machine
   evaluation_interval ENGAGE 2.0 sec
   state ENGAGE  # Engages and fires the weapon if it can
      next_state ENGAGE
         bool launched = false;
         if (InInterceptEnvelopeOf(PLATFORM.Weapon(WEAPON_NAME)))
         {
             writeln_d("Trying to launch weapon " );
             launched = LaunchWeapon();
         }
         return launched;
      end_next_state
   end_state
end_processor

################################################################################
# Define the platform type for notional EW radar site.
platform_type EW_RADAR_SITE WSF_PLATFORM

   sensor ew-radar-1 TPS-1D_SENSOR
      processor track-proc
   end_sensor

   // This processor simply receives the tracks from the sensor and stores them
   // in the master track list
   processor track-proc WSF_TRACK_PROCESSOR
   end_processor

   // This processor runs periodically and simply dumps out the track list.
   processor show-tracks-proc WSF_SCRIPT_PROCESSOR
      update_interval 2 min

      // An example of how to create instance variables.  These can be used
      // in any scripts defined within the current processor.
      script_variables
         int mMyInt = 888;
         double mMyDouble = -123.456;
         WsfPlatform mMyPlatform = PLATFORM;
      end_script_variables

      // This is an example of how to create a script that is available
      // on the current processor.
      script void PrintPlatformName(WsfPlatform aPlatform)
         // Print name using script argument.
         writeln("The platform\'s name is ", aPlatform.Name());

         // Print name using the script variable (declared in script_variables).
         writeln("The platform\'s name is ", mMyPlatform.Name());
      end_script

      // on_initialize is a 'common' script provided by several WSF components
      // (see User's guide for a complete list).  Notice the syntax is different
      // from how regular scripts are declared.
      on_initialize
         writeln("on_initialize");
      end_on_initialize

      // on_update is a 'common' script provided by several WSF components
      // (see User's guide for a complete list).  Notice the syntax is different
      // from how regular scripts are declared..
      on_update
         writeln("on_update");

         // Calls to external script must be externed.
         extern void PrintPlatformName(WsfPlatform);
         PrintPlatformName(PLATFORM);

         writeln("Platform ", PLATFORM.Name(), " is at location LLA ",
                           PLATFORM.Latitude(), ", ",
                           PLATFORM.Longitude(), ", ",
                           PLATFORM.Altitude(),
                           " XYZ ", PLATFORM.X(), ", ", PLATFORM.Y(), ", ", PLATFORM.Z());

         writeln("Print my member variables");
         writeln("--- mMyPlatform name = ", mMyPlatform.Name());
         writeln("--- mMyInt = ", mMyInt);
         writeln("--- mMyDouble = ", mMyDouble);

         WsfLocalTrackList trackList = PLATFORM.MasterTrackList();
         if (trackList.TrackCount() > 0)
         {
            writeln("T=", TIME_NOW, "; Track List for ", PLATFORM.Name());
         }

         foreach (WsfTrack track in trackList)
         {
            WsfTrackId trackId = track.TrackId();
            writeln("Track ", trackId.OwningPlatform(), " <", trackId.TrackNumber(), ">",
                  "; Update Count=", track.UpdateCount(), " Update Time=", track.UpdateTime());
            writeln("  Sensor: ", track.SensorName(), ".", track.SensorType(),
                  " (", track.SensorName(), ".", track.SensorType(), ")");
            if (track.RangeValid())
            {
               writeln("  Range=", track.Range(), " m");
            }
            if (track.BearingValid())
            {
               writeln("  Bearing=", track.Bearing(), " deg");
            }
            if (track.ElevationValid())
            {
               writeln("  Elevation=", track.Elevation(), " deg");
            }
            if (track.TypeValid())
            {
               writeln("  Type=", track.Type());
            }
            if (track.SideValid())
            {
               writeln("  Side=", track.Side());
            }
            if (track.SignalToNoiseValid())
            {
               writeln("  S/N=", track.SignalToNoise(), " absolute");
            }
            if (track.LocationValid())
            {
               writeln("  Location: Lat=", track.Latitude(),
                     " Lon=", track.Longitude(), " Alt=", track.Altitude());
            }
            if (track.FrequencyValid())
            {
               writeln("  Frequency=", track.Frequency(), " hz");
            }
            writeln("  Track Quality=", track.TrackQuality());
         }
      end_on_update
   end_processor

end_platform_type

################################################################################
// Define the platform type for the notional AWACS.

platform_type AWACS WSF_PLATFORM
   mover WSF_AIR_MOVER
   end_mover
   comm rcvr-1 WSF_RADIO_RCVR
      frequency 1200 mhz
   end_comm
   comm xmtr-1 WSF_RADIO_XMTR
      frequency 1200 mhz
   end_comm
   // The 'perfect' ESM device.  It can perfectly locate any transmitter in L-band
   sensor esm-1 WSF_ESM_SENSOR
      on
      frame_time 5 sec
      frequency_band 1000 mhz 2000 mhz    // L-band
      reports_location
      reports_frequency
      processor track-proc
      ignore no_awacs_esm
   end_sensor
   processor track-proc WSF_TRACK_PROCESSOR
      update_interval 2 sec
      report_to GOOD_GUYS subordinates via xmtr-1
   end_processor
end_platform_type
################################################################################
# Define the platform type for the notional F-18.
platform_type F-18 WSF_PLATFORM
   // This is used to prevent the AWACS ESM from attempting to detect me.
   // (We aren't interested in these detections and they just confuse the output).
   category no_awacs_esm

   mover WSF_AIR_MOVER
   end_mover

   // The receiver will receive the track updates from the AWACS and
   // internally forward them to the track processor and the attack processor.
   comm rcvr-1 WSF_RADIO_RCVR
      frequency 1200 mhz
      processor track-proc
      processor attack-proc
   end_comm

   comm xmtr-1 WSF_RADIO_XMTR
      frequency 1200 mhz
   end_comm

   // The track processor does nothing more than gather the tracks and maintain
   // them in the track list.
   processor track-proc WSF_TRACK_PROCESSOR
   end_processor

   processor attack-proc WSF_SCRIPT_PROCESSOR
      on_message
         type WSF_TRACK_MESSAGE
            script
               WsfTrackMessage trackMsg = (WsfTrackMessage)MESSAGE;
               WsfTrack        track    = trackMsg.Track();
               WsfTrackId      trackId  = track.TrackId();

               if (TIME_NOW < 50.0)
               {
                  writeln("Received track message from ", trackId.OwningPlatform());
               }

               // If we aren't attacking then start the 'attack'
               WsfProcessor launchComputer = PLATFORM.Processor("jdam-1000-launch-computer");
               if (! launchComputer.IsTurnedOn())
               {
                  writeln("Starting attack at T=", TIME_NOW);
                  launchComputer.TurnOn();
               }
            end_script

         type default
            script
               writeln("Received message of type ", MESSAGE.Type());
            end_script
      end_on_message
   end_processor

   // This is an example single shot processor that runs only once.
   // It dumps out a bunch of information about the platform
   processor show-config-proc WSF_SCRIPT_PROCESSOR
      update_interval 1.0 sec

      script_variables
         int mMyInt = 999;
         double mMyDouble = 123.456;
         WsfPlatform mMyPlatform;
      end_script_variables

      on_update
         mMyPlatform = PLATFORM;

         writeln("Print my member variables");
         writeln("--- mMyPlatform name = ", mMyPlatform.Name());
         writeln("--- mMyInt = ", mMyInt);
         writeln("--- mMyDouble = ", mMyDouble);

         writeln("Information for ", PLATFORM.Name(), ".", PLATFORM.Type());
         int i;
         int j;
         writeln("  Command Chains");
         for (i = 0; i < PLATFORM.CommandChainCount(); i = i + 1)
         {
            WsfCommandChain chain = PLATFORM.CommandChainEntry(i);
            writeln("    ", chain.Name());
            if (chain.Commander().IsValid())
            {
               writeln("      Commander: ", chain.Commander().Name());
            }
            writeln("      Peers");
            foreach (WsfPlatform peer in chain.Peers())
            {
               writeln("          ", peer.Name());
            }
            writeln("      Subordinates");
            foreach (WsfPlatform subordinate in chain.Subordinates())
            {
               writeln("          ", subordinate.Name());
            }
         }
         writeln("  Comm Systems");
         for (i = 0; i < PLATFORM.CommCount(); i = i + 1)
         {
            WsfComm comm = PLATFORM.CommEntry(i);
            writeln("    ", comm.Name(), "; Type=", comm.Type(),
                  " On=", comm.IsTurnedOn());
         }
         writeln("  Sensor Systems");
         for (i = 0; i < PLATFORM.SensorCount(); i = i + 1)
         {
            WsfSensor sensor = PLATFORM.SensorEntry(i);
            writeln("    ", sensor.Name(), "; Type=", sensor.Type(),
                  " On=", sensor.IsTurnedOn());
         }
         writeln("  Weapon Systems");
         for (i = 0; i < PLATFORM.WeaponCount(); i = i + 1)
         {
            WsfWeapon weapon = PLATFORM.WeaponEntry(i);
            writeln("    ", weapon.Name(), "; Type=", weapon.Type(),
                  "; quantity=", weapon.QuantityRemaining());
         }
         writeln("  Processors");
         for (i = 0; i < PLATFORM.ProcessorCount(); i = i + 1)
         {
            WsfProcessor processor = PLATFORM.ProcessorEntry(i);
            writeln("    ", processor.Name(), "; Type=", processor.Type(),
                  " On=", processor.IsTurnedOn(),
                  " UpdateInterval=", processor.UpdateInterval());
         }

         // Disable future calls.
         PROCESSOR.TurnOff();
      end_on_update
   end_processor

   weapon jdam-1000 GBU_1000_LB
   end_weapon

   processor jdam-1000-launch-computer GBU_1000_LB_LAUNCH_COMPUTER
     on
     update_interval 2 sec
   end_processor
end_platform_type

################################################################################
# And now the scenario

platform threat-ew-1 EW_RADAR_SITE
   side red
   position 39:31:42.42n 91:38:35.111w

   sensor ew-radar-1
      on
   end_sensor
end_platform

platform awacs-1 AWACS
   side blue
   command_chain GOOD_GUYS SELF

   sensor esm-1
      on
   end_sensor

   route
      position 39n 90w altitude 30000 ft speed 450 kts
      position 40n 90w
      position 40n 89:30w
      position 39n 89:30w
   end_route
end_platform

platform strike-1 F-18
   side blue
   command_chain GOOD_GUYS awacs-1
   route
#     Take off
      position 38:44:52.3n 90:21:36.4w altitude 6 ft agl speed 20 kts
      position 38:45:07.6n 90:22:09.4w altitude 6 ft agl speed 120 kts # climb_rate 1000 fpm
      position 38:49:00n 90:29:00w altitude 15000 ft speed 400 kts
      position 39:29:00n 91:30:00w altitude 35000 ft
      position 38:45:00n 90:06:08w
      position 38:38:24n 90:07:46w altitude 10000 ft speed 250 kts
#     Landing
      position 38:44:52.3n 90:21:36.4w altitude 6 ft agl speed 120 kts
      position 38:45:07.6n 90:22:09.4w altitude 6 ft agl speed 0 kts
   end_route

   weapon jdam-1000
      quantity 4
      firing_interval 2 sec
   end_weapon
end_platform

end_time 2200 sec