Beispiel #1
0
        public void CompareTo_ShouldConsiderDNFSlower()
        {
            Beacon martijnBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 1 }, 2);
            Rider  martijn       = new Rider("Martijn", martijnBeacon);

            //make a regular lap
            IdEvent     startId     = new IdEvent(DateTime.Now, martijn, "StartId", Direction.Enter);
            TimingEvent startTiming = new TimingEvent(DateTime.Now, martijn, 100, 0);
            IdEvent     endId       = new IdEvent(DateTime.Now, martijn, "EndId", Direction.Enter);
            TimingEvent endTiming   = new TimingEvent(DateTime.Now, martijn, 200, 1);

            FinishedEvent finish = new FinishedEvent(startId, startTiming, endTiming, endId);

            Lap normalLap = new Lap(finish);

            //make a DNF lap
            IdEvent dnfStartId = new IdEvent(DateTime.Now, martijn, "StartId", Direction.Enter);

            ManualDNFEvent manualDnf = new ManualDNFEvent(dnfStartId, "staff");
            UnitDNFEvent   unitDnf   = new UnitDNFEvent(finish, dnfStartId);

            Lap manualDnfLap = new Lap(manualDnf);
            Lap unitDnfLap   = new Lap(unitDnf);

            //a dnf lap should always be slower (bigger) than a finished lap
            Assert.AreEqual(1, manualDnfLap.CompareTo(normalLap));
            Assert.AreEqual(-1, normalLap.CompareTo(manualDnfLap));

            Assert.AreEqual(1, unitDnfLap.CompareTo(normalLap));
            Assert.AreEqual(-1, normalLap.CompareTo(unitDnfLap));

            //dnf laps have no mutual ordering
            Assert.AreEqual(1, manualDnfLap.CompareTo(unitDnfLap));
            Assert.AreEqual(1, unitDnfLap.CompareTo(manualDnfLap));
        }
Beispiel #2
0
        public void OnTimer_ForStart_WitWaitingRider_ShouldMatchWithRider()
        {
            Beacon beacon  = new Beacon(new byte[] { 0, 0, 0, 0, 0, 1 }, 0);
            Rider  martijn = new Rider("Martijn", beacon);

            //rider enters start box
            startId.EmitIdEvent(martijn, new DateTime(2000, 1, 1, 1, 1, 1));

            //rider triggers timing gate
            timer.EmitTriggerEvent(100, "Timer", 0, new DateTime(2000, 1, 1, 1, 1, 1));

            source.Cancel();

            RaceSummary summary = race.Result;
            var         state   = subject.GetState;

            //we expect an EnteredEvent and a TimingEvent, in that order
            Assert.AreEqual(2, summary.Events.Count);

            IdEvent     id    = summary.Events[0] as IdEvent;
            TimingEvent start = summary.Events[1] as TimingEvent;

            Assert.AreEqual(state.onTrack[0].id, id);
            Assert.AreEqual(state.onTrack[0].timer, start);

            Assert.AreEqual("Martijn", start.Rider.Name);
            Assert.AreEqual(100L, start.Microseconds);
            Assert.AreEqual(new DateTime(2000, 1, 1, 1, 1, 1), start.Time);

            Assert.AreEqual(0, state.waiting.Count);
            Assert.AreEqual(0, state.unmatchedIds.Count);
            Assert.AreEqual(0, state.unmatchedTimes.Count);
        }
Beispiel #3
0
        /// <summary>
        /// Get the first time at which the floor position of a given timing group is equal to a given value.
        /// </summary>
        /// <param name="floorposition">The target value of the timing group's floor position.</param>
        /// <param name="timingGroup">The timing group to search in.</param>
        /// <returns>The first time at which the floor postion of group <paramref name="timingGroup"/> is equal to <paramref name="floorposition"/></returns>
        public int GetFirstTimingFromFloorPosition(float floorposition, int timingGroup)
        {
            int maxIndex = timingEventGroups[timingGroup].Length;

            floorposition /= scrollSpeed;

            TimingEvent first = timingEventGroups[timingGroup][0];

            if (first.bpm * (floorposition - first.baseFloorPosition) < 0)
            {
                return(Mathf.RoundToInt((floorposition - first.baseFloorPosition) / first.bpm));
            }

            for (int i = 0; i < maxIndex - 1; i++)
            {
                TimingEvent curr = timingEventGroups[timingGroup][i];
                TimingEvent next = timingEventGroups[timingGroup][i + 1];

                if ((curr.baseFloorPosition < floorposition && next.baseFloorPosition > floorposition) ||
                    (curr.baseFloorPosition > floorposition && next.baseFloorPosition < floorposition))
                {
                    float result = (floorposition - curr.baseFloorPosition) / curr.bpm + curr.timing;
                    return(Mathf.RoundToInt(result));
                }
            }

            TimingEvent last       = timingEventGroups[timingGroup][maxIndex - 1];
            float       lastresult = (floorposition - last.baseFloorPosition) / last.bpm + last.timing;

            return(Mathf.RoundToInt(lastresult));
        }
