Click here to Skip to main content
15,896,348 members
Articles / Programming Languages / C#

Universal Framework for Science and Engineering - Part 6: Determination of Orbits of Artificial Satellites

Rate me:
Please Sign up or sign in to vote.
4.88/5 (28 votes)
8 Jul 2011CPOL19 min read 82.6K   6.6K   82  
An article on framework applications to determine the orbits of artificial satellites
using System;
using System.Collections.Generic;
using System.Text;


using OrdinaryDifferentialEquations;
using RealMatrixProcessor;
using ClassicalAlgebra;

namespace ControlSystems
{
    /// <summary>
    /// Rational transformation function
    /// </summary>
    public class RationalTransformControlSystemFunction : IDifferentialEquationsSystem
    {
        #region Fields

        /// <summary>
        /// Solver of differential equations
        /// </summary>
        private IDifferentialEquationSolver solver;

        /// <summary>
        /// Nominator
        /// </summary>
        protected double[] nom;

        /// <summary>
        /// Denominator
        /// </summary>
        protected double[] denom;

        /// <summary>
        /// State
        /// </summary>
        protected double[] state;

        /// <summary>
        /// Initial state
        /// </summary>
        double[] initialState;

        /// <summary>
        /// Count of variables
        /// </summary>
        int count;

        /// <summary>
        /// The "should stable" sign 
        /// </summary>
        protected bool shouldStable = true;

        /// <summary>
        /// Laplace Transform Letter
        /// </summary>
        static private char laplaceTransformChar = 's';

        protected double action;

        protected double maxderi;

        #endregion

        #region Ctor

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="nom">Nominator</param>
        /// <param name="denom">Denominator</param>
        public RationalTransformControlSystemFunction(double[] nom, double[] denom)
        {
            Set(nom, denom);
        }

        #endregion

        #region IDifferentialEquationsSystem Members

        double[] IDifferentialEquationsSystem.InitialState
        {
            get { return initialState; }
        }

        int IDifferentialEquationsSystem.Count
        {
            get { return count; }
        }

        double[] IDifferentialEquationsSystem.State
        {
            get { return state; }
        }

        void IDifferentialEquationsSystem.Calculate(double time, double[] derivations)
        {
            for (int i = 0; i < count - 1; i++)
            {
                derivations[i] = state[i + 1];
            }
            double a = action;
            for (int i = 0; i < count; i++)
            {
                a -= denom[i] * state[i];
            }
            maxderi = a;
            derivations[count - 1] = a;
        }

        #endregion

        #region Members

        /// <summary>
        /// Solver
        /// </summary>
        public IDifferentialEquationSolver Solver
        {
            set
            {
                solver = value;
                solver.System = this;
            }
        }

        /// <summary>
        /// The "should stable" sign 
        /// </summary>
        public virtual bool ShouldStable
        {
            get
            {
                return shouldStable;
            }
            set
            {
                shouldStable = value;
            }
        }

        /// <summary>
        /// The "is stable" sign
        /// </summary>
        public bool IsStable
        {
            get
            {
                return IsStablePolynom(denom);
            }
        }

        /// <summary>
        /// Steps
        /// </summary>
        /// <param name="timeBegin">Begin time</param>
        /// <param name="timeEnd">End time</param>
        /// <param name="action">Right action</param>
        public void Step(double timeBegin, double timeEnd, double action)
        {
            this.action = action;
            solver.Step(timeBegin, timeEnd);
        }

        /// <summary>
        /// Transformation
        /// </summary>
        /// <param name="timeBegin">Begin time</param>
        /// <param name="timeEnd">End time</param>
        /// <param name="action">Right action</param>
        /// <returns>Transformation result</returns>
        public double Transform(double timeBegin, double timeEnd, double action)
        {
            Step(timeBegin, timeEnd, action);
            return Output;
        }

        /// <summary>
        /// Output
        /// </summary>
        public double Output
        {
            get
            {
                double a = 0;
                for (int i = 0; i < nom.Length & i < state.Length; i++)
                {
                    a += nom[i] * state[i];
                }
                if (nom.Length == denom.Length)
                {
                    a += nom[nom.Length - 1] * maxderi;
                }
                return a;
            }
        }

        /// <summary>
        /// High frequency coefficient
        /// </summary>
        public double HighFrequecyCoefficient
        {
            get
            {
                if (denom.Length > nom.Length)
                {
                    return 0;
                }
                int n = nom.Length - 1;
                return nom[n] / denom[n];
            }
        }


        /// <summary>
        /// Order of nominator
        /// </summary>
        public int NomOrder
        {
            get
            {
                for (int i = 0; i < nom.Length; i++)
                {
                    if (Math.Abs(nom[i]) > 0)
                    {
                        return i;
                    }
                }
                return 0;
            }
        }

        /// <summary>
        /// Norms of denominator roots
        /// </summary>
        public double[] DenomRootNorms
        {
            get
            {
                return ClassicalAlgebraPerformer.GetNorms(denom);
            }
        }

        /// <summary>
        /// Roots of nominatror
        /// </summary>
        public double[] NomRootNorms
        {
            get
            {
                if (nom.Length > 1)
                {
                    return ClassicalAlgebraPerformer.GetNorms(nom);
                }
                return null;
            }
        }


        /// <summary>
        /// Coefficient
        /// </summary>
        public double Coefficient
        {
            get
            {
                return nom[0] / denom[0];
            }
        }


