Exemplo n.º 1
0
        private void PushConsistSpeedLimit(TrainCar loco)
        {
            var length  = loco.trainset.OverallLength();
            var lastCar = TrainsetUtils.CarAtEnd(loco, loco.GetComponent <LocoControllerBase>().reverser < 0);
            var bogie   = lastCar.Bogies[0];

            if (bogie.track == null)
            {
                return;
            }
            var startLimit       = TrackFollower.GetSpeedLimit(bogie.track, bogie.traveller.Span, bogie.trackDirection >= 0) ?? 0f;
            var intraTrainLimits = TrackFollower.FollowTrack(bogie.track, bogie.traveller.Span, bogie.trackDirection * length)
                                   .ResolveJunctionSpeedLimits()
                                   .TakeWhile(ev => ev.span < length)
                                   .OfType <SpeedLimitEvent>()
                                   .Select(ev => ev.limit);
            var limits = (startLimit > 0f ? intraTrainLimits.Prepend((int)startLimit) : intraTrainLimits).ToArray();

            Main.DebugLog($"limits affecting train: {string.Join(",", limits)}");
            if (limits.Length > 0)
            {
                tablet !.SetSpeedMax(limits.Last());
                tablet !.SetSpeedLimitConsist(limits.Min());
            }
        }
Exemplo n.º 2
0
        private void PushEvents(TrainCar loco)
        {
            var bogie = loco.Bogies[1];

            if (bogie.track == null)
            {
                return;
            }
            var direction = bogie.trackDirection;

            if (loco.GetComponent <LocoControllerBase>().reverser < 0)
            {
                direction *= -1;
            }

            var prevGradeEvent = TrackFollower.GetGrade(bogie.track, bogie.traveller.Span, direction >= 0);

            var events = TrackFollower.FollowTrack(bogie.track, bogie.traveller.Span, direction * double.PositiveInfinity)
                         .ResolveJunctionSpeedLimits()
                         .FilterRedundantSpeedLimits()
                         .FilterGradeEvents(prevGradeEvent?.grade ?? 0f)
                         .TakeWhile(ev => ev.span < Main.settings.trackInfoSettings.maxEventSpan)
                         .ToArray();

            var speedEvents = events.OfType <SpeedLimitEvent>().Select(ev => ((float)ev.span, (float)ev.limit)).ToArray();

            tablet !.SetTrackSpeedItems(speedEvents);

            var gradeEvents = prevGradeEvent != null
                ? events.OfType <GradeEvent>().Prepend(new GradeEvent(-prevGradeEvent.span, true, prevGradeEvent.grade))
                : events.OfType <GradeEvent>();

            Main.DebugLog($"relevant grade events: {string.Join(",", gradeEvents)}");
            var gradeItems = gradeEvents
                             .Zip(
                gradeEvents.Skip(1),
                (a, b) => ((float)a.span, a.grade * 10, (float)(b.span - a.span)))
                             .Where(item => (int)item.Item2 != 0);

            Main.DebugLog($"setting grade items: {string.Join(",", gradeItems)}");
            tablet.SetTrackGradeItems(gradeItems);

            var nextJunction = events.OfType <JunctionEvent>().Select(ev => ev.junction).FirstOrDefault();

            if (nextJunction != default)
            {
                tablet.SetNextJunction(nextJunction);
                tablet.SetNextWyeDir(nextJunction.selectedBranch == 0 ? 1 : -1);
            }
            else
            {
                tablet.SetNextWyeDir(0);
            }
        }
Exemplo n.º 3
0
        private static void DrawConsistSpeedLimit()
        {
            if (Instance == null)
            {
                return;
            }
            if (sortedTrainSet == null)
            {
                return;
            }

            scanCar   = scanDir > 0 ? sortedTrainSet.cars.Last().trainCar : sortedTrainSet.cars.First().trainCar;
            scanBogie = scanCar.Bogies[(sortedTrainSet[scanCar].forward == (scanDir > 0)) ? 0 : scanCar.Bogies.Length - 1];

            var track = scanBogie.track;

            if (track == null)
            {
                return;
            }

            var startSpan    = scanBogie.traveller.Span;
            var direction    = !(sortedTrainSet[scanCar].forward == (scanDir > 0)) ^ (scanBogie.trackDirection > 0);
            var currentGrade = TrackIndexer.Grade(scanBogie.point1) * (direction ? 1 : -1);

            var events = TrackFollower.FollowTrack(
                track,
                startSpan,
                direction ? trainLength : -trainLength);

            var eventDescriptions = events
                                    .ExceptUnnamedTracks()
                                    .ResolveJunctionSpeedLimits()
                                    .FilterRedundantSpeedLimits()
                                    .FilterGradeEvents(currentGrade)
                                    .Take(Main.settings.maxEventCount)
                                    .TakeWhile(ev => ev.span < trainLength);

            var speeds = eventDescriptions.Where(e => e is SpeedLimitEvent).Cast <SpeedLimitEvent>().Select(s => ((float)s.span, (float)s.limit));
            var limit  = (speeds.Count() > 0) ? speeds.Min(s => s.Item2) : 200;

            limit = Mathf.Min(limit, TrackFollower.GetSpeedLimit(track, startSpan, direction) ?? 0f);
            Instance.SetSpeedLimitConsist(speedLimitConsist = limit);
        }