Beispiel #4
0
        /// <summary>
        /// Create necessary information for a given timing event group, including correct base floor positions.
        /// </summary>
        /// <param name="timingGroups">The raw aff timing components.</param>
        /// <param name="i">The index of the timing group to set up.</param>
        private void SetupTimingGroup(List <List <TimingRaw> > timingGroups, int i)
        {
            var tg = timingGroups[i];

            tg.Sort((item1, item2) => item1.timing.CompareTo(item2.timing));

            timingEventGroups[i] = new TimingEvent[tg.Count];

            timingEventGroups[i][0] = new TimingEvent
            {
                timing            = tg[0].timing,
                baseFloorPosition = 0,
                bpm = tg[0].bpm
            };

            for (int j = 1; j < tg.Count; j++)
            {
                timingEventGroups[i][j] = new TimingEvent
                {
                    timing = tg[j].timing,
                    //Calculate the base floor position
                    baseFloorPosition = tg[j - 1].bpm
                                        * (tg[j].timing - tg[j - 1].timing)
                                        + timingEventGroups[i][j - 1].baseFloorPosition,
                    bpm = tg[j].bpm
                };
            }
        }
Beispiel #5
0
        public void RaceSummary_ReadAndWrite_ShouldBeSymmetric()
        {
            Beacon martijnBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 1 }, 2);

            martijnBeacon.Rssi          = 3;
            martijnBeacon.MeasuredPower = 4;

            Beacon bertBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 5 }, 6);

            bertBeacon.Rssi          = 7;
            bertBeacon.MeasuredPower = 8;

            IdEvent     entered = new IdEvent(new DateTime(2000, 1, 1), new Rider("Martijn", martijnBeacon), "StartId", Direction.Enter);
            TimingEvent timing  = new TimingEvent(new DateTime(2000, 1, 1), new Rider("Bert", bertBeacon), 100, 1);

            TrackerConfig config = new TrackerConfig
            {
                EndMatchTimeout   = 9,
                StartTimingGateId = 10,
                EndTimingGateId   = 11
            };

            RaceSummary subject = new RaceSummary(new List <RaceEvent> {
                entered, timing
            }, config, "StartId", "EndId");

            MemoryStream stream = new MemoryStream();

            subject.WriteSummary(stream);

            stream.Seek(0, SeekOrigin.Begin);

            RaceSummary parsed = RaceSummary.ReadSummary(stream);

            foreach ((Rider r1, Rider r2) in subject.Riders.Zip(parsed.Riders))
            {
                Assert.IsTrue(CompareRiders(r1, r2));
            }

            CollectionAssert.AreEqual(subject.Events.Select(e => e.EventId).ToList(), parsed.Events.Select(e => e.EventId).ToList());
            CollectionAssert.AreEqual(subject.Events.Select(e => e.GetType()).ToList(), parsed.Events.Select(e => e.GetType()).ToList());

            foreach ((RaceEvent e1, RaceEvent e2) in subject.Events.Zip(parsed.Events))
            {
                Assert.IsTrue(CompareRiders(e1.Rider, e2.Rider));
            }

            Assert.AreEqual("StartId", parsed.StartId);
            Assert.AreEqual("EndId", parsed.EndId);

            Assert.AreEqual(config.StartTimingGateId, parsed.Config.StartTimingGateId);
            Assert.AreEqual(config.EndTimingGateId, parsed.Config.EndTimingGateId);
            Assert.AreEqual(config.EndMatchTimeout, parsed.Config.EndMatchTimeout);
        }
