コード例 #1
0
        private double PredictCollision(Vector myDV)
        {
            Vector myPos     = s.S;
            Vector myV       = s.V;
            Vector targetPos = s.T;
            var    modTv     = Math.Sqrt(Physics.mu / s.TargetOrbitR);
            Vector targetV   = new Vector(targetPos.y, -targetPos.x).Norm() * modTv;

            //векторное произведение [v x pos] должно быть > 0 (подгонка - у нас все время движение против часовой стрелки)
            if (targetV.x * targetPos.y - targetV.y * targetPos.x < 0)
            {
                targetV *= -1;
            }

            //вычисляю полупериод Хофмана - настолько нам нужно заглянуть в будущее
            var    targetT = 2 * Math.PI * s.TargetOrbitR / modTv;
            double tmp     = (s.CurrentOrbitR + s.TargetOrbitR) / (2 * s.TargetOrbitR);
            var    dT      = targetT * Math.Sqrt(tmp * tmp * tmp);

            for (int t = 0; t < dT; t++)
            {
                Vector nextPos, nextV;
                Physics.Forecast(myPos, myV, t == 0 ? myDV : Vector.Zero, out nextPos, out nextV);
                myPos = nextPos;
                myV   = nextV;
                Physics.Forecast(targetPos, targetV, Vector.Zero, out nextPos, out nextV);
                targetPos = nextPos;
                targetV   = nextV;
            }
            var dist = (targetPos - myPos).Len();

            SolverLogger.Log(string.Format("Predicted collision distance: {0:F0}", dist));
            return(dist);
        }
コード例 #2
0
        public bool IsEnd()
        {
            bool end = solver.State != null && solver.State.Score != 0.0;

            if (end)
            {
                SolverLogger.Log("{0} {1}", stepCount, solver.State);
            }
            return(end);
        }
コード例 #3
0
        public override Vector CalculateDV()
        {
//			double desirableV = Math.Sqrt(Physics.mu / s.S.Len());
//			SolverLogger.Log("OrbitV = " + desirableV + " RealV = " + s.V.Len());
//			SolverLogger.Log("R = " + s.S.Len());
            //			var targetOrbit = Physics.CalculateOrbit(s.T, s.TV);
            //			SolverLogger.Log("TARGET ORBIT ANGLE = " + targetOrbit.TransformAngle);
            dvs.MoveNext();
            if (dvs.Current.Len() > 0)
            {
                SolverLogger.Log("IMPULSE " + dvs.Current);
            }
            return(dvs.Current);
        }
コード例 #4
0
        public override Vector CalculateDV()
        {
            SolverLogger.Log("Current : V = " + s.V + "  POS = " + s.S);
            Vector nextV;
            Vector nextPos;

            Physics.Forecast(s.S, s.V, Vector.Zero, out nextPos, out nextV);
            SolverLogger.Log("Forecast: V = " + nextV + "  POS = " + nextPos);
            double r0 = Math.Sqrt(s.Sx * s.Sx + s.Sy * s.Sy);
            double r1 = s.TargetOrbitR;
            double desirableV;

            if (algoState == HohmannAlgoState.ReadyToJump)
            {
                //desirableV = GetDvForFirstJump(r1, r0);
                //algoState = HohmannAlgoState.Jumping;
                //var dv = GetDV(desirableV);

                //avk
                algoState  = HohmannAlgoState.Jumping;
                desirableV = Math.Sqrt(2 * Physics.mu * r1 / (r0 * (r0 + r1)));
                var dv = (1 - desirableV / s.V.Len()) * s.V;

                SolverLogger.Log("IMPULSE 1 " + dv.x + ", " + dv.y + "\r\n");
                return(dv);
            }
            if ((Math.Abs(r0 - r1) < 500) && algoState == HohmannAlgoState.Jumping)
            {
                algoState  = HohmannAlgoState.Finishing;
                desirableV = GetDvForSecondJump(nextPos.Len()) * 0.71;
                var dv = GetDV(desirableV);

                //avk
                //algoState = HohmannAlgoState.Finishing;
                //desirableV = Math.Sqrt(Physics.mu / r0);
                //var desirableVector = new Vector(desirableV * s.Sy / s.S.Len(), -desirableV * s.Sx / s.S.Len());
                //var dv = s.V - desirableVector;

                SolverLogger.Log("IMPULSE 2 " + dv.x + ", " + dv.y + "\r\n");
                return(dv);
            }
            return(new Vector(0, 0));
        }
コード例 #5
0
        private Vector GetDV(double desirableV)
        {
            Vector nextV;
            Vector nextPos;

            Physics.Forecast(s.S, s.V, Vector.Zero, out nextPos, out nextV);
            var nextR           = nextPos.Len();
            var desirableVector = new Vector(desirableV * nextPos.y / nextR, -desirableV * nextPos.x / nextR);

            SolverLogger.Log("DesirableVector: " + desirableVector.x + ", " + desirableVector.y);
            var vector = new Vector(nextV.x - desirableVector.x, nextV.y - desirableVector.y);

            SolverLogger.Log("DV: " + vector.x + ", " + vector.y);
            //return new Vector(0, 0);
            if (s.Fuel < 5 || vector.x * vector.x + vector.y * vector.y < 1)
            {
                return(new Vector(0, 0));
            }
            return(vector);
        }
