Click here to Skip to main content
15,881,803 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.4K   6.6K   82  
An article on framework applications to determine the orbits of artificial satellites
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

using CategoryTheory;

using DiagramUI;
using DiagramUI.Interfaces;
using DiagramUI.Labels;

using DataPerformer.Interfaces;
using DataPerformer.Abstract;
using DataPerformer.Helpers;

namespace DataPerformer.Advanced.Accumulators
{
    /// <summary>
    /// Base class for all accumulatotrs
    /// </summary>
    public class AccumulatorBase : AbstractDataTransformer,
        ISerializable, ITimeMeasureProvider, IBlocking, IPostSetArrow
    {
        #region Fields

        /// <summary>
        /// Time measure
        /// </summary>
        protected IMeasure timeMeasure;

        /// <summary>
        /// Time
        /// </summary>
        protected double time;

        /// <summary>
        /// Type of variable
        /// </summary>
        static private readonly Double a = 0;

        /// <summary>
        /// Array of arguments
        /// </summary>
        protected double[] arg;


        /// <summary>
        /// Table of time functions
        /// </summary>
        Dictionary<IMeasure, TimeFunction> functions = new Dictionary<IMeasure, TimeFunction>();

        /// <summary>
        /// Dependent daca consumers
        /// </summary>
        private IList dep;

        /// <summary>
        /// Updatable objects
        /// </summary>
        private List<IUpdatableObject> upd = new List<IUpdatableObject>();

        /// <summary>
        /// Consumers
        /// </summary>
        private List<IDataConsumer> consumers = new List<IDataConsumer>();

        /// <summary>
        /// Dynamical
        /// </summary>
        private List<IDynamical> dyn = new List<IDynamical>();

        private List<IStep> steps = new List<IStep>();

        /// <summary>
        /// Degree of interpolation
        /// </summary>
        private int degree = 1;

        /// <summary>
        /// The "is active" sign
        /// </summary>
        private bool isActive = true;

        /// <summary>
        /// Block
        /// </summary>
        private bool block = false;

        /// <summary>
        /// Processor
        /// </summary>
        private IDifferentialEquationProcessor processor;


        /// <summary>
        /// Step
        /// </summary>
        protected double step;

        /// <summary>
        /// Runtime wrapper
        /// </summary>
        protected RuntimeWrapper rtw;

        /// <summary>
        /// Bloked sign
        /// </summary>
        protected bool blocked = false;



        #endregion

        #region Ctor

        /// <summary>
        /// Default constructor
        /// </summary>
        protected AccumulatorBase()
        {
            rtw = new RuntimeWrapper(this);
            processor = new InternalRungeProcessor(this);
            timeMeasure = new MeasureDerivation(a, new Func<object>(GetTime), new ConstantMeasure(1), "Time");
        }

        /// <summary>
        /// Deserialization constructor
        /// </summary>
        /// <param name="info">Serialization info</param>
        /// <param name="context">Streaming context</param>
        protected AccumulatorBase(SerializationInfo info, StreamingContext context)
            : this()
        {
            try
            {
                Degree = (int)info.GetValue("Degree", typeof(int));
                isActive = (bool)info.GetValue("IsActive", typeof(bool));
            }
            catch (Exception ex)
            {
                ex.Log();
            }
        }


        #endregion

        #region IPostSetArrow Members

        void IPostSetArrow.PostSetArrow()
        {
            Post();
        }

        #endregion

        #region ISerializable Members

        /// <summary>
        /// ISerializable interface implementation
        /// </summary>
        /// <param name="info">Serialization info</param>
        /// <param name="context">Streaming context</param>
        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Degree", degree, typeof(int));
            info.AddValue("IsActive", isActive, typeof(bool));
        }

        #endregion

        #region ITimeMeasureProvider Members

        IMeasure ITimeMeasureProvider.TimeMeasure
        {
            get { return timeMeasure; }
        }

        double ITimeMeasureProvider.Time
        {
            get
            {
                return time;
            }
            set
            {
                time = value;
            }
        }

        double ITimeMeasureProvider.Step
        {
            get
            {
                return step;
            }
            set
            {
                step = value;
            }
        }


        #endregion

        #region IBlocking Members

        bool IBlocking.Blocked
        {
            get
            {
                return blocked;
            }
            set
            {
                blocked = value;
            }
        }

        #endregion

        #region Specific Members

        #region Overriden Members

        /// <summary>
        /// Updates measurements data
        /// </summary>
        public override void UpdateMeasurements()
        {
            Update();
        }

        #endregion

        #region Public


        /// <summary>
        /// Approximation degree
        /// </summary>
        public int Degree
        {
            get
            {
                return degree;
            }
            set
            {
                degree = value;
                SetDegree();
            }
        }

        /// <summary>
        /// The "is active" sign
        /// </summary>
        public bool IsActive
        {
            get
            {
                return isActive;
            }
            set
            {
                isActive = value;
            }
        }


        #endregion

        #region Protected

        /// <summary>
        /// Post operation
        /// This funtion is called afrer editing of propreties
        /// </summary>
        protected virtual void Post()
        {
            //TimeMeasurePerformer.SetProvider(this);
            //measurementsOut.Clear();
            functions.Clear();
            List<IMeasure> measures = new List<IMeasure>();
            for (int i = 0; i < measurements.Count; i++)
            {
                Perform(measurements[i], measures);
            }
            dep = this.GetDependentObjects();
            consumers.Clear();
            upd.Clear();
            dyn.Clear();
            steps.Clear();
            foreach (object o in dep)
            {
                Add(o);
            }
            mea = measures.ToArray();
            Degree = degree;
        }


        #endregion

        #region Private

