Beispiel #1
0
        public void Unlink(ref ExtVehicle extVehicle)
        {
#if DEBUG
            if (DebugSwitch.VehicleLinkingToSegmentEnd.Get())
            {
                Log._Debug(
                    $"ExtVehicleManager.Unlink({extVehicle.vehicleId}) called: Unlinking vehicle " +
                    $"from all segment ends\nstate:{extVehicle}");
            }

            ushort prevSegmentId = extVehicle.currentSegmentId;
            bool   prevStartNode = extVehicle.currentStartNode;
#endif
            extVehicle.lastPositionUpdate = Now();

            if (extVehicle.previousVehicleIdOnSegment != 0)
            {
                ExtVehicles[extVehicle.previousVehicleIdOnSegment].nextVehicleIdOnSegment =
                    extVehicle.nextVehicleIdOnSegment;
            }
            else if (extVehicle.currentSegmentId != 0)
            {
                IExtSegmentEndManager segmentEndMan = Constants.ManagerFactory.ExtSegmentEndManager;
                int endIndex = segmentEndMan.GetIndex(
                    extVehicle.currentSegmentId,
                    extVehicle.currentStartNode);
                if (segmentEndMan.ExtSegmentEnds[endIndex].firstVehicleId == extVehicle.vehicleId)
                {
                    segmentEndMan.ExtSegmentEnds[endIndex].firstVehicleId =
                        extVehicle.nextVehicleIdOnSegment;
                }
                else
                {
                    Log.Error(
                        $"ExtVehicleManager.Unlink({extVehicle.vehicleId}): Unexpected first " +
                        $"vehicle on segment {extVehicle.currentSegmentId}: " +
                        $"{segmentEndMan.ExtSegmentEnds[endIndex].firstVehicleId}");
                }
            }

            if (extVehicle.nextVehicleIdOnSegment != 0)
            {
                ExtVehicles[extVehicle.nextVehicleIdOnSegment].previousVehicleIdOnSegment =
                    extVehicle.previousVehicleIdOnSegment;
            }

            extVehicle.nextVehicleIdOnSegment     = 0;
            extVehicle.previousVehicleIdOnSegment = 0;

            extVehicle.currentSegmentId = 0;
            extVehicle.currentStartNode = false;
            extVehicle.currentLaneIndex = 0;

            extVehicle.lastPathId            = 0;
            extVehicle.lastPathPositionIndex = 0;

#if DEBUG
            if (DebugSwitch.PedestrianPathfinding.Get())
            {
                string vehicleChainDebugInfo =
                    ExtSegmentEndManager.Instance.GenerateVehicleChainDebugInfo(
                        prevSegmentId,
                        prevStartNode);
                Log._Debug(
                    $"ExtVehicleManager.Unlink({extVehicle.vehicleId}) finished: Unlinked vehicle " +
                    $"from all segment ends\nstate:{extVehicle}\nold segment end vehicle chain: " +
                    vehicleChainDebugInfo);
            }
#endif
        }
Beispiel #2
0
        public void UpdatePosition(ref ExtVehicle extVehicle,
                                   ref Vehicle vehicleData,
                                   ref ExtSegmentEnd segEnd,
                                   ref PathUnit.Position curPos,
                                   ref PathUnit.Position nextPos)
        {
#if DEBUG
            bool logVehicleLinking = DebugSwitch.VehicleLinkingToSegmentEnd.Get();
#else
            const bool logVehicleLinking = false;
#endif
            if (logVehicleLinking)
            {
                Log._Debug($"ExtVehicleManager.UpdatePosition({extVehicle.vehicleId}) called: {extVehicle}");
            }

            if ((extVehicle.flags & ExtVehicleFlags.Spawned) == ExtVehicleFlags.None)
            {
                if (logVehicleLinking)
                {
                    Log._Debug(
                        $"ExtVehicleManager.UpdatePosition({extVehicle.vehicleId}): Vehicle is not yet spawned.");
                }

                OnSpawn(ref extVehicle, ref vehicleData);
            }

            if (extVehicle.nextSegmentId != nextPos.m_segment ||
                extVehicle.nextLaneIndex != nextPos.m_lane)
            {
                extVehicle.nextSegmentId = nextPos.m_segment;
                extVehicle.nextLaneIndex = nextPos.m_lane;
            }

            bool startNode = IsTransitNodeCurStartNode(ref curPos, ref nextPos);

            if (extVehicle.currentSegmentId != segEnd.segmentId ||
                extVehicle.currentStartNode != segEnd.startNode ||
                extVehicle.currentLaneIndex != curPos.m_lane)
            {
                if (logVehicleLinking)
                {
                    Log._Debug(
                        $"ExtVehicleManager.UpdatePosition({extVehicle.vehicleId}): " +
                        $"Current segment end changed. seg. {extVehicle.currentSegmentId}, " +
                        $"start {extVehicle.currentStartNode}, lane {extVehicle.currentLaneIndex} -> " +
                        $"seg. {segEnd.segmentId}, start {segEnd.startNode}, lane {curPos.m_lane}");
                }

                if (extVehicle.currentSegmentId != 0)
                {
                    if (logVehicleLinking)
                    {
                        Log._Debug(
                            $"ExtVehicleManager.UpdatePosition({extVehicle.vehicleId}): " +
                            "Unlinking from current segment end");
                    }

                    Unlink(ref extVehicle);
                }

                extVehicle.lastPathId            = vehicleData.m_path;
                extVehicle.lastPathPositionIndex = vehicleData.m_pathPositionIndex;

                extVehicle.waitTime = 0;

#if DEBUGVSTATE
                if (logVehicleLinking)
                {
                    Log._DebugFormat(
                        "ExtVehicleManager.UpdatePosition({0}): Linking vehicle to segment end {1} " +
                        "@ {2} ({3}). Current position: Seg. {4}, lane {5}, offset {6} / " +
                        "Next position: Seg. {7}, lane {8}, offset {9}",
                        extVehicle.vehicleId, segEnd.segmentId, segEnd.startNode, segEnd.nodeId,
                        curPos.m_segment, curPos.m_lane, curPos.m_offset, nextPos.m_segment,
                        nextPos.m_lane, nextPos.m_offset);
                }
#endif
                if (segEnd.segmentId != 0)
                {
                    Link(ref extVehicle, ref segEnd, curPos.m_lane);
                }

                SetJunctionTransitState(ref extVehicle, VehicleJunctionTransitState.Approach);
            }

            if (logVehicleLinking)
            {
                Log._Debug($"ExtVehicleManager.UpdatePosition({extVehicle.vehicleId}) finshed: {extVehicle}");
            }
        }