コード例 #6
0
        public override Vector CalculateDV()
        {
            //проверить, что крутимся в одну сторону


            Vector nextV;
            Vector nextPos;

            Physics.Forecast(s.S, s.V, Vector.Zero, out nextPos, out nextV);

            double r0 = s.CurrentOrbitR;
            double r1 = s.TargetOrbitR;

            if (algoState == HohmannAlgoState.ReadyToJump)
            {
                double tmp        = (r0 + r1) / (2 * r1);
                var    tau        = Math.Sqrt(tmp * tmp * tmp);
                double desiredPhi = r1 > r0 ? Math.PI * (1 - tau) : Math.PI * (tau - 1);

                var thetaS = s.S.PolarAngle;
                if (thetaS < 0)
                {
                    thetaS += 2 * Math.PI;
                }
                var thetaT = s.T.PolarAngle;
                if (thetaT < 0)
                {
                    thetaT += 2 * Math.PI;
                }
                var actualPhi = r1 > r0 ? thetaS - thetaT : thetaT - thetaS;
                if (actualPhi < 0)
                {
                    actualPhi += 2 * Math.PI;
                }

                SolverLogger.Log(string.Format("DesiredPhi: {0}, ActualPhi: {1}, Diff=: {2}", desiredPhi * 180 / Math.PI,
                                               actualPhi * 180 / Math.PI, desiredPhi - actualPhi));

                if (algoState == HohmannAlgoState.ReadyToJump && Math.Abs(desiredPhi - actualPhi) < Eps)
                {
                    SolverLogger.Log(string.Format("My POS: {0}, V: {1}", s.S, s.V));
                    SolverLogger.Log(string.Format("Target POS: {0}", s.T));
                    algoState = HohmannAlgoState.Jumping;
                    double desirableV = Math.Sqrt(2 * Physics.mu * r1 / (r0 * (r0 + r1)));
                    //var dv = GetDV(desirableV);
                    return((1 - desirableV / s.V.Len()) * s.V);
                }
            }

            if (algoState == HohmannAlgoState.Jumping)
            {
                if (((int)s.ST.Len() < 500))
                {
                    algoState = HohmannAlgoState.Finishing;
                    return(GetStabilizingJump(s.V, s.S));
                }
                else
                {
                    SolverLogger.Log("DISTANCE TO = " + s.ST.Len());
                }
            }
            if (algoState == HohmannAlgoState.Finishing)
            {
                double myOrbit   = s.S.Len();
                double myOrbitV  = Math.Sqrt(Physics.mu / myOrbit);
                double myV       = s.V.Len();
                double hisOrbitV = Math.Sqrt(Physics.mu / s.TargetOrbitR);
                SolverLogger.Log(string.Format("Gagarin: {0} Orbit={1} V={2} OrbitV={3}", s.S, myOrbit, myV, myOrbitV));
                SolverLogger.Log(string.Format("Target : {0} Orbit={1} V={2}", s.T, s.TargetOrbitR, hisOrbitV));
                SolverLogger.Log(string.Format("Summary: ErrV = {0} ErrOrbit={1} DistanceToTarget={2}",
                                               s.V.Len() - myOrbitV,
                                               myOrbit - s.TargetOrbitR,
                                               s.ST.Len()
                                               ));
            }

            return(new Vector(0, 0));
        }
