Integrating with STK from Delegates

Overview

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 Moxie excels. Moxie 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
Moxie Installation You must have installed Moxie and have the prerequisites for developing delegates for Moxie.
STK Installation You must have installed 12 .
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 Moxie 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 Moxie installation: \documentation\tutorialFiles\03\UAVMission.vdf.

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

Instructions

Moxie uses the MoxieTime class to represent time in simulations and to handle conversions to standard time formats. Moxie 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. In the initializeStkObject() method, add the following code to delay the UAV flight:
    mStkUav = (IAgAircraft) mStkUavObject;

    //Set the override time for the aircraft ephemeris (position over time) to not start yet.
    IAgVePropagatorStkExternal propagator = (IAgVePropagatorStkExternal) mStkUav.getRoute();
    propagator.setOverride(true);
    propagator.getEphemerisStartEpoch().setExplicitTime(new AgVariant(3600)); //1 hour after scenario start
    propagator.propagate();

    //Set the override time for the aircraft attitude (orientation) over time to not start yet.
    IAgVeAttExternal attitude = ((IAgVeRouteAttitudeStandard) mStkUav.getAttitude()).getExternal();
    attitude.setOverride(true);
    attitude.getAttitudeStartEpoch().setExplicitTime(new AgVariant(3600)); //1 hour after scenario start
    attitude.reload();
  5. In the takeOff() method, add the following code to start the UAV flight:
    StkTimeHelper stkTimeHelper = mStkToolbox.getTimeHelper();
    AgVariant currentTime = stkTimeHelper.moxieTimeToStkAgVariant(mTimeProvider.getCurrentTime());

    //Set the override time for the aircraft ephemeris (position over time) to current time.
    IAgVePropagatorStkExternal propagator = (IAgVePropagatorStkExternal) mStkUav.getRoute();
    propagator.setOverride(true);
    propagator.getEphemerisStartEpoch().setExplicitTime(currentTime);
    propagator.propagate();

    //Set the override time for the aircraft attitude (orientation) over time to current time.
    IAgVeAttExternal attitude = ((IAgVeRouteAttitudeStandard) mStkUav.getAttitude()).getExternal();
    attitude.setOverride(true);
    attitude.getAttitudeStartEpoch().setExplicitTime(currentTime);
    attitude.reload();
  6. Save your work and re-install the delegate module.
  7. Open the UAVMission.mdzip project from the previous section.
  8. Run () the simulation and observe that the UAV in the STK scenario now waits to take off until the startup procedures in the SysML have been completed.
  9. 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 re-install the delegate module.
  9. Run () the simulation again and observe that the SysML now waits for the UAV in the STK scenario to complete its flight and land back at its home base before the simulation ends.

    Because the Moxie 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 >