/// <summary>
        /// Collects a new piece of data.
        /// </summary>
        public void Collect(DataPiece piece)
        {
            if (_previous != null)
            {
                if (_previous.TrackId == piece.TrackId)
                {
                    _ppeAccumulator += piece.Ppe;
                    _ppeCount       += 1;
                    _ppeBins[PpeMapper.GetBinIndex(piece.Ppe)] += 1;
                    if (piece.Ppe > _ppeMax)
                    {
                        _ppeMax = piece.Ppe;
                    }

                    if (piece.StartTimestamp < _tsStart)
                    {
                        _tsStart = piece.StartTimestamp;
                    }
                    if (piece.EndTimestamp > _tsEnd)
                    {
                        _tsEnd = piece.EndTimestamp;
                    }
                    _elapsed += (piece.EndTimestamp - piece.StartTimestamp);

                    var traveledDistance = GeoHelper.DistanceBetweenPoints(
                        _previous.Latitude, _previous.Longitude,
                        piece.Latitude, piece.Longitude
                        ) * DistanceFactor;
                    _distance += traveledDistance;

                    Log.Debug("Traveled {0:F3}km, count {1} {2:t}-{3:t}", traveledDistance, _ppeCount, _tsStart, _tsEnd);
                }
                else
                {
                    Log.Warning(new ArgumentException(nameof(piece.TrackId)), "Different track ID seen while collecting statistics");

                    CompleteSession();
                }
            }

            // Dump data
            // Generates approximately 42 bytes per measurement (~147 KB/hour)
            if (_dumpWriter == null)
            {
                var dumpStream = FileOperations.AppendFile(FileNaming.GetDataTrackFilepath(piece.TrackId));
                _dumpWriter = new StreamWriter(dumpStream);
            }
            _dumpWriter.WriteLine(
                string.Format(CultureInfo.InvariantCulture, "{0},{1:F5},{2:F5},{3:F2}", piece.StartTimestamp.Ticks, piece.Latitude, piece.Longitude, piece.Ppe)
                );

            _previous = piece;

            Log.Debug("Data piece collected");
        }
Esempio n. 2
0
        /// <summary>
        /// Collects a new piece of data.
        /// </summary>
        public void Collect(DataPiece piece)
        {
            if (_record != null && (_record.TrackId != piece.TrackId))
            {
                Log.Warning(new ArgumentException(nameof(piece.TrackId)), "Different track ID seen while collecting statistics");

                CompleteSession();
            }

            if (_record == null)
            {
                _record = GetRecordForPiece(piece);
            }

            // Record set, update
            _ppeAccumulator += piece.Ppe;
            _ppeCount       += 1;
            _record.Bins[PpeMapper.GetBinIndex(piece.Ppe)] += 1;
            if (piece.Ppe > _record.MaxPpe)
            {
                _record.MaxPpe = piece.Ppe;
            }
            _record.AvgPpe               = _ppeAccumulator / _ppeCount;
            _record.DataPieceCount       = (int)_ppeCount;
            _record.End                  = piece.EndTimestamp;
            _record.ElapsedTime         += (piece.EndTimestamp - piece.StartTimestamp);
            _record.LocationEndLatitude  = piece.Latitude;
            _record.LocationEndLongitude = piece.Longitude;

            if (_previous != null)
            {
                var traveledDistance = GeoHelper.DistanceBetweenPoints(
                    _previous.Latitude, _previous.Longitude,
                    piece.Latitude, piece.Longitude
                    ) * DistanceFactor;
                _record.DistanceTraveled += traveledDistance;

                Log.Debug("Traveled {0:F3}km, count {1} {2:t}-{3:t}",
                          traveledDistance, _ppeCount, _record.Start, _record.End);
            }

            _previous = piece;

            // Flush every few minutes
            if (_ppeCount > 0 && (_ppeCount % FlushIntervalSize == 0))
            {
                Flush();
            }

            // Dump data
            // Generates approximately 89 bytes per measurement (~313 KB/hour)
            if (_dumpWriter == null)
            {
                var outputFilepath = FileNaming.GetDataTrackFilepath(piece.TrackId);
                Log.Debug("Appending to file {0}", outputFilepath);

                var dumpStream = FileOperations.AppendFile(outputFilepath);
                _dumpWriter = new StreamWriter(dumpStream);
                _dumpWriter.WriteLine("# SRS Track {0:N} {1:u}", piece.TrackId, DateTime.Now);
                _dumpWriter.WriteLine("# Start,End,Lat,Lng,PPE,PPEx,PPEy,PPEz,Speed,Bearing,Accuracy");
            }
            _dumpWriter.WriteLine(
                string.Format(CultureInfo.InvariantCulture, "{0},{1},{2:F5},{3:F5},{4:F3},{5:F2},{6:F2},{7:F2},{8:F1},{9:D},{10:D}",
                              piece.StartTimestamp.Ticks,
                              piece.EndTimestamp.Ticks,
                              piece.Latitude,
                              piece.Longitude,
                              piece.Ppe,
                              piece.PpeX,
                              piece.PpeY,
                              piece.PpeZ,
                              piece.Speed,
                              (int)piece.Bearing,
                              piece.Accuracy
                              )
                );

            Log.Debug("Data piece collected");
        }
