Пример #1
0
        public ICoordinate GetResult(int objectId, params IDistance[] distances)
        {
            List <Particle3D> particles = CreateParticles(objectId, distances, out bool doesExist);

            ICoordinate result;

            if (distances.Length == 1)
            {
                var distance = distances[0];
                var anchor   = _anchors[distance.FromAnchorId];
                result = new Coordinate(anchor.X, anchor.Z, anchor.Y);
                return(result);
            }
            else
            {
                result = GenerateCoordinates(distances, particles, out IList <Particle3D> trainedParticles, doesExist);

                if (trainedParticles.Count == 0)
                {
                    return(null);
                }

                double averageX = trainedParticles.Average(x => x.X);
                double averageY = trainedParticles.Average(x => x.Y);
                double averageZ = trainedParticles.Average(x => x.Z);

                for (int i = trainedParticles.Count; i < _numberOfParticles; i++)
                {
                    double x = averageX + Random.Next(-_numberOfCircleDistances, _numberOfCircleDistances);
                    double y = averageY + Random.Next(-_numberOfCircleDistances, _numberOfCircleDistances);
                    double z = averageZ + Random.Next(-_numberOfCircleDistances, _numberOfCircleDistances);

                    var particle = new Particle3D(x, y, z);
                    particle.SetNoise(_numberOfCircleDistances);
                    trainedParticles.Add(particle);
                }

                _particles[objectId].Particles = trainedParticles as List <Particle3D> ?? trainedParticles.ToList();
                DateTime now = DateTime.Now;
                ApplyKalmanFilter(objectId, result, now);
                _particles[objectId].AddHistoric(result, now);
            }

            return(result);
        }
Пример #2
0
        private ICoordinate GenerateCoordinates(IEnumerable <IDistance> distances, IList <Particle3D> particles,
                                                out IList <Particle3D> trainedParticles, bool secondTime)
        {
            var weights   = new List <double>(_numberOfParticles);
            var maxWeight = 0d;

            distances = distances.OrderBy(x => x.Distance);
            IDistance[] distanceArray = distances.ToArray();
            double      distanceSum   = distanceArray.Sum(x => x.Distance);

            foreach (var pJay in particles)
            {
                double prob = 1;
                foreach (IDistance distance in distanceArray)
                {
                    IAnchor anchor = _anchors[distance.FromAnchorId];
                    double  dist   = Math.Sqrt(Math.Pow(pJay.X - anchor.X, 2) + Math.Pow(pJay.Y - anchor.Y, 2) + Math.Pow(pJay.Z - anchor.Z, 2));
                    prob *= GaussianProbabilityDistribution(dist, pJay.NumberOfCircleDistances, distance.Distance)
                            // * (1 - (distance.Distance / distanceSum))
                    ;
                }

                weights.Add(prob);
                if (maxWeight < prob)
                {
                    maxWeight = prob;
                }
            }

            var    newParticles   = new List <Particle3D>(_numberOfParticles);
            double beta           = (secondTime ? 0.9 : 0.7) * maxWeight;
            var    resultPosition = new Coordinate(0, 0, 0);
            var    weightTotal    = 0d;

            for (var i = 0; i < _numberOfParticles; i++)
            {
                try
                {
                    if (beta < weights[i])
                    {
                        newParticles.Add(particles[i]);
                        resultPosition.X += particles[i].X * weights[i];
                        resultPosition.Y += particles[i].Y * weights[i];
                        resultPosition.Z += particles[i].Z * weights[i];
                        weightTotal      += weights[i];
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }

            resultPosition.X /= weightTotal;
            resultPosition.Z /= weightTotal;
            resultPosition.Y /= weightTotal;

            if (!secondTime)
            {
                var i = 0;
                int currentParticleNumber = newParticles.Count;
                while (_numberOfParticles > newParticles.Count && currentParticleNumber > 0)
                {
                    i %= currentParticleNumber;
                    double xx = newParticles[i].X + Random.Next(-_numberOfCircleDistances, _numberOfCircleDistances);
                    double yy = newParticles[i].Y + Random.Next(-_numberOfCircleDistances, _numberOfCircleDistances);
                    double zz = newParticles[i].Z + Random.Next(-_numberOfCircleDistances, _numberOfCircleDistances);

                    var particle = new Particle3D(xx, yy, zz);
                    particle.SetNoise(_numberOfCircleDistances);
                    newParticles.Add(particle);
                    i++;
                }
            }

            particles        = newParticles;
            trainedParticles = newParticles;
            if (!secondTime)
            {
                return(GenerateCoordinates(distanceArray, particles, out trainedParticles, true));
            }

            return(resultPosition);
        }
Пример #3
0
        private List <Particle3D> CreateParticles(int objectId, IDistance[] distances, out bool doesExist)
        {
            double minH = double.MaxValue;
            double maxH = 0;
            double maxW = 0;
            double minW = double.MaxValue;
            double minL = double.MaxValue;
            double maxL = 0;

            foreach (IDistance distance in distances)
            {
                IAnchor anchor = _anchors[distance.FromAnchorId];
                if (maxH < anchor.Y + distance.Distance)
                {
                    maxH = anchor.Y + distance.Distance;
                }

                if (minH > anchor.Y - distance.Distance)
                {
                    minH = anchor.Y - distance.Distance;
                }

                if (maxW < anchor.X + distance.Distance)
                {
                    maxW = anchor.X + distance.Distance;
                }

                if (minW > anchor.X - distance.Distance)
                {
                    minW = anchor.X - distance.Distance;
                }

                if (maxL < anchor.Z + distance.Distance)
                {
                    maxL = anchor.Z + distance.Distance;
                }

                if (minL > anchor.Z - distance.Distance)
                {
                    minL = anchor.Z - distance.Distance;
                }
            }

            maxH += 50;
            minH -= 50;
            maxW += 50;
            minW -= 50;
            maxL += 50;
            minL -= 50;

            var worldSizeInfo = new WorldSizeInfo();

            worldSizeInfo.WorldSizeWidthMin  = minW;
            worldSizeInfo.WorldSizeWidthMax  = maxW;
            worldSizeInfo.WorldSizeHeightMin = 50;
            worldSizeInfo.WorldSizeHeightMax = maxH;
            worldSizeInfo.WorldSizeLengthMax = maxL;
            worldSizeInfo.WorldSizeLengthMin = minL;
            List <Particle3D> particles;

            doesExist = false;
            lock (_particles)
            {
                if (_particles.ContainsKey(objectId))
                {
                    particles = _particles[objectId].Particles;
                    doesExist = true;
                }
                else
                {
                    particles = new List <Particle3D>(_numberOfParticles);
                    for (int i = 0; i < _numberOfParticles; i++)
                    {
                        double x = Random.Next((int)worldSizeInfo.WorldSizeWidthMin,
                                               (int)worldSizeInfo.WorldSizeWidthMax);
                        double y = Random.Next((int)worldSizeInfo.WorldSizeHeightMin,
                                               (int)worldSizeInfo.WorldSizeHeightMax);
                        double z = Random.Next((int)worldSizeInfo.WorldSizeLengthMin,
                                               (int)worldSizeInfo.WorldSizeLengthMax);

                        var particle = new Particle3D(x, y, z);
                        particle.SetNoise(_numberOfCircleDistances);
                        particles.Add(particle);
                    }

                    _particles.TryAdd(objectId, new ParticleHistory3D(10)
                    {
                        Particles = particles,
                    });
                }
            }

            return(particles);
        }