示例#1
0
        private void DisplaySelected_Click(object sender, EventArgs e)
        {
            if (listView1.FocusedItem != null && listView1.FocusedItem.Index != -1)
            {
                if (CommonData.HasManeuvers)
                {
                    IAgStkObject passiveSatObj = CreatorFunctions.GetCreateSatellite("PassiveCheck");
                    IAgSatellite passiveSat    = passiveSatObj as IAgSatellite;
                    passiveSat.VO.OrbitSystems.InertialByWindow.IsVisible = false;
                    passiveSat.VO.OrbitSystems.RemoveAll();
                    passiveSat.VO.OrbitSystems.Add("Satellite/" + CommonData.TargetName + " VVLH System");
                    passiveSat.SetPropagatorType(AgEVePropagatorType.ePropagatorAstrogator);
                    IAgVADriverMCS passiveDriver = passiveSat.Propagator as IAgVADriverMCS;

                    IAgVAMCSInitialState          intState = passiveDriver.MainSequence[0] as IAgVAMCSInitialState;
                    IAgVAMCSPropagate             prop     = passiveDriver.MainSequence[1] as IAgVAMCSPropagate;
                    IAgVAStoppingConditionElement sc1      = prop.StoppingConditions[0];
                    IAgVAStoppingCondition        sc       = sc1.Properties as IAgVAStoppingCondition;
                    sc.Trip = CommonData.RunList[listView1.FocusedItem.Index].PropTime;

                    AgVAElementCartesian element = intState.Element as AgVAElementCartesian;
                    intState.OrbitEpoch = CommonData.RunList[listView1.FocusedItem.Index].ManeuverTime;
                    element.Vx          = CommonData.RunList[listView1.FocusedItem.Index].Vx;
                    element.Vy          = CommonData.RunList[listView1.FocusedItem.Index].Vy;
                    element.Vz          = CommonData.RunList[listView1.FocusedItem.Index].Vz;
                    element.X           = CommonData.RunList[listView1.FocusedItem.Index].X;
                    element.Y           = CommonData.RunList[listView1.FocusedItem.Index].Y;
                    element.Z           = CommonData.RunList[listView1.FocusedItem.Index].Z;

                    passiveDriver.RunMCS();
                }
                else
                {
                    MessageBox.Show("Actor satellite has no maneuvers. Visualization is simply the Actor's current trjectory");
                }
            }
        }