        /// <summary>
        /// Matrix of classical Rauss�Gurvitz stability
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static double[,] GetGurvitzMatrix(double[] p)
        {
            int dim = p.Length;
            int n = dim - 1;
            double[,] a = new double[n, n];
            for (int i = 0; i < n; i++)
            {
                int k = i + 1;
                for (int j = 0; j < n; j++)
                {
                    int l = k - j;
                    l = dim - l;
                    if ((l < 0) | (l >= dim))
                    {
                        a[j, i] = 0;
                    }
                    else
                    {
                        a[j, i] = p[l];
                    }
                }
            }
            return a;
        }


        /// <summary>
        /// Checks stability of polynom
        /// </summary>
        /// <param name="polynom">Polynom</param>
        /// <returns>True if stable and false otherwise</returns>
        public static bool IsStablePolynom(double[] polynom)
        {
            if (polynom.Length == 1)
            {
                return true;
            }
            if (polynom.Length == 2)
            {
                return (polynom[0] * polynom[1]) > 0;
            }
            double[,] a = GetGurvitzMatrix(polynom);
            double det = RealMatrix.Det(a);
            if (det <= 0)
            {
                return false;
            }
            for (int i = 1; i < a.GetLength(0); i++)
            {
                double[,] b = RealMatrix.GetMainMinor(a, i);
                det = RealMatrix.Det(b);
                if (det <= 0)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Character of Laplace transformation
        /// </summary>
        public static char LaplaceTransformChar
        {
            get
            {
                return laplaceTransformChar;
            }
            set
            {
                laplaceTransformChar = value;
            }
        }


 


        /// <summary>
        /// Gets frequency characteristics
        /// </summary>
        /// <param name="frequency">Frequency</param>
        /// <param name="amplitude">Ampliture</param>
        /// <param name="phase">Phase</param>
        public void GetFrequencyCharacteristics(double frequency, out double amplitude, out double phase)
        {
            double nomRe;
            double nomIm;
            GetFrequencyChar(frequency, nom, out nomRe, out nomIm);
            double denomRe;
            double denomIm;
            GetFrequencyChar(frequency, denom, out denomRe, out denomIm);
            amplitude = Math.Sqrt(((nomRe * nomRe + nomIm * nomIm)) / ((denomRe * denomRe) + (denomIm * denomIm)));
            double p1 = Math.Atan2(nomIm, nomRe);
            double p2 = Math.Atan2(-denomIm, denomRe);
            double p = p1 + p2;
            if (p > Math.PI)
            {
                p -= Math.PI;
            }
            if (p < -Math.PI)
            {
                p += Math.PI;
            }
            phase = p;
        }

        /// <summary>
        /// Minimal and maximal frequency
        /// </summary>
        public double[] MinMaxFrequency
        {
            get
            {
                double[] d = AllNorms;
                return new double[] { d[0], d[d.Length - 1] };
            }
        }
        
        /// <summary>
        /// All norms of roots
        /// </summary>
        protected double[] AllNorms
        {
            get
            {
                double[] dn = DenomRootNorms;
                double[] n = NomRootNorms;
                List<double> l = new List<double>(dn);
                if (n != null)
                {
                    l.AddRange(n);
                }
                l.Sort();
                return l.ToArray();
            }
        }

        /// <summary>
        /// Sets transform function parameters
        /// </summary>
        /// <param name="nom">Nominator</param>
        /// <param name="denom">Denominator</param>
        protected void Set(double[] nom, double[] denom)
        {
            if (nom.Length > denom.Length)
            {
                throw new Exception("Illegal transformation");
            }
            this.nom = new double[nom.Length];
            this.denom = new double[denom.Length];
            double a = 1 / denom[denom.Length - 1];
            for (int i = 0; i < nom.Length; i++)
            {
                this.nom[i] = a * nom[i];
            }
            for (int i = 0; i < denom.Length; i++)
            {
                this.denom[i] = a * denom[i];
            }
            count = denom.Length - 1;
            state = new double[count];
            initialState = new double[count];

        }

        /// <summary>
        /// Gets frequency characteristics
        /// </summary>
        /// <param name="frequency">Frequency</param>
        /// <param name="p">Polynom</param>
        /// <param name="re">Real part</param>
        /// <param name="im">Image part</param>
        private static void GetFrequencyChar(double frequency, double[] p, out double re, out double im)
        {
            bool r = true;
            double sing = 1;
            double f = 1;
            re = 0;
            im = 0;
            for (int i = 0; i < p.Length; i++)
            {
                double x = f * p[i] * sing;
                if (r)
                {
                    re += x;
                }
                else
                {
                    im += x;
                    sing = -sing;
                }
                r = !r;
                f *= frequency;
            }
        }


        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Russian Federation Russian Federation
Ph. D. Petr Ivankov worked as scientific researcher at Russian Mission Control Centre since 1978 up to 2000. Now he is engaged by Aviation training simulators http://dinamika-avia.com/ . His additional interests are:

1) Noncommutative geometry

http://front.math.ucdavis.edu/author/P.Ivankov

2) Literary work (Russian only)

http://zhurnal.lib.ru/editors/3/3d_m/

3) Scientific articles
http://arxiv.org/find/all/1/au:+Ivankov_Petr/0/1/0/all/0/1

Comments and Discussions