Exemplo n.º 4
0
        private static void DrawUpcomingEvents()
        {
            if (Instance == null)
            {
                return;
            }
            if (sortedTrainSet == null)
            {
                return;
            }

            scanCar   = scanDir > 0 ? sortedTrainSet.cars.First().trainCar : sortedTrainSet.cars.Last().trainCar;
            scanBogie = scanCar.Bogies[(sortedTrainSet[scanCar].forward == (scanDir > 0)) ? scanCar.Bogies.Length - 1 : 0];

            var track = scanBogie.track;

            if (track == null)
            {
                return;
            }

            var startSpan    = scanBogie.traveller.Span;
            var direction    = !(sortedTrainSet[scanCar].forward == (scanDir > 0)) ^ (scanBogie.trackDirection > 0);          // !(scanDir >= 0f) ^ (scanBogie.trackDirection > 0);
            var currentGrade = TrackIndexer.Grade(scanBogie.point1) * (direction ? 1 : -1);
            var scanDistance = Instance.TrackPlannerDisplayDistance + 100;

            var events = TrackFollower.FollowTrack(
                track,
                startSpan,
                direction ? scanDistance : -scanDistance);

            var eventDescriptions = events
                                    .ExceptUnnamedTracks()
                                    .ResolveJunctionSpeedLimits()
                                    .FilterRedundantSpeedLimits()
                                    .FilterGradeEvents(currentGrade)
                                    .Take(Main.settings.maxEventCount)
                                    .TakeWhile(ev => ev.span < Main.settings.maxEventSpan);

            IEnumerable <(float span, float limit)> trackSpeedEvents = eventDescriptions.Where(e => e is SpeedLimitEvent).Cast <SpeedLimitEvent>().Select(s => ((float)s.span, (float)s.limit));
            var nextSpeedEvents = trackSpeedEvents.Where(e => e.span < 250);



            (float span, float limit)nextForSpan  = trackSpeedEvents.Aggregate((a, b) => a.span < b.span ? a : b);
            (float span, float limit)nextForLimit = trackSpeedEvents.Aggregate((a, b) => a.limit < b.limit ? a : b);

            float lerpVal  = Mathf.Clamp01(nextForLimit.span * 0.002f);
            float maxSpeed = Mathf.Min(Mathf.Lerp(nextForLimit.limit, speedLimitConsist, lerpVal), speedLimitConsist);

            Instance.SetSpeedMax(maxSpeed);

            if (nextForSpan.span <= 0.1f)
            {
                Instance.SetSpeedLimitNext(currentSpeedLimitNext = nextForSpan.limit);
            }
            if (currentSpeedLimitNext > nextForLimit.limit)
            {
                Instance.SetSpeedLimitNext(currentSpeedLimitNext = nextForLimit.limit);
            }



            Instance.SetTrackSpeedItems(trackSpeedEvents.ToArray());

            Instance.SetTrackGradeItems(eventDescriptions.Where(e => e is GradeEvent).Cast <GradeEvent>().Select(s => ((float)s.span, (float)s.grade * 10, -1f)).ToArray());

            var      junctionEvents = eventDescriptions.Where(e => e is JunctionEvent);
            Junction?nextJunction   = null;

            if (junctionEvents.Any())
            {
                nextJunction = ((JunctionEvent)junctionEvents.Aggregate((a, b) => a.span < b.span ? a : b)).junction;
                Instance.SetTrackJunctionItems(junctionEvents.Cast <JunctionEvent>().Select(s => ((float)(s.span - 1.3), (float)0)).ToArray());
            }
            Instance.NextJunction = nextJunction;
            Instance.SetNextWyeDir((nextJunction == null) ? WyeDirection.NA : (nextJunction.selectedBranch == 0) ? WyeDirection.Left : WyeDirection.Right);
        }