示例#2
0
        //Main Function
        private void Generate_Click(object sender, EventArgs e)
        {
            int check = FieldCheck();

            if (check == 0)
            {
                RemoveProximityGeometry();
                try
                {
                    CommonData.StkRoot.UnitPreferences.SetCurrentUnit("Distance", "km");
                    CommonData.RunList.Clear();
                    CommonData.TargetName = TargetSat.Text;
                    CommonData.ActorName  = ActorSat.Text;
                    //Set user bounds for safety
                    double userMinRange = Double.Parse(SphericalMag.Text) / 1000;
                    double userMinR     = Double.Parse(RMag.Text) / 1000;
                    double userMinI     = Double.Parse(IMag.Text) / 1000;
                    double userMinC     = Double.Parse(CMag.Text) / 1000;

                    IAgScenario  scenario = CommonData.StkRoot.CurrentScenario as IAgScenario;
                    IAgStkObject satObj   = CommonData.StkRoot.GetObjectFromPath("Satellite/" + ActorSat.Text);
                    IAgSatellite sat      = satObj as IAgSatellite;

                    //Get all maneuver end times for actor satellite
                    IAgDataProviderGroup   maneuverDpGroup = satObj.DataProviders["Astrogator Maneuver Ephemeris Block Final"] as IAgDataProviderGroup;
                    IAgDataPrvTimeVar      maneuverDp      = maneuverDpGroup.Group["Cartesian Elems"] as IAgDataPrvTimeVar;
                    IAgDrResult            result          = maneuverDp.Exec(scenario.StartTime, scenario.StopTime, 60);
                    IAgDrDataSetCollection maneuverData    = result.DataSets;



                    //If there is maneuvers, run iterations for each maneuver. If no maneuvers then just pull closest RIC data for entire trajectory
                    if (maneuverData.Count != 0)
                    {
                        CommonData.HasManeuvers = true;

                        //Get maneuver numbers
                        IAgDataPrvInterval summaryDp     = satObj.DataProviders["Maneuver Summary"] as IAgDataPrvInterval;
                        IAgDrResult        summaryResult = summaryDp.Exec(scenario.StartTime, scenario.StopTime);
                        Array maneuverNumbers            = summaryResult.DataSets.GetDataSetByName("Maneuver Number").GetValues();
                        int   maxManeuverNum             = maneuverNumbers.Length;

                        //Get handles to cartesian position and velocity to seed passive safety runs
                        IAgDataProviderGroup cartPos   = satObj.DataProviders["Cartesian Position"] as IAgDataProviderGroup;
                        IAgDataPrvTimeVar    cartPosDP = cartPos.Group["ICRF"] as IAgDataPrvTimeVar;

                        IAgDataProviderGroup cartVel   = satObj.DataProviders["Cartesian Velocity"] as IAgDataProviderGroup;
                        IAgDataPrvTimeVar    cartVelDP = cartVel.Group["ICRF"] as IAgDataPrvTimeVar;

                        //Create passive safety satellite. Set to Astrogator and pull handles to initial state and propagate segments
                        IAgStkObject passiveSatObj = CreatorFunctions.GetCreateSatellite("PassiveCheck");
                        IAgSatellite passiveSat    = passiveSatObj as IAgSatellite;
                        passiveSat.SetPropagatorType(AgEVePropagatorType.ePropagatorAstrogator);
                        IAgVADriverMCS passiveDriver = passiveSat.Propagator as IAgVADriverMCS;

                        IAgVAMCSInitialState          intState = passiveDriver.MainSequence[0] as IAgVAMCSInitialState;
                        IAgVAMCSPropagate             prop     = passiveDriver.MainSequence[1] as IAgVAMCSPropagate;
                        IAgVAStoppingConditionElement sc1      = prop.StoppingConditions[0];
                        IAgVAStoppingCondition        sc       = sc1.Properties as IAgVAStoppingCondition;
                        sc.Trip = PropTime.Text;

                        AgVAElementCartesian element = intState.Element as AgVAElementCartesian;
                        Array    epoch;
                        Array    vx;
                        Array    vy;
                        Array    vz;
                        Array    x;
                        Array    y;
                        Array    z;
                        String   epochCur;
                        DateTime dateCur;
                        //Assign cartesian elements to PassiveCheck satellite from actor maneuver maneuver data. Run each iteration to see if resulting trajectory violates constraints
                        for (int i = 0; i < maxManeuverNum; i++)
                        {
                            //Get maneuver time and offset in time by 0.25 sec to account for boundrary conditions around impulsive maneuvers
                            epoch    = maneuverData[0 + (i * 7)].GetValues();
                            epochCur = epoch.GetValue(0).ToString();
                            dateCur  = DateTime.Parse(epochCur);
                            dateCur  = dateCur.AddMilliseconds(250);
                            //dateCur = DateTime.ParseExact(epochCur, "dd MMM yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture);
                            epochCur = dateCur.ToString("dd MMM yyyy HH:mm:ss.fff");

                            //Get cartesian state vector for given time
                            result = cartPosDP.ExecSingle(epochCur);
                            x      = result.DataSets.GetDataSetByName("x").GetValues();
                            y      = result.DataSets.GetDataSetByName("y").GetValues();
                            z      = result.DataSets.GetDataSetByName("z").GetValues();

                            result = cartVelDP.ExecSingle(epochCur);
                            vx     = result.DataSets.GetDataSetByName("x").GetValues();
                            vy     = result.DataSets.GetDataSetByName("y").GetValues();
                            vz     = result.DataSets.GetDataSetByName("z").GetValues();

                            //Create passive run output to be used in visualization
                            PassiveRun run = new PassiveRun();
                            run.UserMinRange    = Double.Parse(SphericalMag.Text) / 1000;
                            run.UserMinR        = Double.Parse(RMag.Text) / 1000;
                            run.UserMinI        = Double.Parse(IMag.Text) / 1000;
                            run.UserMinC        = Double.Parse(CMag.Text) / 1000;
                            intState.OrbitEpoch = epochCur;
                            element.Vx          = Double.Parse(vx.GetValue(0).ToString());
                            element.Vy          = Double.Parse(vy.GetValue(0).ToString());
                            element.Vz          = Double.Parse(vz.GetValue(0).ToString());
                            element.X           = Double.Parse(x.GetValue(0).ToString());
                            element.Y           = Double.Parse(y.GetValue(0).ToString());
                            element.Z           = Double.Parse(z.GetValue(0).ToString());

                            passiveDriver.RunMCS();

                            run.Vx       = Double.Parse(vx.GetValue(0).ToString());
                            run.Vy       = Double.Parse(vy.GetValue(0).ToString());
                            run.Vz       = Double.Parse(vz.GetValue(0).ToString());
                            run.X        = Double.Parse(x.GetValue(0).ToString());
                            run.Y        = Double.Parse(y.GetValue(0).ToString());
                            run.Z        = Double.Parse(z.GetValue(0).ToString());
                            run.PropTime = Double.Parse(PropTime.Text);

                            //Pull closest point to target for each iteration and save to passive run output
                            IAgDataProvider psatDp = passiveSatObj.DataProviders["RIC Coordinates"] as IAgDataProvider;
                            psatDp.PreData = "Satellite/" + TargetSat.Text;
                            IAgDataPrvTimeVar psatDpTimeVar = psatDp as IAgDataPrvTimeVar;
                            IAgDrResult       psatDp2       = psatDpTimeVar.Exec(scenario.StartTime, scenario.StopTime, Double.Parse(TimeStep.Text));
                            run.Range         = psatDp2.DataSets.GetDataSetByName("Range").GetValues();
                            run.Intrack       = psatDp2.DataSets.GetDataSetByName("In-Track").GetValues();
                            run.Crosstrack    = psatDp2.DataSets.GetDataSetByName("Cross-Track").GetValues();
                            run.Radial        = psatDp2.DataSets.GetDataSetByName("Radial").GetValues();
                            run.MinRange      = MathFunctions.ArrayMin(run.Range);
                            run.MinIntrack    = MathFunctions.ArrayMinAbs(run.Intrack);
                            run.MinCrosstrack = MathFunctions.ArrayMinAbs(run.Crosstrack);
                            run.MinRadial     = MathFunctions.ArrayMinAbs(run.Radial);
                            //run.ManeuverTime = epoch.GetValue(0).ToString();
                            run.ManeuverTime = epochCur;

                            //spherical
                            if (radioButton1.Checked)
                            {
                                run.IsSpherical = true;
                                if (run.MinRange < userMinRange)
                                {
                                    run.Safe = false;
                                }
                                else
                                {
                                    run.Safe = true;
                                }
                            }
                            //independent axis
                            else
                            {
                                run.IsSpherical = false;
                                if (Math.Abs(run.MinIntrack) < userMinI && Math.Abs(run.MinRadial) < userMinR && Math.Abs(run.MinCrosstrack) < userMinC)
                                {
                                    bool tripped = false;
                                    for (int j = 0; j < run.Range.Length; j++)
                                    {
                                        if (Math.Abs(Double.Parse(run.Intrack.GetValue(j).ToString())) < userMinI && Math.Abs(Double.Parse(run.Radial.GetValue(j).ToString())) < userMinR && Math.Abs(Double.Parse(run.Crosstrack.GetValue(j).ToString())) < userMinC)
                                        {
                                            run.Safe = false;
                                            tripped  = true;
                                            break;
                                        }
                                    }
                                    if (!tripped)
                                    {
                                        run.Safe = true;
                                    }
                                }
                                else
                                {
                                    run.Safe = true;
                                }
                            }

                            CommonData.RunList.Add(run);
                        }
                    }
                    else
                    {
                        CommonData.HasManeuvers = false;
                        PassiveRun      run   = new PassiveRun();
                        IAgDataProvider satDp = satObj.DataProviders["RIC Coordinates"] as IAgDataProvider;
                        satDp.PreData = "Satellite/" + TargetSat.Text;
                        IAgDataPrvTimeVar satDpTimeVar = satDp as IAgDataPrvTimeVar;
                        IAgDrResult       satDp2       = satDpTimeVar.Exec(scenario.StartTime, scenario.StopTime, Double.Parse(TimeStep.Text));
                        run.Range         = satDp2.DataSets.GetDataSetByName("Range").GetValues();
                        run.Intrack       = satDp2.DataSets.GetDataSetByName("In-Track").GetValues();
                        run.Crosstrack    = satDp2.DataSets.GetDataSetByName("Cross-Track").GetValues();
                        run.Radial        = satDp2.DataSets.GetDataSetByName("Radial").GetValues();
                        run.MinRange      = MathFunctions.ArrayMin(run.Range);
                        run.MinIntrack    = MathFunctions.ArrayMinAbs(run.Intrack);
                        run.MinCrosstrack = MathFunctions.ArrayMinAbs(run.Crosstrack);
                        run.MinRadial     = MathFunctions.ArrayMinAbs(run.Radial);
                        run.ManeuverTime  = "N/A";

                        //spherical
                        if (radioButton1.Checked)
                        {
                            run.IsSpherical = true;
                            if (run.MinRange < userMinRange)
                            {
                                run.Safe = false;
                            }
                            else
                            {
                                run.Safe = true;
                            }
                        }
                        //independent axis
                        else
                        {
                            run.IsSpherical = false;
                            if (Math.Abs(run.MinIntrack) < userMinI && Math.Abs(run.MinRadial) < userMinR && Math.Abs(run.MinCrosstrack) < userMinC)
                            {
                                bool tripped = false;
                                for (int j = 0; j < run.Range.Length; j++)
                                {
                                    if (Math.Abs(Double.Parse(run.Intrack.GetValue(j).ToString())) < userMinI && Math.Abs(Double.Parse(run.Radial.GetValue(j).ToString())) < userMinR && Math.Abs(Double.Parse(run.Crosstrack.GetValue(j).ToString())) < userMinC)
                                    {
                                        run.Safe = false;
                                        tripped  = true;
                                        break;
                                    }
                                }
                                if (!tripped)
                                {
                                    run.Safe = true;
                                }
                            }
                            else
                            {
                                run.Safe = true;
                            }
                        }

                        CommonData.RunList.Add(run);
                    }
                    CommonData.BeenRun = true;
                }
                catch (Exception)
                {
                    MessageBox.Show("Passive Safety Check Failed");
                }
            }
        }