Beispiel #3
0
        protected void MeasureOutgoingVehicle(bool logDebug,
                                              IDictionary <ushort, uint>[] ret,
                                              bool includeStopped,
                                              uint avgSegmentLength,
                                              ushort vehicleId,
                                              ref Vehicle vehicle,
                                              ref ExtVehicle state,
                                              ref int numProcessed)
        {
            if (logDebug)
            {
                Log._DebugFormat(
                    " MeasureOutgoingVehicle: (Segment {0}, Node {1} (start={2})) Checking vehicle {3}. " +
                    "Coming from seg. {4}, start {5}, lane {6} going to seg. {7}, lane {8}",
                    SegmentId, NodeId, StartNode, vehicleId, state.currentSegmentId,
                    state.currentStartNode, state.currentLaneIndex, state.nextSegmentId, state.nextLaneIndex);
            }

            if ((state.flags & ExtVehicleFlags.Spawned) == ExtVehicleFlags.None)
            {
                Log._DebugIf(
                    logDebug,
                    () => $" MeasureOutgoingVehicle: Vehicle {vehicleId} is unspawned. Ignoring.");
                return;
            }

#if DEBUG
            if (state.currentSegmentId != SegmentId || state.currentStartNode != StartNode)
            {
                if (logDebug)
                {
                    Log._Debug(
                        $" MeasureOutgoingVehicle: (Segment {SegmentId}, Node {NodeId} " +
                        $"(start={StartNode})) Vehicle {vehicleId} error: Segment end mismatch! {state}");
                }

                return;
            }
#endif

            if (state.nextSegmentId == 0)
            {
                if (logDebug)
                {
                    Log._Debug($" MeasureOutgoingVehicle: (Segment {SegmentId}, Node {NodeId} " +
                               $"(start={StartNode})) Vehicle {vehicleId}: Ignoring vehicle");
                }

                return;
            }

            if (state.currentLaneIndex >= ret.Length ||
                !ret[state.currentLaneIndex].ContainsKey(state.nextSegmentId))
            {
                if (logDebug)
                {
                    Log._DebugFormat(
                        " MeasureOutgoingVehicle: (Segment {0}, Node {1} (start={2})) Vehicle {3} is " +
                        "on lane {4} and wants to go to segment {5} but one or both are invalid: {6}",
                        SegmentId, NodeId, StartNode, vehicleId, state.currentLaneIndex,
                        state.nextSegmentId, ret.CollectionToString());
                }

                return;
            }

            if (!includeStopped && vehicle.GetLastFrameVelocity().sqrMagnitude
                < GlobalConfig.Instance.PriorityRules.MaxStopVelocity
                * GlobalConfig.Instance.PriorityRules.MaxStopVelocity)
            {
                if (logDebug)
                {
                    Log._DebugFormat(
                        "  MeasureOutgoingVehicle: (Segment {0}, Node {1}) Vehicle {2}: too slow ({3})",
                        SegmentId, NodeId, vehicleId, vehicle.GetLastFrameVelocity().sqrMagnitude);
                }

                ++numProcessed;
                return;
            }


            uint normLength = 10u;

            if (avgSegmentLength > 0)
            {
                // TODO +1 because the vehicle length calculation for trains/monorail in the method VehicleState.OnVehicleSpawned returns 0 (or a very small number maybe?)
                normLength = Math.Min(100u, (uint)(Math.Max(1u, state.totalLength) * 100u) / avgSegmentLength) + 1;
            }

            if (logDebug)
            {
                Log._DebugFormat(
                    "  MeasureOutgoingVehicle: (Segment {0}, Node {1}) NormLength of vehicle {2}: " +
                    "{3} -> {4} (avgSegmentLength={5})",
                    SegmentId, NodeId, vehicleId, state.totalLength, normLength, avgSegmentLength);
            }

            ret[state.currentLaneIndex][state.nextSegmentId] += normLength;
            ++numProcessed;

            if (logDebug)
            {
                Log._DebugFormat(
                    "  MeasureOutgoingVehicle: (Segment {0}, Node {1}) Vehicle {2}: ***ADDED*** " +
                    "({3}@{4} -> {5}@{6})!",
                    SegmentId, NodeId, vehicleId, state.currentSegmentId, state.currentLaneIndex,
                    state.nextSegmentId, state.nextLaneIndex);
            }
        }