示例#1
0
        private double Tasklet(AscentSimulationControl currentBestGuess, double currentBestScore, double perturbationScale, bool print,
                               out AscentSimulationControl control,
                               out LookAheadState lookAheadState,
                               out State state)
        {
            control = new AscentSimulationControl()
            {
                InitialVerticalTime = Math.Max(5, currentBestGuess.InitialVerticalTime + (perturbationScale * _random.NextDouble(1))),
                KickPitchTime       = Math.Max(0, currentBestGuess.KickPitchTime + (perturbationScale * _random.NextDouble(4))),
                KickPitchAngle      = currentBestGuess.KickPitchAngle, //Math.Max(0, currentBestGuess.KickPitchAngle + (perturbationScale * _random.NextDouble(1))),
                StagingAngle        = Math.Max(0, Math.Min(90, currentBestGuess.StagingAngle + (perturbationScale * _random.NextDouble(2)))),
                MaxAcceleration     = Math.Max(0, currentBestGuess.MaxAcceleration + (perturbationScale * _random.NextDouble(0.1))),
                Rocket = currentBestGuess.Rocket
                         //Stage1Duration = currentBestGuess.Stage1Duration, // + (perturbationScale * _random.NextDouble(3)),
                         //Stage2Duration = currentBestGuess.Stage2Duration, // + (perturbationScale * _random.NextDouble(3)),
                         //Stage1InitialAcceleration = currentBestGuess.Stage1InitialAcceleration,
                         //Stage1MaxAcceleration = currentBestGuess.Stage1MaxAcceleration,
                         //Stage2InitialAcceleration = currentBestGuess.Stage2InitialAcceleration,
                         //Stage2MaxAcceleration = currentBestGuess.Stage2MaxAcceleration
                         //InitialTurnDuration = currentBestGuess.InitialTurnDuration + (perturbationScale *  _random.NextDouble(0.2)),
                         //MaxThrust1 = currentBestGuess.MaxThrust1,
                         //MinThrust1 = currentBestGuess.MinThrust1,
                         //MaxThrust2 = currentBestGuess.MaxThrust2,
                         //MinThrust2 = currentBestGuess.MinThrust2,
                         //ThrustCutoff = 1000, // Math.Max(0, currentBestGuess.ThrustCutoff + (perturbationScale * _random.NextDouble(5))),
                         ////ThrustCurve = Math.Max(0, currentBestGuess.ThrustCurve + (perturbationScale * _random.NextDouble(5))),
                         //ThrustDuration1 = Math.Max(0, currentBestGuess.ThrustDuration1 + (perturbationScale * _random.NextDouble(5))),
                         //ThrustDuration2 = Math.Max(0, currentBestGuess.ThrustDuration2 + (perturbationScale * _random.NextDouble(5))),
                         //TurnDelay = currentBestGuess.TurnDelay, //Math.Max(0, currentBestGuess.TurnDelay + (perturbationScale * _random.NextDouble(1))),
                         //TurnDuration = Math.Max(0, currentBestGuess.TurnDuration + (perturbationScale * _random.NextDouble(1))),
            };

            var    simulation    = new AscentSimulation(Goal, control, InitialState, SurfaceVelocity);
            double totalFuelMass = control.Rocket.TotalFuelMass();

            while (!simulation.CurrentState.IsDone)
            {
                //Console.WriteLine("{0} {1}", simulation.CurrentState.ExpendedMass - totalFuelMass, simulation.CurrentState.Time);
                simulation.FastTick(TimeStep, MicroSteps);
                if (simulation.LookAheadState.Apoapsis / 1000.0 > (Goal.Apoapsis + 15) || simulation.LookAheadState.Periapsis / 1000.0 > (Goal.Periapsis + 15))
                {
                    //control.Stage2Duration = Math.Max(0, simulation.CurrentState.Time - control.Stage1Duration);
                    break;
                }
            }
            if (print)
            {
                Print(Goal, simulation.LookAheadState, simulation.CurrentState, control, currentBestScore);
            }
            lookAheadState = simulation.LookAheadState;
            state          = simulation.CurrentState;
            return(ComputeScore(Goal, simulation.LookAheadState, state, control));
        }
示例#2
0
 private static void Print(AscentSimulationGoal goal, LookAheadState lookAheadState, State state, AscentSimulationControl guess, double bestScore)
 {
     Console.WriteLine("{0,1:F} {1,1:F}, {2,2:F}/{3,2:F}: g {4,1:F}, d {5,1:F}, mass left {6,2:F} kg - score {7,3:F}/{8,3:F}",
                       (lookAheadState.Periapsis) / 1000.0,
                       (lookAheadState.Apoapsis) / 1000.0,
                       (state.Position.Length - Constants.EarthRadius) / 1000.0,
                       state.ReachedAltitude / 1000.0,
                       state.LossesToGravity,
                       state.LossesToDrag,
                       guess.Rocket.TotalFuelMass() - state.ExpendedMass,
                       ComputeScore(goal, lookAheadState, state, guess),
                       bestScore
                       );
 }