示例#3
0
        public static PropagationResults PropagateAstrogatorSatellite(AgStkObjectRoot root, AgUiApplication app, InitialState state, TLE tle, Data satData, Uncertainty uncertainty, int runId, int nRuns, string propName)
        {
            PropagationResults propResults = new PropagationResults();

            propResults.RunNumber = runId.ToString().PadLeft(3, '0');
            IAgSatellite sat = root.CurrentScenario.Children.New(AgESTKObjectType.eSatellite, tle.GetSatNumber() + "Astrogator") as IAgSatellite;

            //Set the propagator to Astrogator
            sat.SetPropagatorType(AgEVePropagatorType.ePropagatorAstrogator);
            //get the Driver for the Propagator
            IAgVADriverMCS driver = sat.Propagator as IAgVADriverMCS;

            //Clear all segments from the MCS
            driver.MainSequence.RemoveAll();

            //// Target Sequence ////
            IAgVAMCSTargetSequence ts = driver.MainSequence.Insert(AgEVASegmentType.eVASegmentTypeTargetSequence, "SetupState", "-") as IAgVAMCSTargetSequence;

            ts.Action = AgEVATargetSeqAction.eVATargetSeqActionRunActiveProfiles;

            // add the initial state segment in the target sequence
            IAgVAMCSInitialState initState = ts.Segments.Insert(AgEVASegmentType.eVASegmentTypeInitialState, "InitialState", "-") as IAgVAMCSInitialState;

            initState.OrbitEpoch = ((IAgScenario)root.CurrentScenario).StartTime;
            // define elements
            initState.SetElementType(AgEVAElementType.eVAElementTypeCartesian);
            IAgVAElementCartesian cart = initState.Element as IAgVAElementCartesian;

            cart.X  = Convert.ToDouble(state.CartesianPosX);
            cart.Y  = Convert.ToDouble(state.CartesianPosY);
            cart.Z  = Convert.ToDouble(state.CartesianPosZ);
            cart.Vx = Convert.ToDouble(state.CartesianVelX);
            cart.Vy = Convert.ToDouble(state.CartesianVelY);
            cart.Vz = Convert.ToDouble(state.CartesianVelZ);

            // spacecraft parameters
            IAgVASpacecraftParameters spacecraftParameters = (IAgVASpacecraftParameters)initState.SpacecraftParameters;

            spacecraftParameters.DryMass  = satData.Mass;
            spacecraftParameters.Cd       = satData.Cd;
            spacecraftParameters.DragArea = satData.DragArea;
            spacecraftParameters.Cr       = satData.Cr;
            spacecraftParameters.SolarRadiationPressureArea = satData.SunArea;
            spacecraftParameters.RadiationPressureArea      = 1e-10;
            IAgVAFuelTank fuelTank = (IAgVAFuelTank)initState.FuelTank;

            fuelTank.FuelMass = 0;

            // enable the control parameter for the state variables
            initState.EnableControlParameter(AgEVAControlInitState.eVAControlInitStateCartesianX);
            initState.EnableControlParameter(AgEVAControlInitState.eVAControlInitStateCartesianY);
            initState.EnableControlParameter(AgEVAControlInitState.eVAControlInitStateCartesianZ);
            initState.EnableControlParameter(AgEVAControlInitState.eVAControlInitStateCartesianVx);
            initState.EnableControlParameter(AgEVAControlInitState.eVAControlInitStateCartesianVy);
            initState.EnableControlParameter(AgEVAControlInitState.eVAControlInitStateCartesianVz);

            // add the results
            ((IAgVAMCSSegment)initState).Results.Add("Relative Motion/InTrack");
            IAgVAStateCalcRelMotion intrackRel = ((IAgVAMCSSegment)initState).Results[0] as IAgVAStateCalcRelMotion;

            intrackRel.ReferenceSelection = AgEVACalcObjectReference.eVACalcObjectReferenceSpecified;
            IAgLinkToObject link_1 = intrackRel.Reference as IAgLinkToObject;

            link_1.BindTo("Satellite/" + tle.GetSatNumber().ToString());

            ((IAgVAMCSSegment)initState).Results.Add("Relative Motion/Radial");
            IAgVAStateCalcRelMotion radialRel = ((IAgVAMCSSegment)initState).Results[1] as IAgVAStateCalcRelMotion;

            radialRel.ReferenceSelection = AgEVACalcObjectReference.eVACalcObjectReferenceSpecified;
            IAgLinkToObject link_2 = radialRel.Reference as IAgLinkToObject;

            link_2.BindTo("Satellite/" + tle.GetSatNumber().ToString());

            ((IAgVAMCSSegment)initState).Results.Add("Relative Motion/CrossTrack");
            IAgVAStateCalcRelMotion crosstrackRel = ((IAgVAMCSSegment)initState).Results[2] as IAgVAStateCalcRelMotion;

            crosstrackRel.ReferenceSelection = AgEVACalcObjectReference.eVACalcObjectReferenceSpecified;
            IAgLinkToObject link_3 = crosstrackRel.Reference as IAgLinkToObject;

            link_3.BindTo("Satellite/" + tle.GetSatNumber().ToString());

            ((IAgVAMCSSegment)initState).Results.Add("Relative Motion/InTrackRate");
            IAgVAStateCalcRelMotion intrackrateRel = ((IAgVAMCSSegment)initState).Results[3] as IAgVAStateCalcRelMotion;

            intrackrateRel.ReferenceSelection = AgEVACalcObjectReference.eVACalcObjectReferenceSpecified;
            IAgLinkToObject link_4 = intrackrateRel.Reference as IAgLinkToObject;

            link_4.BindTo("Satellite/" + tle.GetSatNumber().ToString());

            ((IAgVAMCSSegment)initState).Results.Add("Relative Motion/RadialRate");
            IAgVAStateCalcRelMotion radialrateRel = ((IAgVAMCSSegment)initState).Results[4] as IAgVAStateCalcRelMotion;

            radialrateRel.ReferenceSelection = AgEVACalcObjectReference.eVACalcObjectReferenceSpecified;
            IAgLinkToObject link_5 = radialrateRel.Reference as IAgLinkToObject;

            link_5.BindTo("Satellite/" + tle.GetSatNumber().ToString());

            ((IAgVAMCSSegment)initState).Results.Add("Relative Motion/CrossTrackRate");
            IAgVAStateCalcRelMotion crosstrackrateRel = ((IAgVAMCSSegment)initState).Results[5] as IAgVAStateCalcRelMotion;

            crosstrackrateRel.ReferenceSelection = AgEVACalcObjectReference.eVACalcObjectReferenceSpecified;
            IAgLinkToObject link_6 = crosstrackrateRel.Reference as IAgLinkToObject;

            link_6.BindTo("Satellite/" + tle.GetSatNumber().ToString());

            /// differential corrector setup ///
            IAgVAProfileDifferentialCorrector dc = ts.Profiles["Differential Corrector"] as IAgVAProfileDifferentialCorrector;

            // control parameters
            IAgVADCControl xControlParam = dc.ControlParameters.GetControlByPaths("InitialState", "InitialState.Cartesian.X");

            xControlParam.Enable       = true;
            xControlParam.MaxStep      = 1;
            xControlParam.Perturbation = 0.1;
            IAgVADCControl yControlParam = dc.ControlParameters.GetControlByPaths("InitialState", "InitialState.Cartesian.Y");

            yControlParam.Enable       = true;
            yControlParam.MaxStep      = 1;
            yControlParam.Perturbation = 0.1;
            IAgVADCControl zControlParam = dc.ControlParameters.GetControlByPaths("InitialState", "InitialState.Cartesian.Z");

            zControlParam.Enable       = true;
            zControlParam.MaxStep      = 1;
            zControlParam.Perturbation = 0.1;
            IAgVADCControl vxControlParam = dc.ControlParameters.GetControlByPaths("InitialState", "InitialState.Cartesian.Vx");

            vxControlParam.Enable       = true;
            vxControlParam.MaxStep      = 0.001;
            vxControlParam.Perturbation = 1e-04;
            IAgVADCControl vyControlParam = dc.ControlParameters.GetControlByPaths("InitialState", "InitialState.Cartesian.Vy");

            vyControlParam.Enable       = true;
            vyControlParam.MaxStep      = 0.001;
            vyControlParam.Perturbation = 1e-04;
            IAgVADCControl vzControlParam = dc.ControlParameters.GetControlByPaths("InitialState", "InitialState.Cartesian.Vz");

            vzControlParam.Enable       = true;
            vzControlParam.MaxStep      = 0.001;
            vzControlParam.Perturbation = 1e-04;

            // results
            double[] deviations = uncertainty.GetRandomDeviation();

            IAgVADCResult intrackResult = dc.Results.GetResultByPaths("InitialState", "InTrack");

            intrackResult.Enable       = true;
            intrackResult.DesiredValue = deviations[0];
            intrackResult.Tolerance    = 0.01;
            IAgVADCResult radialResult = dc.Results.GetResultByPaths("InitialState", "Radial");

            radialResult.Enable       = true;
            radialResult.DesiredValue = deviations[1];
            radialResult.Tolerance    = 0.01;
            IAgVADCResult crosstrackResult = dc.Results.GetResultByPaths("InitialState", "CrossTrack");

            crosstrackResult.Enable       = true;
            crosstrackResult.DesiredValue = deviations[2];
            crosstrackResult.Tolerance    = 0.01;
            IAgVADCResult intrackRateResult = dc.Results.GetResultByPaths("InitialState", "InTrackRate");

            intrackRateResult.Enable       = true;
            intrackRateResult.DesiredValue = deviations[3] / 1000;
            intrackRateResult.Tolerance    = 0.001;
            IAgVADCResult radialRateResult = dc.Results.GetResultByPaths("InitialState", "RadialRate");

            radialRateResult.Enable       = true;
            radialRateResult.DesiredValue = deviations[4] / 1000;
            radialRateResult.Tolerance    = 0.001;
            IAgVADCResult crosstrackRateResult = dc.Results.GetResultByPaths("InitialState", "CrossTrackRate");

            crosstrackRateResult.Enable       = true;
            crosstrackRateResult.DesiredValue = deviations[5] / 1000;
            crosstrackRateResult.Tolerance    = 0.001;

            /// Propagator ///
            IAgVAMCSPropagate propagate = driver.MainSequence.Insert(AgEVASegmentType.eVASegmentTypePropagate, "ToGround", "-") as IAgVAMCSPropagate;

            ((IAgVAMCSSegment)propagate).Properties.Color = Color.Red;
            //propagate.PropagatorName = "CustomProp";
            propagate.PropagatorName = propName;

            // add an Epoch stopping condition
            IAgVAStoppingConditionCollection propStoppingConditions = propagate.StoppingConditions as IAgVAStoppingConditionCollection;
            IAgVAStoppingConditionElement    epochElement           = propStoppingConditions.Add("Epoch");
            IAgVAStoppingCondition           epoch = (IAgVAStoppingCondition)epochElement.Properties;

            epoch.Trip = ((IAgScenario)root.CurrentScenario).StopTime;
            // add an Altitude stopping condition
            IAgVAStoppingConditionElement altitudeElement = propStoppingConditions.Add("Altitude");
            IAgVAStoppingCondition        altitude        = (IAgVAStoppingCondition)altitudeElement.Properties;

            altitude.Trip = 0;
            // remove the original stopping condition
            propagate.StoppingConditions.Remove("Duration");

            // run the MCS
            driver.RunMCS();
            driver.ClearDWCGraphics();


            // get the stop time
            IAgDataPrvInterval dp          = ((IAgStkObject)sat).DataProviders.GetDataPrvIntervalFromPath("Astrogator MCS Ephemeris Segments") as IAgDataPrvInterval;
            IAgDrResult        result      = dp.Exec(((IAgScenario)root.CurrentScenario).StartTime, ((IAgScenario)root.CurrentScenario).StopTime);
            string             satStopTime = result.DataSets[3].GetValues().GetValue(1).ToString();

            if (satStopTime.Equals((Convert.ToString(((IAgScenario)root.CurrentScenario).StopTime))))
            {
                // the satellite does not decay (it is propagated until the scenario stop time)
                propResults.IsDecayed = false;
            }
            else
            {
                propResults.IsDecayed   = true;
                propResults.ImpactEpoch = satStopTime;
                // remove the millisecond part
                satStopTime = satStopTime.Split('.')[0];

                //ask for LLA data at stop time
                IAgDataPrvTimeVar dpInfo  = ((IAgStkObject)sat).DataProviders.GetDataPrvInfoFromPath("LLA State//Fixed") as IAgDataPrvTimeVar;
                IAgDrResult       resInfo = dpInfo.ExecSingle(satStopTime);
                string            lat     = resInfo.DataSets[1].GetValues().GetValue(0).ToString();
                string            lon     = resInfo.DataSets[2].GetValues().GetValue(0).ToString();
                string            alt     = resInfo.DataSets[3].GetValues().GetValue(0).ToString();
                propResults.ImpactLat = lat;
                propResults.ImpactLon = lon;
                propResults.ImpactAlt = alt;

                // create a target object
                IAgTarget target = root.CurrentScenario.Children.New(AgESTKObjectType.eTarget, "Target" + (runId).ToString().PadLeft(3, '0')) as IAgTarget;
                target.Graphics.Color        = Color.Red;
                target.Graphics.LabelVisible = false;
                IAgPosition pos = target.Position;
                pos.AssignGeodetic(lat, lon, 0);

                // create and display the time event
                IAgCrdnProvider   provider   = root.CurrentScenario.Children["Target" + (runId).ToString().PadLeft(3, '0')].Vgt;
                IAgCrdnEventEpoch eventEpoch = provider.Events.Factory.CreateEventEpoch(runId.ToString().PadLeft(3, '0') + "_Impact", "Impact Epoch") as IAgCrdnEventEpoch;
                eventEpoch.Epoch = satStopTime;
                try { root.ExecuteCommand("Timeline * TimeComponent Add ContentView \"Scenario Availability\" \"Target/Target" + (runId).ToString().PadLeft(3, '0') + " " + runId.ToString().PadLeft(3, '0') + "_Impact Time Instant\""); }
                catch (Exception) { }
                root.ExecuteCommand("Timeline * Refresh");

                // create a unique ephemeris file for each Astrogator run
                DateTime now = DateTime.Now;
                string   satEphemerisPath = Directory.GetCurrentDirectory() + "\\Ephemeris\\Reentry_run_" + (runId).ToString().PadLeft(3, '0') + ".e";
                root.ExecuteCommand("ExportDataFile */Satellite/" + tle.GetSatNumber() + "Astrogator Ephemeris \"" + satEphemerisPath + "\" Type STK CoordSys ICRF CentralBody Earth InterpBoundaries Include");
                propResults.EphemerisFilePath = satEphemerisPath;
                // unload Astrogator satellite
                root.CurrentScenario.Children[tle.GetSatNumber() + "Astrogator"].Unload();

                if (runId == nRuns)
                {
                    // remove the TLE sat
                    // root.CurrentScenario.Children[tle.GetSatNumber()].Unload();
                }
            }

            try
            {
                AGI.Ui.Core.IAgUiWindowsCollection windows = app.Windows;
                foreach (dynamic window in app.Windows)
                {
                    string windowCaption = (string)window.Caption;
                    if (windowCaption.Contains("Setup"))
                    {
                        window.Close();
                    }
                }
            }
            catch (Exception ex)
            {
            }

            return(propResults);
        }