コード例 #7
0
        public Vector CalculateDv2()
        {
            //проверить, что крутимся в одну сторону

            Vector nextV;
            Vector nextPos;

            Physics.Forecast(s.S, s.V, Vector.Zero, out nextPos, out nextV);
            var r0 = s.CurrentOrbitR;
            var r1 = s.TargetOrbitR;

            var distance = s.ST.Len();

            if (distance < minDistance_)
            {
                minDistance_ = distance;
                SolverLogger.Log(string.Format("Min DistanceToTarget={0:F0}, CurrentR={1:F0}, TargetR={2:F0}", minDistance_, r0, r1));
            }

            if (algoState == HohmannAlgoState.ReadyToJump)
            {
                double tmp        = (r0 + r1) / (2 * r1);
                var    tau        = Math.Sqrt(tmp * tmp * tmp);
                double desiredPhi = r1 > r0 ? Math.PI * (1 - tau) : Math.PI * (tau - 1);

                var thetaS = s.S.PolarAngle;
                if (thetaS < 0)
                {
                    thetaS += 2 * Math.PI;
                }
                var thetaT = s.T.PolarAngle;
                if (thetaT < 0)
                {
                    thetaT += 2 * Math.PI;
                }
                var actualPhi = r1 > r0 ? thetaS - thetaT : thetaT - thetaS;
                if (actualPhi < 0)
                {
                    actualPhi += 2 * Math.PI;
                }

                bool jump       = false;
                var  difference = desiredPhi - actualPhi;
                if (prevDifference_.HasValue)
                {
                    jump = prevDifference_ * difference < 0;
                }
                prevDifference_ = difference;
                if (jump)
                //if (Math.Abs(desiredPhi - actualPhi) < 0.01)
                {
                    //SolverLogger.Log(string.Format("My POS: {0}, V: {1}", s.S, s.V));
                    //SolverLogger.Log(string.Format("Target POS: {0}", s.T));

                    var desirableV = GetDvForFirstJump(r1, r0);
                    var dv         = GetDV(desirableV);

                    //var desirableV = Math.Sqrt(2 * Physics.mu * r1 / (r0 * (r0 + r1)));
                    //var dv = (1 - desirableV / s.V.Len()) * s.V;

                    if (PredictCollision(dv) < 1000)
                    {
                        SolverLogger.Log("IMPULSE 1 " + dv.x + ", " + dv.y + "\r\n");
                        algoState = HohmannAlgoState.Jumping;
                        return(dv);
                    }
                }
            }

            if (algoState == HohmannAlgoState.Jumping && (Math.Abs(r0 - r1) < 10))
            //if (algoState == HohmannAlgoState.Jumping && distance < 1000)
            {
                //algoState = HohmannAlgoState.Finishing;
                //var desirableV = GetDvForSecondJump(nextPos.Len()) * 0.71;
                //var dv = GetDV(desirableV);

                algoState = HohmannAlgoState.Finishing;
                var desirableV = Math.Sqrt(Physics.mu / r1);
                var dv         = (1 - desirableV / s.V.Len()) * s.V;

                SolverLogger.Log("IMPULSE 2 " + dv.x + ", " + dv.y + "\r\n");
                return(dv);
            }

            return(new Vector(0, 0));
        }
コード例 #8
0
        private IEnumerable <Vector> GetSolutions()
        {
            yield return(Physics.GetStabilizingJump(s.V, s.S));

            yield return(Physics.GetStabilizingJump(s.V, s.S));

            var orbit  = Physics.CalculateOrbit(s.T, s.TV);
            var polar  = Normalize(s.S.PolarAngle);
            var tangle = Normalize(orbit.TransformAngle + Math.PI);


            while (Math.Abs(polar - tangle) > EPS)
            {
                polar  = Normalize(s.S.PolarAngle);
                tangle = Normalize(orbit.TransformAngle + Math.PI);
                SolverLogger.Log("Polar = " + polar);
                SolverLogger.Log("Orbit = " + tangle);
                yield return(new Vector(0, 0));
            }

            var perigeyDistance = orbit.a * (1 - orbit.e);
            var phi             = (s.T.PolarAngle - orbit.TransformAngle);
            var area            = orbit.S(phi);  //phi * s.T.Len2() / 2;
            var waitTime        = area / CalculateH(s.T, s.T - s.TV);
            var tempR           = 13736813.23;

            yield return(Physics.CalculateHohmannJump(s.S, s.V, tempR));

            polar  = Normalize(s.S.PolarAngle);
            tangle = Normalize(orbit.TransformAngle);
            while (Math.Abs(polar - tangle) > EPS)
            {
                polar  = Normalize(s.S.PolarAngle);
                tangle = Normalize(orbit.TransformAngle);
                yield return(Vector.Zero);
            }
            yield return(Physics.CalculateHohmannJump(s.S, s.V, perigeyDistance) * 1.00001);

            polar  = Normalize(s.S.PolarAngle);
            tangle = Normalize(orbit.TransformAngle + Math.PI);

            while (Math.Abs(polar - tangle) > 0.01)
            {
                polar  = Normalize(s.S.PolarAngle);
                tangle = Normalize(orbit.TransformAngle + Math.PI);
//				SolverLogger.Log("Polar = " + polar);
//				SolverLogger.Log("Orbit = " + tangle);
                yield return(new Vector(0, 0));
            }
            SolverLogger.Log("DISTANCE = " + (s.S - s.T).Len());
            var dv = s.V - s.TV;

            SolverLogger.Log("DV = " + dv);
            var d = (s.T.PolarAngle - s.S.PolarAngle);

            SolverLogger.Log("O = " + d);
            var vt = Physics.mu * (1 + orbit.e) / CalculateH(s.T, s.T - s.TV) / 2;

            yield return(dv);           // *0.999939;

            //yield return s.V - Physics.GetTangentVector(s.S, vt);
            var len      = (s.S - s.T).Len();
            int count    = 0;
            int maxCount = 0;

            while (true)
            {
                len = (s.S - s.T).Len();
                if (len < 1000)
                {
                    d = (s.T.PolarAngle - s.S.PolarAngle);
                    SolverLogger.Log("O = " + d);
                    SolverLogger.Log("DISTANCE = " + len + "\tcount = " + count + "\t maxCount = " + maxCount + " o=" + d + " MER = " + s.S.Len() + " hisR=" + s.T.Len());
                    count++;
                }
                else
                {
                    count = 0;
                }
                if (maxCount < count)
                {
                    maxCount = count;
                }
                yield return(Vector.Zero);
            }
        }