Click here to Skip to main content
15,886,799 members
Articles / Programming Languages / C#

Grandiose Projects 3. Compatibility with Simulink

Rate me:
Please Sign up or sign in to vote.
4.27/5 (11 votes)
8 Feb 2010CPOL23 min read 47.7K   5.9K   38  
Import of Simulink files
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

using CategoryTheory;
using DiagramUI;
using DiagramUI.Interfaces;


using DataPerformer;
using DataPerformer.Interfaces;

using Motion6D.Intrefaces;

namespace Motion6D
{
    /// <summary>
    /// Accelerated position
    /// </summary>
    [Serializable()]
    public class AcceleratedPosition : CategoryObject, ISerializable, IAlias, IPosition,
        IAcceleration, IDifferentialEquationSolver, IVelocity,
        IStarted, IChildrenObject, IDataConsumer, IPostSetArrow
    {
        #region Fields

        const Double a = 0;


        private double[] position = new double[3];

        protected double[] relativeAcc = new double[3];

        private double[] absoluteAcc = new double[3];

        private bool isUpdated = false;

        private double[] absoluteVel = new double[3];

        private double[] relativeVel = new double[3];

        private double[] initialVector = new double[3];

        private double[] buffer = new double[3];

        private double[] buffer1 = new double[3];

        private double[] initial = new double[6];

        private MeasureDerivation[] measures = new MeasureDerivation[6];

        private IAssociatedObject[] children = new IAssociatedObject[1];

        private RelativeField field = new RelativeField(true);

        static private readonly string[] names = new string[] { "x", "y", "z", "Vx", "Vy", "Vz" };

        private Dictionary<string, int> dn = new Dictionary<string, int>();

        private List<string> ln = new List<string>();

        private TransformVector transform;

        private IReferenceFrame parent;

        private ReferenceFrame frame;

        private IAcceleration acc;

        private IAngularAcceleration angacc;

        private IVelocity vel;

        private IAngularVelocity angvel;

        private IList<IMeasurements> measurements = new List<IMeasurements>();

        private IMeasure[] measuresAcc = new IMeasure[3];

        private Dictionary<int, string> meas = new Dictionary<int, string>();

        private IDataConsumer cons;

        private bool isSerialized = false;
        
        #endregion

        #region Ctor

        public AcceleratedPosition()
        {
            PostConstruct();
        }

        /// <summary>
        /// Deserialization constructor
        /// </summary>
        /// <param name="info">Serialization info</param>
        /// <param name="context">Streaming context</param>
        protected AcceleratedPosition(SerializationInfo info, StreamingContext context)
        {
            initial = info.GetValue("Initial", typeof(double[])) as double[];
            meas = info.GetValue("Measures", typeof(Dictionary<int, string>)) as Dictionary<int, string>;
            field = RelativeField.Load(info, this);
            PostConstruct();
            isSerialized = true;
        }

        #endregion

        #region ISerializable Members

        public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Initial", initial, typeof(double[]));
            info.AddValue("Measures", meas, typeof(Dictionary<int, string>));
            field.Save(info);
        }

        #endregion

        #region IAlias Members

        IList<string> IAlias.AliasNames
        {
            get { return ln; }
        }

        object IAlias.this[string name]
        {
            get
            {
                return initial[dn[name]];
            }
            set
            {
                initial[dn[name]] = (double)value;
            }
        }

        object IAlias.GetType(string name)
        {
            return a;
        }

        #endregion

        #region IPosition Members

        double[] IPosition.Position
        {
            get { return position; }
        }

        IReferenceFrame IPosition.Parent
        {
            get
            {
                return parent as IReferenceFrame;
            }
            set
            {
                parent = value;
                if (!isSerialized)
                {
                    PostCreateFrame();
                }
            }
        }

        object IPosition.Parameters
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        void IPosition.Update()
        {
        }

        #endregion

        #region IVelocity Members

        double[] IVelocity.Velocity
        {
            get { return absoluteVel; }
        }
/*
        double[] IVelocity.RevativeVelocity
        {
            get { return relativeVel; }
        }
*/
        #endregion

        #region IAcceleration Members

        double[] IAcceleration.LinearAcceleration
        {
            get { return absoluteAcc; }
        }

        double[] IAcceleration.RelativeAcceration
        {
            get { return relativeAcc; }
        }

        #endregion

        #region IDifferentialEquationSolver Members

        void IDifferentialEquationSolver.CalculateDerivations()
        {
        }

        void IDifferentialEquationSolver.CopyVariablesToSolver(int offset, double[] variables)
        {
            Array.Copy(position, offset, variables, 0, 3);
            Array.Copy(relativeVel, offset + 3, variables, 3, 3);
        }

        int IDifferentialEquationSolver.VariablesCount
        {
            get
            {
                IMeasurements m = this;
                return m.Count;
            }
        }


        #endregion

        #region IMeasurements Members

        int IMeasurements.Count
        {
            get { return measures.Length; }
        }