Esempio n. 3
0
        /// <summary>
        /// Reports a new location value from the GPS sensor.
        /// </summary>
        /// <param name="latitude">Latitude in degrees.</param>
        /// <param name="longitude">Longitude in degrees.</param>
        /// <param name="speed">Speed in m/s.</param>
        /// <param name="bearing">Bearing in degrees.</param>
        /// <param name="accuracy">Accuracy in meters.</param>
        protected void ReportNewLocation(double latitude, double longitude, float speed, float bearing, int accuracy)
        {
            LocationSensorStatus = LocationSensorStatus.Working;

            var timestamp    = DateTime.UtcNow;
            var intervalTime = timestamp - _gpsLastUpdate;

            _gpsLastUpdate = timestamp;

            Log.Debug("Location ({0:F3};{1:F3}) at {2:F2} m/s, accuracy {3:F0} m, elapsed {4:F1} ms",
                      latitude,
                      longitude,
                      speed,
                      accuracy,
                      intervalTime.TotalMilliseconds);

            if (accuracy > MinimumAccuracy)
            {
                Log.Debug("Location too inaccurate, discarding");
                return;
            }

            //TODO: add location interpolation here

            if (_gpsLastLatitude.IsValid() && _gpsLastLongitude.IsValid())
            {
                //We use very naïve measurements here
                var measuredDistance = GeoHelper.DistanceBetweenPoints(_gpsLastLatitude, _gpsLastLongitude, latitude, longitude) * 1000.0; // m
                var measuredSpeed    = measuredDistance / intervalTime.TotalSeconds;                                                       // m/s

                Log.Debug("Traveled {0:F5} m, at {1:F1} m/s: {2}",
                          measuredDistance, measuredSpeed,
                          (measuredSpeed > GpsUnmovingSpeed) ? ((measuredSpeed > GpsFastEnoughSpeed) ? ((measuredSpeed > GpsTooFastSpeed) ? "too fast" : "OK") : "slow") : "unmoving"
                          );

                _gpsLastSpeed = (float)measuredSpeed;

                if (measuredSpeed >= GpsUnmovingSpeed)
                {
                    _lastTimeMoved = timestamp;

                    if (measuredSpeed >= GpsFastEnoughSpeed)
                    {
                        IsMovingSlowly = false;

                        if (measuredSpeed >= GpsTooFastSpeed)
                        {
                            Log.Debug("Unforeseen GPS skip of {0} m in {1} ms", measuredDistance, intervalTime.TotalMilliseconds);
                            ResetGpsLocation();
                            return;
                        }
                    }
                    else
                    {
                        IsMovingSlowly = true;
                    }
                }
            }

            _gpsLastLatitude  = latitude;
            _gpsLastLongitude = longitude;
            _gpsLastBearing   = bearing;
            _gpsLastAccuracy  = accuracy;
        }