Integrating with STK from Delegates

Overview

You will only be able to fully follow along in this tutorial if you acquired Behavior Execution Engine as part of STK Enterprise.

Integrating with external analysis tools like STK involves passing information back and forth to control all of the tools together as a single simulation. Timing information is especially important, and this is where Behavior Execution Engine excels. Behavior Execution Engine manages time continuously instead of requiring external tools to use discrete time steps, and it supports multiple time formats, including ISO8601, Gregorian, Julian, and STK's native representations. In this section, you will use the delegates to set (1) the UAV takeoff time in the STK scenario based on the SysML model, and (2) the flight duration in the SysML based on the route in the scenario.

This section covers the following concepts:

Prerequisites

Prerequisite Description
Behavior Execution Engine Installation You must have installed Behavior Execution Engine and have the prerequisites for developing delegates for Behavior Execution Engine.
STK Installation You must have installed STK 12.9 or later.
Tutorial Project

You must start this section with the UAV Mission simulation project and delegate module project from the previous section. If you did not complete the previous section, you can use the files from the Behavior Execution Engine installation: \documentation\tutorialFiles\03\StkConnection, but you may still need to configure the delegate module for your environment.

You also need the UAV Mission STK scenario from the Behavior Execution Engine installation: \documentation\tutorialFiles\03\UAVMission.vdf.

Recommended Reading Before completing this section, you may want to read the following help topics:

Instructions

Behavior Execution Engine uses the MoxieTime class to represent time in simulations and to handle conversions to standard time formats. Behavior Execution Engine also provides both the TimeProvider dependency to facilitate interacting with the simulation time and the StkTimeHelper class to facilitate conversions to and from STK's AgVariant and EpochSeconds formats.

Sync the UAV takeoff time in STK

You can control STK using either the STK object model or STK Connect commands. In this subsection, you will use the object model through the mStkUavObject field that you previously attached to the UAV object in STK. You will use Connect commands heavily in the next section.

  1. In the UAVDelegate class, add the following import statements:
    import agi.core.AgVariant;
    import agi.stkobjects.IAgAircraft;
    import agi.stkobjects.IAgVeAttExternal;
    import agi.stkobjects.IAgVePropagatorStkExternal;
    import agi.stkobjects.IAgVeRouteAttitudeStandard;
    import com.agi.moxie.stk.utilities.StkTimeHelper;
  2. Add the following private field declarations:
    private TimeProvider mTimeProvider;
    private IAgAircraft mStkUav;
  3. In the constructor, add the following field initialization:
    mTimeProvider = timeProvider;
  4. Create the following private helper method to set the override time for the aircraft ephemeris and attitude:
    private void setEphemerisStartTime(AgVariant time) {
        // Set the override time for the aircraft ephemeris (position over time) to the given time.
        IAgVePropagatorStkExternal propagator = (IAgVePropagatorStkExternal) mStkUav.getRoute();
        propagator.setOverride(true);
        propagator.getEphemerisStartEpoch().setExplicitTime(time);
        propagator.propagate();

        // Set the override time for the aircraft attitude (orientation) over time to the given time.
        IAgVeAttExternal attitude = ((IAgVeRouteAttitudeStandard) mStkUav.getAttitude()).getExternal();
        attitude.setOverride(true);
        attitude.getAttitudeStartEpoch().setExplicitTime(time);
        attitude.reload();
    }
  5. At the end of the initializeStkObject() method, add the following code to delay the UAV flight:
    mStkUav = (IAgAircraft) mStkUavObject;

    //Delay the aircraft ephemeris. takeOff() will reset this when called later.
    AgVariant hourAfterScenarioStart = new AgVariant(3600);
    setEphemerisStartTime(hourAfterScenarioStart);
  6. In the takeOff() method, add the following code to start the UAV flight:
    StkTimeHelper stkTimeHelper = mStkToolbox.getTimeHelper();
    AgVariant currentTime = stkTimeHelper.moxieTimeToStkAgVariant(mTimeProvider.getCurrentTime());
    setEphemerisStartTime(currentTime);
  7. Save your work and reinstall the delegate module.
  8. Open the UAVMission.mdzip project from the previous section.
  9. Execute the simulation. The UAV in the STK scenario now waits to take off until the startup procedures in the SysML have been completed. This shows up in the SysML state history but the startup procedures are represented in the SysML model but aren't visually represented in STK.
  10. Close STK without saving.

Sync the UAV flight duration in the SysML

Since the SysML model drives the simulation, you can use an operation to simply get the information you need, instead of having to set it from the delegates.

  1. In the ComputerDelegate class, add the following import statements:
    import com.agi.moxie.api.MoxieTime;
    import com.agi.moxie.api.SimulationLogger;
    import com.agi.moxie.stk.utilities.ConnectCommandResult;
  2. Add the following private field declarations:
    private TimeProvider mTimeProvider;
    private SimulationLogger mSimulationLogger;
  3. In the constructor, add the following dependency injection and field initializations:
    public ComputerDelegate( ...
            @InjectByName("simulationLogger") SimulationLogger simulationLogger,
             ... ) {
        mTimeProvider = timeProvider;
        mSimulationLogger = simulationLogger;
         ...
    }
  4. In the getFlightDurationFromPlan() method, replace the return null; statement with the following code to get the flight duration from the STK scenario:
    //Get the flight duration from the plan.
    UAVDelegate uav = (UAVDelegate) uavProperty().getValue();
    ConnectCommandResult cmdResult = mStkToolbox.sendConnectCommand(String.format("GetTimePeriod %s", uav.getStkObjectPath()));
    String[] interval = cmdResult.getConnectCommandData().get(0).replace("\"","").split(", ");
    double planStart = Double.parseDouble(interval[0]);
    double planStop = Double.parseDouble(interval[1]);
    double flightDuration = planStop - planStart;

    //Log the flight plan for taking off immediately.
    MoxieTime actualStart = mTimeProvider.getCurrentTime();
    MoxieTime actualStop = actualStart.addSeconds(flightDuration);
    mSimulationLogger.info(String.format("UAV Flight Start: %s", actualStart.toIso8601String(6)));
    mSimulationLogger.info(String.format("UAV Flight Stop: %s", actualStop.toIso8601String(6)));

    return TimeDuration.constant(flightDuration);
  5. In the Computer State Machine diagram, double-click the transition going from ProcessingFlightPlan to FlyingMission.
  6. In the Effect Body and Language, replace the defaultFlightDuration property with the getFlightDurationFromPlan() operation so that the Body and Language reads:
    flightDuration = getFlightDurationFromPlan();
    hasProcessedFlightPlan = true;
    sensorPayload.startSearching();
  7. Click Close.
  8. Save your work and reinstall the delegate module.
  9. Execute the simulation again and look in the state history trace to observe that the SysML now waits for the UAV to complete its flight and land back at its home base before the simulation ends.

    Because Behavior Execution Engine jumps the simulation time forward to each next event, the UAV in the scenario appears to instantly takeoff, fly its entire route, and land. You can replay the STK scenario to watch the UAV, and the takeoff time will be the same as when the simulation was controlling it.

  10. Close STK without saving.

For more information on integrating with STK, see the STK Programming Interface Help.

Next Section >