Example #1
0
        public RideProcessor(string userId)
        {
            _outputLock = new ReaderWriterLockSlim();
            UserId = userId;
            // load the turbo
            _spotData = new Spot();
            _lastSpotData = null;

            // Set-up the lease

            LeaseId = GenerateLease(12);

            // Set the initial timeout
            LastUpdateTimestamp = DateTime.UtcNow;

            _messageQueue = new Queue<InterfaceDatum>(QUEUE_CAPACITY);
            _queueLock = new ReaderWriterLockSlim();
            _zeroingTimer = new Timer(CheckZeroing, null, 1000, 4000);

            Rider = Rider.LoadAny(userId);

            // will load either a real or virtual rider
            if (Rider != null)
            {
                Turbo = TurboTrainer.Load(UserId, Rider.CurrentTurbo, Rider.TurboIsCalibrated);
            }
        }
Example #2
0
File: Spot.cs Project: Cycli/Cycli
 public Spot Copy()
 {
     Spot newSp = new Spot();
       newSp.id = id;
       newSp.t = t;
       newSp.s = s;
       newSp.c = c;
       newSp.h = h;
       newSp.p = p;
       return newSp;
 }
Example #3
0
        private void ProcessMessage(InterfaceDatum p)
        {
            try
            {
                if (_outputLock.TryEnterWriteLock(OUTPUT_LOCK_TIMEOUT_MS))
                {

                    if (_lastMessage != null)
                    {
                        _lastSpotData = _spotData.Copy();
                        _spotData.id = UserId;
                        _spotData.t = Utilities.DbTime.ToUnsignedDbTicks(DateTime.UtcNow);
                        // heartrate is easy - just check its not a reset
                        _spotData.h = p.h;

                        // Speed
                       if (p.wt > 0)
                        {
                            double deltaDistance = 0.000001 * (double)p.w * (double)Rider.BikeWheelSizeMm * Math.PI;
                            _spotData.s = (float)(deltaDistance * 1024 * 3600 / (double)p.wt);  // kmph
                        }

                        // Cadence
                        if (p.pt > 0)
                        {
                            _spotData.c = (int)(60 * 1024 * (double)p.p / (double)p.pt);
                        }

                        // Power
                        if (Rider.EstimatedPower && Turbo == null)
                        {
                            _spotData.p = 0;
                        }
                        // This condition will only estimate if we're not calibrating
                        else if (Rider.EstimatedPower && _calibrationTimer == null)
                        {
                            _spotData.p = (int)Turbo.Power(_spotData.s);
                        }
                        else
                        {
                            if (p.ec > 0)
                            {
                                _spotData.p = (int)((float)p.e / (float)p.ec);
                                if (_lastSpotData != null)
                                {
                                    // Take a time average
                                    double dt = 0.001 * (double)(_spotData.t - _lastSpotData.t);
                                    float sf = (float)Math.Exp(-dt / 1.7);
                                    _spotData.p = (int)(sf * _lastSpotData.p + (1 - sf) * _spotData.p);
                                }
                            }
                            else
                            {
                                _spotData.p = 0;
                            }
                        }
                        // Are we calibrating - this
                        if (_calibrationTimer != null)
                        {
                            Turbo.UpdateCalibrationData(this, _spotData);
                            string message = Turbo.GetCalibrationMessage();
                            if (!string.IsNullOrEmpty(message))
                            {
                                CycliManager.Instance.SendCalibrationMessage(UserId, message);
                            }
                        }
                    }
                    _lastMessage = p;
                }

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            finally
            {
                _outputLock.ExitWriteLock();
            }
            // Let the outside world know - this is outside the lock as
            // the race processor will try and access the updated data
            // within a read lock
            System.Diagnostics.Debug.WriteLine(string.Format("Ride Process:{0}     {1}   {2:N2}   {3:N2}", _spotData.id, _spotData.t, _spotData.s, _spotData.p));

            OnSpotData();
        }
Example #4
0
 public void UpdateCalibrationData(RideProcessor rideProcessor, Spot spot)
 {
     _calibrationData.Add(spot.Copy());
 }
Example #5
0
 public void SendSpotData(string userId, Spot spot)
 {
     try
       {
     _ConnectionProcessLock.EnterReadLock();
     // Is the user connection
     string connectionId;
     if (_connections.TryGetValue(userId, out connectionId))
     {
       Context.Clients.Client(connectionId).receiveSpotData(spot);
     }
       }
       finally
       {
     _ConnectionProcessLock.ExitReadLock();
       }
 }
Example #6
0
        private void Start(object state)
        {
            // set the start time before releasing the race logging
            RaceStartTicks = Utilities.DbTime.ToUnsignedDbTicks(DateTime.UtcNow);

            // Enable the race for all - define initial positions
            int position = 1;
            try
            {
                _SpotLock.EnterWriteLock();
                foreach (Race.Participant p in Race.Participants)
                {
                    if (p.Status == @"Scheduled")
                    {
                        // Initial spot data
                        Spot curSpot = new Spot();
                        curSpot.id = p.UserId;
                        curSpot.t = RaceStartTicks;
                        curSpot.s = 0;
                        curSpot.c = 0;
                        curSpot.h = 0;
                        curSpot.p = 0;
                        _Spots.Add(p.UserId, curSpot);
                    }
                }
            }
            finally
            {
                _SpotLock.ExitWriteLock();
            }

            try
            {
                _RaceSpotLock.EnterWriteLock();
                foreach (Race.Participant p in Race.Participants)
                {

                    /////////////// Need to revist this!
                    if (p.Status == @"Scheduled")
                    {

                        // Initial Race data
                        RaceSpot curRaceSpot = new RaceSpot();
                        curRaceSpot.id = p.UserId;
                        curRaceSpot.d = 0;
                        curRaceSpot.t = 0;
                        curRaceSpot.s = 0;
                        curRaceSpot.c = 0;
                        curRaceSpot.k = 0;
                        curRaceSpot.p = 0;
                        curRaceSpot.e = 0;
                        curRaceSpot.h = 0;
                        curRaceSpot.b = 0;
                        curRaceSpot.i = 0;
                        curRaceSpot.v = 0;
                        curRaceSpot.f = false;  // not finished
                        curRaceSpot.a = false;  // not abandonned
                        curRaceSpot.pos = position++;
                        _RaceSpots.Add(p.UserId, curRaceSpot);
                        _RaceSpotHistory.Add(p.UserId, new Stack<RaceSpot>());
                        // Need to clone here or the stack will just contain a reference to the original
                        _RaceSpotHistory[p.UserId].Push(curRaceSpot.Copy());
                    }
                }
                // tell the db
                Race.Start();

            }
            finally
            {
                _RaceSpotLock.ExitWriteLock();
            }
            // Attach the race Processors
            CycliManager.Instance.AttachRiderProcessors(this, Race);
            // Start the race
            CycliManager.Instance.SendStartRace(Race);

            // Start the updater thread
            _UpdateRaceSpotTimer = new Timer(UpdateRaceSpotData, null, 0, 1000);
        }