GetSegmentGeometry() static private method

static private GetSegmentGeometry ( ushort segmentId ) : TrafficManager.Custom.Misc.SegmentGeometry
segmentId ushort
return TrafficManager.Custom.Misc.SegmentGeometry
        public static bool ShouldRecalculatePath(ushort vehicleId, ref Vehicle vehicleData, int maxBlockCounter)
        {
            if (vehicleData.m_leadingVehicle != 0)
            {
                return(false);
            }
            if ((vehicleData.m_flags & Vehicle.Flags.Emergency2) == Vehicle.Flags.None)
            {
                return(false);
            }
            if (!Options.dynamicPathRecalculation)
            {
                return(false);
            }
            if (TrafficPriority.GetVehiclePosition(vehicleId).LastPathRecalculation >= GetVehiclePathRecalculationFrame())
            {
                return(false);
            }
            if (vehicleData.m_path != 0)
            {
                PathUnit.Position pos = Singleton <PathManager> .instance.m_pathUnits.m_buffer[vehicleData.m_path].GetPosition(vehicleData.m_pathPositionIndex >> 1);
                if (pos.m_segment != 0)
                {
                    bool isHighway = CustomRoadAI.GetSegmentGeometry(pos.m_segment).IsHighway();
                    if (isHighway)
                    {
                        return(false);                        // no recalculation on highways
                    }
                }
            }

            return(vehicleData.m_blockCounter >= MIN_BLOCK_COUNTER_PATH_RECALC_VALUE);

            /*float recalcDecisionValue = Math.Max(0.005f, ((float)vehicleData.m_blockCounter - (float)MIN_BLOCK_RECALC_VALUE) / ((float)maxBlockCounter - (float)MIN_BLOCK_RECALC_VALUE));
             * float bias = 1f;
             * switch (Options.simAccuracy) {
             *      case 1:
             *              bias = 1.25f;
             *              break;
             *      case 2:
             *              bias = 1.5f;
             *              break;
             *      case 3:
             *              bias = 2f;
             *              break;
             *      case 4:
             *              bias = 3f;
             *              break;
             * }
             * //Log._Debug($"Path recalculation for vehicle {vehicleId}: recalcDecisionValue={recalcDecisionValue} bias={bias}");
             * recalcDecisionValue *= bias;
             * return UnityEngine.Random.Range(0f, 1f) < recalcDecisionValue;*/
        }