Beispiel #6
0
        public virtual void TestEivlTsFull()
        {
            PhysicalQuantity low = new PhysicalQuantity(new BigDecimal("120"), Ca.Infoway.Messagebuilder.Domainvalue.Basic.UnitsOfMeasureCaseSensitive
                                                        .CENTIMETRE);
            PhysicalQuantity high = new PhysicalQuantity(new BigDecimal("170"), Ca.Infoway.Messagebuilder.Domainvalue.Basic.UnitsOfMeasureCaseSensitive
                                                         .CENTIMETRE);
            Interval <PhysicalQuantity> ivl         = IntervalFactory.CreateLowHigh(low, high);
            TimingEvent timingEvent                 = Ca.Infoway.Messagebuilder.Domainvalue.Basic.TimingEvent.ACM;
            EventRelatedPeriodicIntervalTime @event = new EventRelatedPeriodicIntervalTime(ivl, timingEvent);
            string result = new EivlTsR2PropertyFormatter().Format(CreateContext("EIVL<TS>"), new EIVLImpl <EventRelatedPeriodicIntervalTime
                                                                                                            >(@event));

            Assert.IsTrue(this.result.IsValid());
            AssertXml("xml output", "<eventRelatedPeriod><event code=\"ACM\" codeSystem=\"2.16.840.1.113883.5.139\" codeSystemName=\"TimingEvent\" displayName=\"Acm\"/><offset><low unit=\"cm\" value=\"120\"/><high unit=\"cm\" value=\"170\"/></offset></eventRelatedPeriod>"
                      , result, true);
        }
Beispiel #7
0
        public void CompareTo_ShouldConsiderPernalties()
        {
            Beacon martijnBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 1 }, 2);
            Rider  martijn       = new Rider("Martijn", martijnBeacon);

            //make a fast lap with loads of penalties
            IdEvent     startId     = new IdEvent(DateTime.Now, martijn, "StartId", Direction.Enter);
            TimingEvent startTiming = new TimingEvent(DateTime.Now, martijn, 100, 0);
            IdEvent     endId       = new IdEvent(DateTime.Now, martijn, "EndId", Direction.Enter);
            TimingEvent endTiming   = new TimingEvent(DateTime.Now, martijn, 200, 1);

            FinishedEvent fastFinish = new FinishedEvent(startId, startTiming, endTiming, endId);

            Lap fast = new Lap(fastFinish);

            fast.AddPenalties(new List <PenaltyEvent>
            {
                new PenaltyEvent(DateTime.Now, martijn, "reason", 1, "staff"),
                new PenaltyEvent(DateTime.Now, martijn, "reason", 2, "staff")
            });

            //make a slower lap without penalties
            IdEvent     slowStartId     = new IdEvent(DateTime.Now, martijn, "StartId", Direction.Enter);
            TimingEvent slowStartTiming = new TimingEvent(DateTime.Now, martijn, 100, 0);
            IdEvent     slowEndId       = new IdEvent(DateTime.Now, martijn, "EndId", Direction.Enter);
            TimingEvent slowEndTiming   = new TimingEvent(DateTime.Now, martijn, 300, 1);

            FinishedEvent slowFinish = new FinishedEvent(slowStartId, slowStartTiming, slowEndTiming, slowEndId);

            Lap slow = new Lap(slowFinish);

            //without penalties the lap time should dictate the ordering
            Assert.AreEqual(1, slow.CompareTo(fast, false));
            Assert.AreEqual(-1, fast.CompareTo(slow, false));

            //with penalties the slower lap is actually faster
            Assert.AreEqual(-1, slow.CompareTo(fast, true));
            Assert.AreEqual(1, fast.CompareTo(slow, true));

            //the default should take penalties into account
            Assert.AreEqual(-1, slow.CompareTo(fast));
            Assert.AreEqual(1, fast.CompareTo(slow));
        }
Beispiel #8
0
        public void CompareTo_ShouldConsiderDSQOnFinshedLaps()
        {
            Beacon martijnBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 1 }, 2);
            Rider  martijn       = new Rider("Martijn", martijnBeacon);

            //make a fast lap
            IdEvent     startId     = new IdEvent(DateTime.Now, martijn, "StartId", Direction.Enter);
            TimingEvent startTiming = new TimingEvent(DateTime.Now, martijn, 100, 0);
            IdEvent     endId       = new IdEvent(DateTime.Now, martijn, "EndId", Direction.Enter);
            TimingEvent endTiming   = new TimingEvent(DateTime.Now, martijn, 200, 1);

            FinishedEvent fastFinish = new FinishedEvent(startId, startTiming, endTiming, endId);

            Lap fast = new Lap(fastFinish);

            //make a slower lap without penalties
            IdEvent     slowStartId     = new IdEvent(DateTime.Now, martijn, "StartId", Direction.Enter);
            TimingEvent slowStartTiming = new TimingEvent(DateTime.Now, martijn, 100, 0);
            IdEvent     slowEndId       = new IdEvent(DateTime.Now, martijn, "EndId", Direction.Enter);
            TimingEvent slowEndTiming   = new TimingEvent(DateTime.Now, martijn, 300, 1);

            FinishedEvent slowFinish = new FinishedEvent(slowStartId, slowStartTiming, slowEndTiming, slowEndId);

            Lap slow = new Lap(slowFinish);

            //when both are not DSQ the lap time should decide the order
            Assert.AreEqual(1, slow.CompareTo(fast));
            Assert.AreEqual(-1, fast.CompareTo(slow));

            fast.SetDsq(new DSQEvent(DateTime.Now, martijn, "staff", "reason"));

            //the faster lap has a DSQ, so it should be considered slower
            Assert.AreEqual(-1, slow.CompareTo(fast));
            Assert.AreEqual(1, fast.CompareTo(slow));

            slow.SetDsq(new DSQEvent(DateTime.Now, martijn, "staff", "reason"));

            //both are now DSQ lap time should decide order again
            Assert.AreEqual(1, slow.CompareTo(fast));
            Assert.AreEqual(-1, fast.CompareTo(slow));
        }