        IMeasure IMeasurements.this[int n]
        {
            get { return measures[n]; }
        }

        void IMeasurements.UpdateMeasurements()
        {
            cons.UpdateChildrenData();
            transform(relativeAcc);
            for (int i = 0; i < relativeAcc.Length; i++)
            {
                relativeAcc[i] += (double)measuresAcc[i].Parameter();
            }
        }

        bool IMeasurements.IsUpdated
        {
            get
            {
                return isUpdated;
            }
            set
            {
                isUpdated = value;
            }
        }

        #endregion

        #region IStarted Members

        void IStarted.Start(double time)
        {
            Array.Copy(initial, position, 3);
            Array.Copy(initial, 3, relativeVel, 0, 3);
        }

        #endregion

        #region IChildrenObject Members

        IAssociatedObject[] IChildrenObject.Children
        {
            get { return children; }
        }

        #endregion

        #region IDataConsumer Members

        void IDataConsumer.Add(IMeasurements measurements)
        {
            this.measurements.Add(measurements);
        }

        void IDataConsumer.Remove(IMeasurements measurements)
        {
            this.measurements.Remove(measurements);
        }

        void IDataConsumer.UpdateChildrenData()
        {
            DataPerformerOperations.UpdateChildernData(this);
        }

        int IDataConsumer.Count
        {
            get { return measurements.Count; }
        }

        IMeasurements IDataConsumer.this[int n]
        {
            get { return measurements[n]; }
        }

        void IDataConsumer.Reset()
        {
            DataPerformerOperations.Reset(this);
        }

        #endregion

        #region IPostSetArrow Members

        void IPostSetArrow.PostSetArrow()
        {
            Post();
            PostCreateFrame();
            isSerialized = false;
        }

        #endregion

        #region Specific Members

        /// <summary>
        /// Field
        /// </summary>
        public RelativeField Field
        {
            get
            {
                return field;
            }
        }

        public void Post()
        {
            cons = this;
            transform = VectorOperations.CreateTransformer(InerialAcceleration, this);
            for (int i = 0; i < measuresAcc.Length; i++)
            {
                string s = meas[i];
                IMeasure m = StaticDataPerformer.FindMeasure(this, s, false);
                measuresAcc[i] = m;
            }
        }

        public Dictionary<int, string> Measures
        {
            get
            {
                return meas;
            }
        }


        private void PostConstruct()
        {
            children[0] = field;
            IPositionObject p = field;
            p.Position = this;
            for (int i = 0; i < names.Length; i++)
            {
                ln.Add(names[i]);
                dn[names[i]] = i;
            }
            transform = InerialAcceleration;
            Measure[] ma = new Measure[] { new Measure(getAx, ""), new Measure(getAy, ""), new Measure(getAz, "") };
            MeasureDerivation[] md = new MeasureDerivation[] {
                new MeasureDerivation(a, getVx, ma[0], "Vx"),
                new MeasureDerivation(a, getVy, ma[1], "Vy"),
                new MeasureDerivation(a, getVz, ma[2], "Vz")};
            MeasureDerivation[] mc = new MeasureDerivation[] {
                new MeasureDerivation(a, getX, md[0], "X"),
                new MeasureDerivation(a, getY, md[1], "Y"),
                new MeasureDerivation(a, getZ, md[2], "Z")};
            for (int i = 0; i < 3; i++)
            {
                measures[i] = mc[i];
                measures[i + 3] = md[i];
            }
        }

        private void InerialAcceleration(double[] x)
        {
           ReferenceFrame frame = ReferenceFrame.GetFrame(this);
            IAngularVelocity av = frame as IAngularVelocity;
            Vector3D.V3DOperations.CalculateRelativeAcceleration(absoluteAcc, angvel.Omega, angacc.AngularAcceleration,
                vel.Velocity, position, buffer, buffer1, x);
        }

        private void PostCreateFrame()
        {
            try
            {
                frame = ReferenceFrame.GetFrame(this);
                acc = CategoryOperations.GetSimpleObject<IAcceleration>(frame, "Object should have acceleration");
                angvel = CategoryOperations.GetSimpleObject<IAngularVelocity>(frame, "Object should have angular velocity");
                vel = CategoryOperations.GetSimpleObject<IVelocity>(frame, "Object should have velocity");
                angacc = CategoryOperations.GetSimpleObject<IAngularAcceleration>(frame, "Object should have angular acceleration");

            }
            catch (Exception e)
            {
                IPosition p = this;
                p.Parent = null;
                throw e;
            }
 
        }

        object getAx()
        {
            return relativeAcc[0];
        }

        object getAy()
        {
            return relativeAcc[1];
        }
        object getAz()
        {
            return relativeAcc[2];
        }

        object getVx()
        {
            return relativeVel[0];
        }

        object getVy()
        {
            return relativeVel[1];
        }
        object getVz()
        {
            return relativeVel[2];
        }

        object getX()
        {
            return position[0];
        }

        object getY()
        {
            return position[1];
        }
        object getZ()
        {
            return position[2];
        }
        #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