        private void SetDegree()
        {
            foreach (TimeFunction f in functions.Values)
            {
                f.Degree = degree;
            }
        }

        private object GetTime()
        {
            return time;
        }



        void Add(object o)
        {
            if (o == null)
            {
                return;
            }
            if (o is IDataConsumer)
            {
                IDataConsumer c = o as IDataConsumer;
                if (!consumers.Contains(c))
                {
                    consumers.Add(c);
                }
            }
            if (o is IUpdatableObject)
            {
                IUpdatableObject u = o as IUpdatableObject;
                if (!upd.Contains(u))
                {
                    upd.Add(u);
                }
            }
            if (o is IDynamical)
            {
                IDynamical d = o as IDynamical;
                if (!dyn.Contains(d))
                {
                    dyn.Add(d);
                }
            }
            if (o is IStep)
            {
                IStep s = o as IStep;
                s.Step = 0;
                if (!steps.Contains(s))
                {
                    steps.Add(s);
                }
            }
            if (o is IChildrenObject)
            {
                IChildrenObject ch = o as IChildrenObject;
                IAssociatedObject[] objs = ch.Children;
                foreach (object obj in objs)
                {
                    Add(obj);
                }
            }
            if (o is MeasurementsWrapper)
            {
                MeasurementsWrapper mw = o as MeasurementsWrapper;
                int n = mw.Count;
                for (int i = 0; i < n; i++)
                {
                    Add(mw[i]);
                }
            }
        }

        private void Perform(IMeasurements m, List<IMeasure> measures)
        {
            string s = "";
            if (m is IAssociatedObject)
            {
                IAssociatedObject ao = m as IAssociatedObject;
                s = this.GetRelativeName(ao);
                s = s.Replace("/", "_");
            }
            for (int i = 0; i < m.Count; i++)
            {
                Perform(m[i], s, measures);
            }
        }

        private void Perform(IMeasure m, string str, List<IMeasure> measures)
        {
            string s = str + "_" + m.Name;
            TimeFunction func = new TimeFunction(arg.Length, m.Type);
            functions[m] = func;
            IMeasure mea = new Measure(func, FuncMeasure.createParameter(func), s);
            measures.Add(mea);
        }

        private void Update()
        {
            if (blocked)
            {
                return;
            }
            this.ForEach<IStack>(delegate(IStack s)
            {
                s.Push();
            });

            ITimeMeasureProvider old = processor.TimeProvider;
            processor.TimeProvider = this;
            if (!IsActive)
            {
                return;
            }
            if (block)
            {
                //return;
            }
            block = true;
            using (TimeProviderBackup tb = new TimeProviderBackup(this, this, processor, 0))
            {
                IDataConsumer th = this;
                double last;
                if (arg == null)
                {
                    return;
                }
                if (IsUpdated)
                {
                    return;
                }
                double st = arg[0];
                last = st;
                foreach (IStep s in steps)
                {
                    s.Step = -1;
                }
                //IDifferentialEquationProcessor processor = DifferentialEquationProcessor.Processor;
                if (processor != null)
                {
                    INamedComponent nc = Object as INamedComponent;
                    rtw.Runtime.StartAll(arg[0]);
                    // processor.Set(this.GetDesktop());
                }
                for (int i = 0; i < arg.Length; i++)
                {
                    if (i == 0)
                    {
                        start(arg[0]);
                    }
                    foreach (IUpdatableObject u in upd)
                    {
                        u.UpdateObject();
                    }
                    time = arg[i];
                    if (i > 0 & processor != null)
                    {
                        processor.Step(last, time);
                    }
                    foreach (IDynamical d in dyn)
                    {
                        d.Time = time;
                    }
                    foreach (IStep s in steps)
                    {
                        s.Step = i;
                    }
                    th.UpdateChildrenData();
                    foreach (IMeasure m in functions.Keys)
                    {
                        object o = m.Parameter();
                        TimeFunction f = functions[m];
                        f.Set(i, time, o);
                    }
                    this.FullReset();
                    last = time;
                }
            }
            this.ForEach<IStack>((IStack s) =>
            {
                s.Pop();
            });
            processor.TimeProvider = old;
            block = false;
        }

        private int Step
        {
            set
            {
                foreach (object o in dep)
                {
                    if (o is IStep)
                    {
                        IStep s = o as IStep;
                        s.Step = value;
                    }
                }

            }
        }

        private void start(double time)
        {
            foreach (object o in dep)
            {
                if (o is IStarted)
                {
                    IStarted s = o as IStarted;
                    s.Start(time);
                }
            }
        }

        #endregion

        #endregion

        #region Additional classes

        #region Functional Measure

        class FuncMeasure
        {
            TimeFunction func;
            private FuncMeasure(TimeFunction func)
            {
                this.func = func;
            }

            private object calc()
            {
                return func;
            }

            internal static Func<object> createParameter(TimeFunction f)
            {
                FuncMeasure fm = new FuncMeasure(f);
                return fm.calc;
            }
        }

        #endregion

        #region Internal Runge Processor

        class InternalRungeProcessor : RungeProcessor
        {
            #region Fields

            AccumulatorBase accumulator;

            #endregion

            internal InternalRungeProcessor(AccumulatorBase accumulator)
            {
                this.accumulator = accumulator;
            }

            public override void UpdateMeasurements()
            {
                if (Dim > 0)
                {
                    try
                    {
                        foreach (IMeasurements m in measurements)
                        {
                            if (m == accumulator)
                            {
                                continue;
                            }
                            m.UpdateMeasurements();
                        }
                        foreach (INormalizable n in norm)
                        {
                            n.Normalize();
                        }
                    }
                    catch (Exception e)
                    {
                        e.Log();
                        this.Throw(e);
                    }
                }
            }
        }

        #endregion

        #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