示例#3
0
        public static double ComputeScore(AscentSimulationGoal goal, LookAheadState lookAheadState, State state, AscentSimulationControl guess)
        {
            const double distanceScaling                 = 10.0;
            double       distanceFromApoapsisGoal        = lookAheadState.Apoapsis / 1000.0 - goal.Apoapsis;
            double       distanceFromPeriapsisGoal       = lookAheadState.Periapsis / 1000.0 - goal.Periapsis;
            double       distanceFromReachedAltitudeGoal = state.ReachedAltitude / 1000.0 - goal.Periapsis;
            double       distanceFromAltitudeGoal        = (state.Position.Length - Constants.EarthRadius) / 1000.0 - goal.Periapsis;

            double totalFuel = guess.Rocket.TotalFuelMass();
            double fuelLeft  = (totalFuel - state.ExpendedMass) / totalFuel;

            return(ErrorFunction(distanceFromApoapsisGoal, distanceScaling)
                   + ErrorFunction(distanceFromPeriapsisGoal, distanceScaling)
                   + ErrorFunction(distanceFromReachedAltitudeGoal, distanceScaling)
                   + ErrorFunction(distanceFromAltitudeGoal, distanceScaling)
                   + fuelLeft * 5);
            //+ ErrorFunction((guess.ThrustDuration1 + guess.ThrustDuration2) - guess.ThrustCutoff, 1);
        }
示例#4
0
        public static void CalculateOrbit(ref LookAheadState lookAheadState, State state)
        {
            var mu = Constants.EarthGravitationalConstant;

            var radiusVector   = state.Position;
            var velocityVector = state.Velocity;

            var h = Vector3d.Cross(
                radiusVector,
                velocityVector
                );

            var r = radiusVector.Length;

            var eccentricityVector = (
                (velocityVector.LengthSquared - mu / r) * radiusVector - Vector3d.Dot(radiusVector, velocityVector) * velocityVector
                ) / mu;

            var eccentricity          = eccentricityVector.Length;
            var specificOrbitalEnergy = velocityVector.LengthSquared / 2 - mu / r;

            var semiMajorAxis = -mu / (2 * specificOrbitalEnergy);
            var semiMinorAxis = semiMajorAxis * Math.Sqrt(1 - eccentricity * eccentricity);

            var apoapsis  = (1 + eccentricity) * semiMajorAxis;
            var periapsis = (1 - eccentricity) * semiMajorAxis;

            var semiLatusRectum = periapsis * (1 + eccentricity);

            var thetaFromPeriapsis = Math.Acos(((semiLatusRectum - r) / (eccentricity * r)) % (Math.PI * 2));

            var actualRotation = Math.Atan2(radiusVector.Y, radiusVector.X) + Math.PI / 2;

            double argumentOfPeriapsis;

            if (h.Z < 0)
            {
                thetaFromPeriapsis  = Math.PI * 2 - thetaFromPeriapsis;
                argumentOfPeriapsis = actualRotation - thetaFromPeriapsis;
                //rotationMatrix = Matrix4d.Mult(rotationMatrix, Matrix4d.RotateY(Math.PI));
            }
            else
            {
                argumentOfPeriapsis = actualRotation - thetaFromPeriapsis;
            }
            var rotationMatrix = Matrix4d.CreateRotationZ(argumentOfPeriapsis);


            int    highAccuracyPoints = lookAheadState.FuturePositions.Length / 2;
            double highAccuracyAngle  = Math.PI / 20;

            if (SampleOrbit(ref lookAheadState.FuturePositions, ref rotationMatrix, semiLatusRectum, eccentricity, thetaFromPeriapsis, highAccuracyAngle, 0, highAccuracyPoints))
            {
                SampleOrbit(ref lookAheadState.FuturePositions, ref rotationMatrix, semiLatusRectum, eccentricity, thetaFromPeriapsis - highAccuracyAngle, Math.PI * 2 - highAccuracyAngle, highAccuracyPoints, lookAheadState.FuturePositions.Length - highAccuracyPoints);
            }
            //double approximatePerimeter = Math.PI * (3 * (semiMajorAxis + semiMinorAxis) - Math.Sqrt((3*semiMajorAxis + semiMinorAxis) * (semiMajorAxis + 3*semiMinorAxis)));

            lookAheadState.Apoapsis            = apoapsis - Constants.EarthRadius;
            lookAheadState.Periapsis           = periapsis - Constants.EarthRadius;
            lookAheadState.Eccentricity        = eccentricity;
            lookAheadState.SemiMajorAxis       = semiMajorAxis;
            lookAheadState.SemiMinorAxis       = semiMinorAxis;
            lookAheadState.SemiLatusRectum     = semiLatusRectum;
            lookAheadState.ArgumentOfPeriapsis = argumentOfPeriapsis;
            lookAheadState.Theta = thetaFromPeriapsis;

            //Title = string.Format("e{0,2:F}, {1,2:F} km {2,2:F} km, r {3,2:F}, v {4,2:F} {5,2:F} {6,2:F} {7,2:F}, a{8,2:F} b{9,2:F}", e, (apoapsis - Constants.EarthRadius)/1000, (periapsis - Constants.EarthRadius) / 1000, (radiusVector.Length - Constants.EarthRadius) /1000, velocityVector.Length / 1000, theta2, actualRotation, offset, (a - Constants.EarthRadius)/1000, (b - Constants.EarthRadius)/1000);

            /*
             *          GL.PushMatrix();
             *          //GL.Rotate(offset / Math.PI * 180, Vector3d.UnitZ);
             *          GL.LineWidth(2f);
             *          GL.Color3(1f, 0f, 0f);
             *          GL.Begin(PrimitiveType.LineLoop);
             *          for (var theta = 0.0; theta < Math.PI * 2.0; theta += 0.01)
             *          {
             *              GL.Vertex3(Math.Sin(theta) * b, Math.Cos(theta) * a + (apoapsis - a), 0);
             *          }
             *          GL.End();
             *          GL.PopMatrix();
             */
        }