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;*/ }
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()); } }