Exemple #1
0
 private void ApplyWeights(List <NeighbourPosition> neighbourPositions, EstimatePositionCommand estimatePositionCommand)
 {
     neighbourPositions.ForEach(neighbour =>
     {
         neighbour.SignalScores.ForEach(signalScore =>
         {
             if (signalScore.PositionSignalData.SignalType == SignalType.Wifi)
             {
                 signalScore.Score    *= estimatePositionCommand.WifiWeight;
                 signalScore.Distance /= estimatePositionCommand.WifiWeight;
             }
             else if (signalScore.PositionSignalData.SignalType == SignalType.Bluetooth)
             {
                 signalScore.Score    *= estimatePositionCommand.BleWeight;
                 signalScore.Distance /= estimatePositionCommand.BleWeight;
             }
             else if (signalScore.PositionSignalData.SignalType == SignalType.Magnetometer)
             {
                 signalScore.Score    *= estimatePositionCommand.MagnetometerWeight;
                 signalScore.Distance /= estimatePositionCommand.MagnetometerWeight;
             }
         });
     });
 }
Exemple #2
0
 public async Task <ActionResult <PositionEstimation> > EstimatePosition(
     [FromServices] IPositionEstimationService positionEstimationService,
     [FromBody] EstimatePositionCommand command)
 {
     return(await positionEstimationService.EstimatePosition(command));
 }
Exemple #3
0
 public Task <PositionEstimation> EstimatePosition(EstimatePositionCommand command)
 {
     return(client.Post <PositionEstimation>(positionEstimationsController, command));
 }
Exemple #4
0
        public async Task <PositionEstimation> EstimatePosition(EstimatePositionCommand command)
        {
            if (command.UseBestParameters)
            {
                var localeParameters = await this.databaseContext.LocaleParameters
                                       .OrderBy(parameters => parameters.Missings)
                                       .ThenBy(parameter => parameter.MeanError)
                                       .FirstOrDefaultAsync(parameter => parameter.LocaleId == command.LocaleId && parameter.IsActive);

                if (localeParameters == null)
                {
                    localeParameters = await this.databaseContext.LocaleParameters
                                       .OrderBy(parameters => parameters.Missings)
                                       .ThenBy(parameter => parameter.MeanError)
                                       .FirstOrDefaultAsync(parameter => parameter.LocaleId == command.LocaleId);
                }

                if (localeParameters != null)
                {
                    command.BleWeight              = localeParameters.BleWeight;
                    command.MagnetometerWeight     = localeParameters.MagnetometerWeight;
                    command.Neighbours             = localeParameters.Neighbours;
                    command.UnmatchedSignalsWeight = localeParameters.UnmatchedSignalsWeight;
                    command.WifiWeight             = localeParameters.WifiWeight;
                }
            }

            var signals             = command.Measurements.ToDictionary(signal => signal.SignalId);
            var positionSignalDatas = this.cachedPositionSignalData ?? await this.databaseContext.PositionsSignalsData
                                      .AsNoTracking()
                                      .Include(true, positionSignalData => positionSignalData.Position, position => position !.Zone)
                                      .Where(positionSignalData => positionSignalData.Position !.Zone !.LocaleId == command.LocaleId)
                                      .Where(positionSignalData => positionSignalData.LastSeen.AddDays(30) > command.Measurements.First().DateTime&&
                                             positionSignalData.LastSeen.AddDays(-30) < command.Measurements.First().DateTime)
                                      .ToListAsync();

            this.cachedPositionSignalData = positionSignalDatas;

            var neighbourPositions = new List <NeighbourPosition>();

            if (command.UnmatchedSignalsWeight != null)
            {
                var unmatchedSignals = positionSignalDatas
                                       .Where(positionSignalData => !signals.ContainsKey(positionSignalData.SignalId))
                                       .ToList();
                unmatchedSignals.ForEach(unmatchedSignal =>
                {
                    var neighbourPosition = neighbourPositions
                                            .FirstOrDefault(neighbourPosition => neighbourPosition.Position.Id == unmatchedSignal.PositionId);
                    if (neighbourPosition == null)
                    {
                        neighbourPosition = new NeighbourPosition(unmatchedSignal.Position !);
                        neighbourPositions.Add(neighbourPosition);
                    }

                    neighbourPosition.SignalScores.Add(new SignalScore(unmatchedSignal, command.UnmatchedSignalsWeight.Value, command.StandardDeviationFactor));
                });
            }

            positionSignalDatas
            .Where(positionSignalData => signals.ContainsKey(positionSignalData.SignalId))
            .Where(positionSignalData => this.IsValidEstimation(positionSignalData, signals[positionSignalData.SignalId]))
            .ToList()
            .ForEach(data =>
            {
                var measurement       = signals[data.SignalId];
                var neighbourPosition = neighbourPositions
                                        .FirstOrDefault(neighbourPosition => neighbourPosition.Position.Id == data.PositionId);
                if (neighbourPosition == null)
                {
                    neighbourPosition = new NeighbourPosition(data.Position !);
                    neighbourPositions.Add(neighbourPosition);
                }

                neighbourPosition.SignalScores.Add(new SignalScore(data, measurement, command.StandardDeviationFactor));
            });

            if (command.RealX != null && command.RealY != null)
            {
                this.databaseContext.Add(new UserLocalization()
                {
                    UserId   = 1,
                    LocaleId = command.LocaleId,
                    DateTime = DateTime.UtcNow,
                    RealX    = command.RealX,
                    RealY    = command.RealY,
                    LocalizationMeasurements = command.Measurements.Select(measurement => new LocalizationMeasurement(measurement)).ToList()
                });

                await this.databaseContext.SaveChangesAsync();
            }

            this.ApplyWeights(neighbourPositions, command);

            var nearestNeighbours = !command.UseDistance
                    ? neighbourPositions.OrderByDescending(estimation => estimation.Score).Take(command.Neighbours).ToList()
                    : neighbourPositions.OrderBy(estimation => estimation.Distance).Take(command.Neighbours).ToList();

            if (!command.UseDistance)
            {
                int i = 0;
                while (nearestNeighbours.Any(neighbour => neighbour.Score < 0) && i < 40)
                {
                    neighbourPositions.ForEach(neighbour =>
                    {
                        neighbour.SignalScores.ForEach(signalScore =>
                        {
                            if (signalScore.Score < 0)
                            {
                                signalScore.Score *= 0.8;
                            }
                        });
                    });
                    nearestNeighbours = neighbourPositions.OrderByDescending(estimation => estimation.Score).Take(command.Neighbours).ToList();
                    i++;
                }
            }

            return(new PositionEstimation(nearestNeighbours, command.UseDistance));
        }