示例#2
0
        private static void GetCustomTrafficLightState(ushort vehicleId, ref Vehicle vehicleData, ushort nodeId, ushort fromSegmentId, ushort toSegmentId, out RoadBaseAI.TrafficLightState vehicleLightState, out RoadBaseAI.TrafficLightState pedestrianLightState, TrafficLightSimulation nodeSim = null)
        {
            if (nodeSim == null)
            {
                nodeSim = TrafficLightSimulation.GetNodeSimulation(nodeId);
                if (nodeSim == null)
                {
                    Log.Error($"GetCustomTrafficLightState: node traffic light simulation not found at node {nodeId}! Vehicle {vehicleId} comes from segment {fromSegmentId} and goes to node {nodeId}");
                    throw new ApplicationException($"GetCustomTrafficLightState: node traffic light simulation not found at node {nodeId}! Vehicle {vehicleId} comes from segment {fromSegmentId} and goes to node {nodeId}");
                }
            }

            // get vehicle position

            /*VehiclePosition vehiclePos = TrafficPriority.GetVehiclePosition(vehicleId);
             * if (!vehiclePos.Valid || vehiclePos.FromSegment != fromSegmentId || vehiclePos.ToNode != nodeId) {
             *      Log._Debug($"GetTrafficLightState: Recalculating position for vehicle {vehicleId}! FromSegment={vehiclePos.FromSegment} Valid={vehiclePos.Valid}");
             *      try {
             *              HandleVehicle(vehicleId, ref Singleton<VehicleManager>.instance.m_vehicles.m_buffer[vehicleId], false, false);
             *      } catch (Exception e) {
             *              Log.Error("VehicleAI GetTrafficLightState Error: " + e.ToString());
             *      }
             * }
             *
             * if (!vehiclePos.Valid || vehiclePos.FromSegment != fromSegmentId || vehiclePos.ToNode != nodeId) {
             *      Log.Warning($"GetTrafficLightState: Vehicle {vehicleId} is not moving at segment {fromSegmentId} to node {nodeId}! FromSegment={vehiclePos.FromSegment} ToNode={vehiclePos.ToNode} Valid={vehiclePos.Valid}");
             *      vehicleLightState = RoadBaseAI.TrafficLightState.Red;
             *      pedestrianLightState = RoadBaseAI.TrafficLightState.Red;
             *      return;
             * }*/

            // get vehicle type
            ExtVehicleType?vehicleType = CustomVehicleAI.DetermineVehicleTypeFromVehicle(vehicleId, ref vehicleData);

            if (vehicleData.Info.m_vehicleType == VehicleInfo.VehicleType.Tram && vehicleType != ExtVehicleType.Tram)
            {
                Log.Warning($"vehicleType={vehicleType} ({(int)vehicleType}) for Tram");
            }
            //Log._Debug($"GetCustomTrafficLightState: Vehicle {vehicleId} is a {vehicleType}");
            if (vehicleType == null)
            {
                Log.Warning($"GetTrafficLightState: Could not determine vehicle type of vehicle {vehicleId}!");
                vehicleLightState    = RoadBaseAI.TrafficLightState.Red;
                pedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

            // get responsible traffic light
            CustomSegmentLights lights = CustomTrafficLights.GetSegmentLights(nodeId, fromSegmentId);
            CustomSegmentLight  light  = lights == null ? null : lights.GetCustomLight((ExtVehicleType)vehicleType);

            if (lights == null || light == null)
            {
                Log.Warning($"GetTrafficLightState: No custom light for vehicleType {vehicleType} @ node {nodeId}, segment {fromSegmentId} found. lights null? {lights == null} light null? {light == null}");
                vehicleLightState    = RoadBaseAI.TrafficLightState.Red;
                pedestrianLightState = RoadBaseAI.TrafficLightState.Red;
                return;
            }

            SegmentGeometry geometry = CustomRoadAI.GetSegmentGeometry(fromSegmentId);

            // get traffic light state from responsible traffic light
            if (geometry.IsLeftSegment(toSegmentId, nodeId))
            {
                vehicleLightState = light.GetLightLeft();
            }
            else if (geometry.IsRightSegment(toSegmentId, nodeId))
            {
                vehicleLightState = light.GetLightRight();
            }
            else
            {
                vehicleLightState = light.GetLightMain();
            }

            // get traffic lights state for pedestrians
            pedestrianLightState = (lights.PedestrianLightState != null) ? (RoadBaseAI.TrafficLightState)lights.PedestrianLightState : RoadBaseAI.TrafficLightState.Red;
        }
        public void CustomSegmentSimulationStep(ushort segmentID, ref NetSegment data)
        {
            if (initDone)
            {
                CustomRoadAI.GetSegmentGeometry(segmentID).VerifySegmentsByCount();

                try {
                    TrafficPriority.segmentHousekeeping(segmentID);
                } catch (Exception e) {
                    Log.Error($"Error occured while housekeeping segment {segmentID}: " + e.ToString());
                }

                if (!Options.isStockLaneChangerUsed())
                {
                    try {
                        InStartupPhase = simStartFrame == 0 || simStartFrame >> 14 >= Singleton <SimulationManager> .instance.m_currentFrameIndex >> 14;                       // approx. 3 minutes

                        // calculate traffic density
                        uint curLaneId    = data.m_lanes;
                        int  nextNumLanes = data.Info.m_lanes.Length;
                        uint laneIndex    = 0;
                        bool resetDensity = false;
                        uint maxDensity   = 0u;
                        uint densitySum   = 0u;
                        while (laneIndex < nextNumLanes && curLaneId != 0u)
                        {
                            uint currentDensity = currentLaneDensities[curLaneId];
                            if (maxDensity == 0 || currentDensity > maxDensity)
                            {
                                maxDensity = currentDensity;
                            }
                            densitySum += currentDensity;

                            laneIndex++;
                            curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane;
                        }
                        if (maxDensity > 250)
                        {
                            resetDensity = true;
                        }

                        curLaneId = data.m_lanes;
                        laneIndex = 0;
                        while (laneIndex < nextNumLanes && curLaneId != 0u)
                        {
                            uint buf            = currentLaneTrafficBuffer[curLaneId];
                            uint currentDensity = currentLaneDensities[curLaneId];

                            //currentMeanDensity = (byte)Math.Min(100u, (uint)((currentDensities * 100u) / Math.Max(1u, maxDens))); // 0 .. 100

                            byte currentMeanSpeed = 25;
                            // we use integer division here because it's faster
                            if (buf > 0)
                            {
                                uint currentSpeeds = currentLaneSpeeds[curLaneId];

                                if (!InStartupPhase)
                                {
                                    currentMeanSpeed = (byte)Math.Min(100u, ((currentSpeeds * 100u) / buf) / ((uint)(Math.Max(SpeedLimitManager.GetLockFreeGameSpeedLimit(segmentID, laneIndex, curLaneId, data.Info.m_lanes[laneIndex]) * 8f, 1f))));                                     // 0 .. 100, m_speedLimit of highway is 2, actual max. vehicle speed on highway is 16, that's why we use x*8 == x<<3 (don't ask why CO uses different units for velocity)
                                }
                            }
                            else
                            {
                                if (!InStartupPhase)
                                {
                                    currentMeanSpeed = 100;
                                }
                            }

                            /*if (segmentID == 22980) {
                             *      Log._Debug($"Lane {curLaneId}: currentMeanSpeed={currentMeanSpeed} currentMeanDensity={currentMeanDensity}");
                             * }*/

                            if (currentMeanSpeed >= laneMeanSpeeds[curLaneId])
                            {
                                laneMeanSpeeds[curLaneId] = (byte)Math.Min((int)laneMeanSpeeds[curLaneId] + 10, currentMeanSpeed);
                            }
                            else
                            {
                                laneMeanSpeeds[curLaneId] = (byte)Math.Max((int)laneMeanSpeeds[curLaneId] - 10, 0);
                            }

                            if (densitySum > 0)
                            {
                                laneMeanDensities[curLaneId] = (byte)Math.Min(100u, (currentDensity * 100u) / densitySum);
                            }
                            else
                            {
                                laneMeanDensities[curLaneId] = (byte)0;
                            }
                            currentLaneTrafficBuffer[curLaneId] = 0;
                            currentLaneSpeeds[curLaneId]        = 0;

                            if (resetDensity)
                            {
                                currentLaneDensities[curLaneId] /= 10u;
                            }

                            laneIndex++;
                            curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane;
                        }
                    } catch (Exception e) {
                        Log.Error("Error occured while calculating lane traffic density: " + e.ToString());
                    }
                }
            }
            try {
                OriginalSimulationStep(segmentID, ref data);
            } catch (Exception ex) {
                Log.Error("Error in CustomRoadAI.SimulationStep: " + ex.ToString());
            }
        }