Beispiel #9
0
        public void OnEndId_WithDifferentRiderOnTrack_ShouldIgnoreEvent()
        {
            Beacon martijnBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 1 }, 0);
            Rider  martijn       = new Rider("Martijn", martijnBeacon);

            Beacon richardBeacon = new Beacon(new byte[] { 0, 0, 0, 0, 0, 2 }, 0);
            Rider  richard       = new Rider("Richard", richardBeacon);

            //rider enters start box
            startId.EmitIdEvent(martijn, new DateTime(2000, 1, 1, 1, 1, 1));

            //rider triggers timing gate
            timer.EmitTriggerEvent(100, "Timer", 0, new DateTime(2000, 1, 1, 1, 1, 1));

            //rider not on track triggers end id
            endId.EmitIdEvent(richard, new DateTime(2000, 1, 1, 1, 1, 1));

            source.Cancel();

            RaceSummary summary = race.Result;
            var         state   = subject.GetState;

            //we expect only the events for Martijn tto be recorded
            Assert.AreEqual(2, summary.Events.Count);

            IdEvent     id    = summary.Events[0] as IdEvent;
            TimingEvent start = summary.Events[1] as TimingEvent;

            Assert.AreEqual(state.onTrack[0].id, id);
            Assert.AreEqual(state.onTrack[0].timer, start);

            Assert.AreEqual("Martijn", start.Rider.Name);
            Assert.AreEqual(100L, start.Microseconds);
            Assert.AreEqual(new DateTime(2000, 1, 1, 1, 1, 1), start.Time);

            //no riders should be waiting at the start.
            //no end times or ids shoudl be waiting to be matched
            Assert.AreEqual(0, state.waiting.Count);
            Assert.AreEqual(0, state.unmatchedIds.Count);
            Assert.AreEqual(0, state.unmatchedTimes.Count);
        }
Beispiel #10
0
        public void OnTimer_ForEnd_WithoutRiderLeft_ShouldSaveEvent()
        {
            //1 is the end gate
            timer.EmitTriggerEvent(100, "Timer", 1, new DateTime(2000, 1, 1, 1, 1, 1));

            source.Cancel();

            RaceSummary summary = race.Result;
            var         state   = subject.GetState;

            //It is possible for the end timing gate to be triggered before the rider id is caught be the end id unit
            //save the timer event for later matching
            Assert.AreEqual(1, summary.Events.Count);

            //the state should match the summary
            TimingEvent end = summary.Events[0] as TimingEvent;

            Assert.AreEqual(state.unmatchedTimes[0], end);

            Assert.AreEqual(null, end.Rider); //a lone timer event cannot have a rider
            Assert.AreEqual(100L, end.Microseconds);
            Assert.AreEqual(new DateTime(2000, 1, 1, 1, 1, 1), end.Time);
        }
Beispiel #11
0
 public EventRelatedPeriodicIntervalTime(Interval <PhysicalQuantity> offset, TimingEvent timingEvent)
 {
     Offset = offset;
     Event  = timingEvent;
 }
Beispiel #12
0
 private bool EventShouldOccur(TimingEvent e, float previousTime, float currentTime)
 {
     return((e.time > previousSourceTime) && (e.time <= currentTime));
 }
 public ITrackerTimingEvent CreateTimingEvent(string categoryName, string action, string label)
 {
     return(TimingEvent.Create(elapsed => SendTiming(categoryName, action, label, (long)elapsed.TotalMilliseconds)));
 }