/*
         * public TimeSpan RunFrequency => TimeSpan.FromMinutes(60);
         *
         * public void ProcessEntity(Entity entity, int deltaSeconds)
         * {
         *  SetEntityProfile(entity);
         * }
         *
         * public void ProcessManager(EntityManager manager, int deltaSeconds)
         * {
         *  Stopwatch timer = new Stopwatch();
         *  timer.Start();
         *  var entites = manager.GetAllEntitiesWithDataBlob<SensorProfileDB>();
         *  foreach (var entity in entites)
         *  {
         *      ProcessEntity(entity, deltaSeconds);
         *  }
         *  var ms = timer.ElapsedMilliseconds;
         *  var numEntites = entites.Count;
         * }
         */

        internal static void SetEntityProfile(Entity entity, DateTime atDate)
        {
            var position  = entity.GetDataBlob <PositionDB>();
            var sensorSig = entity.GetDataBlob <SensorProfileDB>();

            sensorSig.LastPositionOfReflectionSet = position.AbsolutePosition_AU;
            sensorSig.LastDatetimeOfReflectionSet = atDate;

            var emmiters          = entity.Manager.GetAllEntitiesWithDataBlob <SensorProfileDB>();
            int numberOfEmmitters = emmiters.Count;

            sensorSig.ReflectedEMSpectra.Clear();

            PercentValue reflectionPercent = 0.1f; //TODO: this should be calculated from crossSection(size), distance, and a reflectivity value(stealth armor?/ other design factors?).

            foreach (var emittingEntity in emmiters)
            {
                if (emittingEntity != entity) // don't reflect our own emmision.
                {
                    double distance    = PositionDB.GetDistanceBetween(position, emittingEntity.GetDataBlob <PositionDB>());
                    var    emmissionDB = emittingEntity.GetDataBlob <SensorProfileDB>();

                    foreach (var emitedItem in emmissionDB.EmittedEMSpectra)
                    {
                        var reflectedMagnatude = SensorProcessorTools.AttenuationCalc(emitedItem.Value, distance) * reflectionPercent;

                        sensorSig.ReflectedEMSpectra.Add(emitedItem.Key, emitedItem.Value);
                    }
                }
            }
        }
        /// <summary>
        /// TODO: Refactor: each entity (or parent) should have thier own Random based off a seed.
        /// all random should be psudo random and threadsafe. or at least, we need to be aware of higher level randoms which can be called by any thread. ie avoid this.
        /// some random should be able to be figured out by remote clients, and some not.
        /// </summary>
        /// <returns>The sigmoid.</returns>
        /// <param name="acurateNumber">Acurate number.</param>
        /// <param name="acuracy">Acuracy.</param>
        public static double RndSigmoid(double acurateNumber, PercentValue acuracy, Random rng)
        {
            double sigmoid = Math.Tanh(acuracy * 10);
            double maxRand = Rnd(1, sigmoid, rng);
            double result  = Rnd(acurateNumber + (acurateNumber * maxRand), acurateNumber - (acurateNumber * maxRand), rng);

            return(result);
        }
        internal static SensorReturnValues DetectonQuality(SensorReceverAtbDB recever, SensorProfileDB target)
        {
            /*
             * Thoughts (spitballing):
             *
             * What we need:
             * detect enough of a signal to get a position
             * decide what "enough" is. probibly get this from the signal strength. - should the target SensorSigDB define what enough is?
             * we could require more than one detection (ie two ships in different locations) to get an acurate position, but that could get tricky to code.
             * and how would we display a non acurate position? maybe a line out to a question mark, showing the angle of detection but not range?
             *
             * detect enough of a signal to get intel if it's a ship
             * decide what "enough" for this is. maybe compare the detected waveform and the emited waveform and compare the angles to see if the triangle is simular.
             *
             * it'd be nifty if we could include background noise in there too, ie so ships close to a sun would be hidden.
             * also have resoulution be required to pick out multiple ships close together instead of just one big signal.
             *
             * With range attenuation, we'll never get the full signal uneless we're right ontop of it.
             * maybe if we get half the emited strength and its a simular triange (all same angles) we get "Full" intel?
             *
             * should we add time into the mix as well? multiple detections over a given time period to get position/velocity/orbitDB?
             *
             *
             * how are multiple components on a ship going to work? they are entitys in and of themselfs, so they could have a SensorSigDB all of thier own.
             * that could help with getting intel on individual components of a target.
             *
             * recever resolution should play into how much gets detected.
             *
             * Note that each entity will(may) have multiple waveforms.
             *
             * Data that can be glened from this detection system:
             * detectedStrength (altitide of the intersecting triangle)
             * detectedArea - the area of the detected intersection, could compare this to the target signal as well.
             * compare angles of the detected intersection and the target signal to see if the shape is simular?
             * if range is known acurately, this could affect the intel gathered.
             */
            var        myPosition = recever.OwningEntity.GetDataBlob <ComponentInstanceInfoDB>().ParentEntity.GetDataBlob <PositionDB>();//recever is a componentDB. not a shipDB
            PositionDB targetPosition;

            if (target.OwningEntity.HasDataBlob <PositionDB>())
            {
                targetPosition = target.OwningEntity.GetDataBlob <PositionDB>();
            }
            else
            {
                targetPosition = target.OwningEntity.GetDataBlob <ComponentInstanceInfoDB>().ParentEntity.GetDataBlob <PositionDB>();//target may be a componentDB. not a shipDB
            }
            double distance = PositionDB.GetDistanceBetween(myPosition, targetPosition);

            var detectionResolution = recever.Resolution;

            var signalAtPosition = AttenuatedForDistance(target, distance);

            double       receverSensitivityFreqMin   = recever.RecevingWaveformCapabilty.WavelengthMin_nm;
            double       receverSensitivityFreqAvg   = recever.RecevingWaveformCapabilty.WavelengthAverage_nm;
            double       receverSensitivityFreqMax   = recever.RecevingWaveformCapabilty.WavelengthMax_nm;
            double       receverSensitivityBest      = recever.BestSensitivity_kW;
            double       receverSensitivityAltitiude = recever.BestSensitivity_kW - recever.WorstSensitivity_kW;
            PercentValue quality           = new PercentValue(0.0f);
            double       detectedMagnatude = 0;

            foreach (var waveSpectra in signalAtPosition)
            {
                double signalWaveSpectraFreqMin      = waveSpectra.Key.WavelengthMin_nm;
                double signalWaveSpectraFreqAvg      = waveSpectra.Key.WavelengthAverage_nm;
                double signalWaveSpectraFreqMax      = waveSpectra.Key.WavelengthMax_nm;
                double signalWaveSpectraMagnatude_kW = waveSpectra.Value;



                if (signalWaveSpectraMagnatude_kW > recever.BestSensitivity_kW) //check if the sensitivy is enough to pick anything up at any frequency.
                {
                    if (Math.Max(receverSensitivityFreqMin, signalWaveSpectraFreqMin) < Math.Max(signalWaveSpectraFreqMin, signalWaveSpectraFreqMax))
                    {
                        //we've got something we can detect
                        double minDetectableWavelength = Math.Min(receverSensitivityFreqMin, signalWaveSpectraFreqMin);
                        double maxDetectableWavelenght = Math.Min(receverSensitivityFreqMax, signalWaveSpectraFreqMax);

                        double detectedAngleA = Math.Atan(receverSensitivityAltitiude / (receverSensitivityFreqAvg - receverSensitivityFreqMin));
                        double receverBaseLen = maxDetectableWavelenght - minDetectableWavelength;
                        double detectedAngleB = Math.Atan(signalWaveSpectraMagnatude_kW / (signalWaveSpectraFreqAvg - signalWaveSpectraFreqMax));

                        bool   doesIntersect;
                        double intersectPointX;
                        double intersectPointY;
                        double distortion;

                        if (signalWaveSpectraFreqAvg < receverSensitivityFreqAvg)  //RightsideDetection (recever's ideal wavelenght is higher than the signal wavelenght at it's loudest)
                        {
                            doesIntersect = Get_line_intersection(
                                signalWaveSpectraFreqAvg, signalWaveSpectraMagnatude_kW,
                                signalWaveSpectraFreqMin, 0,

                                receverSensitivityFreqAvg, recever.BestSensitivity_kW,
                                receverSensitivityFreqMax, recever.WorstSensitivity_kW,

                                out intersectPointX, out intersectPointY);
                            //offsetFromCenter = intersectPointX - signalWaveSpectraFreqAvg; //was going to use this for distortion but decided to simplify.
                            distortion = receverSensitivityFreqAvg - signalWaveSpectraFreqAvg;
                        }
                        else                                                        //LeftSideDetection
                        {
                            doesIntersect = Get_line_intersection(
                                signalWaveSpectraFreqAvg, signalWaveSpectraMagnatude_kW,
                                signalWaveSpectraFreqMax, 0,

                                receverSensitivityFreqAvg, recever.BestSensitivity_kW,
                                receverSensitivityFreqMin, recever.WorstSensitivity_kW,

                                out intersectPointX, out intersectPointY);
                            //offsetFromCenter = intersectPointX - signalWaveSpectraFreqAvg;
                            distortion = signalWaveSpectraFreqAvg - receverSensitivityFreqAvg;
                        }

                        if (doesIntersect) // then we're not detecting the peak of the signal
                        {
                            detectedMagnatude = intersectPointY - recever.BestSensitivity_kW;
                            distortion       *= 2; //pentalty to quality of signal
                        }
                        else
                        {
                            detectedMagnatude = signalWaveSpectraMagnatude_kW - recever.BestSensitivity_kW;
                        }

                        quality = new PercentValue((float)(100 - distortion / signalWaveSpectraFreqMax));
                    }
                }
            }



            return(new SensorReturnValues()
            {
                SignalStrength_kW = detectedMagnatude,
                SignalQuality = quality
            });
        }
示例#4
0
 public static byte GetRawValue(PercentValue percentValue)
 {
     return(percentValue._percent);
 }